Compare commits

...

340 Commits

Author SHA1 Message Date
Joe Cheng
ab69d7292c Only show the lighter curtain if autoreload is on
I added this cause I'm slightly worried about other server environments
sending the same 1012 close code.
2023-10-18 16:59:54 -07:00
Joe Cheng
36a99287d6 Make autoreload survive laptop suspend
Also simplify the implementation for softening the grey curtain when
autoreload is in progress (only applies to Shiny for Python)
2023-10-18 16:59:18 -07:00
Joe Cheng
6560c59c8f Soften visually jarring greyout when autoreloading
This change detects when Shiny is autoreloading, and instead of
showing the typical disconnection treatment (dark grey), it
initially shows nothing and then quickly fades to very light
grey.

The goal is for instant autoreloads to feel seamless, but longer
autoreloads to make it clear when the autoreload has completed,
and still not feel as jarring as a full disconnect.
2023-10-18 16:58:13 -07:00
Garrick Aden-Buie
68546c319e Increase touch target area of slider input (#3859) 2023-08-07 15:14:35 -04:00
Garrick Aden-Buie
69188fef22 chore(desc): Add GitHub repo to URL (#3864) 2023-08-03 13:20:33 -04:00
Garrick Aden-Buie
6be6dfbfeb Finer-grained control over shiny-provided input bindings (#3861)
Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
Co-authored-by: Joe Cheng <joe@rstudio.com>
Co-authored-by: gadenbuie <gadenbuie@users.noreply.github.com>
2023-07-31 10:41:27 -05:00
Garrick Aden-Buie
6fc06281bd docs(navbarPage): Be less specific about collapsible breakpoint (#3853) 2023-07-07 10:42:39 -04:00
Barret Schloerke
f724128d41 Merge pull request #3850 from rstudio/rc-v1.7.4.1 2023-07-07 09:56:25 -04:00
Barret Schloerke
518ef0f9f8 Merge branch 'main' into rc-v1.7.4.1
* main: (55 commits)
  Catch errors receiving individual input messages (#3843)
  Clarify what's ignored by ignoreNULL (#3827)
  Remove tests/testthat/apps/ (#3841)
  Correctly set width on `textarea` input element (#3838)
  Update selectize.js documentation URLs (#3836)
  test(json digits): Try unsetting option in test to get default behavior (#3837)
  Rebuild docs
  Update README.md
  fix typo in the docs for bindCache (#3825)
  Allow for `shiny:::toJSON()` to respect if `digits` has class `AsIs` to represent `use_signif=` (#3819)
  More complete `downloadButton()` example
  Rename actionQueue to taskQueue, add more context to the NEWS item (#3801)
  Remove unneeded packages from package.json
  Rebuild docs
  Rebuild shiny.js
  Update @types/node
  Rebuild yarn.lock
  Fix brush resetting behavior. Closes #3785
  Bump fastmap dependency to 1.1.1
  Sync package version (GitHub Actions)
  ...
2023-07-07 09:39:01 -04:00
Winston Chang
f5b395485e shiny v1.7.4.1
Remove use of as.numeric_version()
Closes #3849
2023-07-07 09:33:14 -04:00
Garrick Aden-Buie
31aca7aa70 Catch errors receiving individual input messages (#3843) 2023-06-30 17:10:17 -04:00
Garrick Aden-Buie
b38a630224 Clarify what's ignored by ignoreNULL (#3827)
Co-authored-by: gadenbuie <gadenbuie@users.noreply.github.com>
2023-06-30 10:44:43 -04:00
Winston Chang
1b7709411b Remove tests/testthat/apps/ (#3841) 2023-06-16 16:55:14 -05:00
Garrick Aden-Buie
2b48aa0d91 Correctly set width on textarea input element (#3838)
Co-authored-by: gadenbuie <gadenbuie@users.noreply.github.com>
2023-06-12 15:57:49 -04:00
Viviane Girardin
6fdf23752e Update selectize.js documentation URLs (#3836)
Co-authored-by: Neal Richardson <neal.p.richardson@gmail.com>
Co-authored-by: Winston Chang <winston@stdout.org>
2023-06-09 15:43:21 -05:00
Barret Schloerke
8542f5d017 test(json digits): Try unsetting option in test to get default behavior (#3837) 2023-06-09 15:30:02 -05:00
Winston Chang
e7b830755a Rebuild docs 2023-06-01 15:44:18 -05:00
Gordon Shotwell
23c7b0683a Update README.md
Add Discord link
2023-06-01 15:43:20 -05:00
Tom Jemmett
5805895581 fix typo in the docs for bindCache (#3825) 2023-05-23 08:52:42 -05:00
Barret Schloerke
90539bff25 Allow for shiny:::toJSON() to respect if digits has class AsIs to represent use_signif= (#3819) 2023-05-16 16:14:03 -04:00
Winston Chang
62bb21d5b6 Merge pull request #3804 from rstudio/docs/ex-download-button 2023-04-14 15:48:19 -05:00
Garrick Aden-Buie
4f85268d44 More complete downloadButton() example 2023-04-13 09:04:40 -04:00
Carson Sievert
611e517bb8 Rename actionQueue to taskQueue, add more context to the NEWS item (#3801) 2023-03-31 14:38:28 -05:00
Winston Chang
4d05a568c1 Remove unneeded packages from package.json 2023-03-06 17:01:43 -06:00
Winston Chang
1330325519 Rebuild docs 2023-03-01 21:38:10 -06:00
Winston Chang
92d850efa6 Rebuild shiny.js 2023-03-01 21:26:59 -06:00
Winston Chang
7bf56125eb Update @types/node 2023-03-01 21:26:59 -06:00
Winston Chang
69f861cc8a Rebuild yarn.lock 2023-03-01 21:20:56 -06:00
Winston Chang
a94be7b128 Fix brush resetting behavior. Closes #3785 2023-03-01 20:58:26 -06:00
Winston Chang
703766fb2e Merge pull request #3782 from rstudio/plot-interact-init 2023-02-24 16:59:42 -06:00
Winston Chang
8e73749e21 Bump fastmap dependency to 1.1.1 2023-02-24 10:30:07 -06:00
wch
dc8ffa115b Sync package version (GitHub Actions) 2023-02-23 20:32:23 +00:00
Winston Chang
a0385da0d7 Rebuild shiny.js 2023-02-23 14:18:21 -06:00
Winston Chang
a6b7dee4cd Send initial values for plot interaction 2023-02-23 14:14:01 -06:00
Winston Chang
f9ff5c2637 Bump version to 1.7.4.9002 2023-01-25 11:19:40 -06:00
Winston Chang
6a1fbc57f4 Clarify comments 2023-01-25 11:18:20 -06:00
Winston Chang
38337a926f Ensure that reactiveValues keys and values are sorted (#3774) 2023-01-25 11:10:05 -06:00
Winston Chang
bf6b87886c Merge pull request #3775 from rstudio/map-loadtime 2023-01-24 13:55:37 -06:00
Winston Chang
33e6b0a305 Add on_load function for registering expressions to run on load 2023-01-23 17:25:26 -06:00
Winston Chang
cb5eac052f Initialize Map objects at load time instead of build time 2023-01-23 16:26:44 -06:00
Winston Chang
39fee3782f Merge pull request #3772 from rstudio/fix-slider-stoppropagation 2023-01-23 10:59:47 -06:00
Winston Chang
654f30a312 Udpate NEWS 2023-01-20 17:04:21 -06:00
Winston Chang
a763da2b94 Fix stopPropagation error in ion.rangeSlider 2023-01-20 17:00:12 -06:00
Jon Calder
0c177d30dc Fix two typos in insertUI() docs (#3712)
* Fix two typos in insertUI() docs

* document()

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
2023-01-13 11:41:44 -06:00
gsmolinski
20f8a181d4 Change size 'xl' of modalDialog to 'l' if Bootstrap 3 (#3593)
* closes issue #3631 - documenting that 'xl' modal dialog will be changed to 'm' in Bootstrap 3

* Update R/modal.R

adds note about how to switch to Bootstrap 4+ with bslib

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>

* add note about how to use Bootstrap 4+ with bslib to get 'xl' modal dialog

* Update NEWS.md

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
2023-01-12 11:41:49 -06:00
Carson Sievert
eebcf70bb9 Add snapshot test for #3519 (#3520)
* Add snapshot test for https://github.com/rstudio/shiny/issues/3519 which was fixed via https://github.com/rstudio/bslib/pull/372

* sync package version (GitHub Actions)

* yarn build (GitHub Actions)

* `yarn build` (GitHub Actions)

* Sync package version (GitHub Actions)

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2023-01-12 10:38:06 -06:00
Winston Chang
e7d62f55ca Merge pull request #3666 from rstudio/async-load-script-2 2023-01-06 13:47:52 -08:00
Winston Chang
3a4e5f3982 Rebuild JS and CSS 2023-01-06 15:40:58 -06:00
Winston Chang
3381c3a6b9 Bump version to 1.7.4.9001 2023-01-06 15:39:42 -06:00
Winston Chang
e42c920587 Merge branch 'main' into async-load-script-2 2023-01-06 15:39:19 -06:00
Winston Chang
4635665394 Build shiny.js 2022-12-22 11:53:29 -06:00
Winston Chang
08ff066fa3 Append script elements one at a time 2022-12-22 11:53:13 -06:00
Winston Chang
816072fc29 Use Promise.allSettled 2022-12-21 16:40:45 -06:00
Carson Sievert
5eb442aa03 Make ?shiny-package topic internal in pkgdown (#3758)
* Make ?shiny-package help page internal

Otherwise, pkgdown wants it to appear in the reference, which we probably don't want

* Revert "Make ?shiny-package help page internal"

This reverts commit 4ab4cb0e46.

* Use pkgdown's  to drop the shiny-package contents (only in the pkgdown reference)

* Avoid 'incomplete final line' warning when reading pkgdown.yml
2022-12-16 10:05:12 -06:00
Carson Sievert
c32db50585 Run yarn build (#3757)
* Run yarn build

* `devtools::document()` (GitHub Actions)

* Sync package version (GitHub Actions)

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2022-12-15 11:37:11 -06:00
Carson Sievert
1d9dde52df Start new version (#3756) 2022-12-15 11:16:28 -06:00
Carson Sievert
6176f03ad0 v1.7.4 release candidate (#3749)
* Start release candidate

* Get rid of warnings about qplot() usage in tests

* Clean up news

* `yarn build` (GitHub Actions)

* Sync package version (GitHub Actions)

* Remote remotes (htmltools is now in CRAN)

* Change header syntax in NEWS.md (to match what usethis does)

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2022-12-15 11:12:19 -06:00
Winston Chang
0fc1be52eb Render deps before modal or notification element is created 2022-12-13 17:21:59 -06:00
Carson Sievert
f12334e839 Properly check for NaN values upon resizing a brushable image. (#3754)
Regression introduced by https://github.com/rstudio/shiny/pull/3644/files#diff-9aad79e444091956075dc1e1dc5ab9202b5e998f5d441e69f040319b6c00d100L228-L230

JS error discovered by 104-plot-interaction-select (with showcase mode)
2022-12-08 14:32:27 -06:00
Winston Chang
ffb6736f11 Don't add "use strict" to external libraries (#3746)
* Add missing var in loop

* `yarn build` (GitHub Actions)

Co-authored-by: wch <wch@users.noreply.github.com>
2022-12-06 14:17:36 -06:00
Winston Chang
f084d3a34f Merge pull request #3747 from rstudio/eslint-newline-after-var
Remove eslint `newline-after-var rule`
2022-12-06 13:07:43 -06:00
Winston Chang
0fe7cad876 Remove eslint newline-after-var rule 2022-12-05 16:34:23 -06:00
Carson Sievert
ecff638920 Don't supply width/height to the device if they aren't defined (#3740)
* Close #1409: don't supply width/height to the device if they aren't defined

* Update news

* Update unit tests to reflect that plotPNG()/startPNG() now handles NULL dimensions

* Add a note about NULL dimensions on plotPNG() help page

* Update news
2022-12-02 20:27:07 -06:00
Winston Chang
db2ad780c0 Don't ignore errors when loading or executing a script 2022-12-01 17:16:59 -06:00
Winston Chang
5cd848bd28 Await running each action in actionQueue 2022-12-01 17:01:00 -06:00
Carson Sievert
ed6022e3f2 Have renderPlot() error early if height/width of a plot aren't yet defined (#3739)
* Close #3704. Close #3735. Close #1409. Throw informative error in renderPlot() early if height/width of a plot aren't yet defined

* `devtools::document()` (GitHub Actions)

* Add unit tests

* Use consistent filename; add intentional failure (to get artifact uploads)

* Make output id argument name more unique

* Update news

* plotPNG() test isn't worth it

* Don't try to provide a suggestion on how to fix the issue (it's no worse than what we currently have, and we probably should be defaulting to an 'arbitrary' size anyway

* update news

* minimize diff

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2022-11-22 17:23:19 -06:00
Winston Chang
a063540407 Build shiny.js 2022-11-01 21:30:29 -05:00
Winston Chang
aa932532f3 Add sync and async versions of renderContent, renderHtml, renderDependencies 2022-11-01 21:30:15 -05:00
Winston Chang
8160f8c726 Add .d.ts files 2022-10-31 16:51:13 -05:00
Winston Chang
af900d1037 Use actionQueue 2022-10-31 16:51:13 -05:00
Winston Chang
49320e6edd Make HtmlOutputBinding.renderValue an async function 2022-10-31 16:51:13 -05:00
Winston Chang
4308887296 Fix types for message.multiple 2022-10-31 16:51:13 -05:00
Winston Chang
dffd8bc7fd Commit .d.ts files 2022-10-31 16:51:13 -05:00
Winston Chang
554f835293 Make sure not to send input values during dispatchMessage 2022-10-31 16:51:13 -05:00
Winston Chang
50e7b6768d Use async queue to handle incoming messages 2022-10-31 16:51:13 -05:00
Winston Chang
db222af7e0 Make sure dynamic scripts run in order 2022-10-31 16:51:13 -05:00
Winston Chang
5b688707b7 Add await for renderContent() calls 2022-10-31 16:51:13 -05:00
Winston Chang
8dfd8f5b33 Convert renderDependency() to async 2022-10-31 16:51:13 -05:00
Carson Sievert
20cc8e26b5 Use getBoundingClientRect() over offsetHeight/offsetWidth to get more precise sizing (#3720)
* Use getBoundingClientRect() over offsetHeight/offsetWidth to get more precise sizing

* Update news
2022-10-28 15:55:24 -05:00
Carson Sievert
e48e9c6904 Add fill arguments to plotOutput(), imageOutput(), and uiOutput() (#3715)
* Add fill arguments to plotOutput(), imageOutput(), and uiOutput()

* Update news

* Code review

* `devtools::document()` (GitHub Actions)

* `yarn build` (GitHub Actions)

* Sync package version (GitHub Actions)

* Update news

* Update to use bindFillRole()

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2022-10-26 11:52:26 -05:00
Joe Cheng
87c673f283 Bump version to v1.7.3.9000 2022-10-25 18:01:14 -07:00
Joe Cheng
dfaefa8905 Merge tag 'v1.7.3' 2022-10-25 17:59:18 -07:00
Joe Cheng
cd4f406234 Squelch R CMD check message
"Package has help file(s) containing install/render-stage \Sexpr{} expressions but no prebuilt PDF manual."
2022-10-24 18:37:15 -07:00
Joe Cheng
190b542613 Use v1.7.3 instead
Something in our yarn build toolchain doesn't like version numbers
with 4 segments
2022-10-24 16:54:54 -07:00
Joe Cheng
73e48ab5f4 Remove Remotes, add NEWS item 2022-10-24 16:22:42 -07:00
Barret Schloerke
62a95b9ce2 Reverting selectize logic change from #3644 (#3716) 2022-10-24 12:18:00 -04:00
Barret Schloerke
999eb1de3c Add fontawesome remote 2022-10-21 15:47:39 -04:00
Barret Schloerke
55985740de Skip template tests even if shinytest2 is available. Install shinytest2 from CRAN
We will bring these tests back after this release.
We will move shinytest2 to suggests after this release
2022-10-21 15:30:00 -04:00
Barret Schloerke
e82b71da65 Update template code to work with latest shinytest2 2022-10-21 14:54:05 -04:00
Joe Cheng
9ce1e6c549 Fix unit test to be compatible with fontawesome 0.4.0 2022-10-21 11:05:04 -07:00
Winston Chang
cda59da698 Remove types-jquery.patch (#3710)
Co-authored-by: wch <wch@users.noreply.github.com>
Co-authored-by: Barret Schloerke <schloerke@gmail.com>
2022-10-05 10:50:19 -04:00
Winston Chang
51da80d381 Merge pull request #3709 from rstudio/blob 2022-10-03 12:36:29 -05:00
wch
412606c594 yarn build (GitHub Actions) 2022-10-03 17:26:14 +00:00
Winston Chang
da2df5ac58 Use correct type for messages 2022-10-03 12:20:59 -05:00
Winston Chang
98f17e0cd2 Disable eslint rules only within scope 2022-10-03 11:41:28 -05:00
Winston Chang
9b2c04f298 Remove redundant setting 2022-09-30 19:57:03 -05:00
Winston Chang
ed4a97154d Remove makeBlob
Blob has long been available on all major browsers, so makeBlob is no longer needed.
2022-09-30 16:29:38 -05:00
Winston Chang
9dcd62f944 Update eslint 2022-09-30 16:17:19 -05:00
Winston Chang
213c645524 Upgrade esbuild and typescript 2022-09-30 15:59:24 -05:00
Winston Chang
f1c0ac2b30 Upgrade to yarn 3.2.3 2022-09-30 15:57:51 -05:00
Barret Schloerke
16c6d55f60 Enable TypeScript strict mode (#3644) 2022-09-29 16:03:05 -04:00
Hedley
6e40a3dd39 Update jQuery-UI to 1.13.2 (#3697) 2022-09-21 10:34:51 -04:00
Joe Cheng
04ad1453c1 Merge pull request #3694 from rstudio/rook-doc-link
Add link to Rook spec from docs
2022-09-07 17:38:36 -07:00
jcheng5
80eeff68ab Sync package version (GitHub Actions) 2022-09-07 14:27:51 -07:00
jcheng5
6128a3ab65 yarn build (GitHub Actions) 2022-09-07 20:43:50 +00:00
Joe Cheng
5f25537079 Add link to Rook spec from docs 2022-09-07 13:37:37 -07:00
Winston Chang
c21ba0baca Bump version to 1.7.2.9000 2022-07-19 09:18:16 -05:00
Winston Chang
ebf786c2eb Merge tag 'v1.7.2'
Shiny 1.7.2 on CRAN
2022-07-19 09:16:45 -05:00
wch
b39ffafea9 devtools::document() (GitHub Actions) 2022-07-19 00:16:11 +00:00
Winston Chang
4441945a68 Use inherits() instead of if(class(x)==y) 2022-07-18 19:11:24 -05:00
Winston Chang
cd95e058e6 Remove URL because CRAN doesn't like it 2022-07-18 19:11:24 -05:00
Winston Chang
a0144d77ef Remove broken link 2022-07-18 19:11:24 -05:00
Carson
64cec08a74 Check in most recent revdep results 2022-07-08 11:53:50 -05:00
Winston Chang
7a77b55e6a Merge branch 'main' into rc-v1.7.2 2022-07-05 20:08:10 -05:00
Winston Chang
54e5a6b43c Merge branch 'dvg-p4-fix-throttle' 2022-07-05 20:03:22 -05:00
Winston Chang
9653cc2893 Rebuild shiny.js 2022-07-05 20:01:22 -05:00
Winston Chang
47dc5b4116 Code and comment cleanup 2022-07-05 19:37:44 -05:00
dvg-p4
9db9ef527a Fixed check for isPending and rebuilt javascript 2022-07-04 10:21:22 -04:00
dvg-p4
9285a1f7fc Update srcts/src/time/throttle.ts
Based on suggestion

Co-authored-by: Winston Chang <winston@stdout.org>
2022-07-01 19:02:26 -04:00
dvg-p4
d22eb1524a Updated NEWS.md 2022-07-01 17:15:09 -04:00
dvg-p4
5e3971c776 Fixed major bug in throttle.ts 2022-07-01 16:58:41 -04:00
Carson
dbe4896102 Merge branch 'main' into rc-v1.7.2 2022-06-27 12:12:55 -05:00
Joe Cheng
ff5ef52dd5 Fix #3250 (#3602)
* Fix #3250

pruneStackTrace was interacting badly with dplyr errors. I'm still
not sure what causes these new cases, but the new behavior seems to
be much better, with no downside that I can think of.

* Fix existing unit tests

* Update news

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
2022-06-27 12:05:28 -05:00
Joe Cheng
634b1c7c3c Don't kill the session when a debounced/throttled reactive expr errors (#3624)
* Don't kill the session when a debounced/throttled reactive expr errors

Fixes #3581

* Update NEWS with PR number

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
2022-06-27 10:57:10 -05:00
Carson
1c9f8940a9 Merge branch 'main' into rc-v1.7.2 2022-06-24 17:53:49 -05:00
Carson Sievert
d4527cdc28 Use ragg::agg_png over Cairo::CairoPNG if available (#3654)
* Close #3626: use ragg::agg_png over Cairo::CairoPNG if available

* Update documentation
2022-06-24 17:50:58 -05:00
cpsievert
514206850a Sync package version (GitHub Actions) 2022-06-14 15:43:58 +00:00
cpsievert
809bc8c6de yarn build (GitHub Actions) 2022-06-14 15:42:16 +00:00
cpsievert
0d720616f3 devtools::document() (GitHub Actions) 2022-06-14 15:39:35 +00:00
Carson
0c325d422f Groom NEWS.md 2022-06-14 10:35:36 -05:00
Carson
d368aa72c3 Update URLs 2022-06-14 10:35:36 -05:00
Carson
27e1348dcb Start v1.7.2 release candidate 2022-06-14 10:35:36 -05:00
Carson Sievert
474f14003b Follow up to #3385: warn instead of message; update unit tests to reflect some parameters can now succeed when others fail (#3652) 2022-06-14 10:34:20 -05:00
Carson Sievert
8a5da25545 Fix/update news (#3651) 2022-06-14 09:18:51 -05:00
Barret Schloerke
540d68ed9f Update the _inputs_ and _values_ regular expr to support a trailing = (#3648) 2022-06-10 11:39:12 -04:00
Khaled Al-Shamaa
1ad49b153c Enable fileInput to set the capture attribute (#3481)
Co-authored-by: Barret Schloerke <barret@rstudio.com>
Co-authored-by: Barret Schloerke <schloerke@gmail.com>
Co-authored-by: Winston Chang <winston@stdout.org>
2022-06-10 10:30:34 -05:00
Winston Chang
15885cbb5f Update NEWS 2022-06-10 10:07:00 -05:00
Dean Attali
b6979d135c fix bookmarking bug #2297: don't break all bookmarking system if some URL params don't parse correctly (#3385)
Co-authored-by: Barret Schloerke <barret@rstudio.com>
2022-06-10 10:04:47 -05:00
Winston Chang
d4b19820a4 Update NEWS 2022-06-10 10:02:30 -05:00
Dieter Menne
8d529095a7 Corrected for stricter length checking in R 4.2.0 (#3625)
* Corrected for stricter length checking in R 4.2.0

* Update R/bootstrap-layout.R

Fine! I had thought of that case, but could not find that elegant solution

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
2022-06-10 09:59:14 -05:00
Winston Chang
77f9052ab5 Make mathjax configurable (#3650)
Co-authored-by: Neutron3529 <qweytr_1@163.com>
Co-authored-by: Joe Cheng <joe@rstudio.com>
2022-06-10 09:57:02 -05:00
Ryan Barnard
9fcc1fe8ad Fixed automatic guessing of Content-Type in downloadHandler (#3393)
* Set default downloadHandler contentType to NULL.

The change from %OR% to %||% broke automatic guessing of content type
since `NA %||% ...` evaluates to `NA`. Setting the default contentType
to NULL restores the previous behavior of automatically setting the
content type based on the file extension.

* Updated NEWS.md: downloadHandler contentType fix.

* Update NEWS.md

Co-authored-by: Winston Chang <winston@stdout.org>
Co-authored-by: Barret Schloerke <barret@rstudio.com>
2022-06-10 09:39:00 -05:00
Barret Schloerke
5d30b55372 Spelling defintion -> definition (#3649) 2022-06-09 16:52:27 -04:00
Carson Sievert
78d77ce373 insertUI() now supports execution of <script> (#3630) 2022-05-10 11:43:21 -05:00
Joe Cheng
2cae04186b Merge pull request #3628 from rstudio/joe/feature/autoreload-custom-url
Add ability for autoreload ws to be at a custom URL
2022-05-04 16:35:39 -07:00
Joe Cheng
59bddea1e9 Use external, not internal, sourcemaps for extras 2022-05-04 16:23:48 -07:00
Joe Cheng
d6bd3d9f9b Add ability for autoreload ws to be at a custom URL 2022-05-04 09:05:53 -07:00
Joe Cheng
8eb7b056f2 devmode should activate autoreload (#3620)
devmode should activate autoreload

It said it didn't, but until this commit, it appeared not to
2022-04-27 13:51:02 -07:00
Barret Schloerke
40ae9a903e Spelling (#3618) 2022-04-23 12:25:11 -04:00
Barret Schloerke
5b6c80d4b2 Update shinyAppTemplate() content to use {shinytest2} (#3599) 2022-04-22 16:10:11 -04:00
Dean Attali
fd7518018c Update internal docs: reexports.yml -> reexports.json (#3522) 2022-03-11 11:59:35 -05:00
Kathryn Doering
5c03326a8c Use HEAD for ref instead of master in runGitHub() (#3564)
Co-authored-by: Kathryn Doering <kathryn.doering@noaa.gov>
2022-02-14 15:53:33 -05:00
Barret Schloerke
2c82ee0235 Bump dev version (#3588) 2022-02-14 15:24:47 -05:00
Barret Schloerke
ac84be956a Opt-in to C collate order in test snapshots (#3515) 2022-02-14 14:12:25 -05:00
Winston Chang
0fb154cc1e Trigger input event even when there is no input binding (#3584)
Co-authored-by: Winston Chang <winston@stdout.org>
Co-authored-by: Barret Schloerke <schloerke@gmail.com>
2022-02-14 13:45:59 -05:00
Carson Sievert
837e8d33f6 Update stack trace test expectations (#3550) 2022-02-14 13:14:10 -05:00
Winston Chang
3365bfc395 Merge pull request #3583 from ismirsehregal/main 2022-02-09 17:27:18 -06:00
ismirsehregal
135fe21278 Update runapp.R
Fixed typo
2022-02-09 15:11:34 +01:00
Carson Sievert
fc7e237000 Pass args from knit_print.shiny.render.function() down to it's use of the knit_print() generic (#3569)
Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
Co-authored-by: Barret Schloerke <barret@rstudio.com>
Co-authored-by: schloerke <schloerke@users.noreply.github.com>
2022-01-11 12:21:18 -06:00
Winston Chang
de8134742d Update NEWS 2022-01-11 10:41:19 -06:00
Winston Chang
f814034835 Merge pull request #3570 from romainfrancois/shinyActionButtonValue 2022-01-11 10:38:28 -06:00
Romain Francois
6d9fad29f3 put the extension class on the left.
from: https://github.com/tidyverse/dplyr/issues/6154
2022-01-11 12:49:48 +01:00
Lionel Henry
313ae9044d Handle chained errors (#3567)
Closes tidyverse/dplyr#5552
Part of #3566
2022-01-10 18:33:14 -08:00
Barret Schloerke
9389160af0 Cache the reactlog version found. Remove mustWork argument to system_file(). (#3554) 2021-12-08 15:30:37 -05:00
Barret Schloerke
6a7ffeff68 master -> main; use shiny-workflows (#3535) 2021-11-19 17:50:57 -05:00
Winston Chang
bc6ff57cb7 Remove old unused JS files (#3547) 2021-11-17 22:01:19 -06:00
Carson Sievert
b52b9e4520 Some UI-related speed improvements (#3541) 2021-11-17 16:25:27 -06:00
Winston Chang
fb71ab6146 Editor configuration improvements 2021-11-16 15:38:21 -06:00
Carson Sievert
d8c7a634ff Fix failing tabPanel() test broken by testthat 3.1.0 (#3543) 2021-11-05 16:45:16 -05:00
Winston Chang
396dd2632e Merge pull request #3537 from rstudio/htmldep 2021-11-05 15:56:09 -05:00
Winston Chang
c11875a5f0 Fix appending to list 2021-11-05 15:52:14 -05:00
Winston Chang
2e599faf1f Fix comment 2021-11-05 15:47:23 -05:00
Winston Chang
a5a8385420 Use all_files=FALSE for html dependencies
This commit sets all_files=FALSE for html dependencies in www/shared.
2021-11-04 11:24:46 -05:00
Winston Chang
33ed698e5b Remove “file =“ 2021-11-04 11:15:01 -05:00
Winston Chang
ed547fdf40 Rebuild JS files 2021-11-03 21:28:15 -05:00
Winston Chang
0b1c35c92b Use .map() and .forEeach() instead of for loops 2021-11-03 21:28:11 -05:00
Winston Chang
d304bdf333 Rename HtmlDepSimplified to HtmlDepNormalized 2021-11-03 20:54:53 -05:00
Winston Chang
a9255e6b12 Extract jquery-ui dependency into function 2021-11-03 20:54:53 -05:00
Winston Chang
45429fb798 Streamline code for adding scripts and attachments 2021-11-03 13:56:37 -05:00
Winston Chang
1206d1d3ba Use array of objects to represent meta tags 2021-11-03 13:56:37 -05:00
Winston Chang
af44a447a1 Fix type specification of HTML dependency meta values 2021-11-03 11:40:49 -05:00
Winston Chang
d7fb6d1793 Fixes for strict null checks 2021-11-03 11:40:49 -05:00
Winston Chang
cb0083adb2 Update VSCode editor settings 2021-11-03 11:40:49 -05:00
Winston Chang
77bae68f26 Update NEWS 2021-11-03 11:40:48 -05:00
Winston Chang
e9f8b4d552 Use htmlDependencies with ‘src=file’ for showcase mode 2021-11-03 11:39:28 -05:00
Winston Chang
aee6b74cfb Minor cleanups 2021-11-03 11:39:28 -05:00
Winston Chang
29b6b03297 Extract restyle code into separate code path 2021-11-03 11:39:28 -05:00
Winston Chang
b5ebd8a645 Fix attachment handling and add more specific types 2021-11-03 11:39:28 -05:00
Winston Chang
356ba8c5a1 Add simplifyHtmlDependency() function 2021-11-03 11:39:28 -05:00
Winston Chang
5aa5cb1794 Make dep.src.href field optional 2021-11-03 11:39:28 -05:00
Winston Chang
09c609e417 Bump version to 1.7.1.9001 2021-11-03 11:39:28 -05:00
Winston Chang
10e7d11846 Allow array of attributes for stylesheets 2021-11-03 11:39:28 -05:00
Winston Chang
4e442312a7 Serve HTML dependencies from dynamic paths 2021-11-03 11:39:28 -05:00
Winston Chang
8ea97df3f2 Fix getid access of data-input-id attribute (#3538) 2021-11-03 11:38:54 -05:00
Winston Chang
a8c14dab96 Bump version to 1.7.1.9000 2021-10-04 11:09:26 -05:00
Winston Chang
00775b90e8 Bump version to 1.7.1 2021-09-30 14:48:12 -05:00
Winston Chang
c6ae4c0034 Update NEWS 2021-09-30 14:48:06 -05:00
Winston Chang
1efcaa0b5d Use esbuild option preserveSymlinks
This allows the node_modules directory to be a symlink, without causing weird
build problems.
2021-09-30 14:44:17 -05:00
Carson Sievert
e6d94f6f66 Fix regression in repeated appendTab()s when navbarMenu() is present (#3518) 2021-09-30 14:43:09 -05:00
Barret Schloerke
5a8a02626c add news item for #3512 2021-09-28 18:00:36 -04:00
Hadley Wickham
c23293750d Re-arrange conditions for testthat 1.0.0 compatibility (#3512) 2021-09-28 17:51:45 -04:00
Winston Chang
9de74048a2 Bump version to 1.7.0.9000 2021-09-28 16:39:35 -05:00
wch
0fc861afb4 yarn build (GitHub Actions) 2021-09-10 20:05:12 +00:00
wch
2300dae10b sync package version (GitHub Actions) 2021-09-10 20:02:58 +00:00
wch
dfbb98abfd Document (GitHub Actions) 2021-09-10 20:02:19 +00:00
Winston Chang
9670839235 Fix example parse errors 2021-09-10 14:55:53 -05:00
Winston Chang
1e2326c2b6 Update reexports 2021-09-10 14:46:30 -05:00
Carson
6f46b847e2 Address check NOTE: Undeclared package ‘htmlwidgets’ in Rd xrefs 2021-09-07 15:10:52 -05:00
Carson
8c44559a1f Fix DT Rd link 2021-09-07 14:48:34 -05:00
Carson
d245a972ee simplify gha 2021-09-07 14:23:22 -05:00
Carson
c153d0591f bump version 2021-09-07 14:14:50 -05:00
Barret Schloerke
2ce18ef324 Update GHA workflows to use latest versions (#3492) 2021-08-24 14:59:52 -04:00
Barret Schloerke
2792d65e40 Fix link to DT::renderDataTable() (#3490) 2021-08-20 09:14:57 -05:00
Barret Schloerke
7b00f605aa Remove rlang remote (#3487) 2021-08-19 18:07:23 -04:00
Barret Schloerke
4cb3f05e8e Adjust app port tests to use random port values (#3488) 2021-08-19 18:06:43 -04:00
Winston Chang
8e40c815eb Merge pull request #3485 from rstudio/wch-fix-checkbox-radio 2021-08-13 13:56:35 -05:00
Winston Chang
6dfd8bc0ff Only ignore node_modules at top level 2021-08-13 13:50:54 -05:00
wch
2ef397f024 yarn build (GitHub Actions) 2021-08-13 18:08:05 +00:00
wch
94749f6114 yarn lint (GitHub Actions) 2021-08-13 18:08:05 +00:00
Winston Chang
4a39588d00 Update NEWS 2021-08-13 13:00:57 -05:00
Winston Chang
f5d5832149 Fix invisible checkboxes and radio buttons in RStudio on Mac 2021-08-13 12:58:12 -05:00
Barret Schloerke
68deab9b0e Remove console.log("Shiny version: ", Shiny.version) statement (#3480) 2021-08-05 18:16:39 -04:00
Winston Chang
96efac2bd7 Merge pull request #3478 from rstudio/install_expr_news_entry 2021-08-05 10:17:50 -05:00
Barret Schloerke
a67059f9f9 update news 2021-08-04 15:31:56 -04:00
Barret Schloerke
cdc51c09c7 Add test for inject()ed quosures when extracting the cacheHint (#3476) 2021-08-04 13:35:50 -04:00
Barret Schloerke
a6f02cf214 Fix bash logic in action step (#3474) 2021-08-02 22:35:11 -04:00
Barret Schloerke
7600770a6e Fix Rituals workflow validating commits have not been made (#3473) 2021-08-02 22:19:31 -04:00
Barret Schloerke
1b3ed88bd1 exprToFunction() and installExprFunction() support quosures (#3472)
Co-authored-by: Barret Schloerke <schloerke@gmail.com>
Co-authored-by: Winston Chang <winston@stdout.org>
Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
Co-authored-by: Joe Cheng <joe@rstudio.com>
2021-08-02 22:09:19 -04:00
Barret Schloerke
f01dc9f0fb Move user documentation up to the top of Readme (#3464) 2021-08-02 22:06:09 -04:00
Barret Schloerke
9a65890e92 Update esbuild-plugin-sass to latest version (#3463) 2021-08-02 21:41:02 -04:00
Carson Sievert
ffef0c2eb1 Interpret NULL discrete limits as NA, fixes #2666 (#2668)
Co-authored-by: Winston Chang <winston@stdout.org>
Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2021-07-27 14:02:58 -05:00
Barret Schloerke
8b74338b0f Add sustainEnvAndQuoted(). Remove getQuosure() (#3468)
Documentation to come in a later PR

Co-authored-by: Barret Schloerke <schloerke@gmail.com>
Co-authored-by: Winston Chang <winston@stdout.org>
2021-07-26 17:54:37 -04:00
Winston Chang
ed3c676548 Merge pull request #3466 from rstudio/wch-exprfunction-fix 2021-07-16 16:14:38 -05:00
Winston Chang
30c0a2bd29 Update NEWS 2021-07-16 15:17:37 -05:00
Winston Chang
997e5e5ce5 Fix handling of getQuosure3(expr, env, quoted=TRUE) 2021-07-16 15:14:28 -05:00
Winston Chang
aba6b2e4db Fix NEWS entry 2021-07-15 17:52:59 -05:00
Winston Chang
3f48e3b0af Merge pull request #3462 from rstudio/wch-exprfunction-quosures 2021-07-15 17:51:22 -05:00
Winston Chang
b4879a342c Update NEWS 2021-07-15 17:50:40 -05:00
Winston Chang
5070146061 Fix example 2021-07-15 17:21:15 -05:00
Winston Chang
d28c3e15ad Update pkgdown.yml 2021-07-15 17:14:47 -05:00
Winston Chang
4b496be520 Update documentation 2021-07-15 17:11:36 -05:00
Winston Chang
979288a590 Add quosure tests for custom render functions 2021-07-14 16:31:23 -05:00
Winston Chang
9365d4f3c4 Update comment 2021-07-14 16:30:53 -05:00
Winston Chang
e1daf8aae7 Export getQuosure() and add internal getQuosure3() 2021-07-09 17:36:46 -05:00
Winston Chang
8a57dbf608 Rename get_quosure to getQuosure 2021-07-06 12:36:45 -05:00
Winston Chang
ac9b76c651 Modify exprToFunction to accept quosures 2021-07-02 15:45:10 -05:00
Winston Chang
139526ef2d Move expression/quosure functions to utils-lang.R 2021-07-02 14:25:46 -05:00
Winston Chang
d1e7e6c63a Add note about R version support 2021-07-02 14:04:35 -05:00
Winston Chang
29b574bf94 Merge pull request #3456 from heds1/update-rejected-ports 2021-07-01 16:34:25 -05:00
Barret Schloerke
7e4248bbca TypeScript: Globally declare Shiny variable, window.Shiny variable, and Shiny type (#3457) 2021-07-01 14:51:16 -04:00
heds1
fee267dc2e docs: update runapp port parameter docs, and add three more tcp ports to be blocked 2021-07-01 21:40:59 +12:00
Carson Sievert
9864130435 Use random inline styles to ensure transitionend fires everytime (#3452)
* Follow up to #3333: use random inline styles to ensure transitionend fires everytime

* yarn lint (GitHub Actions)

* Add missing '#'

* yarn lint (GitHub Actions)

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2021-06-30 15:26:49 -05:00
Carson Sievert
c9770cbd03 Close #3443: Fix sliderInput()'s grid tick positioning without Bootstrap (#3444) 2021-06-29 15:56:47 -05:00
Carson Sievert
ed6a40ba41 Close #3446: get removeModel() working with Bootstrap 4 (#3447) 2021-06-29 15:54:48 -05:00
Carson
3c22cdf90c roxygenize 2021-06-29 15:11:39 -05:00
Marcus Spittler
e55749b897 Update utils.R example to validate() (#2809)
Added an empty option to `choices` in `selectizeInput` in order to make the second `need` statement in `validate` meaningful. Otherwise the second `need` ("Please choose a state") is never displayed.
2021-06-29 15:10:42 -05:00
Carson Sievert
88cd87a5f7 Revert "Set selectize dropdownParent to "body" to prevent clipping" (#3450)
This reverts commit ce90d5cd0a.
2021-06-29 12:22:33 -05:00
Barret Schloerke
244fdc72bc Leverage more eslint rules (#3439) 2021-06-22 21:20:54 -04:00
Barret Schloerke
b9d163a71d TypeScript other distributed JS/CSS files (#3436) 2021-06-18 10:18:51 -04:00
Barret Schloerke
61ee467dee Replace dev versions with -alpha versions for JS code (#3435) 2021-06-17 16:02:39 -04:00
Carson Sievert
7c0829d553 Change from .nav-item to .dropdown-item when inserting inside .dropdown-menu (#3434)
* Change from .nav-item to .dropdown-item when inserting inside .dropdown-menu

* Update srcts/src/shiny/shinyapp.ts

* Update srcts/src/shiny/shinyapp.ts

* yarn lint (GitHub Actions)

* yarn build (GitHub Actions)

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2021-06-16 17:44:03 -05:00
Carson Sievert
68eb4c6965 update news for breaking insertTab() change (#3433) 2021-06-16 16:41:07 -05:00
Barret Schloerke
6d4015f61b ./package.json updates to make TS Types package cleaner to install (#3430)
Co-authored-by: Barret Schloerke <schloerke@gmail.com>
Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
2021-06-16 16:08:50 -04:00
Barret Schloerke
d89513b7e0 Match casing for plot alt text "Plot object" (#3432)
* Match spelling for Plot Object phrase

From #3398

* Document (GitHub Actions)

* Consistent casing for `"Plot object"` for plot alt text

Co-authored-by: schloerke <schloerke@users.noreply.github.com>
2021-06-16 15:08:13 -05:00
Carson Sievert
a159594a45 insertTab(position = "after") by default (#3431)
* Follow up to #3404: change insertTab()'s default position so that default behavior doesn't change

* Update news

* Document (GitHub Actions)

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2021-06-16 15:01:36 -05:00
Carson Sievert
78c62ad819 Various cleanup (#3428)
* Follow up to #3366: don't change sliderInput()'s default accent color

* Update news

* nav_append not tab_append 🤦

* bslib no longer tries to mark a non-tabPanel as active
2021-06-15 16:45:23 -05:00
Barret Schloerke
b3247d5a3b Move ./srcts configs to top level to support types installation from GitHub (#3425) 2021-06-15 14:18:53 -04:00
Winston Chang
91f920e14c Merge pull request #3413 from rstudio/feature/selectize-dropdown-parent-body
Set selectize dropdownParent to "body" to prevent clipping
2021-06-15 11:50:37 -05:00
Carson Sievert
bcb7cde44b insertTab() now handles position correctly when target is NULL (#3404)
* Close #3403: insertTab() now handles position correctly when target is NULL

* Have insertTab()'s target default to NULL

* yarn tsc (GitHub Actions)

* yarn build (GitHub Actions)

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2021-06-14 15:51:38 -05:00
Carson Sievert
052c9458b7 yarn add node-gyp; yarn build (#3424) 2021-06-14 15:51:03 -05:00
Barret Schloerke
3fe8c27d21 Export TypeScript type definitions to local folder (#3418) 2021-06-14 14:25:05 -04:00
Barret Schloerke
1dd256b210 TypeScript: Remove any types / improve type definitions (#3414) 2021-06-14 14:22:39 -04:00
Carson Sievert
dc9c6ae769 Better color constrasting in sliderInput() (#3366)
* Better color constrasting in sliderInput()

Closes https://github.com/rstudio/bslib/issues/228

* Update build script; recompile

* bslib tabsets now include data-bs-toggle
2021-06-14 12:48:57 -05:00
Carson Sievert
2cdafed2e0 Use ggplot2::get_alt_text() if available to provide better default alt text (#3398)
* Close #3397: Use ggplot2::get_alt_text() if available to provide more informative default alt text for ggplots in renderPlot()

* Update R/render-plot.R

Co-authored-by: Winston Chang <winston@stdout.org>

* better Rd docs

* make logic more self-contained

* Add news

Co-authored-by: Winston Chang <winston@stdout.org>
2021-06-14 10:22:07 -05:00
JJ Allaire
ce90d5cd0a Set selectize dropdownParent to "body" to prevent clipping
To prevent clipping of the selectize drop-down we set the dropdownParent to "body". This might be necessary if e.g. overflow-x: scroll is set on it's container, which forces overflow-y to 'auto' (as per https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-y).

See option docs here: https://github.com/selectize/selectize.js/blob/master/docs/usage.md

Additional discussion of usage here: https://github.com/selectize/selectize.js/issues/192
2021-06-09 19:41:10 -04:00
Barret Schloerke
b4caa9137d Distribute TypeScript code into separate files (#3317)
Co-authored-by: Barret Schloerke <schloerke@gmail.com>
Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
2021-06-09 14:54:47 -04:00
Carson Sievert
dcca77c936 Fix tab input value updating for BS4 dropdowns (#3412)
* Fix tab input value updating for BS4 dropdowns

* Add comments

* yarn build (GitHub Actions)

* Better comment

* yarn lint (GitHub Actions)

* yarn build (GitHub Actions)

Co-authored-by: Barret Schloerke <barret@rstudio.com>
Co-authored-by: schloerke <schloerke@users.noreply.github.com>
Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2021-06-02 15:55:32 -05:00
Carson Sievert
871b1baacc Follow up to #3410: bump version and update news (#3411) 2021-06-02 13:03:09 -05:00
Carson Sievert
4deb699066 Bootstrap 5 support (#3410)
* Bootstrap 5 support for modals & showcase mode

* selectizeInput() BS5 compatibility

* Both BS4 and 5 define window.bootstrap

* Document (GitHub Actions)

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2021-06-02 12:36:04 -05:00
Carson Sievert
ccc8e053c6 Use bslib's new nav() api to implement tabPanel() and friends (#3388)
* Use bslib's new nav() api to implement tabPanel() and friends

* bslib won't be re-exporting prepend/append tab since they've been superceded by insertTab()

* Update DESCRIPTION

* Use the new bslib::page_navbar()

* Leverage bslib::page_navbar()'s more intelligent title->windowTitle handling

Closes #2310

* fix name change

* Make sure navbarPage() isn't browsable by default
2021-06-02 12:10:41 -05:00
Barret Schloerke
6405056c92 Install Cairo macOS devel brew dependency (#3408) 2021-05-26 17:06:27 -04:00
Barret Schloerke
9f9304fdc5 Remove Font Awesome 5 message about the level-up icon (#3407) 2021-05-26 16:31:15 -04:00
Carson Sievert
3d3b05c7a5 Correctly render script tags defined as list() objects (#3395)
* Close #3345: correctly render script tags defined as list() objects

* implement boolean attrs; use vanilla JS

* Update news

* avoid toggleAttribute

* yarn lint (GitHub Actions)

* code review

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2021-05-20 17:44:34 -05:00
Carson Sievert
543a6b5836 Fix CRAN note (#3394)
* Follow up to #3392: update tabPanel() baselines

* Fix check NOTE

* Revert "Follow up to #3392: update tabPanel() baselines"

This reverts commit c97022c386.

Issue will be fixed in htmltools
2021-05-20 13:58:16 -05:00
Carson Sievert
b0de68919a tagify() dynamic UI before attempting to write the tags (#3392)
* Close #3391: properly tagify() dynamic UI before attempting to write the tags

* Document (GitHub Actions)

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2021-05-18 12:28:17 -05:00
Richard Iannone
d65ad5ea90 Modify icon() function to call fontawesome::fa_i() for equivalent functionality (#3302)
* Use `fontawesome::fa_i()` for FA <i> tags

* Remove fontawesome vendor files

* Add fontawesome pkg to Imports & Remotes

* Remove FontAwesome `person()` entry

* Remove Font Awesome license info

* Delete font-awesome.R

* Update 'Collate' field (removes 'font-awesome.R')

* Delete updateFontAwesome.R

* Prefer use of `fontawesome::fa()`

* Improve function documentation

* Update help file using roxygen

* Modify icon name

* Update icon name in example

* Modify icon name in example

* Update help files

* Update bootstrap.R

* Update icon.Rd

* Update bootstrap.R

* Revert `showcaseCodeTabs()` to use FA v4 name

* Revert icon name in example (back to FA v4)

* Remove `call. = FALSE` in `stop()`

* Remove `fontawesome` from Remotes

* Add min version req for the fontawesome pkg

* Increase minimum version requirement for fontawesome

* Update roxygen docs for `icon()`

* Document (GitHub Actions)

* Update icon.Rd

* Generate early return <i> tag for tabsetPanel logic

* Close #3384 and #3383: simplify and correct icon() logic

* Install htmltools PR for now

* Document (GitHub Actions)

* Avoid using tag attribs to hold non-attribute values

* Better legacy support

* No need to call prepTabIcon() twice

* code review

* Fix glyphicon class creation

* update news

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
Co-authored-by: rich-iannone <rich-iannone@users.noreply.github.com>
Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2021-05-12 14:26:09 -05:00
Carson Sievert
383fa6c0e0 Follow up to #3372: fix oversight in refactor (#3387) 2021-05-10 09:58:30 -05:00
Barret Schloerke
8d40b3af70 Revert "Do not double pull within rituals"
This reverts commit 9c80d7a4ec.
2021-05-10 10:49:54 -04:00
Barret Schloerke
9c80d7a4ec Do not double pull within rituals 2021-05-07 15:15:41 -04:00
Winston Chang
2360bde13e Remove deprecated code and parameters (#3137)
* Remove deprecated reactive* functions

* Remove deprecated code

* Update NEWS

* Remove extractStackTrace and formatStackTrace

* remove responsive from bootstrapPage() wrappers

* Move extractStackTrace() to tests so they pass

* Don't force suggested pkgs in devel on GHA

Co-authored-by: Carson <cpsievert1@gmail.com>
2021-05-06 09:46:30 -05:00
Winston Chang
d25ae099d4 Merge pull request #3333 from rstudio/reportCssOnLoad 2021-05-05 18:12:17 -05:00
Winston Chang
2d492886e4 Prettify TS 2021-05-05 18:04:35 -05:00
Winston Chang
33741436c7 Merge remote-tracking branch 'origin/master' into reportCssOnLoad 2021-05-05 18:03:41 -05:00
Winston Chang
318cc7fcaf Rebuild JS files 2021-05-05 18:02:32 -05:00
Winston Chang
bebcf0b196 Add important flag 2021-05-05 18:02:32 -05:00
Winston Chang
f2be2e4eb1 Update comments 2021-05-05 17:48:39 -05:00
Winston Chang
a2ea017046 Add sendImageSize2 2021-05-05 17:40:46 -05:00
Winston Chang
fc338c8958 Use removeSheet() 2021-05-05 16:17:34 -05:00
Winston Chang
bbb27f1224 Make more CSS properties !important 2021-05-05 15:56:50 -05:00
Winston Chang
d2fbdb6c48 Add note about synchronous behavior in IE 2021-05-05 15:56:29 -05:00
Winston Chang
38c70842d9 Rebuild JS files 2021-05-05 15:18:01 -05:00
Winston Chang
0e22c4c591 Simplify IE CSS handling 2021-05-05 14:53:12 -05:00
Winston Chang
70e0eede16 New strategy for sending information when CSS loads 2021-05-05 14:50:39 -05:00
Barret Schloerke
4858a379e7 Make sure dev version of rlang is available (#3382) 2021-05-05 15:01:47 -04:00
Carson Sievert
3e33755a9e Reduce complexity and 'black-boxed' nature of tab panel logic (#3372)
* Follow up to #3315: reduce complexity and 'black-boxed' nature of tab panel logic

* asTags(selected = FALSE) is now root()

* tagAddRenderHook

* Add bslib to remotes

* Document (GitHub Actions)

* root() was recently changed to allTags()

* code review

* tagQuery() doesn't necessarily preserve order of attributes

* place href attribute before data attributes

* add nav-item/nav-link to BS4+ dropdowns

* Make sure .nav-item is removed in .dropdown-menu

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2021-05-05 10:05:24 -05:00
Carson Sievert
f2ad004f33 Install dev version of rlang (#3379)
Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
Co-authored-by: Barret Schloerke <schloerke@gmail.com>
2021-05-05 10:44:19 -04:00
Carson
16e0d9e355 Comment about the hoisting 2021-05-04 14:33:54 -05:00
Carson
d430b80191 Use sendImageSize instead of Shiny.bindAll to resend CSS info 2021-05-04 14:19:40 -05:00
Carson
2ffa8707ea Merge branch 'master' into reportCssOnLoad 2021-05-04 12:13:37 -05:00
Carson
cbd06cbd8e Merge branch 'master' into reportCssOnLoad 2021-05-04 12:11:56 -05:00
Carson Sievert
d3aa1acfbf Use tab instead of tooltip constructor to check Bootstrap version (#3377)
Closes https://github.com/rstudio/shinycoreci-apps/issues/138
2021-05-04 08:15:27 -05:00
Winston Chang
c2232ae07a Merge pull request #3373 from rstudio/nested-quo-to-func 2021-04-27 12:38:33 -05:00
Winston Chang
cf0a865d6f Remove ... args from function 2021-04-27 12:29:34 -05:00
Carson
4942b3e6ad Add news item 2021-04-22 16:49:40 -05:00
Joe Cheng
f374a1512a Fix rlang::inject with render functions
Render functions use quoToFunction() to convert quosures to
functions; quoToFunction() was using new_function, which leads
to non-tidy evaluation, so nested quosures are not evaluated.

See https://github.com/rstudio/shiny/pull/3361#issuecomment-820672180
2021-04-22 11:57:24 -07:00
Barret Schloerke
1558c848f4 Export register_devmode_option() (#3364) 2021-04-20 17:33:58 -04:00
Barret Schloerke
4a2bb8fc43 Add ORCID info (#3363) 2021-04-09 16:35:49 -04:00
Barret Schloerke
fad21af146 Make external libs builder leveraging esbuild (#3357) 2021-04-07 16:06:05 -04:00
Winston Chang
850a628978 Fix variable name 2021-04-06 12:52:14 -05:00
Winston Chang
4d2311841d Merge pull request #3334 from rstudio/boostrapPageJQuery
bootstrapPage() now includes jQuery so static rendering works as expected
2021-04-06 12:10:12 -05:00
Winston Chang
5c4175cd5f Merge pull request #3353 from rstudio/wch-fix-tab-title 2021-04-02 14:51:44 -05:00
Winston Chang
2931e40c7b Update 2021-04-02 14:50:36 -05:00
Winston Chang
6a6eae1ce1 Update R/bootstrap.R
Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
2021-04-02 14:49:37 -05:00
Winston Chang
210642e96c Update R/bootstrap.R
Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
2021-04-02 14:49:26 -05:00
Winston Chang
c97fad30ef Fix html tags in tab titles 2021-04-02 13:27:22 -05:00
Carson Sievert
268c9afec3 Close #3299: bootstrapLib() should always call setCurrentTheme() when shiny is running (#3300) 2021-03-26 15:12:54 -05:00
Carson Sievert
5c919ae565 Make ensureTabsetHasVisibleTab() is aware of BS4+ markup (#3349)
* Close https://github.com/rstudio/shinycoreci-apps/issues/126: Make ensureTabsetHasVisibleTab() aware of BS4+ markup

* yarn build (GitHub Actions)

* Update srcts/src/main.ts

* yarn lint (GitHub Actions)

* yarn build (GitHub Actions)

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2021-03-26 15:11:48 -05:00
Hadley Wickham
e29d92c5ff Allow trailing commas in more places (#3328)
* Allow trailing commas in more places

I grepped for list(...) and replaced with rlang::list2(...). This also enables !!! which is generally not important for Shiny because it automatically splices lists/tagLists, but I doubt it will affect any existing code.

* update news; no need to rlang::

* missed one

* Update NEWS.md

Co-authored-by: Hadley Wickham <h.wickham@gmail.com>

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
2021-03-23 14:24:21 -05:00
Carson
0a331e3366 update news 2021-03-22 16:00:39 -05:00
Carson Sievert
32d0e146ad Various improvements to tab panels (#3315)
* 'Native' Bootstrap 4 tabset panel support

* downgrade error to warning; improve the messaging

* Make tab anchor selectors more a bit more sensible and consistent across versions

* More of the same

* fix silly bug

* Be more careful about unpacking a .nav-item into a .dropdown-item

* Keep refactoring R logic to make it cleaner and easier to reuse elsewhere

* Go back to the purely class based CSS selectors for BS4 tab input

* Keep supporting off-label behavior of shiny.tag getting transformed into 'empty' nav/tab

* Add header and footer args to tabsetPanel()/navlistPanel() since there is precedence in navbarPage() and mention them in the warning

* Drop NULLs instead of creating an empty nav from them, closes #1928

* Remove tabPanelMenu() alias

* Add a card argument for wrapping content in a card

* Throw an error if card=T is used outside of a BS4+ context

* No more tabPanelMenu() alias

* Document (GitHub Actions)

* Port JS changes to TypeScript

* Allow liTag to be assigned a new value

* abort() is no longer being used

* Add some unit tests

* Document the new card argument

* Get tests passing on older R versions

* Get tests passing on older R versions

* Get tests passing on older R versions

* Skip snapshots on R < 3.6

* require dev version of htmltools

* remove card argument (at least for now)

* Document (GitHub Actions)

* Update tests/testthat/test-tabPanel.R

Co-authored-by: Winston Chang <winston@stdout.org>

* Have processDeps() call renderTags() on tagFunction() objects

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
Co-authored-by: Winston Chang <winston@stdout.org>
2021-03-22 12:37:57 -05:00
Carson
c94f411fc6 Specify both href and file 2021-03-12 17:17:01 -06:00
Carson
22d408aa7b Close #3316: bootstrapPage() now includes jQuery so static rendering works as expected 2021-03-12 16:50:24 -06:00
Carson
a44fdc1b11 remove logs 2021-03-11 17:01:25 -06:00
Carson
50ca830ec6 Poll every 0.1sec for 10secs 2021-03-11 16:57:20 -06:00
Carson
e643cd3824 request on next tick 2021-03-11 12:37:41 -06:00
Carson
2660a50d31 try using requestAnimationFrame 2021-03-11 11:46:17 -06:00
Carson
927912efe3 Try sending multiple times 2021-03-11 11:13:51 -06:00
Carson
9b49a24e74 Try not debouncing 2021-03-11 11:03:28 -06:00
Carson
0824b22532 Add debug statements 2021-03-11 10:49:16 -06:00
Carson
000feead00 When refreshing a stylesheet, schedule a report CSS values once the sheet is loaded 2021-03-11 09:50:49 -06:00
517 changed files with 48448 additions and 75346 deletions

View File

@@ -21,3 +21,19 @@
^TODO-promises.md$
^manualtests$
^\.github$
^\.yarn$
^\.vscode$
^\.madgerc$
^\.prettierrc\.yml$
^babel\.config\.json$
^jest\.config\.js$
^package\.json$
^tsconfig\.json$
^yarn\.lock$
^node_modules$
^coverage$
^.ignore$
^\.browserslistrc$
^\.eslintrc\.yml$
^\.yarnrc\.yml$

105
.eslintrc.yml Normal file
View File

@@ -0,0 +1,105 @@
root: true
env:
browser: true
es6: true
extends:
- 'eslint:recommended'
- 'plugin:@typescript-eslint/recommended'
- 'plugin:jest/recommended'
- 'plugin:prettier/recommended'
- 'plugin:jest-dom/recommended'
globals:
Atomics: readonly
SharedArrayBuffer: readonly
parser: '@typescript-eslint/parser'
parserOptions:
ecmaVersion: 2018
sourceType: module
plugins:
- '@typescript-eslint'
- prettier
- jest-dom
- unicorn
rules:
"@typescript-eslint/explicit-function-return-type":
- off
"@typescript-eslint/no-explicit-any":
- off
"@typescript-eslint/explicit-module-boundary-types":
- error
default-case:
- error
indent:
- error
- 2
- SwitchCase: 1
linebreak-style:
- error
- unix
quotes:
- error
- double
- avoid-escape
semi:
- error
- always
dot-location:
- error
- property
camelcase:
# - error
- "off"
unicorn/filename-case:
- error
- case: camelCase
"@typescript-eslint/array-type":
- error
- default: array-simple
readonly: array-simple
"@typescript-eslint/consistent-indexed-object-style":
- error
- index-signature
"@typescript-eslint/sort-type-union-intersection-members":
- error
"@typescript-eslint/consistent-type-imports":
- error
"@typescript-eslint/naming-convention":
- error
- selector: default
format: [camelCase]
- selector: method
modifiers: [private]
format: [camelCase]
leadingUnderscore: require
- selector: method
modifiers: [protected]
format: [camelCase]
leadingUnderscore: require
- selector: variable
format: [camelCase]
trailingUnderscore: forbid
leadingUnderscore: forbid
- selector: parameter
format: [camelCase]
trailingUnderscore: allow
leadingUnderscore: forbid
- selector: [enum, enumMember]
format: [PascalCase]
- selector: typeLike
format: [PascalCase]
custom:
regex: "(t|T)ype$"
match: false

2
.gitattributes vendored
View File

@@ -1,4 +1,6 @@
/NEWS merge=union
/inst/www/shared/shiny.js -merge -diff
/inst/www/shared/shiny-*.js -merge -diff
/inst/www/shared/shiny*.css -merge -diff
*.min.js -merge -diff
*.js.map -merge -diff

12
.github/shiny-workflows/routine.sh vendored Normal file
View File

@@ -0,0 +1,12 @@
#!/bin/bash -e
. ./tools/documentation/checkDocsCurrent.sh
echo "Updating package.json version to match DESCRIPTION Version"
Rscript ./tools/updatePackageJsonVersion.R
if [ -n "$(git status --porcelain package.json)" ]
then
yarn build
git add ./inst package.json && git commit -m 'Sync package version (GitHub Actions)' || echo "No package version to commit"
else
echo "No package version difference detected; package.json is current."
fi

View File

@@ -1,142 +1,23 @@
name: R-CMD-check
# Workflow derived from https://github.com/rstudio/shiny-workflows
#
# NOTE: This Shiny team GHA workflow is overkill for most R packages.
# For most R packages it is better to use https://github.com/r-lib/actions
on:
push:
branches:
- master
branches: [main, rc-**]
pull_request:
branches:
- master
branches: [main]
schedule:
- cron: '0 5 * * 1' # every monday
name: Package checks
jobs:
website:
uses: rstudio/shiny-workflows/.github/workflows/website.yaml@v1
routine:
uses: rstudio/shiny-workflows/.github/workflows/routine.yaml@v1
with:
node-version: "14.x"
R-CMD-check:
runs-on: ${{ matrix.config.os }}
name: ${{ matrix.config.os }} (${{ matrix.config.r }})
strategy:
fail-fast: false
matrix:
config:
- {os: macOS-latest, r: 'devel'}
- {os: macOS-latest, r: '4.0'}
- {os: windows-latest, r: '4.0'}
- {os: ubuntu-16.04, r: '4.0', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
- {os: ubuntu-16.04, r: '3.6', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
- {os: ubuntu-16.04, r: '3.5', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
- {os: ubuntu-16.04, r: '3.4', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
- {os: ubuntu-16.04, r: '3.3', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
env:
_R_CHECK_FORCE_SUGGESTS_: false
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
RSPM: ${{ matrix.config.rspm }}
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
# https://github.com/actions/checkout/issues/135
- name: Set git to use LF
if: runner.os == 'Windows'
run: |
git config --system core.autocrlf false
git config --system core.eol lf
- uses: actions/checkout@v2
- uses: r-lib/actions/setup-r@master
id: install-r
with:
r-version: ${{ matrix.config.r }}
- uses: r-lib/actions/setup-pandoc@master
- name: Install pak and query dependencies
shell: Rscript {0}
run: |
install.packages("pak", repos = "https://r-lib.github.io/p/pak/dev/")
saveRDS(pak::pkg_deps_tree("local::.", dependencies = TRUE), ".github/r-depends.rds")
- name: Cache R packages
uses: actions/cache@v2
with:
path: ${{ env.R_LIBS_USER }}
key: ${{ matrix.config.os }}-${{ steps.install-r.outputs.installed-r-version }}-1-${{ hashFiles('.github/r-depends.rds') }}
restore-keys: ${{ matrix.config.os }}-${{ steps.install-r.outputs.installed-r-version }}-1-
- name: Install system dependencies
if: runner.os == 'Linux'
shell: Rscript {0}
run: |
pak::local_system_requirements(execute = TRUE)
# xquartz and cairo are needed for Cairo package.
# harfbuzz and fribidi are needed for textshaping package.
- name: Mac systemdeps
if: runner.os == 'macOS'
run: |
brew install --cask xquartz
brew install cairo
brew install harfbuzz fribidi
# Use a shorter temp directory for pak installations, due to filename
# length issues on Windows. https://github.com/r-lib/pak/issues/252
- name: Windows temp dir
if: runner.os == 'Windows'
run: |
New-Item -Path "C:\" -Name "tmp" -ItemType Directory
echo "TMPDIR=c:\tmp" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Install dependencies
run: |
pak::local_install_dev_deps(upgrade = TRUE)
pak::pkg_install("rcmdcheck")
shell: Rscript {0}
- name: Find PhantomJS path
id: phantomjs
run: |
echo "::set-output name=path::$(Rscript -e 'cat(shinytest:::phantom_paths()[[1]])')"
- name: Cache PhantomJS
uses: actions/cache@v2
with:
path: ${{ steps.phantomjs.outputs.path }}
key: ${{ matrix.config.os }}-phantomjs
restore-keys: ${{ matrix.config.os }}-phantomjs
- name: Install PhantomJS
run: >
Rscript
-e "if (!shinytest::dependenciesInstalled()) shinytest::installDependencies()"
- name: Session info
run: |
options(width = 100)
pkgs <- installed.packages()[, "Package"]
sessioninfo::session_info(pkgs, include_base = TRUE)
shell: Rscript {0}
- name: Check
env:
_R_CHECK_CRAN_INCOMING_: false
run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check")
shell: Rscript {0}
- name: Show testthat output
if: always()
run: find check -name 'testthat.Rout*' -exec cat '{}' \; || true
shell: bash
- name: Upload check results
if: failure()
uses: actions/upload-artifact@v2
with:
name: ${{ matrix.config.os }}-r${{ matrix.config.r }}-results
path: check
- name: Fix path for Windows caching
if: runner.os == 'Windows'
# This is needed because if you use the default tar at this stage,
# C:/Rtools/bin/tar.exe, it will say that it can't find gzip.exe. So
# we'll just set the path so that the original tar that would be
# found, will be found.
run: echo "C:/Program Files/Git/usr/bin" >> $GITHUB_PATH
uses: rstudio/shiny-workflows/.github/workflows/R-CMD-check.yaml@v1

View File

@@ -1,153 +0,0 @@
on:
push:
branches:
- master
- ghactions
pull_request:
branches:
- master
name: Rituals
jobs:
rituals:
name: Rituals
# if: false
runs-on: ${{ matrix.config.os }}
strategy:
fail-fast: false
matrix:
config:
- { os: ubuntu-16.04, r: '4.0', node: "14.x", rspm: "https://packagemanager.rstudio.com/all/__linux__/xenial/latest"}
env:
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
RSPM: ${{ matrix.config.rspm }}
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v1
- uses: r-lib/actions/pr-fetch@master
name: Git Pull (PR)
if: github.event_name == 'pull_request'
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: r-lib/actions/setup-r@master
id: install-r
with:
r-version: ${{ matrix.config.r }}
- uses: r-lib/actions/setup-pandoc@master
- name: Git Config
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
- name: Install pak and query dependencies
shell: Rscript {0}
run: |
install.packages("pak", repos = "https://r-lib.github.io/p/pak/dev/")
saveRDS(pak::pkg_deps_tree("local::.", dependencies = TRUE), ".github/r-depends.rds")
- name: Cache R packages
uses: actions/cache@v2
with:
path: ${{ env.R_LIBS_USER }}
key: ${{ matrix.config.os }}-${{ steps.install-r.outputs.installed-r-version }}-1-${{ hashFiles('.github/r-depends.rds') }}
restore-keys: ${{ matrix.config.os }}-${{ steps.install-r.outputs.installed-r-version }}-1-
- name: Install system dependencies
# if: runner.os == 'Linux'
shell: Rscript {0}
run: |
pak::local_system_requirements(execute = TRUE)
- name: Install dependencies
shell: Rscript {0}
run: |
pak::local_install_dev_deps(upgrade = TRUE)
pak::pkg_install("sessioninfo")
pak::pkg_install("devtools")
- name: Session info
shell: Rscript {0}
run: |
options(width = 100)
pkgs <- installed.packages()[, "Package"]
sessioninfo::session_info(pkgs, include_base = TRUE)
- name: Url redirects
# only perform if in an RC branch (`rc-vX.Y.Z`)
if: ${{ github.event_name == 'push' && contains(github.ref, '/rc-v') }}
run: |
Rscript -e 'pak::pkg_install("r-lib/urlchecker"); urlchecker::url_update()'
# throw an error if man files were updated
if [ -n "$(git status --porcelain man)" ]
then
git status --porcelain
>&2 echo "Updated links found in files above"
>&2 echo 'Run `urlchecker::url_update()` to fix links locally'
exit 1
fi
# Add locally changed urls
git add .
git commit -m 'Update links (GitHub Actions)' || echo "No link changes to commit"
- name: Document
run: |
Rscript -e 'devtools::document()'
git add man/\* NAMESPACE
git commit -m 'Document (GitHub Actions)' || echo "No documentation changes to commit"
- name: Check documentation
run: |
./tools/documentation/checkDocsCurrent.sh
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.config.node }}
# https://github.com/actions/cache/blame/ccf96194800dbb7b7094edcd5a7cf3ec3c270f10/examples.md#L185-L200
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: yarn cache
uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ matrix.config.os }}-${{ matrix.config.node }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ matrix.config.os }}-${{ matrix.config.node }}-yarn-
- name: Build JS
run: |
cd srcts
tree src
yarn install --immutable && yarn build
git add ./src && git commit -m 'yarn lint (GitHub Actions)' || echo "No yarn lint changes to commit"
git add ../inst && git commit -m 'yarn build (GitHub Actions)' || echo "No yarn build changes to commit"
- name: Check JS build is latest
run: |
./tools/checkJSCurrent.sh
- name: Git Push (PR)
uses: r-lib/actions/pr-push@master
if: github.event_name == 'pull_request'
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Git Push (MASTER)
if: github.event_name == 'push'
run: |
git push https://${{github.actor}}:${{secrets.GITHUB_TOKEN}}@github.com/${{github.repository}}.git HEAD:${{ github.ref }} || echo "No changes to push"
# Execute after pushing, as no updated files will be produced
- name: Test TypeScript code
run: |
cd srcts
yarn test

13
.gitignore vendored
View File

@@ -11,5 +11,18 @@ README.html
.*.Rnb.cached
tools/yarn-error.log
# TypeScript / yarn
/node_modules/
.cache
.yarn/*
!.yarn/releases
!.yarn/plugins
!.yarn/sdks
!.yarn/versions
.pnp.*
coverage/
madge.svg
# GHA remotes installation
.github/r-depends.rds

7
.madgerc Normal file
View File

@@ -0,0 +1,7 @@
{
"detectiveOptions": {
"ts": {
"skipTypeImports": true
}
}
}

18
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,18 @@
{
"search.exclude": {
"**/.yarn": true,
"**/.pnp.*": true
},
"prettier.prettierPath": "./node_modules/prettier",
"typescript.enablePromptUseWorkspaceTsdk": true,
"[r]": {
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
},
}

File diff suppressed because one or more lines are too long

783
.yarn/releases/yarn-3.2.3.cjs vendored Executable file

File diff suppressed because one or more lines are too long

View File

@@ -3,5 +3,7 @@ nodeLinker: node-modules
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-outdated.cjs
spec: "https://github.com/mskelton/yarn-plugin-outdated/raw/main/bundles/@yarnpkg/plugin-outdated.js"
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"
yarnPath: .yarn/releases/yarn-2.4.0.cjs
yarnPath: .yarn/releases/yarn-3.2.3.cjs

View File

@@ -1,13 +1,13 @@
Package: shiny
Type: Package
Title: Web Application Framework for R
Version: 1.6.0.9000
Version: 1.7.4.9003
Authors@R: c(
person("Winston", "Chang", role = c("aut", "cre"), email = "winston@rstudio.com"),
person("Winston", "Chang", role = c("aut", "cre"), email = "winston@rstudio.com", comment = c(ORCID = "0000-0002-1576-2126")),
person("Joe", "Cheng", role = "aut", email = "joe@rstudio.com"),
person("JJ", "Allaire", role = "aut", email = "jj@rstudio.com"),
person("Carson", "Sievert", role = "aut", email = "carson@rstudio.com"),
person("Barret", "Schloerke", role = "aut", email = "barret@rstudio.com"),
person("Carson", "Sievert", role = "aut", email = "carson@rstudio.com", comment = c(ORCID = "0000-0002-4958-2844")),
person("Barret", "Schloerke", role = "aut", email = "barret@rstudio.com", comment = c(ORCID = "0000-0001-9986-114X")),
person("Yihui", "Xie", role = "aut", email = "yihui@rstudio.com"),
person("Jeff", "Allen", role = "aut", email = "jeff@rstudio.com"),
person("Jonathan", "McPherson", role = "aut", email = "jonathan@rstudio.com"),
@@ -44,8 +44,6 @@ Authors@R: c(
comment = "Bootstrap-datepicker library"),
person("Andrew", "Rowls", role = c("ctb", "cph"),
comment = "Bootstrap-datepicker library"),
person("Dave", "Gandy", role = c("ctb", "cph"),
comment = "Font-Awesome font"),
person("Brian", "Reavis", role = c("ctb", "cph"),
comment = "selectize.js library"),
person("Salmen", "Bejaoui", role = c("ctb", "cph"),
@@ -80,7 +78,8 @@ Imports:
mime (>= 0.3),
jsonlite (>= 0.9.16),
xtable,
htmltools (>= 0.5.0.9001),
fontawesome (>= 0.4.0),
htmltools (>= 0.5.4),
R6 (>= 2.0),
sourcetools,
later (>= 1.0.0),
@@ -88,11 +87,11 @@ Imports:
tools,
crayon,
rlang (>= 0.4.10),
fastmap (>= 1.1.0),
fastmap (>= 1.1.1),
withr,
commonmark (>= 1.7),
glue (>= 1.3.2),
bslib (>= 0.2.2.9002),
bslib (>= 0.3.0),
cachem,
ellipsis,
lifecycle (>= 0.2.0)
@@ -106,14 +105,14 @@ Suggests:
ggplot2,
reactlog (>= 1.0.0),
magrittr,
shinytest (>= 1.4.0.9003),
yaml,
future,
dygraphs,
ragg,
showtext,
sass
URL: https://shiny.rstudio.com/
URL: https://shiny.posit.co/,
https://github.com/rstudio/shiny
BugReports: https://github.com/rstudio/shiny/issues
Collate:
'globals.R'
@@ -134,7 +133,6 @@ Collate:
'devmode.R'
'diagnose.R'
'fileupload.R'
'font-awesome.R'
'graph.R'
'reactives.R'
'reactive-domains.R'
@@ -191,16 +189,24 @@ Collate:
'shinywrappers.R'
'showcase.R'
'snapshot.R'
'staticimports.R'
'tar.R'
'test-export.R'
'test-server.R'
'test.R'
'update-input.R'
'utils-lang.R'
'version_bs_date_picker.R'
'version_ion_range_slider.R'
'version_jquery.R'
'version_jqueryui.R'
'version_selectize.R'
'version_strftime.R'
'viewer.R'
RoxygenNote: 7.1.1
RoxygenNote: 7.2.3
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RdMacros: lifecycle
Config/testthat/edition: 3
Config/Needs/check:
shinytest2

444
LICENSE
View File

@@ -10,7 +10,6 @@ these components are included below):
- Bootstrap, https://github.com/twbs/bootstrap
- bootstrap-accessibility-plugin, https://github.com/paypal/bootstrap-accessibility-plugin
- bootstrap-datepicker, https://github.com/eternicode/bootstrap-datepicker
- Font Awesome, https://github.com/FortAwesome/Font-Awesome
- selectize.js, https://github.com/selectize/selectize.js
- selectize-plugin-a11y, https://github.com/SLMNBJ/selectize-plugin-a11y
- ion.rangeSlider, https://github.com/IonDen/ion.rangeSlider
@@ -308,449 +307,6 @@ bootstrap-datepicker
limitations under the License.
Font Awesome (CSS files are MIT licensed; fonts have SIL Open Font License 1.1, svgs have CC BY 4.0 License)
----------------------------------------------------------------------
The MIT License (MIT)
Copyright (c) 2014 Dave Gandy
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
----
Copyright (c) 2014, Dave Gandy http://fontawesome.com/,
with Reserved Font Name Font Awesome.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
=======================================================================
Creative Commons Attribution 4.0 International Public License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution 4.0 International Public License ("Public License"). To the
extent this Public License may be interpreted as a contract, You are
granted the Licensed Rights in consideration of Your acceptance of
these terms and conditions, and the Licensor grants You such rights in
consideration of benefits the Licensor receives from making the
Licensed Material available under these terms and conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
b. Adapter's License means the license You apply to Your Copyright
and Similar Rights in Your contributions to Adapted Material in
accordance with the terms and conditions of this Public License.
c. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
d. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
e. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
f. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
g. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
h. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
i. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
j. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
k. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part; and
b. produce, reproduce, and Share Adapted Material.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified
form), You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
4. If You Share Adapted Material You produce, the Adapter's
License You apply must not prevent recipients of the Adapted
Material from complying with this Public License.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material; and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.
selectize.js
----------------------------------------------------------------------

View File

@@ -103,7 +103,6 @@ export(enableBookmarking)
export(eventReactive)
export(exportTestValues)
export(exprToFunction)
export(extractStackTrace)
export(fileInput)
export(fillCol)
export(fillPage)
@@ -114,7 +113,6 @@ export(fixedRow)
export(flowLayout)
export(fluidPage)
export(fluidRow)
export(formatStackTrace)
export(freezeReactiveVal)
export(freezeReactiveValue)
export(getCurrentOutputInfo)
@@ -207,13 +205,8 @@ export(radioButtons)
export(reactive)
export(reactiveConsole)
export(reactiveFileReader)
export(reactivePlot)
export(reactivePoll)
export(reactivePrint)
export(reactiveTable)
export(reactiveText)
export(reactiveTimer)
export(reactiveUI)
export(reactiveVal)
export(reactiveValues)
export(reactiveValuesToList)
@@ -222,6 +215,7 @@ export(reactlogReset)
export(reactlogShow)
export(registerInputHandler)
export(registerThemeDependency)
export(register_devmode_option)
export(removeInputHandler)
export(removeModal)
export(removeNotification)
@@ -264,7 +258,6 @@ export(shinyUI)
export(showBookmarkUrlModal)
export(showModal)
export(showNotification)
export(showReactLog)
export(showTab)
export(sidebarLayout)
export(sidebarPanel)
@@ -385,6 +378,7 @@ importFrom(htmltools,tags)
importFrom(htmltools,validateCssUnit)
importFrom(htmltools,withTags)
importFrom(lifecycle,deprecated)
importFrom(lifecycle,is_present)
importFrom(promises,"%...!%")
importFrom(promises,"%...>%")
importFrom(promises,as.promise)
@@ -393,14 +387,18 @@ importFrom(promises,promise)
importFrom(promises,promise_reject)
importFrom(promises,promise_resolve)
importFrom(rlang,"%||%")
importFrom(rlang,"fn_body<-")
importFrom(rlang,"fn_fmls<-")
importFrom(rlang,as_function)
importFrom(rlang,as_quosure)
importFrom(rlang,enexpr)
importFrom(rlang,enquo)
importFrom(rlang,enquo0)
importFrom(rlang,enquos)
importFrom(rlang,enquos0)
importFrom(rlang,eval_tidy)
importFrom(rlang,expr)
importFrom(rlang,fn_body)
importFrom(rlang,get_env)
importFrom(rlang,get_expr)
importFrom(rlang,inject)
@@ -408,10 +406,15 @@ importFrom(rlang,is_false)
importFrom(rlang,is_missing)
importFrom(rlang,is_na)
importFrom(rlang,is_quosure)
importFrom(rlang,list2)
importFrom(rlang,maybe_missing)
importFrom(rlang,missing_arg)
importFrom(rlang,new_function)
importFrom(rlang,new_quosure)
importFrom(rlang,pairlist2)
importFrom(rlang,quo)
importFrom(rlang,quo_get_expr)
importFrom(rlang,quo_is_missing)
importFrom(rlang,quo_set_env)
importFrom(rlang,quo_set_expr)
importFrom(rlang,zap_srcref)

351
NEWS.md
View File

@@ -1,5 +1,127 @@
shiny 1.6.0.9000
================
# shiny 1.7.4.9002
## Full changelog
### Breaking changes
### New features and improvements
* Closed #789: Dynamic UI is now rendered asynchronously, thanks in part to the newly exported `Shiny.renderDependenciesAsync()`, `Shiny.renderHtmlAsync()`, and `Shiny.renderContentAsync()`. Importantly, this means `<script>` tags are now loaded asynchronously (the old way used `XMLHttpRequest`, which is synchronous). In addition, `Shiny` now manages a queue of async tasks (exposed via `Shiny.shinyapp.taskQueue`) so that order of execution is preserved. (#3666)
* For `reactiveValues()` objects, whenever the `$names()` or `$values()` methods are called, the keys are now returned in the order that they were inserted. (#3774)
* `Map` objects are now initialized at load time instead of build time. This avoids potential problems that could arise from storing `fastmap` objects into the built Shiny package. (#3775)
* Allow for `shiny:::toJSON()` to respect if `digits=` has class `"AsIs"` which represents if `use_signif=` is `TRUE` or `FALSE`. This is useful for testing to keep the digits smaller. For example, setting `options(shiny.json.digits = 4)` will save 4 digits after the decimal, rather than the default of `I(16)` which will save 16 significant digits. (#3819)
* Closed #2956: Component authors can now prevent Shiny from creating an input binding on specific elements by adding the `data-shiny-no-bind-input` attribute to the element. The attribute may have any or no value; its presence will prevent binding. This feature is primarily useful for input component authors who want to use standard HTML input elements without causing Shiny to create an input binding for them. Additionally, Shiny now adds custom classes to its inputs. For example, `checkboxInput()` now has a `shiny-input-checkbox` class. These custom classes may be utilized in future updates to Shiny's input binding logic. (#3861)
* Slider inputs created with `sliderInput()` now have a larger target area for clicking or tapping on the slider line or the slider bar. (#3859)
### Bug fixes
* Fixed #3771: Sometimes the error `ion.rangeSlider.min.js: i.stopPropagation is not a function` would appear in the JavaScript console. (#3772)
* Fixed #3833: When `width` is provided to `textAreaInput()`, we now correctly set the width of the `<textarea>` element. (#3838)
* Fixes #3840: `updateSliderInput()` now warns when attempting to set invalid `min`, `max`, or `value` values. Sending an invalid update message to an input no longer causes other update messages to fail. (#3843)
# shiny 1.7.4.1
## Full changelog
* Closed #3849: In R-devel, a warning was raised when Shiny was loaded because `as.numeric_version()` was called with a number instead of a string. (#3850)
# shiny 1.7.4
## Full changelog
### Breaking changes
* Closed #3719: Output container sizes, which are available via [`session$clientData` and `getCurrentOutputInfo()`](https://shiny.rstudio.com/articles/client-data.html), no longer round to the nearest pixel (i.e., they are now more exact, possibly fractional values). (#3720)
* Closed #3704, #3735, and #3740: `renderPlot()` no longer generates an error (or segfault) when it executes before the output is visible. Instead, it'll now use the graphics device's default size for it's initial size. Relatedly, `plotPNG()` now ignores `NULL` values for `width`/`height` (and uses the device's default `width`/`height` instead). (#3739)
### New features and improvements
* `plotOutput()`, `imageOutput()`, and `uiOutput()` gain a `fill` argument. If `TRUE` (the default for `plotOutput()`), the output container is allowed to grow/shrink to fit a fill container (created via `htmltools::bindFillRole()`) with an opinionated height. This means `plotOutput()` will grow/shrink by default [inside of `bslib::card_body_fill()`](https://rstudio.github.io/bslib/articles/cards.html#responsive-sizing), but `imageOutput()` and `uiOutput()` will have to opt-in to similar behavior with `fill = TRUE`. (#3715)
* Closed #3687: Updated jQuery-UI to v1.13.2. (#3697)
* Internal: Added clearer and strict TypeScript type definitions (#3644)
# shiny 1.7.3
### Bug fixes
* Shiny 1.7.0 changed the `icon(lib="fontawesome")` implementation from a bundled copy of fontawesome, to the {fontawesome} package. This led to issue #3688, where icons that were previously working, were now breaking. That's because {fontawesome} 0.3.0 and earlier did not have support for icon names used in Font Awesome 5 and earlier, only the newest icon names used in Font Awesome 6. Now, {fontawesome} 0.4.0 has restored support for those older icon names, and Shiny 1.7.2.1 has updated its {fontawesome} requirement to >=0.4.0.
# shiny 1.7.2
## Full changelog
### Breaking changes
* Closed #3626: `renderPlot()` (and `plotPNG()`) now uses `ragg::agg_png()` by default when the [`{ragg}` package](https://github.com/r-lib/ragg) is installed. To restore the previous behavior, set `options(shiny.useragg = FALSE)`. (#3654)
### New features and improvements
* Closed #1545: `insertUI()` now executes `<script>` tags. (#3630)
* `fileInput()` can set the `capture` attribute to facilitates user access to a device's media capture mechanism, such as a camera, or microphone, from within a file upload control ([W3C HTML Media Capture](https://www.w3.org/TR/html-media-capture/)). (Thanks to khaled-alshamaa, #3481)
* Closed tidyverse/dplyr#5552: Compatibility of dplyr 1.0 (and rlang chained errors in general) with `req()`, `validate()`, and friends.
* Closed tidyverse/dplyr#6154: Values from an `actionButton()` had S3 classes in the incorrect order.
* Closed #3346: Default for `ref` input in `runGithub()` changed from `"master"` to `"HEAD"`. (#3564)
* Closed #3619: In R 4.2, `splitLayout()` no longer raises warnings about incorrect length in an `if` statement. (Thanks to @dmenne, #3625)
### Bug fixes
* Closed #3250:`{rlang}`/`{tidyeval}` conditions (i.e., warnings and errors) are no longer filtered from stack traces. (#3602)
* Closed #3581: Errors in throttled/debounced reactive expressions no longer cause the session to exit. (#3624)
* Closed #3657: `throttle.ts` and the `Throttler` typescript objects it provides now function as intended. (Thanks gto @dvg-p4, #3659)
* The auto-reload feature (`options(shiny.autoreload=TRUE)`) was not being activated by `devmode(TRUE)`, despite a console message asserting that it was. (#3620)
* Closed #2297: If an error occurred in parsing a value in a bookmark query string, an error would be thrown and nothing would be restored. Now a message is displayed and that value is ignored. (Thanks to @daattali, #3385)
* Restored the previous behavior of automatically guessing the `Content-Type` header for `downloadHandler` functions when no explicit `contentType` argument is supplied. (#3393)
* Previously, updating an input value without a corresponding Input binding element did not trigger a JavaScript `shiny:inputchanged` event. Now, if no Input binding element is found, the `shiny:inputchanged` event is triggered on `window.document`. (#3584)
* Closed #2955: Input and output bindings previously attempted to use `el['data-input-id']`, but that never worked. They now use `el.getAttribute('data-input-id')` instead. (#3538)
### Minor improvements
* When taking a test snapshot, the sort order of the json keys of the `input`, `output`, and `export` fields is currently sorted using the locale of the machine. This can lead to inconsistent test snapshot results. To opt-in to a consistent ordering of snapshot fields with `{shinytest}`, please set the global option `options(shiny.snapshotsortc = TRUE)`. `{shinytest2}` users do not need to set this value. (#3515)
* Closed rstudio/shinytest2#222: When restoring a context (i.e., bookmarking) from a URL, Shiny now better handles a trailing `=` after `_inputs_` and `_values_`. (#3648)
* Shiny's internal HTML dependencies are now mounted dynamically instead of statically. (#3537)
* HTML dependencies that are sent to dynamic UI now have better type checking, and no longer require a `dep.src.href` field. (#3537)
# shiny 1.7.1
## Bug Fixes
* Closed #3516: Fix regression in repeated calls to `appendTab()` when `navbarMenu()` is already present within a `tabsetPanel()`/`navbarPage()`. (#3518)
* Re-arranged conditions for testthat 1.0.0 compatibility. (#3512)
# shiny 1.7.0
## Full changelog
@@ -7,30 +129,62 @@ shiny 1.6.0.9000
* The `format` and `locale` arguments to `sliderInput()` have been removed. They have been deprecated since 0.10.2.2 (released on 2014-12-08).
### Minor new features and improvements
* Closed #3403: `insertTab()`'s `position` parameter now defaults to `"after"` instead of `"before"`. This has the benefit of allowing us to fix a bug in positioning when `target = NULL`, but has the drawback of changing the default behavior when `target` is not `NULL`. (#3404)
* Shiny's core JavaScript code was converted to TypeScript. For the latest development information, please see the [README.md in `./srcts`](https://github.com/rstudio/shiny/tree/master/srcts). (#3296)
### New features and improvements
* Bootstrap 5 support. (#3410 and rstudio/bslib#304)
* As explained [here](https://rstudio.github.io/bslib/index.html#basic-usage), to opt-in to Bootstrap 5, provide `bslib::bs_theme(version = 5)` to a page layout function with a `theme` argument (e.g., `fluidPage()`, `navbarPage()`, etc).
* Closed #3322, #3313, #1823, #3321, #3320, #1928, and #2310: Various improvements to `navbarPage()`, `tabsetPanel()`, `tabPanel()`, `navbarMenu()`, etc. Also, these functions are now powered by the `{bslib}` package's new `nav()` API (consider using `{bslib}`'s API to create better looking and more fully featured navs). (#3388)
* All uses of `list(...)` have been replaced with `rlang::list2(...)`. This means that you can use trailing `,` without error and use rlang's `!!!` operator to "splice" a list of argument values into `...`. We think this'll be particularly useful for passing a list of `tabPanel()` to their consumers (i.e., `tabsetPanel()`, `navbarPage()`, etc). For example, `tabs <- list(tabPanel("A", "a"), tabPanel("B", "b")); navbarPage(!!!tabs)`. (#3315 and #3328)
* `installExprFunction()` and `exprToFunction()` are now able to handle quosures when `quoted = TRUE`. So `render`-functions which call these functions (such as with `htmlwidgets`) can now understand quosures. Users can also use `rlang::inject()` to unquote a quosure for evaluation. This also means that `render` function no longer need `env` and `quoted` parameters; that information can be embedded into a quosure which is then passed to the `render` function. Better documentation was added for how to create `render` functions. (#3472)
* `icon(lib="fontawesome")` is now powered by the `{fontawesome}` package, which will make it easier to use the latest FA icons in the future (by updating the `{fontawesome}` package). (#3302)
* Closed #3397: `renderPlot()` new uses `ggplot2::get_alt_text()` to inform an `alt` text default (for `{ggplot2}` plots). (#3398)
* `modalDialog()` gains support for `size = "xl"`. (#3410)
* Addressed #2521: Updated the list of TCP ports that will be rejected by default in runapp.R, adding 5060, 5061 and 6566. Added documentation describing the port range (3000:8000) and which ports are rejected. (#3456)
### Other improvements
* Shiny's core JavaScript code was converted to TypeScript. For the latest development information, please see the [README.md in `./srcts`](https://github.com/rstudio/shiny/tree/v1.7.0/srcts). (#3296)
* Switched from `digest::digest()` to `rlang::hash()` for hashing. (#3264)
* Switched from internal `Stack` class to `fastmap::faststack()`, and used `fastmap::fastqueue()`. (#3176)
* Some long-deprecated functions and function parameters were removed. (#3137)
### Bug fixes
* Closed #3345: Shiny now correctly renders `htmltools::htmlDependency()`(s) with a `list()` of `script` attributes when used in a dynamic UI context. This fairly new `htmlDependency()` feature was added in `{htmltools}` v0.5.1. (#3395)
* Fixed [#2666](https://github.com/rstudio/shiny/issues/2666) and [#2670](https://github.com/rstudio/shiny/issues/2670): `nearPoints()` and `brushedPoints()` weren't properly account for missing values (#2666 was introduced in v1.4.0). ([#2668](https://github.com/rstudio/shiny/pull/2668))
* Closed #3374: `quoToFunction()` now works correctly with nested quosures; and as a result, quasi-quotation with rendering function (e.g., `renderPrint()`, `renderPlot()`, etc) now works as expected with nested quosures. (#3373)
* Exported `register_devmode_option()`. This method was described in the documentation for `devmode()` but was never exported. See `?devmode()` for more details on how to register Shiny Developer options using `register_devmode_option()`. (#3364)
* Closed #3484: In the RStudio IDE on Mac 11.5, selected checkboxes and radio buttons were not visible. (#3485)
### Library updates
* Closed #3286: Updated to Font-Awesome 5.15.2. (#3288)
* Updated to jQuery 3.6.0. (#3311)
shiny 1.6.0
===========
# shiny 1.6.0
This release focuses on improvements in three main areas:
1. Better theming (and Bootstrap 4) support:
* The `theme` argument of `fluidPage()`, `navbarPage()`, and `bootstrapPage()` all now understand `bslib::bs_theme()` objects, which can be used to opt-into Bootstrap 4, use any Bootswatch theme, and/or implement custom themes without writing any CSS.
* The `session` object now includes `$setCurrentTheme()` and `$getCurrentTheme()` methods to dynamically update (or obtain) the page's `theme` after initial load, which is useful for things such as [adding a dark mode switch to an app](https://rstudio.github.io/bslib/articles/theming.html#dynamic-shiny) or some other "real-time" theming tool like `bslib::bs_themer()`.
* The `session` object now includes `$setCurrentTheme()` and `$getCurrentTheme()` methods to dynamically update (or obtain) the page's `theme` after initial load, which is useful for things such as [adding a dark mode switch to an app](https://rstudio.github.io/bslib/articles/theming.html#dynamic) or some other "real-time" theming tool like `bslib::bs_themer()`.
* For more details, see [`{bslib}`'s website](https://rstudio.github.io/bslib/)
2. Caching of `reactive()` and `render*()` (e.g. `renderText()`, `renderTable()`, etc) expressions.
@@ -133,8 +287,7 @@ This release focuses on improvements in three main areas:
* Removed es5-shim library, which was internally used within `selectInput()` for ECMAScript 5 compatibility. (#2993)
shiny 1.5.0
===========
# shiny 1.5.0
## Full changelog
@@ -152,7 +305,7 @@ shiny 1.5.0
* The new `moduleServer` function provides a simpler interface for creating and using modules. (#2773)
* Resolved #2732: `markdown()` is a new function for writing Markdown with Github extensions directly in Shiny UIs. Markdown rendering is performed by the [commonmark](https://github.com/jeroen/commonmark) package. (#2737)
* Resolved #2732: `markdown()` is a new function for writing Markdown with Github extensions directly in Shiny UIs. Markdown rendering is performed by the [commonmark](https://github.com/r-lib/commonmark) package. (#2737)
* The `getCurrentOutputInfo()` function can now return the background color (`bg`), foreground color (`fg`), `accent` (i.e., hyperlink) color, and `font` information of the output's HTML container. This information is reported by `plotOutput()`, `imageOutput()`, and any other output bindings containing a class of `.shiny-report-theme`. This feature allows developers to style an output's contents based on the container's CSS styling. (#2740)
@@ -187,20 +340,17 @@ shiny 1.5.0
* Updated from Font-Awesome 5.3.1 to 5.13.0, which includes icons related to COVID-19. For upgrade notes, see https://github.com/FortAwesome/Font-Awesome/blob/master/UPGRADING.md. (#2891)
shiny 1.4.0.2
===========
# shiny 1.4.0.2
Minor patch release: fixed some timing-dependent tests failed intermittently on CRAN build machines.
shiny 1.4.0.1
===========
# shiny 1.4.0.1
Minor patch release to account for changes to the grid package that will be upcoming in the R 4.0 release (#2776).
shiny 1.4.0
===========
# shiny 1.4.0
## Full changelog
@@ -263,8 +413,7 @@ shiny 1.4.0
* Fixed #2329, #1817: These bugs were reported as fixed in Shiny 1.3.0 but were not actually fixed because some JavaScript changes were accidentally not included in the release. The fix resolves issues that occur when `withProgressBar()` or bookmarking are combined with the [networkD3](https://christophergandrud.github.io/networkD3/) package's Sankey plot.
shiny 1.3.2
===========
# shiny 1.3.2
### Bug fixes
@@ -273,8 +422,7 @@ shiny 1.3.2
* Fixed #2280: Shiny applications that used a www/index.html file did not serve up the index file. (#2382)
shiny 1.3.1
===========
# shiny 1.3.1
## Full changelog
@@ -283,8 +431,7 @@ shiny 1.3.1
* Fixed a performance issue introduced in v1.3.0 when using large nested lists within Shiny. (#2377)
shiny 1.3.0
===========
# shiny 1.3.0
## Full changelog
@@ -315,8 +462,7 @@ shiny 1.3.0
* Fixed #2247: `renderCachedPlot` now supports using promises for either `expr` or `cacheKeyExpr`. (Shiny v1.2.0 supported async `expr`, but only if `cacheKeyExpr` was async as well; now you can use any combination of sync/async for `expr` and `cacheKeyExpr`.) #2261
shiny 1.2.0
===========
# shiny 1.2.0
This release features plot caching, an important new tool for improving performance and scalability. Using `renderCachedPlot` in place of `renderPlot` can greatly improve responsiveness for apps that show the same plot many times (for example, a dashboard or report where all users view the same data). Shiny gives you a fair amount of control in where the cache is stored and how cached plots are invalidated, so be sure to read [this article](https://shiny.rstudio.com/articles/plot-caching.html) to get the most out of this feature.
@@ -381,8 +527,7 @@ This release features plot caching, an important new tool for improving performa
* Addressed #1864 by changing `optgroup` documentation to use `list` instead of `c`. (#2084)
shiny 1.1.0
===========
# shiny 1.1.0
This is a significant release for Shiny, with a major new feature that was nearly a year in the making: support for asynchronous operations! Until now, R's single-threaded nature meant that performing long-running calculations or tasks from Shiny would bring your app to a halt for other users of that process. This release of Shiny deeply integrates the [promises](https://rstudio.github.io/promises/) package to allow you to execute some tasks asynchronously, including as part of reactive expressions and outputs. See the [promises](https://rstudio.github.io/promises/) documentation to learn more.
@@ -418,7 +563,7 @@ This is a significant release for Shiny, with a major new feature that was nearl
* Removed the (ridiculously outdated) "experimental feature" tag from the reference documentation for `renderUI`. (#2036)
* Addressed #1907: the `ignoreInit` argument was first added only to `observeEvent`. Later, we also added it to `eventReactive`, but forgot to update the documentation. Now done, thanks [@flo12392](https://github.com/flo12392)! (#2036)
* Addressed #1907: the `ignoreInit` argument was first added only to `observeEvent`. Later, we also added it to `eventReactive`, but forgot to update the documentation. Now done, thanks @flo12392! (#2036)
### Bug fixes
@@ -432,7 +577,7 @@ This is a significant release for Shiny, with a major new feature that was nearl
* Fixed #1600: URL-encoded bookmarking did not work with sliders that had dates or date-times. (#1961)
* Fixed #1962: [File dragging and dropping](https://blog.rstudio.com/2017/08/15/shiny-1-0-4/) broke in the presence of jQuery version 3.0 as introduced by the [rhandsontable](https://jrowen.github.io/rhandsontable/) [htmlwidget](https://www.htmlwidgets.org/). (#2005)
* Fixed #1962: [File dragging and dropping](https://posit.co/blog/shiny-1-0-4/) broke in the presence of jQuery version 3.0 as introduced by the [rhandsontable](https://jrowen.github.io/rhandsontable/) [htmlwidget](https://www.htmlwidgets.org/). (#2005)
* Improved the error handling inside the `addResourcePath()` function, to give end users more informative error messages when the `directoryPath` argument cannot be normalized. This is especially useful for `runtime: shiny_prerendered` Rmd documents, like `learnr` tutorials. (#1968)
@@ -455,8 +600,7 @@ This is a significant release for Shiny, with a major new feature that was nearl
In some rare cases, interrupting an application (by pressing Ctrl-C or Esc) may result in the message `Error in execCallbacks(timeoutSecs) : c++ exception (unknown reason)`. Although this message sounds alarming, it is harmless, and will go away in a future version of the later package (more information [here](https://github.com/r-lib/later/issues/55)).
shiny 1.0.5
===========
# shiny 1.0.5
## Full changelog
@@ -469,8 +613,7 @@ shiny 1.0.5
* Fixed #1824: HTTP HEAD requests on static files caused the application to stop. (#1825)
shiny 1.0.4
===========
# shiny 1.0.4
There are three headlining features in this release of Shiny. It is now possible to add and remove tabs from a `tabPanel`; there is a new function, `onStop()`, which registers callbacks that execute when an application exits; and `fileInput`s now can have files dragged and dropped on them. In addition to these features, this release has a number of minor features and bug fixes. See the full changelog below for more details.
@@ -531,8 +674,7 @@ There are three headlining features in this release of Shiny. It is now possible
* Fixed #1474: A `browser()` call in an observer could cause an error in the RStudio IDE on Windows. (#1802)
shiny 1.0.3
================
# shiny 1.0.3
This is a hotfix release of Shiny. With previous versions of Shiny, when running an application on the newly-released version of R, 3.4.0, it would print a message: `Warning in body(fun) : argument is not a function`. This has no effect on the application, but because the message could be alarming to users, we are releasing a new version of Shiny that fixes this issue.
@@ -545,8 +687,7 @@ This is a hotfix release of Shiny. With previous versions of Shiny, when running
* Fixed #1676: On R 3.4.0, running a Shiny application gave a warning: `Warning in body(fun) : argument is not a function`. (#1677)
shiny 1.0.2
================
# shiny 1.0.2
This is a hotfix release of Shiny. The primary reason for this release is because the web host for MathJax JavaScript library is scheduled to be shut down in the next few weeks. After it is shut down, Shiny applications that use MathJax will no longer be able to load the MathJax library if they are run with Shiny 1.0.1 and below. (If you don't know whether your application uses MathJax, it probably does not.) For more information about why the MathJax CDN is shutting down, see https://www.mathjax.org/cdn-shutting-down/.
@@ -565,8 +706,7 @@ This is a hotfix release of Shiny. The primary reason for this release is becaus
* Fixed #1653: wrong code example in documentation. (#1658)
shiny 1.0.1
================
# shiny 1.0.1
This is a maintenance release of Shiny, mostly aimed at fixing bugs and introducing minor features. The most notable additions in this version of Shiny are the introduction of the `reactiveVal()` function (it's like `reactiveValues()`, but it only stores a single value), and that the choices of `radioButtons()` and `checkboxGroupInput()` can now contain HTML content instead of just plain text.
@@ -636,8 +776,7 @@ in shiny apps. For more info, see the documentation (`?updateQueryString` and `?
* Closed #1500: Updated ion.rangeSlider to 2.1.6. (#1540)
shiny 1.0.0
===========
# shiny 1.0.0
Shiny has reached a milestone: version 1.0.0! In the last year, we've added two major features that we considered essential for a 1.0.0 release: bookmarking, and support for testing Shiny applications. As usual, this version of Shiny also includes many minor features and bug fixes.
@@ -702,8 +841,7 @@ Now there's an official way to slow down reactive values and expressions that in
* Updated to Font Awesome 4.7.0.
shiny 0.14.2
============
# shiny 0.14.2
This is a maintenance release of Shiny, with some bug fixes and minor new features.
@@ -731,8 +869,7 @@ This is a maintenance release of Shiny, with some bug fixes and minor new featur
* Fixed a bug where, in versions of R before 3.2, Shiny applications could crash due to a bug in R's implementation of `list2env()`. (#1446)
shiny 0.14.1
============
# shiny 0.14.1
This is a maintenance release of Shiny, with some bug fixes and minor new features.
@@ -762,8 +899,7 @@ This is a maintenance release of Shiny, with some bug fixes and minor new featur
* Updated to jQuery UI 1.12.1. Previously, Shiny included a build of 1.11.4 which was missing the datepicker component due to a conflict with the bootstrap-datepicker used by Shiny's `dateInput()` and `dateRangeInput()`. (#1374)
shiny 0.14
==========
# shiny 0.14
A new Shiny release is upon us! There are many new exciting features, bug fixes, and library updates. We'll just highlight the most important changes here, but you can browse through the full changelog below for details. This will likely be the last release before shiny 1.0, so get out your party hats!
@@ -962,14 +1098,12 @@ There are many more minor features, small improvements, and bug fixes than we ca
* Updated to jQuery 1.12.4.
shiny 0.13.2
============
# shiny 0.13.2
* Updated documentation for `htmlTemplate`.
shiny 0.13.1
============
# shiny 0.13.1
* `flexCol` did not work on RStudio for Windows or Linux.
@@ -978,8 +1112,7 @@ shiny 0.13.1
* BREAKING CHANGE: The long-deprecated ability to pass functions (rather than expressions) to reactive() and observe() has finally been removed.
shiny 0.13.0
============
# shiny 0.13.0
* Fixed #962: plot interactions did not work with the development version of ggplot2 (after ggplot2 1.0.1).
@@ -1030,8 +1163,7 @@ shiny 0.13.0
* Added support for the new htmltools 0.3 feature `htmlTemplate`. It's now possible to use regular HTML markup to design your UI, but still use R expressions to define inputs, outputs, and HTML widgets.
shiny 0.12.2
============
# shiny 0.12.2
* GitHub changed URLs for gists from .tar.gz to .zip, so `runGist` was updated to work with the new URLs.
@@ -1054,16 +1186,14 @@ shiny 0.12.2
* Shiny now correctly handles HTTP HEAD requests. (#876)
shiny 0.12.1
============
# shiny 0.12.1
* Fixed an issue where unbindAll() causes subsequent bindAll() to be ignored for previously bound outputs. (#856)
* Undeprecate `dataTableOutput` and `renderDataTable`, which had been deprecated in favor of the new DT package. The DT package is a bit too new and has a slightly different API, we were too hasty in deprecating the existing Shiny functions.
shiny 0.12.0
============
# shiny 0.12.0
In addition to the changes listed below (in the *Full Changelog* section), there is an infrastructure change that could affect existing Shiny apps.
@@ -1119,8 +1249,7 @@ Shiny 0.12.0 deprecated Shiny's dataTableOutput and renderDataTable functions an
* renderDataTable() and dataTableOutput() have been deprecated in shiny and will be removed in future versions of shiny. Please use the DT package instead: http://rstudio.github.io/DT/ (#807)
shiny 0.11.1
============
# shiny 0.11.1
* Major client-side performance improvements for pages that have many conditionalPanels, tabPanels, and plotOutputs. (#693, #717, #723)
@@ -1147,8 +1276,7 @@ shiny 0.11.1
* downloadHandler content callback functions are now invoked with a temp file name that has the same extension as the final filename that will be used by the download. This is to deal with the fact that some file writing functions in R will auto-append the extension for their file type (pdf, zip).
shiny 0.11
==========
# shiny 0.11
Shiny 0.11 switches away from the Bootstrap 2 web framework to the next version, Bootstrap 3. This is in part because Bootstrap 2 is no longer being developed, and in part because it allows us to tap into the ecosystem of Bootstrap 3 themes.
@@ -1226,20 +1354,17 @@ Along with the release of Shiny 0.11, we've packaged up some Bootstrap 3 themes
* Password input fields can now be used, with `passwordInput()`. (#672)
shiny 0.10.2.2
==============
# shiny 0.10.2.2
* Remove use of `rstudio::viewer` in a code example, for R CMD check.
shiny 0.10.2.1
==============
# shiny 0.10.2.1
* Changed some examples to use \donttest instead of \dontrun.
shiny 0.10.2
============
# shiny 0.10.2
* The minimal version of R required for the shiny package is 3.0.0 now.
@@ -1272,8 +1397,7 @@ shiny 0.10.2
* Added `position` parameter to `navbarPage`.
shiny 0.10.1
============
# shiny 0.10.1
* Added Unicode support for Windows. Shiny apps running on Windows must use the UTF-8 encoding for ui.R and server.R (also the optional global.R) if they contain non-ASCII characters. See this article for details and examples: http://shiny.rstudio.com/gallery/unicode-characters.html (#516)
@@ -1286,8 +1410,7 @@ shiny 0.10.1
* Added support for option groups in the select/selectize inputs. When the `choices` argument for `selectInput()`/`selectizeInput()` is a list of sub-lists and any sub-list is of length greater than 1, the HTML tag `<optgroup>` will be used. See an example at http://shiny.rstudio.com/gallery/option-groups-for-selectize-input.html (#542)
shiny 0.10.0
============
# shiny 0.10.0
* BREAKING CHANGE: By default, observers now terminate themselves if they were created during a session and that session ends. See ?domains for more details.
@@ -1324,14 +1447,12 @@ shiny 0.10.0
* `runGitHub()` can also take a value of the form "username/repo" in its first argument, e.g. both runGitHub("shiny_example", "rstudio") and runGitHub("rstudio/shiny_example") are valid ways to run the GitHub repo.
shiny 0.9.1
===========
# shiny 0.9.1
* Fixed warning 'Error in Context$new : could not find function "loadMethod"' that was happening to dependent packages on "R CMD check".
shiny 0.9.0
===========
# shiny 0.9.0
* BREAKING CHANGE: Added a `host` parameter to runApp() and runExample(), which defaults to the shiny.host option if it is non-NULL, or "127.0.0.1" otherwise. This means that by default, Shiny applications can only be accessed on the same machine from which they are served. To allow other clients to connect, as in previous versions of Shiny, use "0.0.0.0" (or the IP address of one of your network interfaces, if you care to be explicit about it).
@@ -1404,8 +1525,7 @@ shiny 0.9.0
* Dots are now legal characters for inputId/outputId. (Thanks, Kevin Lindquist. #358)
shiny 0.8.0
===========
# shiny 0.8.0
* Debug hooks are registered on all user-provided functions and (reactive) expressions (e.g., in renderPlot()), which makes it possible to set breakpoints in these functions using the latest version of the RStudio IDE, and the RStudio visual debugging tools can be used to debug Shiny apps. Internally, the registration is done via installExprFunction(), which is a new function introduced in this version to replace exprToFunction() so that the registration can be automatically done.
@@ -1424,8 +1544,7 @@ shiny 0.8.0
* The minimal required version for the httpuv package was increased to 1.2 (on CRAN now).
shiny 0.7.0
===========
# shiny 0.7.0
* Stopped sending websocket subprotocol. This fixes a compatibility issue with Google Chrome 30.
@@ -1454,8 +1573,7 @@ shiny 0.7.0
* Add shiny.sharedSecret option, to require the HTTP header Shiny-Shared-Secret to be set to the given value.
shiny 0.6.0
===========
# shiny 0.6.0
* `tabsetPanel()` can be directed to start with a specific tab selected.
@@ -1486,8 +1604,7 @@ shiny 0.6.0
* Shiny apps can be run without a server.r and ui.r file.
shiny 0.5.0
===========
# shiny 0.5.0
* Switch from websockets package for handling websocket connections to httpuv.
@@ -1504,16 +1621,14 @@ shiny 0.5.0
* Fix bug #55, where `renderTable()` would throw error with an empty data frame.
shiny 0.4.1
===========
# shiny 0.4.1
* Fix bug where width and height weren't passed along properly from `reactivePlot` to `renderPlot`.
* Fix bug where infinite recursion would happen when `reactivePlot` was passed a function for width or height.
shiny 0.4.0
===========
# shiny 0.4.0
* Added suspend/resume capability to observers.
@@ -1528,8 +1643,7 @@ shiny 0.4.0
* Fixed a bug where empty values in a numericInput were sent to the R process as 0. They are now sent as NA.
shiny 0.3.1
===========
# shiny 0.3.1
* Fix issue #91: bug where downloading files did not work.
@@ -1538,8 +1652,7 @@ shiny 0.3.1
* Reactive functions now preserve the visible/invisible state of their returned values.
shiny 0.3.0
===========
# shiny 0.3.0
* Reactive functions are now evaluated lazily.
@@ -1564,52 +1677,44 @@ shiny 0.3.0
* Fix issue #64, where pressing Enter in a textbox would cause a form to submit.
shiny 0.2.4
===========
# shiny 0.2.4
* `runGist` has been updated to use the new download URLs from https://gist.github.com.
* Shiny now uses `CairoPNG()` for output, when the Cairo package is available. This provides better-looking output on Linux and Windows.
shiny 0.2.3
===========
# shiny 0.2.3
* Ignore request variables for routing purposes
shiny 0.2.2
===========
# shiny 0.2.2
* Fix CRAN warning (assigning to global environment)
shiny 0.2.1
===========
# shiny 0.2.1
* [BREAKING] Modify API of `downloadHandler`: The `content` function now takes a file path, not writable connection, as an argument. This makes it much easier to work with APIs that only write to file paths, not connections.
shiny 0.2.0
===========
# shiny 0.2.0
* Fix subtle name resolution bug--the usual symptom being S4 methods not being invoked correctly when called from inside of ui.R or server.R
shiny 0.1.14
===========
# shiny 0.1.14
* Fix slider animator, which broke in 0.1.10
shiny 0.1.13
===========
# shiny 0.1.13
* Fix temp file leak in reactivePlot
shiny 0.1.12
===========
# shiny 0.1.12
* Fix problems with runGist on Windows
@@ -1618,8 +1723,7 @@ shiny 0.1.12
* Add CSS hooks for app-wide busy indicators
shiny 0.1.11
===========
# shiny 0.1.11
* Fix input binding with IE8 on Shiny Server
@@ -1628,8 +1732,7 @@ shiny 0.1.11
* Allow dynamic sizing of reactivePlot (i.e. using a function instead of a fixed value)
shiny 0.1.10
===========
# shiny 0.1.10
* Support more MIME types when serving out of www
@@ -1642,8 +1745,7 @@ shiny 0.1.10
* Fix plot rendering with IE8 on Shiny Server
shiny 0.1.9
===========
# shiny 0.1.9
* Much less flicker when updating plots
@@ -1652,8 +1754,7 @@ shiny 0.1.9
* Add `includeText`, `includeHTML`, and `includeMarkdown` functions for putting text, HTML, and Markdown content from external files in the application's UI.
shiny 0.1.8
===========
# shiny 0.1.8
* Add `runGist` function for conveniently running a Shiny app that is published on gist.github.com.
@@ -1666,8 +1767,7 @@ shiny 0.1.8
* Add `bootstrapPage` function for creating new Bootstrap based layouts from scratch.
shiny 0.1.7
===========
# shiny 0.1.7
* Fix issue #26: Shiny.OutputBindings not correctly exported.
@@ -1676,8 +1776,7 @@ shiny 0.1.7
* Transcode JSON into UTF-8 (prevents non-ASCII reactivePrint values from causing errors on Windows).
shiny 0.1.6
===========
# shiny 0.1.6
* Import package dependencies, instead of attaching them (with the exception of websockets, which doesn't currently work unless attached).
@@ -1686,8 +1785,7 @@ shiny 0.1.6
* bindAll was not correctly sending initial values to the server; fixed.
shiny 0.1.5
===========
# shiny 0.1.5
* BREAKING CHANGE: JS APIs Shiny.bindInput and Shiny.bindOutput removed and replaced with Shiny.bindAll; Shiny.unbindInput and Shiny.unbindOutput removed and replaced with Shiny.unbindAll.
@@ -1702,8 +1800,7 @@ shiny 0.1.5
* htmlOutput (CSS class `shiny-html-output`) can contain inputs and outputs.
shiny 0.1.4
===========
# shiny 0.1.4
* Allow Bootstrap tabsets to act as reactive inputs; their value indicates which tab is active
@@ -1716,8 +1813,7 @@ shiny 0.1.4
* Add Shiny.bindInputs(scope), .unbindInputs(scope), .bindOutputs(scope), and .unbindOutputs(scope) JS API calls to allow dynamic binding/unbinding of HTML elements
shiny 0.1.3
===========
# shiny 0.1.3
* Introduce Shiny.inputBindings.register JS API and InputBinding class, for creating custom input controls
@@ -1730,7 +1826,6 @@ shiny 0.1.3
* Fix issue #10: Plots in tabsets not rendered
shiny 0.1.2
===========
# shiny 0.1.2
* Initial private beta release!

View File

@@ -10,8 +10,7 @@
#' 2: app.R : Main application file
#' 3: R/example.R : Helper file with R code
#' 4: R/example-module.R : Example module
#' 5: tests/shinytest/ : Tests using the shinytest package
#' 6: tests/testthat/ : Tests using the testthat package
#' 5: tests/testthat/ : Tests using the testthat and shinytest2 package
#' ```
#'
#' If option 1 is selected, the full example application including the
@@ -24,13 +23,12 @@
#' | |- example-module.R
#' | `- example.R
#' `- tests
#' |- shinytest.R
#' |- shinytest
#' | `- mytest.R
#' |- testthat.R
#' `- testthat
#' |- setup-shinytest2.R
#' |- test-examplemodule.R
#' |- test-server.R
#' |- test-shinytest2.R
#' `- test-sort.R
#' ```
#'
@@ -45,20 +43,21 @@
#' * `tests/` contains various tests for the application. You may
#' choose to use or remove any of them. They can be executed by the
#' [runTests()] function.
#' * `tests/shinytest.R` is a test runner for test files in the
#' `tests/shinytest/` directory.
#' * `tests/shinytest/mytest.R` is a test that uses the
#' [shinytest](https://rstudio.github.io/shinytest/) package to do
#' snapshot-based testing.
#' * `tests/testthat.R` is a test runner for test files in the
#' `tests/testthat/` directory using the [testthat](https://testthat.r-lib.org/) package.
#' `tests/testthat/` directory using the
#' [shinytest2](https://rstudio.github.io/shinytest2/reference/test_app.html)
#' package.
#' * `tests/testthat/setup-shinytest2.R` is setup file to source your `./R` folder into the testing environment.
#' * `tests/testthat/test-examplemodule.R` is a test for an application's module server function.
#' * `tests/testthat/test-server.R` is a test for the application's server code
#' * `tests/testthat/test-shinytest2.R` is a test that uses the
#' [shinytest2](https://rstudio.github.io/shinytest2/) package to do
#' snapshot-based testing.
#' * `tests/testthat/test-sort.R` is a test for a supporting function in the `R/` directory.
#'
#' @param path Path to create new shiny application template.
#' @param examples Either one of "default", "ask", "all", or any combination of
#' "app", "rdir", "module", "shinytest", and "testthat". In an
#' "app", "rdir", "module", and "tests". In an
#' interactive session, "default" falls back to "ask"; in a non-interactive
#' session, "default" falls back to "all". With "ask", this function will
#' prompt the user to select which template items will be added to the new app
@@ -79,15 +78,19 @@ shinyAppTemplate <- function(path = NULL, examples = "default", dryrun = FALSE)
# =======================================================
choices <- c(
app = "app.R : Main application file",
rdir = "R/example.R : Helper file with R code",
module = "R/example-module.R : Example module",
shinytest = "tests/shinytest/ : Tests using the shinytest package",
testthat = "tests/testthat/ : Tests using the testthat package"
app = "app.R : Main application file",
rdir = "R/example.R : Helper file with R code",
module = "R/example-module.R : Example module",
tests = "tests/testthat/ : Tests using {testthat} and {shinytest2}"
)
# Support legacy value
examples[examples == "shinytest"] <- "tests"
examples[examples == "testthat"] <- "tests"
examples <- unique(examples)
if (identical(examples, "default")) {
if (interactive()) {
if (rlang::is_interactive()) {
examples <- "ask"
} else {
examples <- "all"
@@ -124,18 +127,8 @@ shinyAppTemplate <- function(path = NULL, examples = "default", dryrun = FALSE)
return(invisible())
}
if ("shinytest" %in% examples) {
if (!is_available("shinytest", "1.4.0"))
{
message(
"The tests/shinytest directory needs shinytest 1.4.0 or later to work properly."
)
if (is_available("shinytest")) {
message("You currently have shinytest ",
utils::packageVersion("shinytest"), " installed.")
}
}
if ("tests" %in% examples) {
rlang::check_installed("shinytest2", "for {testthat} tests to work as expected", version = "0.2.0")
}
# =======================================================
@@ -152,7 +145,7 @@ shinyAppTemplate <- function(path = NULL, examples = "default", dryrun = FALSE)
# Helper to resolve paths relative to our template
template_path <- function(...) {
system.file("app_template", ..., package = "shiny")
system_file("app_template", ..., package = "shiny")
}
# Resolve path relative to destination
@@ -208,16 +201,13 @@ shinyAppTemplate <- function(path = NULL, examples = "default", dryrun = FALSE)
}
# Copy the files for a tests/ subdirectory
copy_test_dir <- function(name) {
copy_test_dir <- function() {
files <- dir(template_path("tests"), recursive = TRUE)
# Note: This is not the same as using dir(pattern = "^shinytest"), since
# that will not match files inside of shinytest/.
files <- files[grepl(paste0("^", name), files)]
# Filter out files that are not module files in the R directory.
if (! "rdir" %in% examples) {
# find all files in the testthat folder that are not module or server files
is_r_folder_file <- (!grepl("module|server", basename(files))) & (dirname(files) == "testthat")
is_r_folder_file <- !grepl("module|server|shinytest2|testthat", basename(files))
files <- files[!is_r_folder_file]
}
@@ -282,12 +272,10 @@ shinyAppTemplate <- function(path = NULL, examples = "default", dryrun = FALSE)
copy_file(file.path("R", module_files))
}
# tests/ dir
if ("shinytest" %in% examples) {
copy_test_dir("shinytest")
}
if ("testthat" %in% examples) {
copy_test_dir("testthat")
# tests/testthat dir
if ("tests" %in% examples) {
copy_test_dir()
}
invisible()
}

View File

@@ -159,8 +159,8 @@ utils::globalVariables(".GenericCallEnv", add = TRUE)
#' ```
#'
#' To use different settings for a session-scoped cache, you can set
#' `self$cache` at the top of your server function. By default, it will create
#' a 200 MB memory cache for each session, but you can replace it with
#' `session$cache` at the top of your server function. By default, it will
#' create a 200 MB memory cache for each session, but you can replace it with
#' something different. To use the session-scoped cache, you must also call
#' `bindCache()` with `cache="session"`. This will create a 100 MB cache for
#' the session:
@@ -255,7 +255,7 @@ utils::globalVariables(".GenericCallEnv", add = TRUE)
#' the cache.
#'
#' You may need to provide a `cacheHint` to [createRenderFunction()] (or
#' [htmlwidgets::shinyRenderWidget()], if you've authored an htmlwidget) in
#' `htmlwidgets::shinyRenderWidget()`, if you've authored an htmlwidget) in
#' order for `bindCache()` to correctly compute a cache key.
#'
#' The potential problem is a cache collision. Consider the following:
@@ -292,11 +292,11 @@ utils::globalVariables(".GenericCallEnv", add = TRUE)
#' In some cases, however, the automatic cache hint inference is not
#' sufficient, and it is necessary to provide a cache hint. This is true
#' for `renderPrint()`. Unlike `renderText()`, it wraps the user-provided
#' expression in another function, before passing it to [markRenderFunction()]
#' expression in another function, before passing it to [createRenderFunction()]
#' (instead of [createRenderFunction()]). Because the user code is wrapped in
#' another function, `markRenderFunction()` is not able to automatically
#' another function, `createRenderFunction()` is not able to automatically
#' extract the user-provided code and use it in the cache key. Instead,
#' `renderPrint` calls `markRenderFunction()`, it explicitly passes along a
#' `renderPrint` calls `createRenderFunction()`, it explicitly passes along a
#' `cacheHint`, which includes a label and the original user expression.
#'
#' In general, if you need to provide a `cacheHint`, it is best practice to
@@ -310,19 +310,19 @@ utils::globalVariables(".GenericCallEnv", add = TRUE)
#'
#' ```
#' renderMyWidget <- function(expr) {
#' expr <- substitute(expr)
#' q <- rlang::enquo0(expr)
#'
#' htmlwidgets::shinyRenderWidget(expr,
#' htmlwidgets::shinyRenderWidget(
#' q,
#' myWidgetOutput,
#' quoted = TRUE,
#' env = parent.frame(),
#' cacheHint = list(label = "myWidget", userExpr = expr)
#' cacheHint = list(label = "myWidget", userQuo = q)
#' )
#' }
#' ```
#'
#' If your `render` function sets any internal state, you may find it useful
#' in your call to [createRenderFunction()] or [markRenderFunction()] to use
#' in your call to [createRenderFunction()] to use
#' the `cacheWriteHook` and/or `cacheReadHook` parameters. These hooks are
#' functions that run just before the object is stored in the cache, and just
#' after the object is retrieved from the cache. They can modify the data
@@ -339,8 +339,8 @@ utils::globalVariables(".GenericCallEnv", add = TRUE)
#' effects or modify some external state, and they must re-execute each time
#' in order to work properly.
#'
#' For developers of such code, they should call [createRenderFunction()] or
#' [markRenderFunction()] with `cacheHint = FALSE`.
#' For developers of such code, they should call [createRenderFunction()] (or
#' [markRenderFunction()]) with `cacheHint = FALSE`.
#'
#'
#' @section Caching with `renderPlot()`:

View File

@@ -321,34 +321,38 @@ RestoreContext <- R6Class("RestoreContext",
if (substr(queryString, 1, 1) == '?')
queryString <- substr(queryString, 2, nchar(queryString))
# The "=" after "_inputs_" is optional. Shiny doesn't generate URLs with
# "=", but httr always adds "=".
inputs_reg <- "(^|&)_inputs_=?(&|$)"
values_reg <- "(^|&)_values_=?(&|$)"
# Error if multiple '_inputs_' or '_values_'. This is needed because
# strsplit won't add an entry if the search pattern is at the end of a
# string.
if (length(gregexpr("(^|&)_inputs_(&|$)", queryString)[[1]]) > 1)
if (length(gregexpr(inputs_reg, queryString)[[1]]) > 1)
stop("Invalid state string: more than one '_inputs_' found")
if (length(gregexpr("(^|&)_values_(&|$)", queryString)[[1]]) > 1)
if (length(gregexpr(values_reg, queryString)[[1]]) > 1)
stop("Invalid state string: more than one '_values_' found")
# Look for _inputs_ and store following content in inputStr
splitStr <- strsplit(queryString, "(^|&)_inputs_(&|$)")[[1]]
splitStr <- strsplit(queryString, inputs_reg)[[1]]
if (length(splitStr) == 2) {
inputStr <- splitStr[2]
# Remove any _values_ (and content after _values_) that may come after
# _inputs_
inputStr <- strsplit(inputStr, "(^|&)_values_(&|$)")[[1]][1]
inputStr <- strsplit(inputStr, values_reg)[[1]][1]
} else {
inputStr <- ""
}
# Look for _values_ and store following content in valueStr
splitStr <- strsplit(queryString, "(^|&)_values_(&|$)")[[1]]
splitStr <- strsplit(queryString, values_reg)[[1]]
if (length(splitStr) == 2) {
valueStr <- splitStr[2]
# Remove any _inputs_ (and content after _inputs_) that may come after
# _values_
valueStr <- strsplit(valueStr, "(^|&)_inputs_(&|$)")[[1]][1]
valueStr <- strsplit(valueStr, inputs_reg)[[1]][1]
} else {
valueStr <- ""
@@ -359,16 +363,20 @@ RestoreContext <- R6Class("RestoreContext",
values <- parseQueryString(valueStr, nested = TRUE)
valuesFromJSON <- function(vals) {
mapply(names(vals), vals, SIMPLIFY = FALSE,
varsUnparsed <- c()
valsParsed <- mapply(names(vals), vals, SIMPLIFY = FALSE,
FUN = function(name, value) {
tryCatch(
safeFromJSON(value),
error = function(e) {
stop("Failed to parse URL parameter \"", name, "\"")
varsUnparsed <<- c(varsUnparsed, name)
warning("Failed to parse URL parameter \"", name, "\"")
}
)
}
)
valsParsed[varsUnparsed] <- NULL
valsParsed
}
inputs <- valuesFromJSON(inputs)
@@ -444,8 +452,10 @@ RestoreInputSet <- R6Class("RestoreInputSet",
)
)
# This is a fastmap::faststack(); value is assigned in .onLoad().
restoreCtxStack <- NULL
on_load({
restoreCtxStack <- fastmap::faststack()
})
withRestoreContext <- function(ctx, expr) {
restoreCtxStack$push(ctx)

View File

@@ -6,7 +6,7 @@
#' @param sidebarPanel The [sidebarPanel] containing input controls
#' @param mainPanel The [mainPanel] containing outputs
#' @keywords internal
#' @return A UI defintion that can be passed to the [shinyUI] function
#' @return A UI definition that can be passed to the [shinyUI] function
#' @export
pageWithSidebar <- function(headerPanel,
sidebarPanel,

View File

@@ -11,11 +11,9 @@
#' @param ... Elements to include within the page
#' @param title The browser window title (defaults to the host URL of the page).
#' Can also be set as a side effect of the [titlePanel()] function.
#' @param responsive This option is deprecated; it is no longer optional with
#' Bootstrap 3.
#' @inheritParams bootstrapPage
#'
#' @return A UI defintion that can be passed to the [shinyUI] function.
#' @return A UI definition that can be passed to the [shinyUI] function.
#'
#' @details To create a fluid page use the `fluidPage` function and include
#' instances of `fluidRow` and [column()] within it. As an
@@ -85,10 +83,9 @@
#' }
#' @rdname fluidPage
#' @export
fluidPage <- function(..., title = NULL, responsive = deprecated(), theme = NULL, lang = NULL) {
fluidPage <- function(..., title = NULL, theme = NULL, lang = NULL) {
bootstrapPage(div(class = "container-fluid", ...),
title = title,
responsive = responsive,
theme = theme,
lang = lang)
}
@@ -112,11 +109,9 @@ fluidRow <- function(...) {
#'
#' @param ... Elements to include within the container
#' @param title The browser window title (defaults to the host URL of the page)
#' @param responsive This option is deprecated; it is no longer optional with
#' Bootstrap 3.
#' @inheritParams bootstrapPage
#'
#' @return A UI defintion that can be passed to the [shinyUI] function.
#' @return A UI definition that can be passed to the [shinyUI] function.
#'
#' @details To create a fixed page use the `fixedPage` function and include
#' instances of `fixedRow` and [column()] within it. Note that
@@ -153,10 +148,9 @@ fluidRow <- function(...) {
#'
#' @rdname fixedPage
#' @export
fixedPage <- function(..., title = NULL, responsive = deprecated(), theme = NULL, lang = NULL) {
fixedPage <- function(..., title = NULL, theme = NULL, lang = NULL) {
bootstrapPage(div(class = "container", ...),
title = title,
responsive = responsive,
theme = theme,
lang = lang)
}
@@ -396,7 +390,7 @@ mainPanel <- function(..., width = 8) {
#' }
#' @export
verticalLayout <- function(..., fluid = TRUE) {
lapply(list(...), function(row) {
lapply(list2(...), function(row) {
col <- column(12, row)
if (fluid)
fluidRow(col)
@@ -433,7 +427,7 @@ verticalLayout <- function(..., fluid = TRUE) {
#' @export
flowLayout <- function(..., cellArgs = list()) {
children <- list(...)
children <- list2(...)
childIdx <- !nzchar(names(children) %||% character(length(children)))
attribs <- children[!childIdx]
children <- children[childIdx]
@@ -516,13 +510,13 @@ inputPanel <- function(...) {
#' @export
splitLayout <- function(..., cellWidths = NULL, cellArgs = list()) {
children <- list(...)
children <- list2(...)
childIdx <- !nzchar(names(children) %||% character(length(children)))
attribs <- children[!childIdx]
children <- children[childIdx]
count <- length(children)
if (length(cellWidths) == 0 || is.na(cellWidths)) {
if (length(cellWidths) == 0 || isTRUE(is.na(cellWidths))) {
cellWidths <- sprintf("%.3f%%", 100 / count)
}
cellWidths <- rep(cellWidths, length.out = count)
@@ -614,7 +608,7 @@ fillCol <- function(..., flex = 1, width = "100%", height = "100%") {
}
flexfill <- function(..., direction, flex, width = width, height = height) {
children <- list(...)
children <- list2(...)
attrs <- list()
if (!is.null(names(children))) {

View File

@@ -14,8 +14,6 @@ NULL
#'
#' @param ... The contents of the document body.
#' @param title The browser window title (defaults to the host URL of the page)
#' @param responsive This option is deprecated; it is no longer optional with
#' Bootstrap 3.
#' @param theme One of the following:
#' * `NULL` (the default), which implies a "stock" build of Bootstrap 3.
#' * A [bslib::bs_theme()] object. This can be used to replace a stock
@@ -26,30 +24,24 @@ NULL
#' This will be used as the lang in the \code{<html>} tag, as in \code{<html lang="en">}.
#' The default (NULL) results in an empty string.
#'
#' @return A UI defintion that can be passed to the [shinyUI] function.
#' @return A UI definition that can be passed to the [shinyUI] function.
#'
#' @note The `basicPage` function is deprecated, you should use the
#' [fluidPage()] function instead.
#'
#' @seealso [fluidPage()], [fixedPage()]
#' @export
bootstrapPage <- function(..., title = NULL, responsive = deprecated(), theme = NULL, lang = NULL) {
if (lifecycle::is_present(responsive)) {
shinyDeprecated(
"0.10.2.2", "bootstrapPage(responsive=)",
details = "The 'responsive' argument is no longer used with the latest version of Bootstrap."
)
}
bootstrapPage <- function(..., title = NULL, theme = NULL, lang = NULL) {
args <- list(
jqueryDependency(),
if (!is.null(title)) tags$head(tags$title(title)),
if (is.character(theme)) {
if (length(theme) > 1) stop("`theme` must point to a single CSS file, not multiple files.")
tags$head(tags$link(rel="stylesheet", type="text/css", href=theme))
},
# remainder of tags passed to the function
list(...)
list2(...)
)
# If theme is a bslib::bs_theme() object, bootstrapLib() needs to come first
@@ -91,6 +83,10 @@ getLang <- function(ui) {
#' @export
bootstrapLib <- function(theme = NULL) {
tagFunction(function() {
if (isRunning()) {
setCurrentTheme(theme)
}
# If we're not compiling Bootstrap Sass (from bslib), return the
# static Bootstrap build.
if (!is_bs_theme(theme)) {
@@ -112,7 +108,6 @@ bootstrapLib <- function(theme = NULL) {
# Note also that since this is shinyOptions() (and not options()), the
# option is automatically reset when the app (or session) exits
if (isRunning()) {
setCurrentTheme(theme)
registerThemeDependency(bs_theme_deps)
} else {
@@ -143,8 +138,7 @@ bs_theme_deps <- function(theme) {
}
is_bs_theme <- function(x) {
is_available("bslib", "0.2.0.9000") &&
bslib::is_bs_theme(x)
bslib::is_bs_theme(x)
}
#' Obtain Shiny's Bootstrap Sass theme
@@ -163,6 +157,15 @@ getCurrentTheme <- function() {
getShinyOption("bootstrapTheme", default = NULL)
}
getCurrentThemeVersion <- function() {
theme <- getCurrentTheme()
if (bslib::is_bs_theme(theme)) {
bslib::theme_version(theme)
} else {
strsplit(bootstrapVersion, ".", fixed = TRUE)[[1]][[1]]
}
}
setCurrentTheme <- function(theme) {
shinyOptions(bootstrapTheme = theme)
}
@@ -211,11 +214,10 @@ registerThemeDependency <- function(func) {
bootstrapDependency <- function(theme) {
htmlDependency(
"bootstrap", "3.4.1",
c(
href = "shared/bootstrap",
file = system.file("www/shared/bootstrap", package = "shiny")
),
"bootstrap",
bootstrapVersion,
src = "www/shared/bootstrap",
package = "shiny",
script = c(
"js/bootstrap.min.js",
# Safely adding accessibility plugin for screen readers and keyboard users; no break for sighted aspects (see https://github.com/paypal/bootstrap-accessibility-plugin)
@@ -230,6 +232,8 @@ bootstrapDependency <- function(theme) {
)
}
bootstrapVersion <- "3.4.1"
#' @rdname bootstrapPage
#' @export
@@ -370,19 +374,17 @@ collapseSizes <- function(padding) {
#' @param inverse `TRUE` to use a dark background and light text for the
#' navigation bar
#' @param collapsible `TRUE` to automatically collapse the navigation
#' elements into a menu when the width of the browser is less than 940 pixels
#' (useful for viewing on smaller touchscreen device)
#' @param collapsable Deprecated; use `collapsible` instead.
#' elements into an expandable menu on mobile devices or narrow window widths.
#' @param fluid `TRUE` to use a fluid layout. `FALSE` to use a fixed
#' layout.
#' @param responsive This option is deprecated; it is no longer optional with
#' Bootstrap 3.
#' @param windowTitle The title that should be displayed by the browser window.
#' Useful if `title` is not a string.
#' @param windowTitle the browser window title (as a character string). The
#' default value, `NA`, means to use any character strings that appear in
#' `title` (if none are found, the host URL of the page is displayed by
#' default).
#' @inheritParams bootstrapPage
#' @param icon Optional icon to appear on a `navbarMenu` tab.
#'
#' @return A UI defintion that can be passed to the [shinyUI] function.
#' @return A UI definition that can be passed to the [shinyUI] function.
#'
#' @details The `navbarMenu` function can be used to create an embedded
#' menu within the navbar that in turns includes additional tabPanels (see
@@ -420,86 +422,20 @@ navbarPage <- function(title,
footer = NULL,
inverse = FALSE,
collapsible = FALSE,
collapsable = deprecated(),
fluid = TRUE,
responsive = deprecated(),
theme = NULL,
windowTitle = title,
windowTitle = NA,
lang = NULL) {
if (lifecycle::is_present(collapsable)) {
shinyDeprecated("0.10.2.2", "navbarPage(collapsable =)", "navbarPage(collapsible =)")
collapsible <- collapsable
}
# alias title so we can avoid conflicts w/ title in withTags
pageTitle <- title
# navbar class based on options
navbarClass <- "navbar navbar-default"
position <- match.arg(position)
if (!is.null(position))
navbarClass <- paste(navbarClass, " navbar-", position, sep = "")
if (inverse)
navbarClass <- paste(navbarClass, "navbar-inverse")
if (!is.null(id))
selected <- restoreInput(id = id, default = selected)
# build the tabset
tabs <- list(...)
tabset <- buildTabset(tabs, "nav navbar-nav", NULL, id, selected)
# function to return plain or fluid class name
className <- function(name) {
if (fluid)
paste(name, "-fluid", sep="")
else
name
}
# built the container div dynamically to support optional collapsibility
if (collapsible) {
navId <- paste("navbar-collapse-", p_randomInt(1000, 10000), sep="")
containerDiv <- div(class=className("container"),
div(class="navbar-header",
tags$button(type="button", class="navbar-toggle collapsed",
`data-toggle`="collapse", `data-target`=paste0("#", navId),
span(class="sr-only", "Toggle navigation"),
span(class="icon-bar"),
span(class="icon-bar"),
span(class="icon-bar")
),
span(class="navbar-brand", pageTitle)
),
div(class="navbar-collapse collapse", id=navId, tabset$navList)
)
} else {
containerDiv <- div(class=className("container"),
div(class="navbar-header",
span(class="navbar-brand", pageTitle)
),
tabset$navList
)
}
# build the main tab content div
contentDiv <- div(class=className("container"))
if (!is.null(header))
contentDiv <- tagAppendChild(contentDiv, div(class="row", header))
contentDiv <- tagAppendChild(contentDiv, tabset$content)
if (!is.null(footer))
contentDiv <- tagAppendChild(contentDiv, div(class="row", footer))
# build the page
bootstrapPage(
title = windowTitle,
responsive = responsive,
remove_first_class(bslib::page_navbar(
..., title = title, id = id, selected = selected,
position = match.arg(position),
header = header, footer = footer,
inverse = inverse, collapsible = collapsible,
fluid = fluid,
theme = theme,
lang = lang,
tags$nav(class=navbarClass, role="navigation", containerDiv),
contentDiv
)
window_title = windowTitle,
lang = lang
))
}
#' @param menuName A name that identifies this `navbarMenu`. This
@@ -509,11 +445,7 @@ navbarPage <- function(title,
#' @rdname navbarPage
#' @export
navbarMenu <- function(title, ..., menuName = title, icon = NULL) {
structure(list(title = title,
menuName = menuName,
tabs = list(...),
iconClass = iconClass(icon)),
class = "shiny.navbarmenu")
bslib::nav_menu(title, ..., value = menuName, icon = icon)
}
#' Create a well panel
@@ -648,27 +580,14 @@ helpText <- function(...) {
#' @export
#' @describeIn tabPanel Create a tab panel that can be included within a [tabsetPanel()] or a [navbarPage()].
tabPanel <- function(title, ..., value = title, icon = NULL) {
div(
class = "tab-pane",
title = title,
`data-value` = value,
`data-icon-class` = iconClass(icon),
...
)
bslib::nav(title, ..., value = value, icon = icon)
}
#' @export
#' @describeIn tabPanel Create a tab panel that drops the title argument.
#' This function should be used within `tabsetPanel(type = "hidden")`. See [tabsetPanel()] for example usage.
tabPanelBody <- function(value, ..., icon = NULL) {
if (
!is.character(value) ||
length(value) != 1 ||
any(is.na(value)) ||
nchar(value) == 0
) {
stop("`value` must be a single, non-empty string value")
}
tabPanel(title = NULL, ..., value = value, icon = icon)
bslib::nav_content(value, ..., icon = icon)
}
#' Create a tabset panel
@@ -691,8 +610,7 @@ tabPanelBody <- function(value, ..., icon = NULL) {
#' conjunction with [tabPanelBody()] and [updateTabsetPanel()] to control the
#' active tab via other input controls. (See example below)}
#' }
#' @param position This argument is deprecated; it has been discontinued in
#' Bootstrap 3.
#' @inheritParams navbarPage
#' @return A tabset that can be passed to [mainPanel()]
#'
#' @seealso [tabPanel()], [updateTabsetPanel()],
@@ -742,29 +660,21 @@ tabsetPanel <- function(...,
id = NULL,
selected = NULL,
type = c("tabs", "pills", "hidden"),
position = deprecated()) {
if (lifecycle::is_present(position)) {
shinyDeprecated(
"0.10.2.2", "bootstrapPage(position =)",
details = "The 'position' argument is no longer used with the latest version of Bootstrap."
)
}
header = NULL,
footer = NULL) {
if (!is.null(id))
selected <- restoreInput(id = id, default = selected)
func <- switch(
match.arg(type),
tabs = bslib::navs_tab,
pills = bslib::navs_pill,
hidden = bslib::navs_hidden
)
# build the tabset
tabs <- list(...)
type <- match.arg(type)
tabset <- buildTabset(tabs, paste0("nav nav-", type), NULL, id, selected)
# create the content
first <- tabset$navList
second <- tabset$content
# create the tab div
tags$div(class = "tabbable", first, second)
# bslib adds a class to make the content browsable() by default,
# but that's probably too big of a change for shiny
remove_first_class(
func(..., id = id, selected = selected, header = header, footer = footer)
)
}
#' Create a navigation list panel
@@ -784,8 +694,10 @@ tabsetPanel <- function(...,
#' navigation list.
#' @param fluid `TRUE` to use fluid layout; `FALSE` to use fixed
#' layout.
#' @param widths Column withs of the navigation list and tabset content areas
#' @param widths Column widths of the navigation list and tabset content areas
#' respectively.
#' @inheritParams tabsetPanel
#' @inheritParams navbarPage
#'
#' @details You can include headers within the `navlistPanel` by including
#' plain text elements in the list. Versions of Shiny before 0.11 supported
@@ -812,194 +724,23 @@ tabsetPanel <- function(...,
navlistPanel <- function(...,
id = NULL,
selected = NULL,
header = NULL,
footer = NULL,
well = TRUE,
fluid = TRUE,
widths = c(4, 8)) {
# text filter for headers
textFilter <- function(text) {
tags$li(class="navbar-brand", text)
}
if (!is.null(id))
selected <- restoreInput(id = id, default = selected)
# build the tabset
tabs <- list(...)
tabset <- buildTabset(tabs,
"nav nav-pills nav-stacked",
textFilter,
id,
selected)
# create the columns
columns <- list(
column(widths[[1]], class=ifelse(well, "well", ""), tabset$navList),
column(widths[[2]], tabset$content)
)
# return the row
if (fluid)
fluidRow(columns)
else
fixedRow(columns)
remove_first_class(bslib::navs_pill_list(
..., id = id, selected = selected,
header = header, footer = footer,
well = well, fluid = fluid, widths = widths
))
}
# Helpers to build tabsetPanels (& Co.) and their elements
markTabAsSelected <- function(x) {
attr(x, "selected") <- TRUE
remove_first_class <- function(x) {
class(x) <- class(x)[-1]
x
}
isTabSelected <- function(x) {
isTRUE(attr(x, "selected", exact = TRUE))
}
containsSelectedTab <- function(tabs) {
any(vapply(tabs, isTabSelected, logical(1)))
}
findAndMarkSelectedTab <- function(tabs, selected, foundSelected) {
tabs <- lapply(tabs, function(div) {
if (foundSelected || is.character(div)) {
# Strings are not selectable items
} else if (inherits(div, "shiny.navbarmenu")) {
# Recur for navbarMenus
res <- findAndMarkSelectedTab(div$tabs, selected, foundSelected)
div$tabs <- res$tabs
foundSelected <<- res$foundSelected
} else {
# Base case: regular tab item. If the `selected` argument is
# provided, check for a match in the existing tabs; else,
# mark first available item as selected
if (is.null(selected)) {
foundSelected <<- TRUE
div <- markTabAsSelected(div)
} else {
tabValue <- div$attribs$`data-value` %||% div$attribs$title
if (identical(selected, tabValue)) {
foundSelected <<- TRUE
div <- markTabAsSelected(div)
}
}
}
return(div)
})
return(list(tabs = tabs, foundSelected = foundSelected))
}
# Returns the icon object (or NULL if none), provided either a
# tabPanel, OR the icon class
getIcon <- function(tab = NULL, iconClass = NULL) {
if (!is.null(tab)) iconClass <- tab$attribs$`data-icon-class`
if (!is.null(iconClass)) {
if (grepl("fa-", iconClass, fixed = TRUE)) {
# for font-awesome we specify fixed-width
iconClass <- paste(iconClass, "fa-fw")
}
icon(name = NULL, class = iconClass)
} else NULL
}
# Text filter for navbarMenu's (plain text) separators
navbarMenuTextFilter <- function(text) {
if (grepl("^\\-+$", text)) tags$li(class = "divider")
else tags$li(class = "dropdown-header", text)
}
# This function is called internally by navbarPage, tabsetPanel
# and navlistPanel
buildTabset <- function(tabs, ulClass, textFilter = NULL, id = NULL,
selected = NULL, foundSelected = FALSE) {
res <- findAndMarkSelectedTab(tabs, selected, foundSelected)
tabs <- res$tabs
foundSelected <- res$foundSelected
# add input class if we have an id
if (!is.null(id)) ulClass <- paste(ulClass, "shiny-tab-input")
if (anyNamed(tabs)) {
nms <- names(tabs)
nms <- nms[nzchar(nms)]
stop("Tabs should all be unnamed arguments, but some are named: ",
paste(nms, collapse = ", "))
}
tabsetId <- p_randomInt(1000, 10000)
tabs <- lapply(seq_len(length(tabs)), buildTabItem,
tabsetId = tabsetId, foundSelected = foundSelected,
tabs = tabs, textFilter = textFilter)
tabNavList <- tags$ul(class = ulClass, id = id,
`data-tabsetid` = tabsetId, lapply(tabs, "[[", 1))
tabContent <- tags$div(class = "tab-content",
`data-tabsetid` = tabsetId, lapply(tabs, "[[", 2))
list(navList = tabNavList, content = tabContent)
}
# Builds tabPanel/navbarMenu items (this function used to be
# declared inside the buildTabset() function and it's been
# refactored for clarity and reusability). Called internally
# by buildTabset.
buildTabItem <- function(index, tabsetId, foundSelected, tabs = NULL,
divTag = NULL, textFilter = NULL) {
divTag <- if (!is.null(divTag)) divTag else tabs[[index]]
if (is.character(divTag) && !is.null(textFilter)) {
# text item: pass it to the textFilter if it exists
liTag <- textFilter(divTag)
divTag <- NULL
} else if (inherits(divTag, "shiny.navbarmenu")) {
# navbarMenu item: build the child tabset
tabset <- buildTabset(divTag$tabs, "dropdown-menu",
navbarMenuTextFilter, foundSelected = foundSelected)
# if this navbarMenu contains a selected item, mark it active
containsSelected <- containsSelectedTab(divTag$tabs)
liTag <- tags$li(
class = paste0("dropdown", if (containsSelected) " active"),
tags$a(href = "#",
class = "dropdown-toggle", `data-toggle` = "dropdown",
`data-value` = divTag$menuName,
getIcon(iconClass = divTag$iconClass),
divTag$title, tags$b(class = "caret")
),
tabset$navList # inner tabPanels items
)
# list of tab content divs from the child tabset
divTag <- tabset$content$children
} else {
# tabPanel item: create the tab's liTag and divTag
tabId <- paste("tab", tabsetId, index, sep = "-")
liTag <- tags$li(
tags$a(
href = paste("#", tabId, sep = ""),
`data-toggle` = "tab",
`data-value` = divTag$attribs$`data-value`,
getIcon(iconClass = divTag$attribs$`data-icon-class`),
divTag$attribs$title
)
)
# if this tabPanel is selected item, mark it active
if (isTabSelected(divTag)) {
liTag$attribs$class <- "active"
divTag$attribs$class <- "tab-pane active"
}
divTag$attribs$id <- tabId
divTag$attribs$title <- NULL
}
return(list(liTag = liTag, divTag = divTag))
}
#' Create a text output element
#'
#' Render a reactive output variable as text within an application page.
@@ -1052,7 +793,7 @@ verbatimTextOutput <- function(outputId, placeholder = FALSE) {
#' @export
imageOutput <- function(outputId, width = "100%", height="400px",
click = NULL, dblclick = NULL, hover = NULL, brush = NULL,
inline = FALSE) {
inline = FALSE, fill = FALSE) {
style <- if (!inline) {
# Using `css()` here instead of paste/sprintf so that NULL values will
@@ -1108,7 +849,8 @@ imageOutput <- function(outputId, width = "100%", height="400px",
}
container <- if (inline) span else div
do.call(container, args)
res <- do.call(container, args)
bindFillRole(res, item = fill)
}
#' Create an plot or image output element
@@ -1176,6 +918,11 @@ imageOutput <- function(outputId, width = "100%", height="400px",
#' `imageOutput`/`plotOutput` calls may share the same `id`
#' value; brushing one image or plot will cause any other brushes with the
#' same `id` to disappear.
#' @param fill Whether or not the returned tag should be treated as a fill item,
#' meaning that its `height` is allowed to grow/shrink to fit a fill container
#' with an opinionated height (see [htmltools::bindFillRole()]) with an
#' opinionated height. Examples of fill containers include `bslib::card()` and
#' `bslib::card_body_fill()`.
#' @inheritParams textOutput
#' @note The arguments `clickId` and `hoverId` only work for R base graphics
#' (see the \pkg{\link[graphics:graphics-package]{graphics}} package). They do
@@ -1346,11 +1093,11 @@ imageOutput <- function(outputId, width = "100%", height="400px",
#' @export
plotOutput <- function(outputId, width = "100%", height="400px",
click = NULL, dblclick = NULL, hover = NULL, brush = NULL,
inline = FALSE) {
inline = FALSE, fill = !inline) {
# Result is the same as imageOutput, except for HTML class
res <- imageOutput(outputId, width, height, click, dblclick,
hover, brush, inline)
hover, brush, inline, fill)
res$attribs$class <- "shiny-plot-output"
res
@@ -1365,11 +1112,17 @@ tableOutput <- function(outputId) {
dataTableDependency <- list(
htmlDependency(
"datatables", "1.10.5", c(href = "shared/datatables"),
"datatables",
"1.10.5",
src = "www/shared/datatables",
package = "shiny",
script = "js/jquery.dataTables.min.js"
),
htmlDependency(
"datatables-bootstrap", "1.10.5", c(href = "shared/datatables"),
"datatables-bootstrap",
"1.10.5",
src = "www/shared/datatables",
package = "shiny",
stylesheet = c("css/dataTables.bootstrap.css", "css/dataTables.extra.css"),
script = "js/dataTables.bootstrap.js"
)
@@ -1387,15 +1140,21 @@ dataTableOutput <- function(outputId) {
#' Create an HTML output element
#'
#' Render a reactive output variable as HTML within an application page. The
#' text will be included within an HTML `div` tag, and is presumed to
#' contain HTML content which should not be escaped.
#' text will be included within an HTML `div` tag, and is presumed to contain
#' HTML content which should not be escaped.
#'
#' `uiOutput` is intended to be used with `renderUI` on the server
#' side. It is currently just an alias for `htmlOutput`.
#' `uiOutput` is intended to be used with `renderUI` on the server side. It is
#' currently just an alias for `htmlOutput`.
#'
#' @param outputId output variable to read the value from
#' @param ... Other arguments to pass to the container tag function. This is
#' useful for providing additional classes for the tag.
#' @param fill If `TRUE`, the result of `container` is treated as _both_ a fill
#' item and container (see [htmltools::bindFillRole()]), which means both the
#' `container` as well as its immediate children (i.e., the result of
#' `renderUI()`) are allowed to grow/shrink to fit a fill container with an
#' opinionated height. Set `fill = "item"` or `fill = "container"` to treat
#' `container` as just a fill item or a fill container.
#' @inheritParams textOutput
#' @return An HTML output element that can be included in a panel
#' @examples
@@ -1407,12 +1166,16 @@ dataTableOutput <- function(outputId) {
#' )
#' @export
htmlOutput <- function(outputId, inline = FALSE,
container = if (inline) span else div, ...)
container = if (inline) span else div, fill = FALSE, ...)
{
if (anyUnnamed(list(...))) {
if (any_unnamed(list(...))) {
warning("Unnamed elements in ... will be replaced with dynamic UI.")
}
container(id = outputId, class="shiny-html-output", ...)
res <- container(id = outputId, class = "shiny-html-output", ...)
bindFillRole(
res, item = isTRUE(fill) || isTRUE("item" == fill),
container = isTRUE(fill) || isTRUE("container" == fill)
)
}
#' @rdname htmlOutput
@@ -1436,19 +1199,25 @@ uiOutput <- htmlOutput
#' @examples
#' \dontrun{
#' ui <- fluidPage(
#' p("Choose a dataset to download."),
#' selectInput("dataset", "Dataset", choices = c("mtcars", "airquality")),
#' downloadButton("downloadData", "Download")
#' )
#'
#' server <- function(input, output) {
#' # Our dataset
#' data <- mtcars
#' # The requested dataset
#' data <- reactive({
#' get(input$dataset)
#' })
#'
#' output$downloadData <- downloadHandler(
#' filename = function() {
#' paste("data-", Sys.Date(), ".csv", sep="")
#' # Use the selected dataset as the suggested file name
#' paste0(input$dataset, ".csv")
#' },
#' content = function(file) {
#' write.csv(data, file)
#' # Write the dataset to the `file` that will be downloaded
#' write.csv(data(), file)
#' }
#' )
#' }
@@ -1488,32 +1257,31 @@ downloadLink <- function(outputId, label="Download", class=NULL, ...) {
#' Create an icon
#'
#' Create an icon for use within a page. Icons can appear on their own, inside
#' of a button, or as an icon for a [tabPanel()] within a
#' [navbarPage()].
#' of a button, and/or used with [tabPanel()] and [navbarMenu()].
#'
#' @param name Name of icon. Icons are drawn from the
#' [Font Awesome Free](https://fontawesome.com/) (currently icons from
#' the v5.13.0 set are supported with the v4 naming convention) and
#' [Glyphicons](https://getbootstrap.com/components/#glyphicons)
#' libraries. Note that the "fa-" and "glyphicon-" prefixes should not be used
#' in icon names (i.e. the "fa-calendar" icon should be referred to as
#' "calendar")
#' @param class Additional classes to customize the style of the icon (see the
#' @param name The name of the icon. A name from either [Font
#' Awesome](https://fontawesome.com/) (when `lib="font-awesome"`) or
#' [Bootstrap
#' Glyphicons](https://getbootstrap.com/docs/3.3/components/#glyphicons) (when
#' `lib="glyphicon"`) may be provided. Note that the `"fa-"` and
#' `"glyphicon-"` prefixes should not appear in name (i.e., the
#' `"fa-calendar"` icon should be referred to as `"calendar"`). A `name` of
#' `NULL` may also be provided to get a raw `<i>` tag with no library attached
#' to it.
#' @param class Additional classes to customize the style of an icon (see the
#' [usage examples](https://fontawesome.com/how-to-use) for details on
#' supported styles).
#' @param lib Icon library to use ("font-awesome" or "glyphicon")
#' @param ... Arguments passed to the `<i>` tag of [htmltools::tags]
#' @param lib The icon library to use. Either `"font-awesome"` or `"glyphicon"`.
#' @param ... Arguments passed to the `<i>` tag of [htmltools::tags].
#'
#' @return An icon element
#'
#' @seealso For lists of available icons, see
#' [https://fontawesome.com/icons](https://fontawesome.com/icons) and
#' [https://getbootstrap.com/components/#glyphicons](https://getbootstrap.com/components/#glyphicons).
#' @return An `<i>` (icon) HTML tag.
#'
#' @seealso For lists of available icons, see <https://fontawesome.com/icons>
#' and <https://getbootstrap.com/docs/3.3/components/#glyphicons>
#'
#' @examples
#' # add an icon to a submit button
#' submitButton("Update View", icon = icon("refresh"))
#' submitButton("Update View", icon = icon("redo"))
#'
#' navbarPage("App Title",
#' tabPanel("Plot", icon = icon("bar-chart-o")),
@@ -1522,48 +1290,26 @@ downloadLink <- function(outputId, label="Download", class=NULL, ...) {
#' )
#' @export
icon <- function(name, class = NULL, lib = "font-awesome", ...) {
prefixes <- list(
"font-awesome" = "fa",
"glyphicon" = "glyphicon"
# A NULL name allows for a generic <i> not tied to any library
if (is.null(name)) {
lib <- "none"
}
switch(
lib %||% "",
"none" = iconTag(name, class = class, ...),
"font-awesome" = fontawesome::fa_i(name = name, class = class, ...),
"glyphicon" = iconTag(
name, class = "glyphicon", class = paste0("glyphicon-", name),
class = class, ...
),
stop("Unknown icon library: ", lib, ". See `?icon` for supported libraries.")
)
prefix <- prefixes[[lib]]
# determine stylesheet
if (is.null(prefix)) {
stop("Unknown font library '", lib, "' specified. Must be one of ",
paste0('"', names(prefixes), '"', collapse = ", "))
}
# build the icon class (allow name to be null so that other functions
# e.g. buildTabset can pass an explicit class value)
iconClass <- ""
if (!is.null(name)) {
prefix_class <- prefix
if (prefix_class == "fa" && name %in% font_awesome_brands) {
prefix_class <- "fab"
}
iconClass <- paste0(prefix_class, " ", prefix, "-", name)
}
if (!is.null(class))
iconClass <- paste(iconClass, class)
iconTag <- tags$i(class = iconClass, role = "presentation", `aria-label` = paste(name, "icon"), ...)
# font-awesome needs an additional dependency (glyphicon is in bootstrap)
if (lib == "font-awesome") {
htmlDependencies(iconTag) <- htmlDependency(
"font-awesome", "5.13.0", "www/shared/fontawesome", package = "shiny",
stylesheet = c(
"css/all.min.css",
"css/v4-shims.min.css"
)
)
}
htmltools::browsable(iconTag)
}
# Helper funtion to extract the class from an icon
iconClass <- function(icon) {
if (!is.null(icon)) icon$attribs$class
iconTag <- function(name, ...) {
htmltools::browsable(
tags$i(..., role = "presentation", `aria-label` = paste(name, "icon"))
)
}

View File

@@ -228,7 +228,9 @@ withLogErrors <- function(expr,
if (promises::is.promise(result)) {
result <- promises::catch(result, function(cond) {
# Don't print shiny.silent.error (i.e. validation errors)
if (inherits(cond, "shiny.silent.error")) return()
if (cnd_inherits(cond, "shiny.silent.error")) {
return()
}
if (isTRUE(getOption("show.error.messages"))) {
printError(cond, full = full, offset = offset)
}
@@ -239,7 +241,7 @@ withLogErrors <- function(expr,
},
error = function(cond) {
# Don't print shiny.silent.error (i.e. validation errors)
if (inherits(cond, "shiny.silent.error")) return()
if (cnd_inherits(cond, "shiny.silent.error")) return()
if (isTRUE(getOption("show.error.messages"))) {
printError(cond, full = full, offset = offset)
}
@@ -361,82 +363,6 @@ printStackTrace <- function(cond,
invisible()
}
#' @details `extractStackTrace` takes a list of calls (e.g. as returned
#' from `conditionStackTrace(cond)`) and returns a data frame with one
#' row for each stack frame and the columns `num` (stack frame number),
#' `call` (a function name or similar), and `loc` (source file path
#' and line number, if available). It was deprecated after shiny 1.0.5 because
#' it doesn't support deep stack traces.
#' @rdname stacktrace
#' @export
extractStackTrace <- function(calls,
full = get_devmode_option("shiny.fullstacktrace", FALSE),
offset = getOption("shiny.stacktraceoffset", TRUE)) {
shinyDeprecated(
"1.0.5", "extractStackTrace()",
details = "Please contact the Shiny team if you were using this functionality."
)
srcrefs <- getSrcRefs(calls)
if (offset) {
# Offset calls vs. srcrefs by 1 to make them more intuitive.
# E.g. for "foo [bar.R:10]", line 10 of bar.R will be part of
# the definition of foo().
srcrefs <- c(utils::tail(srcrefs, -1), list(NULL))
}
calls <- setSrcRefs(calls, srcrefs)
callnames <- getCallNames(calls)
# Hide and show parts of the callstack based on ..stacktrace(on|off)..
if (full) {
toShow <- rep.int(TRUE, length(calls))
} else {
# Remove stop(), .handleSimpleError(), and h() calls from the end of
# the calls--they don't add any helpful information. But only remove
# the last *contiguous* block of them, and then, only if they are the
# last thing in the calls list.
hideable <- callnames %in% c("stop", ".handleSimpleError", "h")
# What's the last that *didn't* match stop/.handleSimpleError/h?
lastGoodCall <- max(which(!hideable))
toRemove <- length(calls) - lastGoodCall
# But don't remove more than 5 levels--that's an indication we might
# have gotten it wrong, I guess
if (toRemove > 0 && toRemove < 5) {
calls <- utils::head(calls, -toRemove)
callnames <- utils::head(callnames, -toRemove)
}
# This uses a ref-counting scheme. It might make sense to switch this
# to a toggling scheme, so the most recent ..stacktrace(on|off)..
# directive wins, regardless of what came before it.
# Also explicitly remove ..stacktraceon.. because it can appear with
# score > 0 but still should never be shown.
score <- rep.int(0, length(callnames))
score[callnames == "..stacktraceoff.."] <- -1
score[callnames == "..stacktraceon.."] <- 1
toShow <- (1 + cumsum(score)) > 0 & !(callnames %in% c("..stacktraceon..", "..stacktraceoff..", "..stacktracefloor.."))
# doTryCatch, tryCatchOne, and tryCatchList are not informative--they're
# just internals for tryCatch
toShow <- toShow & !(callnames %in% c("doTryCatch", "tryCatchOne", "tryCatchList"))
}
calls <- calls[toShow]
calls <- rev(calls) # Show in traceback() order
index <- rev(which(toShow))
width <- floor(log10(max(index))) + 1
data.frame(
num = index,
call = getCallNames(calls),
loc = getLocs(calls),
category = getCallCategories(calls),
stringsAsFactors = FALSE
)
}
stripStackTraces <- function(stackTraces, values = FALSE) {
score <- 1L # >=1: show, <=0: hide
lapply(seq_along(stackTraces), function(i) {
@@ -495,8 +421,17 @@ pruneStackTrace <- function(parents) {
# Loop over the parent indices. Anything that is not parented by current_node
# (a.k.a. last-known-good node), or is a dupe, can be discarded. Anything that
# is kept becomes the new current_node.
#
# jcheng 2022-03-18: Two more reasons a node can be kept:
# 1. parent is 0
# 2. parent is i
# Not sure why either of these situations happen, but they're common when
# interacting with rlang/dplyr errors. See issue rstudio/shiny#3250 for repro
# cases.
include <- vapply(seq_along(parents), function(i) {
if (!is_dupe[[i]] && parents[[i]] == current_node) {
if ((!is_dupe[[i]] && parents[[i]] == current_node) ||
parents[[i]] == 0 ||
parents[[i]] == i) {
current_node <<- i
TRUE
} else {
@@ -531,49 +466,12 @@ offsetSrcrefs <- function(calls, offset = TRUE) {
# E.g. for "foo [bar.R:10]", line 10 of bar.R will be part of
# the definition of foo().
srcrefs <- c(utils::tail(srcrefs, -1), list(NULL))
calls <- setSrcRefs(calls, srcrefs)
}
calls
}
#' @details `formatStackTrace` is similar to `extractStackTrace`, but
#' it returns a preformatted character vector instead of a data frame. It was
#' deprecated after shiny 1.0.5 because it doesn't support deep stack traces.
#' @param indent A string to prefix every line of the stack trace.
#' @rdname stacktrace
#' @export
formatStackTrace <- function(calls, indent = " ",
full = get_devmode_option("shiny.fullstacktrace", FALSE),
offset = getOption("shiny.stacktraceoffset", TRUE)) {
shinyDeprecated(
"1.0.5", "formatStackTrace()",
details = "Please contact the Shiny team if you were using this functionality."
)
st <- extractStackTrace(calls, full = full, offset = offset)
if (nrow(st) == 0) {
return(character(0))
}
width <- floor(log10(max(st$num))) + 1
paste0(
indent,
formatC(st$num, width = width),
": ",
mapply(paste0(st$call, st$loc), st$category, FUN = function(name, category) {
if (category == "pkg")
crayon::silver(name)
else if (category == "user")
crayon::blue$bold(name)
else
crayon::white(name)
})
)
}
getSrcRefs <- function(calls) {
lapply(calls, function(call) {
attr(call, "srcref", exact = TRUE)

View File

@@ -9,13 +9,19 @@
#' @param details Additional information to be added after a new line to the displayed message
#' @keywords internal
shinyDeprecated <- function(
version, what, with = NULL, details = NULL
version,
what,
with = NULL,
details = NULL,
type = c("deprecated", "superseded")
) {
if (is_false(getOption("shiny.deprecation.messages"))) {
return(invisible())
}
msg <- paste0("`", what, "` is deprecated as of shiny ", version, ".")
type <- match.arg(type)
msg <- paste0("`", what, "` is ", type, " as of shiny ", version, ".")
if (!is.null(with)) {
msg <- paste0(msg, "\n", "Please use `", with, "` instead.")
}
@@ -32,13 +38,20 @@ deprecatedEnvQuotedMessage <- function() {
if (!in_devmode()) return(invisible())
if (is_false(getOption("shiny.deprecation.messages"))) return(invisible())
# manually
# Capture calling function
grandparent_call <- sys.call(-2)
# Turn language into user friendly string
grandparent_txt <- paste0(utils::capture.output({grandparent_call}), collapse = "\n")
msg <- paste0(
"The `env` and `quoted` arguments are deprecated as of shiny 1.6.0.",
"The `env` and `quoted` arguments are deprecated as of shiny 1.7.0.",
" Please use quosures from `rlang` instead.\n",
"See <https://github.com/rstudio/shiny/issues/3108> for more information."
"See <https://github.com/rstudio/shiny/issues/3108> for more information.\n",
"Function call:\n",
grandparent_txt
)
rlang::inform(message = msg, .frequency = "always", .frequency_id = msg, .file = stderr())
# Call less often as users do not have much control over this warning
rlang::inform(message = msg, .frequency = "regularly", .frequency_id = msg, .file = stderr())
}
@@ -60,7 +73,7 @@ diskCache <- function(
logfile = NULL
) {
shinyDeprecated("1.6.0", "diskCache()", "cachem::cache_disk()")
if (lifecycle::is_present(exec_missing)) {
if (is_present(exec_missing)) {
shinyDeprecated("1.6.0", "diskCache(exec_missing =)")
}
@@ -93,7 +106,7 @@ memoryCache <- function(
logfile = NULL)
{
shinyDeprecated("1.6.0", "diskCache()", "cachem::cache_mem()")
if (lifecycle::is_present(exec_missing)) {
if (is_present(exec_missing)) {
shinyDeprecated("1.6.0", "diskCache(exec_missing =)")
}

View File

@@ -1,6 +1,6 @@
#' Shiny Developer Mode
#'
#' @description \lifecycle{experimental}
#' @description `r lifecycle::badge("experimental")`
#'
#' Developer Mode enables a number of [options()] to make a developer's life
#' easier, like enabling non-minified JS and printing messages about
@@ -190,8 +190,10 @@ devmode_inform <- function(
#' @include map.R
registered_devmode_options <- Map$new()
registered_devmode_options <- NULL
on_load({
registered_devmode_options <- Map$new()
})
#' @describeIn devmode Registers a Shiny Developer Mode option with an updated
#' value and Developer message. This registration method allows package
@@ -233,6 +235,7 @@ registered_devmode_options <- Map$new()
#' devmode_default = FALSE
#' )
#' ```
#'
#' @param name Name of option to look for in `options()`
#' @param default Default value to return if `in_devmode()` returns
#' `TRUE` and the specified option is not set in [`options()`].
@@ -243,6 +246,7 @@ registered_devmode_options <- Map$new()
#' `TRUE` and the specified option is not set in [`options()`]. For
#' `get_devmode_option()`, if `devmode_default` is missing, the
#' registered `devmode_default` value will be used.
#' @export
#' @examples
#' # Ex: Within shiny, we register the option "shiny.minified"
#' # to default to `FALSE` when in Dev Mode
@@ -338,21 +342,22 @@ get_devmode_option <- function(
}
on_load({
register_devmode_option(
"shiny.autoreload",
"Turning on shiny autoreload. To disable, call `options(shiny.autoreload = FALSE)`",
TRUE
)
register_devmode_option(
"shiny.autoreload",
"Turning on shiny autoreload. To disable, call `options(shiny.autoreload = FALSE)`",
TRUE
)
register_devmode_option(
"shiny.minified",
"Using full shiny javascript file. To use the minified version, call `options(shiny.minified = TRUE)`",
FALSE
)
register_devmode_option(
"shiny.minified",
"Using full shiny javascript file. To use the minified version, call `options(shiny.minified = TRUE)`",
FALSE
)
register_devmode_option(
"shiny.fullstacktrace",
"Turning on full stack trace. To disable, call `options(shiny.fullstacktrace = FALSE)`",
TRUE
)
register_devmode_option(
"shiny.fullstacktrace",
"Turning on full stack trace. To disable, call `options(shiny.fullstacktrace = FALSE)`",
TRUE
)
})

View File

@@ -1,461 +0,0 @@
# Generated by tools/updateFontAwesome.R: do not edit by hand
font_awesome_brands <- c(
"500px",
"accessible-icon",
"accusoft",
"acquisitions-incorporated",
"adn",
"adversal",
"affiliatetheme",
"airbnb",
"algolia",
"alipay",
"amazon",
"amazon-pay",
"amilia",
"android",
"angellist",
"angrycreative",
"angular",
"app-store",
"app-store-ios",
"apper",
"apple",
"apple-pay",
"artstation",
"asymmetrik",
"atlassian",
"audible",
"autoprefixer",
"avianex",
"aviato",
"aws",
"bandcamp",
"battle-net",
"behance",
"behance-square",
"bimobject",
"bitbucket",
"bitcoin",
"bity",
"black-tie",
"blackberry",
"blogger",
"blogger-b",
"bluetooth",
"bluetooth-b",
"bootstrap",
"btc",
"buffer",
"buromobelexperte",
"buy-n-large",
"buysellads",
"canadian-maple-leaf",
"cc-amazon-pay",
"cc-amex",
"cc-apple-pay",
"cc-diners-club",
"cc-discover",
"cc-jcb",
"cc-mastercard",
"cc-paypal",
"cc-stripe",
"cc-visa",
"centercode",
"centos",
"chrome",
"chromecast",
"cloudflare",
"cloudscale",
"cloudsmith",
"cloudversify",
"codepen",
"codiepie",
"confluence",
"connectdevelop",
"contao",
"cotton-bureau",
"cpanel",
"creative-commons",
"creative-commons-by",
"creative-commons-nc",
"creative-commons-nc-eu",
"creative-commons-nc-jp",
"creative-commons-nd",
"creative-commons-pd",
"creative-commons-pd-alt",
"creative-commons-remix",
"creative-commons-sa",
"creative-commons-sampling",
"creative-commons-sampling-plus",
"creative-commons-share",
"creative-commons-zero",
"critical-role",
"css3",
"css3-alt",
"cuttlefish",
"d-and-d",
"d-and-d-beyond",
"dailymotion",
"dashcube",
"deezer",
"delicious",
"deploydog",
"deskpro",
"dev",
"deviantart",
"dhl",
"diaspora",
"digg",
"digital-ocean",
"discord",
"discourse",
"dochub",
"docker",
"draft2digital",
"dribbble",
"dribbble-square",
"dropbox",
"drupal",
"dyalog",
"earlybirds",
"ebay",
"edge",
"edge-legacy",
"elementor",
"ello",
"ember",
"empire",
"envira",
"erlang",
"ethereum",
"etsy",
"evernote",
"expeditedssl",
"facebook",
"facebook-f",
"facebook-messenger",
"facebook-square",
"fantasy-flight-games",
"fedex",
"fedora",
"figma",
"firefox",
"firefox-browser",
"first-order",
"first-order-alt",
"firstdraft",
"flickr",
"flipboard",
"fly",
"font-awesome",
"font-awesome-alt",
"font-awesome-flag",
"font-awesome-logo-full",
"fonticons",
"fonticons-fi",
"fort-awesome",
"fort-awesome-alt",
"forumbee",
"foursquare",
"free-code-camp",
"freebsd",
"fulcrum",
"galactic-republic",
"galactic-senate",
"get-pocket",
"gg",
"gg-circle",
"git",
"git-alt",
"git-square",
"github",
"github-alt",
"github-square",
"gitkraken",
"gitlab",
"gitter",
"glide",
"glide-g",
"gofore",
"goodreads",
"goodreads-g",
"google",
"google-drive",
"google-pay",
"google-play",
"google-plus",
"google-plus-g",
"google-plus-square",
"google-wallet",
"gratipay",
"grav",
"gripfire",
"grunt",
"guilded",
"gulp",
"hacker-news",
"hacker-news-square",
"hackerrank",
"hips",
"hire-a-helper",
"hive",
"hooli",
"hornbill",
"hotjar",
"houzz",
"html5",
"hubspot",
"ideal",
"imdb",
"innosoft",
"instagram",
"instagram-square",
"instalod",
"intercom",
"internet-explorer",
"invision",
"ioxhost",
"itch-io",
"itunes",
"itunes-note",
"java",
"jedi-order",
"jenkins",
"jira",
"joget",
"joomla",
"js",
"js-square",
"jsfiddle",
"kaggle",
"keybase",
"keycdn",
"kickstarter",
"kickstarter-k",
"korvue",
"laravel",
"lastfm",
"lastfm-square",
"leanpub",
"less",
"line",
"linkedin",
"linkedin-in",
"linode",
"linux",
"lyft",
"magento",
"mailchimp",
"mandalorian",
"markdown",
"mastodon",
"maxcdn",
"mdb",
"medapps",
"medium",
"medium-m",
"medrt",
"meetup",
"megaport",
"mendeley",
"microblog",
"microsoft",
"mix",
"mixcloud",
"mixer",
"mizuni",
"modx",
"monero",
"napster",
"neos",
"nimblr",
"node",
"node-js",
"npm",
"ns8",
"nutritionix",
"octopus-deploy",
"odnoklassniki",
"odnoklassniki-square",
"old-republic",
"opencart",
"openid",
"opera",
"optin-monster",
"orcid",
"osi",
"page4",
"pagelines",
"palfed",
"patreon",
"paypal",
"penny-arcade",
"perbyte",
"periscope",
"phabricator",
"phoenix-framework",
"phoenix-squadron",
"php",
"pied-piper",
"pied-piper-alt",
"pied-piper-hat",
"pied-piper-pp",
"pied-piper-square",
"pinterest",
"pinterest-p",
"pinterest-square",
"playstation",
"product-hunt",
"pushed",
"python",
"qq",
"quinscape",
"quora",
"r-project",
"raspberry-pi",
"ravelry",
"react",
"reacteurope",
"readme",
"rebel",
"red-river",
"reddit",
"reddit-alien",
"reddit-square",
"redhat",
"renren",
"replyd",
"researchgate",
"resolving",
"rev",
"rocketchat",
"rockrms",
"rust",
"safari",
"salesforce",
"sass",
"schlix",
"scribd",
"searchengin",
"sellcast",
"sellsy",
"servicestack",
"shirtsinbulk",
"shopify",
"shopware",
"simplybuilt",
"sistrix",
"sith",
"sketch",
"skyatlas",
"skype",
"slack",
"slack-hash",
"slideshare",
"snapchat",
"snapchat-ghost",
"snapchat-square",
"soundcloud",
"sourcetree",
"speakap",
"speaker-deck",
"spotify",
"squarespace",
"stack-exchange",
"stack-overflow",
"stackpath",
"staylinked",
"steam",
"steam-square",
"steam-symbol",
"sticker-mule",
"strava",
"stripe",
"stripe-s",
"studiovinari",
"stumbleupon",
"stumbleupon-circle",
"superpowers",
"supple",
"suse",
"swift",
"symfony",
"teamspeak",
"telegram",
"telegram-plane",
"tencent-weibo",
"the-red-yeti",
"themeco",
"themeisle",
"think-peaks",
"tiktok",
"trade-federation",
"trello",
"tripadvisor",
"tumblr",
"tumblr-square",
"twitch",
"twitter",
"twitter-square",
"typo3",
"uber",
"ubuntu",
"uikit",
"umbraco",
"uncharted",
"uniregistry",
"unity",
"unsplash",
"untappd",
"ups",
"usb",
"usps",
"ussunnah",
"vaadin",
"viacoin",
"viadeo",
"viadeo-square",
"viber",
"vimeo",
"vimeo-square",
"vimeo-v",
"vine",
"vk",
"vnv",
"vuejs",
"watchman-monitoring",
"waze",
"weebly",
"weibo",
"weixin",
"whatsapp",
"whatsapp-square",
"whmcs",
"wikipedia-w",
"windows",
"wix",
"wizards-of-the-coast",
"wodu",
"wolf-pack-battalion",
"wordpress",
"wordpress-simple",
"wpbeginner",
"wpexplorer",
"wpforms",
"wpressr",
"xbox",
"xing",
"xing-square",
"y-combinator",
"yahoo",
"yammer",
"yandex",
"yandex-international",
"yarn",
"yelp",
"yoast",
"youtube",
"youtube-square",
"zhihu"
)

View File

@@ -1,74 +1,27 @@
# A scope where we can put mutable global state
.globals <- new.env(parent = emptyenv())
register_s3_method <- function(pkg, generic, class, fun = NULL) {
stopifnot(is.character(pkg), length(pkg) == 1)
stopifnot(is.character(generic), length(generic) == 1)
stopifnot(is.character(class), length(class) == 1)
if (is.null(fun)) {
fun <- get(paste0(generic, ".", class), envir = parent.frame())
} else {
stopifnot(is.function(fun))
}
if (pkg %in% loadedNamespaces()) {
registerS3method(generic, class, fun, envir = asNamespace(pkg))
}
# Always register hook in case pkg is loaded at some
# point the future (or, potentially, but less commonly,
# unloaded & reloaded)
setHook(
packageEvent(pkg, "onLoad"),
function(...) {
registerS3method(generic, class, fun, envir = asNamespace(pkg))
}
)
}
register_upgrade_message <- function(pkg, version) {
msg <- sprintf(
"This version of Shiny is designed to work with '%s' >= %s.
Please upgrade via install.packages('%s').",
pkg, version, pkg
)
if (pkg %in% loadedNamespaces() && !is_available(pkg, version)) {
packageStartupMessage(msg)
}
# Always register hook in case pkg is loaded at some
# point the future (or, potentially, but less commonly,
# unloaded & reloaded)
setHook(
packageEvent(pkg, "onLoad"),
function(...) {
if (!is_available(pkg, version)) packageStartupMessage(msg)
}
)
}
.onLoad <- function(libname, pkgname) {
# R's lazy-loading package scheme causes the private seed to be cached in the
# package itself, making our PRNG completely deterministic. This line resets
# the private seed during load.
withPrivateSeed(set.seed(NULL))
# Create this at the top level, but since the object is from a different
# package, we don't want to bake it into the built binary package.
restoreCtxStack <<- fastmap::faststack()
for (expr in on_load_exprs) {
eval(expr, envir = environment(.onLoad))
}
# Make sure these methods are available to knitr if shiny is loaded but not
# attached.
register_s3_method("knitr", "knit_print", "reactive")
register_s3_method("knitr", "knit_print", "shiny.appobj")
register_s3_method("knitr", "knit_print", "shiny.render.function")
# Shiny 1.4.0 bumps jQuery 1.x to 3.x, which caused a problem
# with static-rendering of htmlwidgets, and htmlwidgets 1.5
# includes a fix for this problem
# https://github.com/rstudio/shiny/issues/2630
register_upgrade_message("htmlwidgets", 1.5)
s3_register("knitr::knit_print", "reactive")
s3_register("knitr::knit_print", "shiny.appobj")
s3_register("knitr::knit_print", "shiny.render.function")
}
on_load_exprs <- list()
# Register an expression to be evaluated when the package is loaded (in the
# .onLoad function).
on_load <- function(expr) {
on_load_exprs[[length(on_load_exprs) + 1]] <<- substitute(expr)
}

View File

@@ -4,7 +4,7 @@
# @param version The version of the package
check_suggested <- function(package, version = NULL) {
if (is_available(package, version)) {
if (is_installed(package, version)) {
return()
}
@@ -94,14 +94,7 @@ reactlogShow <- function(time = TRUE) {
check_reactlog()
reactlog::reactlog_show(reactlog(), time = time)
}
#' @describeIn reactlog This function is deprecated. You should use [reactlogShow()]
#' @export
# legacy purposes
showReactLog <- function(time = TRUE) {
shinyDeprecated("1.2.0", "showReactLog()", "reactlogShow()")
reactlogShow(time = time)
}
#' @describeIn reactlog Resets the entire reactlog stack. Useful for debugging and removing all prior reactive history.
#' @export
reactlogReset <- function() {
@@ -122,22 +115,28 @@ check_reactlog <- function() {
}
# read reactlog version from description file
# prevents version mismatch in code and description file
reactlog_version <- function() {
desc <- read.dcf(system.file("DESCRIPTION", package = "shiny", mustWork = TRUE))
suggests <- desc[1,"Suggests"][[1]]
suggests_pkgs <- strsplit(suggests, "\n")[[1]]
reactlog_version <- local({
version <- NULL
function() {
if (!is.null(version)) return(version)
reactlog_info <- suggests_pkgs[grepl("reactlog", suggests_pkgs)]
if (length(reactlog_info) == 0) {
stop("reactlog can not be found in shiny DESCRIPTION file")
desc <- read.dcf(system_file("DESCRIPTION", package = "shiny"))
suggests <- desc[1,"Suggests"][[1]]
suggests_pkgs <- strsplit(suggests, "\n")[[1]]
reactlog_info <- suggests_pkgs[grepl("reactlog", suggests_pkgs)]
if (length(reactlog_info) == 0) {
stop("reactlog can not be found in shiny DESCRIPTION file")
}
reactlog_info <- sub("^[^\\(]*\\(", "", reactlog_info)
reactlog_info <- sub("\\)[^\\)]*$", "", reactlog_info)
reactlog_info <- sub("^[>= ]*", "", reactlog_info)
version <<- package_version(reactlog_info)
version
}
reactlog_info <- sub("^[^\\(]*\\(", "", reactlog_info)
reactlog_info <- sub("\\)[^\\)]*$", "", reactlog_info)
reactlog_info <- sub("^[>= ]*", "", reactlog_info)
package_version(reactlog_info)
}
})
RLog <- R6Class(
@@ -519,7 +518,7 @@ MessageLogger = R6Class(
return(txt)
},
singleLine = function(txt) {
gsub("[^\\]\\n", "\\\\n", txt)
gsub("([^\\])\\n", "\\1\\\\n", txt)
},
valueStr = function(valueStr) {
paste0(
@@ -560,4 +559,6 @@ MessageLogger = R6Class(
)
)
rLog <- RLog$new("shiny.reactlog", "shiny.reactlog.console")
on_load({
rLog <- RLog$new("shiny.reactlog", "shiny.reactlog.console")
})

View File

@@ -40,11 +40,14 @@ createWebDependency <- function(dependency, scrubFile = TRUE) {
# Given a Shiny tag object, process singletons and dependencies. Returns a list
# with rendered HTML and dependency objects.
# This implementation is very similar to renderTags(), but ignores
# <head> handling (it should only be used after the user session has started)
processDeps <- function(tags, session) {
ui <- takeSingletons(tags, session$singletons, desingleton=FALSE)$ui
tags <- utils::getFromNamespace("tagify", "htmltools")(tags)
ui <- takeSingletons(tags, session$singletons, desingleton = FALSE)$ui
ui <- surroundSingletons(ui)
dependencies <- lapply(
resolveDependencies(findDependencies(ui)),
resolveDependencies(findDependencies(ui, tagify = FALSE)),
createWebDependency
)
names(dependencies) <- NULL

View File

@@ -20,7 +20,6 @@
#' `delay` milliseconds before sending an event.
#' @seealso [brushOpts()] for brushing events.
#' @export
#' @keywords internal
clickOpts <- function(id, clip = TRUE) {
if (is.null(id))
stop("id must not be NULL")

View File

@@ -182,8 +182,8 @@ brushedPoints <- function(df, brush, xvar = NULL, yvar = NULL,
# $ xmax : num 3.78
# $ ymin : num 17.1
# $ ymax : num 20.4
# $ panelvar1: int 6
# $ panelvar2: int 0
# $ panelvar1: chr "6"
# $ panelvar2: chr "0
# $ coords_css:List of 4
# ..$ xmin: int 260
# ..$ xmax: int 298
@@ -267,6 +267,7 @@ nearPoints <- function(df, coordinfo, xvar = NULL, yvar = NULL,
stop("nearPoints: `yvar` ('", yvar ,"') not in names of input")
# Extract data values from the data frame
coordinfo <- fortifyDiscreteLimits(coordinfo)
x <- asNumber(df[[xvar]], coordinfo$domain$discrete_limits$x)
y <- asNumber(df[[yvar]], coordinfo$domain$discrete_limits$y)
@@ -366,8 +367,8 @@ nearPoints <- function(df, coordinfo, xvar = NULL, yvar = NULL,
# $ img_css_ratio:List of 2
# ..$ x: num 1.25
# ..$ y: num 1.25
# $ panelvar1 : int 6
# $ panelvar2 : int 0
# $ panelvar1 : chr "6"
# $ panelvar2 : chr "0"
# $ mapping :List of 4
# ..$ x : chr "wt"
# ..$ y : chr "mpg"
@@ -392,6 +393,7 @@ nearPoints <- function(df, coordinfo, xvar = NULL, yvar = NULL,
# an input brush
within_brush <- function(vals, brush, var = "x") {
var <- match.arg(var, c("x", "y"))
brush <- fortifyDiscreteLimits(brush)
vals <- asNumber(vals, brush$domain$discrete_limits[[var]])
# It's possible for a non-missing data values to not
# map to the axis limits, for example:
@@ -414,11 +416,43 @@ asNumber <- function(x, levels = NULL) {
as.numeric(x)
}
# Ensure the discrete limits/levels of a coordmap received
# from the client matches the data structure sent the client.
#
# When we construct the coordmap (in getGgplotCoordmap()),
# we save a character vector which may contain missing values
# (e.g., c("a", "b", NA)). When that same character is received
# from the client, it runs through decodeMessage() which sets
# simplifyVector=FALSE, which means NA are replaced by NULL
# (because jsonlite::fromJSON('["a", "b", null]') -> list("a", "b", NULL))
#
# Thankfully, it doesn't seem like it's meaningful for limits to
# contains a NULL in the 1st place, so we simply treat NULL like NA.
# For more context, https://github.com/rstudio/shiny/issues/2666
fortifyDiscreteLimits <- function(coord) {
# Note that discrete_limits$x/y are populated iff
# x/y are discrete mappings
coord$domain$discrete_limits <- lapply(
coord$domain$discrete_limits,
function(var) {
# if there is an 'explicit' NULL, then the limits are NA
if (is.null(var)) return(NA)
vapply(var, function(x) {
if (is.null(x) || isTRUE(is.na(x))) NA_character_ else x
}, character(1))
}
)
coord
}
# Given a panelvar value and a vector x, return logical vector indicating which
# items match the panelvar value. Because the panelvar value is always a
# string but the vector could be numeric, it might be necessary to coerce the
# panelvar to a number before comparing to the vector.
panelMatch <- function(search_value, x) {
if (is.null(search_value)) return(is.na(x))
if (is.numeric(x)) search_value <- as.numeric(search_value)
x == search_value
}

View File

@@ -1,22 +1,23 @@
startPNG <- function(filename, width, height, res, ...) {
# shiny.useragg is an experimental option that isn't officially supported or
# documented. It's here in the off chance that someone really wants
# to use ragg (say, instead of showtext, for custom font rendering).
# In the next shiny release, this option will likely be superseded in
# favor of a fully customizable graphics device option
if ((getOption('shiny.useragg') %||% FALSE) && is_available("ragg")) {
pngfun <- ragg::agg_png
pngfun <- if ((getOption('shiny.useragg') %||% TRUE) && is_installed("ragg")) {
ragg::agg_png
} else if (capabilities("aqua")) {
# i.e., png(type = 'quartz')
pngfun <- grDevices::png
} else if ((getOption('shiny.usecairo') %||% TRUE) && is_available("Cairo")) {
pngfun <- Cairo::CairoPNG
grDevices::png
} else if ((getOption('shiny.usecairo') %||% TRUE) && is_installed("Cairo")) {
Cairo::CairoPNG
} else {
# i.e., png(type = 'cairo')
pngfun <- grDevices::png
grDevices::png
}
args <- rlang::list2(filename=filename, width=width, height=height, res=res, ...)
args <- list2(filename = filename, width = width, height = height, res = res, ...)
# It's possible for width/height to be NULL/numeric(0) (e.g., when using
# suspendWhenHidden=F w/ tabsetPanel(), see rstudio/shiny#1409), so when
# this happens let the device determine what the default size should be.
if (length(args$width) == 0) args$width <- NULL
if (length(args$height) == 0) args$height <- NULL
# Set a smarter default for the device's bg argument (based on thematic's global state).
# Note that, technically, this is really only needed for CairoPNG, since the other
@@ -57,33 +58,35 @@ startPNG <- function(filename, width, height, res, ...) {
grDevices::dev.cur()
}
#' Run a plotting function and save the output as a PNG
#' Capture a plot as a PNG file.
#'
#' This function returns the name of the PNG file that it generates. In
#' essence, it calls `png()`, then `func()`, then `dev.off()`.
#' So `func` must be a function that will generate a plot when used this
#' way.
#' The PNG graphics device used is determined in the following order:
#' * If the ragg package is installed (and the `shiny.useragg` is not
#' set to `FALSE`), then use [ragg::agg_png()].
#' * If a quartz device is available (i.e., `capabilities("aqua")` is
#' `TRUE`), then use `png(type = "quartz")`.
#' * If the Cairo package is installed (and the `shiny.usecairo` option
#' is not set to `FALSE`), then use [Cairo::CairoPNG()].
#' * Otherwise, use [grDevices::png()]. In this case, Linux and Windows
#' may not antialias some point shapes, resulting in poor quality output.
#'
#' For output, it will try to use the following devices, in this order:
#' quartz (via [grDevices::png()]), then [Cairo::CairoPNG()],
#' and finally [grDevices::png()]. This is in order of quality of
#' output. Notably, plain `png` output on Linux and Windows may not
#' antialias some point shapes, resulting in poor quality output.
#'
#' In some cases, `Cairo()` provides output that looks worse than
#' `png()`. To disable Cairo output for an app, use
#' `options(shiny.usecairo=FALSE)`.
#' @details
#' A `NULL` value provided to `width` or `height` is ignored (i.e., the
#' default `width` or `height` of the graphics device is used).
#'
#' @param func A function that generates a plot.
#' @param filename The name of the output file. Defaults to a temp file with
#' extension `.png`.
#' @param width Width in pixels.
#' @param height Height in pixels.
#' @param res Resolution in pixels per inch. This value is passed to
#' [grDevices::png()]. Note that this affects the resolution of PNG rendering in
#' @param res Resolution in pixels per inch. This value is passed to the
#' graphics device. Note that this affects the resolution of PNG rendering in
#' R; it won't change the actual ppi of the browser.
#' @param ... Arguments to be passed through to [grDevices::png()].
#' These can be used to set the width, height, background color, etc.
#' @param ... Arguments to be passed through to the graphics device. These can
#' be used to set the width, height, background color, etc.
#'
#' @return A path to the newly generated PNG file.
#'
#' @export
plotPNG <- function(func, filename=tempfile(fileext='.png'),
width=400, height=400, res=72, ...) {

View File

@@ -31,7 +31,7 @@ checkboxInput <- function(inputId, label, value = FALSE, width = NULL) {
value <- restoreInput(id = inputId, default = value)
inputTag <- tags$input(id = inputId, type="checkbox")
inputTag <- tags$input(id = inputId, type="checkbox", class = "shiny-input-checkbox")
if (!is.null(value) && value)
inputTag$attribs$checked <- "checked"

View File

@@ -133,14 +133,13 @@ dateInput <- function(inputId, label, value = NULL, min = NULL, max = NULL,
}
datePickerVersion <- "1.9.0"
datePickerDependency <- function(theme) {
list(
htmlDependency(
name = "bootstrap-datepicker-js",
version = datePickerVersion,
src = c(href = "shared/datepicker"),
version = version_bs_date_picker,
src = "www/shared/datepicker",
package = "shiny",
script = if (getOption("shiny.minified", TRUE)) "js/bootstrap-datepicker.min.js"
else "js/bootstrap-datepicker.js",
# Need to enable noConflict mode. See #1346.
@@ -158,19 +157,20 @@ datePickerCSS <- function(theme) {
if (!is_bs_theme(theme)) {
return(htmlDependency(
name = "bootstrap-datepicker-css",
version = datePickerVersion,
src = c(href = "shared/datepicker"),
version = version_bs_date_picker,
src = "www/shared/datepicker",
package = "shiny",
stylesheet = "css/bootstrap-datepicker3.min.css"
))
}
scss_file <- system.file(package = "shiny", "www/shared/datepicker/scss/build3.scss")
scss_file <- system_file(package = "shiny", "www/shared/datepicker/scss/build3.scss")
bslib::bs_dependency(
input = sass::sass_file(scss_file),
theme = theme,
name = "bootstrap-datepicker",
version = datePickerVersion,
cache_key_extra = shinyPackageVersion()
version = version_bs_date_picker,
cache_key_extra = get_package_version("shiny")
)
}

View File

@@ -23,7 +23,18 @@
#' @param buttonLabel The label used on the button. Can be text or an HTML tag
#' object.
#' @param placeholder The text to show before a file has been uploaded.
#' @param capture What source to use for capturing image, audio or video data.
#' This attribute facilitates user access to a device's media capture
#' mechanism, such as a camera, or microphone, from within a file upload
#' control.
#'
#' A value of `user` indicates that the user-facing camera and/or microphone
#' should be used. A value of `environment` specifies that the outward-facing
#' camera and/or microphone should be used.
#'
#' By default on most phones, this will accept still photos or video. For
#' still photos only, also use `accept="image/*"`. For video only, use
#' `accept="video/*"`.
#' @examples
#' ## Only run examples in interactive R sessions
#' if (interactive()) {
@@ -73,7 +84,8 @@
#'
#' @export
fileInput <- function(inputId, label, multiple = FALSE, accept = NULL,
width = NULL, buttonLabel = "Browse...", placeholder = "No file selected") {
width = NULL, buttonLabel = "Browse...", placeholder = "No file selected",
capture = NULL) {
restoredValue <- restoreInput(id = inputId, default = NULL)
@@ -89,6 +101,7 @@ fileInput <- function(inputId, label, multiple = FALSE, accept = NULL,
inputTag <- tags$input(
id = inputId,
class = "shiny-input-file",
name = inputId,
type = "file",
# Don't use "display: none;" style, which causes keyboard accessibility issue; instead use the following workaround: https://css-tricks.com/places-its-tempting-to-use-display-none-but-dont/
@@ -101,6 +114,9 @@ fileInput <- function(inputId, label, multiple = FALSE, accept = NULL,
if (length(accept) > 0)
inputTag$attribs$accept <- paste(accept, collapse=',')
if (!is.null(capture)) {
inputTag$attribs$capture <- capture
}
div(class = "form-group shiny-input-container",
style = css(width = validateCssUnit(width)),

View File

@@ -35,7 +35,7 @@ numericInput <- function(inputId, label, value, min = NA, max = NA, step = NA,
value <- restoreInput(id = inputId, default = value)
# build input tag
inputTag <- tags$input(id = inputId, type = "number", class="form-control",
inputTag <- tags$input(id = inputId, type = "number", class="shiny-input-number form-control",
value = formatNoSci(value))
if (!is.na(min))
inputTag$attribs$min = min

View File

@@ -35,7 +35,7 @@ passwordInput <- function(inputId, label, value = "", width = NULL,
div(class = "form-group shiny-input-container",
style = css(width = validateCssUnit(width)),
shinyInputLabel(inputId, label),
tags$input(id = inputId, type="password", class="form-control", value=value,
tags$input(id = inputId, type="password", class="shiny-input-password form-control", value=value,
placeholder = placeholder)
)
}

View File

@@ -4,7 +4,7 @@
#' from a list of values.
#'
#' By default, `selectInput()` and `selectizeInput()` use the JavaScript library
#' \pkg{selectize.js} (<https://github.com/selectize/selectize.js>) instead of
#' \pkg{selectize.js} (<https://selectize.dev/) instead of
#' the basic select input element. To use the standard HTML select input
#' element, use `selectInput()` with `selectize=FALSE`.
#'
@@ -106,6 +106,7 @@ selectInput <- function(inputId, label, choices, selected = NULL,
# create select tag and add options
selectTag <- tags$select(
id = inputId,
class = "shiny-input-select",
class = if (!selectize) "form-control",
size = size,
selectOptions(choices, selected, inputId, selectize)
@@ -172,7 +173,7 @@ needOptgroup <- function(choices) {
#' @rdname selectInput
#' @param ... Arguments passed to `selectInput()`.
#' @param options A list of options. See the documentation of \pkg{selectize.js}
#' @param options A list of options. See the documentation of \pkg{selectize.js}(<https://selectize.dev/docs/usage>)
#' for possible options (character option values inside [base::I()] will
#' be treated as literal JavaScript code; see [renderDataTable()]
#' for details).
@@ -213,14 +214,7 @@ selectizeIt <- function(inputId, select, options, nonempty = FALSE) {
deps <- list(selectizeDependency())
if ('drag_drop' %in% options$plugins) {
deps <- c(
deps,
list(htmlDependency(
'jqueryui', '1.12.1',
c(href = 'shared/jqueryui'),
script = 'jquery-ui.min.js'
))
)
deps[[length(deps) + 1]] <- jqueryuiDependency()
}
# Insert script on same level as <select> tag
@@ -243,19 +237,14 @@ selectizeDependency <- function() {
}
selectizeDependencyFunc <- function(theme) {
selectizeVersion <- "0.12.4"
if (!is_bs_theme(theme)) {
return(selectizeStaticDependency(selectizeVersion))
return(selectizeStaticDependency(version_selectize))
}
selectizeDir <- system.file(package = "shiny", "www/shared/selectize/")
selectizeDir <- system_file(package = "shiny", "www/shared/selectize/")
bs_version <- bslib::theme_version(theme)
stylesheet <- file.path(
selectizeDir, "scss",
if ("3" %in% bslib::theme_version(theme)) {
"selectize.bootstrap3.scss"
} else {
"selectize.bootstrap4.scss"
}
selectizeDir, "scss", paste0("selectize.bootstrap", bs_version, ".scss")
)
# It'd be cleaner to ship the JS in a separate, href-based,
# HTML dependency (which we currently do for other themable widgets),
@@ -271,16 +260,18 @@ selectizeDependencyFunc <- function(theme) {
input = sass::sass_file(stylesheet),
theme = theme,
name = "selectize",
version = selectizeVersion,
cache_key_extra = shinyPackageVersion(),
version = version_selectize,
cache_key_extra = get_package_version("shiny"),
.dep_args = list(script = script)
)
}
selectizeStaticDependency <- function(version) {
htmlDependency(
"selectize", version,
src = c(href = "shared/selectize"),
"selectize",
version,
src = "www/shared/selectize",
package = "shiny",
stylesheet = "css/selectize.bootstrap3.css",
script = c(
"js/selectize.min.js",
@@ -297,7 +288,7 @@ selectizeStaticDependency <- function(version) {
#'
#' By default, `varSelectInput()` and `selectizeInput()` use the
#' JavaScript library \pkg{selectize.js}
#' (<https://github.com/selectize/selectize.js>) to instead of the basic
#' (<https://selectize.dev/>) to instead of the basic
#' select input element. To use the standard HTML select input element, use
#' `selectInput()` with `selectize=FALSE`.
#'
@@ -393,7 +384,7 @@ varSelectInput <- function(
#' @rdname varSelectInput
#' @param ... Arguments passed to `varSelectInput()`.
#' @param options A list of options. See the documentation of \pkg{selectize.js}
#' @param options A list of options. See the documentation of \pkg{selectize.js}(<https://selectize.dev/docs/usage>)
#' for possible options (character option values inside [base::I()] will
#' be treated as literal JavaScript code; see [renderDataTable()]
#' for details).

View File

@@ -201,19 +201,21 @@ sliderInput <- function(inputId, label, min, max, value, step = NULL,
}
ionRangeSliderVersion <- "2.3.1"
ionRangeSliderDependency <- function() {
list(
# ion.rangeSlider also needs normalize.css, which is already included in Bootstrap.
htmlDependency(
"ionrangeslider-javascript", ionRangeSliderVersion,
src = c(href = "shared/ionrangeslider"),
"ionrangeslider-javascript",
version_ion_range_slider,
src = "www/shared/ionrangeslider",
package = "shiny",
script = "js/ion.rangeSlider.min.js"
),
htmlDependency(
"strftime", "0.9.2",
src = c(href = "shared/strftime"),
"strftime",
version_strftime,
src = "www/shared/strftime",
package = "shiny",
script = "strftime-min.js"
),
bslib::bs_dependency_defer(ionRangeSliderDependencyCSS)
@@ -224,36 +226,24 @@ ionRangeSliderDependencyCSS <- function(theme) {
if (!is_bs_theme(theme)) {
return(htmlDependency(
"ionrangeslider-css",
ionRangeSliderVersion,
src = c(href = "shared/ionrangeslider"),
version_ion_range_slider,
src = "www/shared/ionrangeslider",
package = "shiny",
stylesheet = "css/ion.rangeSlider.css"
))
}
# Remap some variable names for ionRangeSlider's scss
sass_input <- list(
list(
# The bootswatch materia theme sets $input-bg: transparent;
# which is an issue for the slider's handle(s) (#3130)
bg = "if(alpha($input-bg)==0, $body-bg, $input-bg)",
fg = sprintf(
"if(alpha($input-color)==0, $%s, $input-color)",
if ("3" %in% bslib::theme_version(theme)) "text-color" else "body-color"
),
accent = "$component-active-bg",
`font-family` = "$font-family-base"
),
sass::sass_file(
system.file(package = "shiny", "www/shared/ionrangeslider/scss/shiny.scss")
)
)
bslib::bs_dependency(
input = sass_input,
input = list(
list(accent = "$component-active-bg"),
sass::sass_file(
system_file(package = "shiny", "www/shared/ionrangeslider/scss/shiny.scss")
)
),
theme = theme,
name = "ionRangeSlider",
version = ionRangeSliderVersion,
cache_key_extra = shinyPackageVersion()
version = version_ion_range_slider,
cache_key_extra = get_package_version("shiny")
)
}

View File

@@ -42,7 +42,7 @@ textInput <- function(inputId, label, value = "", width = NULL,
div(class = "form-group shiny-input-container",
style = css(width = validateCssUnit(width)),
shinyInputLabel(inputId, label),
tags$input(id = inputId, type="text", class="form-control", value=value,
tags$input(id = inputId, type="text", class="shiny-input-text form-control", value=value,
placeholder = placeholder)
)
}

View File

@@ -52,7 +52,7 @@ textAreaInput <- function(inputId, label, value = "", width = NULL, height = NUL
style <- css(
# The width is specified on the parent div.
width = if (!is.null(width)) "width: 100%;",
width = if (!is.null(width)) "100%",
height = validateCssUnit(height),
resize = resize
)
@@ -62,7 +62,7 @@ textAreaInput <- function(inputId, label, value = "", width = NULL, height = NUL
style = if (!is.null(width)) paste0("width: ", validateCssUnit(width), ";"),
tags$textarea(
id = inputId,
class = "form-control",
class = "shiny-input-textarea form-control",
placeholder = placeholder,
style = style,
rows = rows,

View File

@@ -41,7 +41,7 @@ normalizeChoicesArgs <- function(choices, choiceNames, choiceValues,
if (length(choiceNames) != length(choiceValues)) {
stop("`choiceNames` and `choiceValues` must have the same length.")
}
if (anyNamed(choiceNames) || anyNamed(choiceValues)) {
if (any_named(choiceNames) || any_named(choiceValues)) {
stop("`choiceNames` and `choiceValues` must not be named.")
}
} else {

View File

@@ -112,35 +112,13 @@
#'
#' }
#' @export
insertTab <- function(inputId, tab, target,
position = c("before", "after"), select = FALSE,
insertTab <- function(inputId, tab, target = NULL,
position = c("after", "before"), select = FALSE,
session = getDefaultReactiveDomain()) {
force(target)
force(select)
position <- match.arg(position)
inputId <- session$ns(inputId)
# Barbara -- August 2017
# Note: until now, the number of tabs in a tabsetPanel (or navbarPage
# or navlistPanel) was always fixed. So, an easy way to give an id to
# a tab was simply incrementing a counter. (Just like it was easy to
# give a random 4-digit number to identify the tabsetPanel). Since we
# can only know this in the client side, we'll just pass `id` and
# `tsid` (TabSetID) as dummy values that will be fixed in the JS code.
item <- buildTabItem("id", "tsid", TRUE, divTag = tab,
textFilter = if (is.character(tab)) navbarMenuTextFilter else NULL)
callback <- function() {
session$sendInsertTab(
inputId = inputId,
liTag = processDeps(item$liTag, session),
divTag = processDeps(item$divTag, session),
menuName = NULL,
target = target,
position = position,
select = select)
}
session$onFlush(callback, once = TRUE)
bslib::nav_insert(
inputId, tab, target,
match.arg(position), select, session
)
}
#' @param menuName This argument should only be used when you want to
@@ -159,63 +137,21 @@ insertTab <- function(inputId, tab, target,
#' @export
prependTab <- function(inputId, tab, select = FALSE, menuName = NULL,
session = getDefaultReactiveDomain()) {
force(select)
force(menuName)
inputId <- session$ns(inputId)
item <- buildTabItem("id", "tsid", TRUE, divTag = tab,
textFilter = if (is.character(tab)) navbarMenuTextFilter else NULL)
callback <- function() {
session$sendInsertTab(
inputId = inputId,
liTag = processDeps(item$liTag, session),
divTag = processDeps(item$divTag, session),
menuName = menuName,
target = NULL,
position = "after",
select = select)
}
session$onFlush(callback, once = TRUE)
bslib::nav_prepend(inputId, tab, menu_title = menuName, select = select, session = session)
}
#' @rdname insertTab
#' @export
appendTab <- function(inputId, tab, select = FALSE, menuName = NULL,
session = getDefaultReactiveDomain()) {
force(select)
force(menuName)
inputId <- session$ns(inputId)
item <- buildTabItem("id", "tsid", TRUE, divTag = tab,
textFilter = if (is.character(tab)) navbarMenuTextFilter else NULL)
callback <- function() {
session$sendInsertTab(
inputId = inputId,
liTag = processDeps(item$liTag, session),
divTag = processDeps(item$divTag, session),
menuName = menuName,
target = NULL,
position = "before",
select = select)
}
session$onFlush(callback, once = TRUE)
bslib::nav_append(inputId, tab, menu_title = menuName, select = select, session = session)
}
#' @rdname insertTab
#' @export
removeTab <- function(inputId, target,
session = getDefaultReactiveDomain()) {
force(target)
inputId <- session$ns(inputId)
callback <- function() {
session$sendRemoveTab(
inputId = inputId,
target = target)
}
session$onFlush(callback, once = TRUE)
bslib::nav_remove(inputId, target, session)
}

View File

@@ -1,6 +1,6 @@
#' Insert and remove UI objects
#'
#' These functions allow you to dynamically add and remove arbirary UI
#' These functions allow you to dynamically add and remove arbitrary UI
#' into your app, whenever you want, as many times as you want.
#' Unlike [renderUI()], the UI generated with `insertUI()` is persistent:
#' once it's created, it stays there until removed by `removeUI()`. Each
@@ -11,7 +11,7 @@
#' function.
#'
#' It's particularly useful to pair `removeUI` with `insertUI()`, but there is
#' no restriction on what you can use on. Any element that can be selected
#' no restriction on what you can use it on. Any element that can be selected
#' through a jQuery selector can be removed through this function.
#'
#' @param selector A string that is accepted by jQuery's selector

View File

@@ -79,8 +79,8 @@ absolutePanel <- function(...,
if (isTRUE(draggable)) {
divTag <- tagAppendAttributes(divTag, class='draggable')
return(tagList(
singleton(tags$head(tags$script(src='shared/jqueryui/jquery-ui.min.js'))),
divTag,
jqueryuiDependency(),
tags$script('$(".draggable").draggable();')
))
} else {
@@ -99,3 +99,14 @@ fixedPanel <- function(...,
width=width, height=height, draggable=draggable, cursor=match.arg(cursor),
fixed=TRUE)
}
jqueryuiDependency <- function() {
htmlDependency(
"jqueryui",
version_jqueryui,
src = "www/shared/jqueryui",
package = "shiny",
script = "jquery-ui.min.js"
)
}

View File

@@ -4,6 +4,7 @@
#' themselves in knitr/rmarkdown documents.
#'
#' @name knitr_methods
#' @keywords internal
#' @param x Object to knit_print
#' @param ... Additional knit_print arguments
NULL
@@ -62,7 +63,7 @@ knit_print.shiny.appobj <- function(x, ...) {
#' @param inline Whether the object is printed inline.
knit_print.shiny.render.function <- function(x, ..., inline = FALSE) {
x <- htmltools::as.tags(x, inline = inline)
output <- knitr::knit_print(tagList(x))
output <- knitr::knit_print(tagList(x), ..., inline = inline)
attr(output, "knit_cacheable") <- FALSE
attr(output, "knit_meta") <- append(attr(output, "knit_meta"),
shiny_rmd_warning())
@@ -76,5 +77,5 @@ knit_print.reactive <- function(x, ..., inline = FALSE) {
renderFunc <- if (inline) renderText else renderPrint
knitr::knit_print(renderFunc({
x()
}), inline = inline)
}), ..., inline = inline)
}

View File

@@ -1,4 +1,3 @@
#' @importFrom fastmap fastmap
Map <- R6Class(
'Map',
portable = FALSE,

View File

@@ -348,7 +348,7 @@ HandlerManager <- R6Class("HandlerManager",
httpResponse(status = 500L,
content_type = "text/html; charset=UTF-8",
content = as.character(htmltools::htmlTemplate(
system.file("template", "error.html", package = "shiny"),
system_file("template", "error.html", package = "shiny"),
message = conditionMessage(err)
))
)

View File

@@ -1,5 +1,5 @@
# Promise helpers taken from:
# https://github.com/rstudio/promises/blob/master/tests/testthat/common.R
# https://github.com/rstudio/promises/blob/main/tests/testthat/common.R
# Block until all pending later tasks have executed
wait_for_it <- function() {
while (!later::loop_empty()) {

View File

@@ -43,7 +43,10 @@ removeModal <- function(session = getDefaultReactiveDomain()) {
#' @param title An optional title for the dialog.
#' @param footer UI for footer. Use `NULL` for no footer.
#' @param size One of `"s"` for small, `"m"` (the default) for medium,
#' or `"l"` for large.
#' `"l"` for large, or `"xl"` for extra large. Note that `"xl"` only
#' works with Bootstrap 4 and above (to opt-in to Bootstrap 4+,
#' pass [bslib::bs_theme()] to the `theme` argument of a page container
#' like [fluidPage()]).
#' @param easyClose If `TRUE`, the modal dialog can be dismissed by
#' clicking outside the dialog box, or be pressing the Escape key. If
#' `FALSE` (the default), the modal dialog can't be dismissed in those
@@ -151,18 +154,25 @@ removeModal <- function(session = getDefaultReactiveDomain()) {
#' }
#' @export
modalDialog <- function(..., title = NULL, footer = modalButton("Dismiss"),
size = c("m", "s", "l"), easyClose = FALSE, fade = TRUE) {
size = c("m", "s", "l", "xl"), easyClose = FALSE, fade = TRUE) {
size <- match.arg(size)
cls <- if (fade) "modal fade" else "modal"
div(id = "shiny-modal", class = cls, tabindex = "-1",
`data-backdrop` = if (!easyClose) "static",
`data-keyboard` = if (!easyClose) "false",
backdrop <- if (!easyClose) "static"
keyboard <- if (!easyClose) "false"
div(
id = "shiny-modal",
class = "modal",
class = if (fade) "fade",
tabindex = "-1",
`data-backdrop` = backdrop,
`data-bs-backdrop` = backdrop,
`data-keyboard` = keyboard,
`data-bs-keyboard` = keyboard,
div(
class = "modal-dialog",
class = switch(size, s = "modal-sm", m = NULL, l = "modal-lg"),
class = switch(size, s = "modal-sm", m = NULL, l = "modal-lg", xl = "modal-xl"),
div(class = "modal-content",
if (!is.null(title)) div(class = "modal-header",
tags$h4(class = "modal-title", title)
@@ -171,14 +181,26 @@ modalDialog <- function(..., title = NULL, footer = modalButton("Dismiss"),
if (!is.null(footer)) div(class = "modal-footer", footer)
)
),
tags$script("$('#shiny-modal').modal().focus();")
# jQuery plugin doesn't work in Bootstrap 5, but vanilla JS doesn't work in Bootstrap 4 :sob:
tags$script(HTML(
"if (window.bootstrap && !window.bootstrap.Modal.VERSION.match(/^4\\./)) {
var modal = new bootstrap.Modal(document.getElementById('shiny-modal'));
modal.show();
} else {
$('#shiny-modal').modal().focus();
}"
))
)
}
#' @export
#' @rdname modalDialog
modalButton <- function(label, icon = NULL) {
tags$button(type = "button", class = "btn btn-default",
`data-dismiss` = "modal", validateIcon(icon), label
tags$button(
type = "button",
class = "btn btn-default",
`data-dismiss` = "modal",
`data-bs-dismiss` = "modal",
validateIcon(icon), label
)
}

View File

@@ -326,6 +326,9 @@ ReactiveValues <- R6Class(
.dedupe = logical(0),
# Key, asList(), or names() have been retrieved
.hasRetrieved = list(),
# All names, in insertion order. The names are also stored in the .values
# object, but it does not preserve order.
.nameOrder = character(0),
initialize = function(
@@ -403,6 +406,11 @@ ReactiveValues <- R6Class(
return(invisible())
}
# If it's new, append key to the name order
if (!key_exists) {
.nameOrder[length(.nameOrder) + 1] <<- key
}
# set the value for better logging
.values$set(key, value)
@@ -444,14 +452,13 @@ ReactiveValues <- R6Class(
},
names = function() {
nameValues <- .values$keys()
if (!isTRUE(.hasRetrieved$names)) {
domain <- getDefaultReactiveDomain()
rLog$defineNames(.reactId, nameValues, .label, domain)
rLog$defineNames(.reactId, .nameOrder, .label, domain)
.hasRetrieved$names <<- TRUE
}
.namesDeps$register()
return(nameValues)
return(.nameOrder)
},
# Get a metadata value. Does not trigger reactivity.
@@ -499,7 +506,7 @@ ReactiveValues <- R6Class(
},
toList = function(all.names=FALSE) {
listValue <- .values$values()
listValue <- .values$mget(.nameOrder)
if (!all.names) {
listValue <- listValue[!grepl("^\\.", base::names(listValue))]
}
@@ -568,7 +575,7 @@ ReactiveValues <- R6Class(
#' @seealso [isolate()] and [is.reactivevalues()].
#' @export
reactiveValues <- function(...) {
args <- list(...)
args <- list2(...)
if ((length(args) > 0) && (is.null(names(args)) || any(names(args) == "")))
rlang::abort("All arguments passed to reactiveValues() must be named.")
@@ -875,8 +882,7 @@ Observable <- R6Class(
invisible(.value)
},
format = function() {
label <- sprintf('reactive(%s)', paste(deparse(body(.origFunc)), collapse='\n'))
strsplit(label, "\n")[[1]]
simpleExprToFunction(fn_body(.origFunc), "reactive")
},
.updateValue = function() {
ctx <- Context$new(.domain, .label, type = 'observable',
@@ -945,14 +951,15 @@ Observable <- R6Class(
#' See the [Shiny tutorial](https://shiny.rstudio.com/tutorial/) for
#' more information about reactive expressions.
#'
#' @param x For `reactive`, an expression (quoted or unquoted). For
#' `is.reactive`, an object to test.
#' @param env The parent environment for the reactive expression. By default,
#' this is the calling environment, the same as when defining an ordinary
#' non-reactive expression.
#' @param quoted Is the expression quoted? By default, this is `FALSE`.
#' This is useful when you want to use an expression that is stored in a
#' variable; to do so, it must be quoted with `quote()`.
#' @param x For `is.reactive()`, an object to test. For `reactive()`, an expression. When passing in a [`quo()`]sure with `reactive()`, remember to use [`rlang::inject()`] to distinguish that you are passing in the content of your quosure, not the expression of the quosure.
#' @template param-env
#' @templateVar x x
#' @templateVar env env
#' @templateVar quoted quoted
#' @template param-quoted
#' @templateVar x x
#' @templateVar quoted quoted
#' @param label A label for the reactive expression, useful for debugging.
#' @param domain See [domains].
#' @param ..stacktraceon Advanced use only. For stack manipulation purposes; see
@@ -961,46 +968,56 @@ Observable <- R6Class(
#' @return a function, wrapped in a S3 class "reactive"
#'
#' @examples
#' library(rlang)
#' values <- reactiveValues(A=1)
#'
#' reactiveB <- reactive({
#' values$A + 1
#' })
#'
#' # Can use quoted expressions
#' reactiveC <- reactive(quote({ values$A + 2 }), quoted = TRUE)
#'
#' # To store expressions for later conversion to reactive, use quote()
#' expr_q <- quote({ values$A + 3 })
#' reactiveD <- reactive(expr_q, quoted = TRUE)
#'
#' # View the values from the R console with isolate()
#' isolate(reactiveB())
#' # 2
#'
#' # To store expressions for later conversion to reactive, use quote()
#' myquo <- rlang::quo(values$A + 2)
#' # Unexpected value! Sending a quosure directly will not work as expected.
#' reactiveC <- reactive(myquo)
#' # We'd hope for `3`, but instead we get the quosure that was supplied.
#' isolate(reactiveC())
#'
#' # Instead, the quosure should be `rlang::inject()`ed
#' reactiveD <- rlang::inject(reactive(!!myquo))
#' isolate(reactiveD())
#' # 3
#'
#' # (Legacy) Can use quoted expressions
#' expr <- quote({ values$A + 3 })
#' reactiveE <- reactive(expr, quoted = TRUE)
#' isolate(reactiveE())
#' # 4
#'
#' @export
reactive <- function(x, env = parent.frame(), quoted = FALSE,
reactive <- function(
x,
env = parent.frame(),
quoted = FALSE,
...,
label = NULL,
domain = getDefaultReactiveDomain(),
..stacktraceon = TRUE)
{
..stacktraceon = TRUE
) {
check_dots_empty()
x <- get_quosure(x, env, quoted)
fun <- as_function(x)
# as_function returns a function that takes `...`. We need one that takes no
# args.
formals(fun) <- list()
func <- installExprFunction(x, "func", env, quoted, wrappedWithLabel = FALSE)
# Attach a label and a reference to the original user source for debugging
label <- exprToLabel(get_expr(x), "reactive", label)
userExpr <- fn_body(func)
label <- exprToLabel(userExpr, "reactive", label)
o <- Observable$new(fun, label, domain, ..stacktraceon = ..stacktraceon)
o <- Observable$new(func, label, domain, ..stacktraceon = ..stacktraceon)
structure(
o$getValue,
observable = o,
cacheHint = list(userExpr = zap_srcref(get_expr(x))),
cacheHint = list(userExpr = zap_srcref(userExpr)),
class = c("reactiveExpr", "reactive", "function")
)
}
@@ -1193,7 +1210,7 @@ Observer <- R6Class(
# validation = function(e) NULL,
# shiny.output.cancel = function(e) NULL
if (inherits(e, "shiny.silent.error")) {
if (cnd_inherits(e, "shiny.silent.error")) {
return()
}
@@ -1325,12 +1342,7 @@ Observer <- R6Class(
#'
#' @param x An expression (quoted or unquoted). Any return value will be
#' ignored.
#' @param env The parent environment for the reactive expression. By default,
#' this is the calling environment, the same as when defining an ordinary
#' non-reactive expression.
#' @param quoted Is the expression quoted? By default, this is `FALSE`.
#' This is useful when you want to use an expression that is stored in a
#' variable; to do so, it must be quoted with `quote()`.
#' @inheritParams reactive
#' @param label A label for the observer, useful for debugging.
#' @param suspended If `TRUE`, start the observer in a suspended state. If
#' `FALSE` (the default), start in a non-suspended state.
@@ -1389,18 +1401,21 @@ Observer <- R6Class(
#' print(values$A + 1)
#' })
#'
#' # Can use quoted expressions
#' obsC <- observe(quote({ print(values$A + 2) }), quoted = TRUE)
#' # To store expressions for later conversion to observe, use rlang::quo()
#' myquo <- rlang::quo({ print(values$A + 3) })
#' obsC <- rlang::inject(observe(!!myquo))
#'
#' # To store expressions for later conversion to observe, use quote()
#' expr_q <- quote({ print(values$A + 3) })
#' obsD <- observe(expr_q, quoted = TRUE)
#' # (Legacy) Can use quoted expressions
#' obsD <- observe(quote({ print(values$A + 2) }), quoted = TRUE)
#'
#' # In a normal Shiny app, the web client will trigger flush events. If you
#' # are at the console, you can force a flush with flushReact()
#' shiny:::flushReact()
#' @export
observe <- function(x, env = parent.frame(), quoted = FALSE,
observe <- function(
x,
env = parent.frame(),
quoted = FALSE,
...,
label = NULL,
suspended = FALSE,
@@ -1411,18 +1426,11 @@ observe <- function(x, env = parent.frame(), quoted = FALSE,
{
check_dots_empty()
x <- get_quosure(x, env, quoted)
fun <- as_function(x)
# as_function returns a function that takes `...`. We need one that takes no
# args.
formals(fun) <- list()
if (is.null(label)) {
label <- sprintf('observe(%s)', paste(deparse(get_expr(x)), collapse='\n'))
}
func <- installExprFunction(x, "func", env, quoted)
label <- funcToLabel(func, "observe", label)
o <- Observer$new(
fun,
func,
label = label,
suspended = suspended,
priority = priority,
@@ -1915,7 +1923,7 @@ reactivePoll <- function(intervalMillis, session, checkFunc, valueFunc) {
#' @export
reactiveFileReader <- function(intervalMillis, session, filePath, readFunc, ...) {
filePath <- coerceToFunc(filePath)
extraArgs <- list(...)
extraArgs <- list2(...)
reactivePoll(
intervalMillis, session,
@@ -2144,23 +2152,30 @@ maskReactiveContext <- function(expr) {
#' @param valueExpr The expression that produces the return value of the
#' `eventReactive`. It will be executed within an [isolate()]
#' scope.
#' @param event.env The parent environment for `eventExpr`. By default,
#' this is the calling environment.
#' @param event.quoted Is the `eventExpr` expression quoted? By default,
#' this is `FALSE`. This is useful when you want to use an expression
#' that is stored in a variable; to do so, it must be quoted with
#' `quote()`.
#' @param handler.env The parent environment for `handlerExpr`. By default,
#' this is the calling environment.
#' @param handler.quoted Is the `handlerExpr` expression quoted? By
#' default, this is `FALSE`. This is useful when you want to use an
#' expression that is stored in a variable; to do so, it must be quoted with
#' `quote()`.
#' @param value.env The parent environment for `valueExpr`. By default,
#' this is the calling environment.
#' @param value.quoted Is the `valueExpr` expression quoted? By default,
#' this is `FALSE`. This is useful when you want to use an expression
#' that is stored in a variable; to do so, it must be quoted with `quote()`.
#' @param event.env The parent environment for the reactive expression. By default,
#' this is the calling environment, the same as when defining an ordinary
#' non-reactive expression. If `eventExpr` is a quosure and `event.quoted` is `TRUE`,
#' then `event.env` is ignored.
#' @param event.quoted If it is `TRUE`, then the [`quote()`]ed value of `eventExpr`
#' will be used when `eventExpr` is evaluated. If `eventExpr` is a quosure and you
#' would like to use its expression as a value for `eventExpr`, then you must set
#' `event.quoted` to `TRUE`.
#' @param handler.env The parent environment for the reactive expression. By default,
#' this is the calling environment, the same as when defining an ordinary
#' non-reactive expression. If `handlerExpr` is a quosure and `handler.quoted` is `TRUE`,
#' then `handler.env` is ignored.
#' @param handler.quoted If it is `TRUE`, then the [`quote()`]ed value of `handlerExpr`
#' will be used when `handlerExpr` is evaluated. If `handlerExpr` is a quosure and you
#' would like to use its expression as a value for `handlerExpr`, then you must set
#' `handler.quoted` to `TRUE`.
#' @param value.env The parent environment for the reactive expression. By default,
#' this is the calling environment, the same as when defining an ordinary
#' non-reactive expression. If `valueExpr` is a quosure and `value.quoted` is `TRUE`,
#' then `value.env` is ignored.
#' @param value.quoted If it is `TRUE`, then the [`quote()`]ed value of `valueExpr`
#' will be used when `valueExpr` is evaluated. If `valueExpr` is a quosure and you
#' would like to use its expression as a value for `valueExpr`, then you must set
#' `value.quoted` to `TRUE`.
#' @param label A label for the observer or reactive, useful for debugging.
#' @param suspended If `TRUE`, start the observer in a suspended state. If
#' `FALSE` (the default), start in a non-suspended state.
@@ -2172,8 +2187,8 @@ maskReactiveContext <- function(expr) {
#' @param autoDestroy If `TRUE` (the default), the observer will be
#' automatically destroyed when its domain (if any) ends.
#' @param ignoreNULL Whether the action should be triggered (or value
#' calculated, in the case of `eventReactive`) when the input is
#' `NULL`. See Details.
#' calculated, in the case of `eventReactive`) when the input event expression
#' is `NULL`. See Details.
#' @param ignoreInit If `TRUE`, then, when this `observeEvent` is
#' first created/initialized, ignore the `handlerExpr` (the second
#' argument), whether it is otherwise supposed to run or not. The default is
@@ -2274,15 +2289,13 @@ observeEvent <- function(eventExpr, handlerExpr,
{
check_dots_empty()
eventExpr <- get_quosure(eventExpr, event.env, event.quoted)
handlerExpr <- get_quosure(handlerExpr, handler.env, handler.quoted)
eventQ <- exprToQuo(eventExpr, event.env, event.quoted)
handlerQ <- exprToQuo(handlerExpr, handler.env, handler.quoted)
if (is.null(label)) {
label <- sprintf('observeEvent(%s)', paste(deparse(get_expr(eventExpr)), collapse='\n'))
}
label <- quoToLabel(eventQ, "observeEvent", label)
handler <- inject(observe(
!!handlerExpr,
!!handlerQ,
label = label,
suspended = suspended,
priority = priority,
@@ -2296,7 +2309,7 @@ observeEvent <- function(eventExpr, handlerExpr,
ignoreInit = ignoreInit,
once = once,
label = label,
!!eventExpr,
!!eventQ,
x = handler
))
@@ -2314,19 +2327,17 @@ eventReactive <- function(eventExpr, valueExpr,
{
check_dots_empty()
eventExpr <- get_quosure(eventExpr, event.env, event.quoted)
valueExpr <- get_quosure(valueExpr, value.env, value.quoted)
eventQ <- exprToQuo(eventExpr, event.env, event.quoted)
valueQ <- exprToQuo(valueExpr, value.env, value.quoted)
if (is.null(label)) {
label <- sprintf('eventReactive(%s)', paste(deparse(get_expr(eventExpr)), collapse='\n'))
}
label <- quoToLabel(eventQ, "eventReactive", label)
invisible(inject(bindEvent(
ignoreNULL = ignoreNULL,
ignoreInit = ignoreInit,
label = label,
!!eventExpr,
x = reactive(!!valueExpr, domain = domain, label = label)
!!eventQ,
x = reactive(!!valueQ, domain = domain, label = label)
)))
}
@@ -2468,11 +2479,11 @@ debounce <- function(r, millis, priority = 100, domain = getDefaultReactiveDomai
# Ensure r() is called only after setting firstRun to FALSE since r()
# may throw an error
r()
try(r(), silent = TRUE)
return()
}
# This ensures r() is still tracked after firstRun
r()
try(r(), silent = TRUE)
# The value (or possibly millis) changed. Start or reset the timer.
v$when <- getDomainTimeMs(domain) + millis()
@@ -2505,7 +2516,7 @@ debounce <- function(r, millis, priority = 100, domain = getDefaultReactiveDomai
# commenting it out and studying the unit test failure that results.
primer <- observe({
primer$destroy()
er()
try(er(), silent = TRUE)
}, label = "debounce primer", domain = domain, priority = priority)
er
@@ -2547,7 +2558,7 @@ throttle <- function(r, millis, priority = 100, domain = getDefaultReactiveDomai
}
# Responsible for tracking when f() changes.
observeEvent(r(), {
observeEvent(try(r(), silent = TRUE), {
if (v$pending) {
# In a blackout period and someone already scheduled; do nothing
} else if (blackoutMillisLeft() > 0) {

View File

@@ -1,6 +1,6 @@
####
# Generated by `./tools/updateReexports.R`: do not edit by hand
# Please call `source('tools/updateReexports.R') from the root folder to update`
# Generated by `./tools/documentation/updateReexports.R`: do not edit by hand
# Please call `source('tools/documentation/updateReexports.R')` from the root folder to update`
####
@@ -90,17 +90,20 @@ htmltools::em
#' @export
htmltools::hr
# htmltools tag.Rd -------------------------------------------------------------
#' @importFrom htmltools tag
#' @export
htmltools::tag
# htmltools tagList.Rd ---------------------------------------------------------
#' @importFrom htmltools tagList
#' @export
htmltools::tagList
# htmltools tagAppendAttributes.Rd ---------------------------------------------
#' @importFrom htmltools tagAppendAttributes
#' @export
htmltools::tagAppendAttributes
@@ -113,6 +116,9 @@ htmltools::tagHasAttribute
#' @export
htmltools::tagGetAttribute
# htmltools tagAppendChild.Rd --------------------------------------------------
#' @importFrom htmltools tagAppendChild
#' @export
htmltools::tagAppendChild

View File

@@ -181,7 +181,7 @@
#' # At the top of app.R, this set the application-scoped cache to be a disk
#' # cache that can be shared among multiple concurrent R processes, and is
#' # deleted when the system reboots.
#' shinyOptions(cache = cachem::cache_disk(file.path(dirname(tempdir()), "myapp-cache"))
#' shinyOptions(cache = cachem::cache_disk(file.path(dirname(tempdir()), "myapp-cache")))
#'
#' # At the top of app.R, this set the application-scoped cache to be a disk
#' # cache that can be shared among multiple concurrent R processes, and

View File

@@ -34,19 +34,19 @@
#' When rendering an inline plot, you must provide numeric values (in pixels)
#' to both \code{width} and \code{height}.
#' @param res Resolution of resulting plot, in pixels per inch. This value is
#' passed to [grDevices::png()]. Note that this affects the resolution of PNG
#' passed to [plotPNG()]. Note that this affects the resolution of PNG
#' rendering in R; it won't change the actual ppi of the browser.
#' @param alt Alternate text for the HTML `<img>` tag
#' if it cannot be displayed or viewed (i.e., the user uses a screen reader).
#' In addition to a character string, the value may be a reactive expression
#' (or a function referencing reactive values) that returns a character string.
#' NULL or "" is not recommended because those should be limited to decorative images
#' (the default is "Plot object").
#' @param ... Arguments to be passed through to [grDevices::png()].
#' @param alt Alternate text for the HTML `<img>` tag if it cannot be displayed
#' or viewed (i.e., the user uses a screen reader). In addition to a character
#' string, the value may be a reactive expression (or a function referencing
#' reactive values) that returns a character string. If the value is `NA` (the
#' default), then `ggplot2::get_alt_text()` is used to extract alt text from
#' ggplot objects; for other plots, `NA` results in alt text of "Plot object".
#' `NULL` or `""` is not recommended because those should be limited to
#' decorative images.
#' @param ... Arguments to be passed through to [plotPNG()].
#' These can be used to set the width, height, background color, etc.
#' @param env The environment in which to evaluate `expr`.
#' @param quoted Is `expr` a quoted expression (with `quote()`)? This
#' is useful if you want to save an expression in a variable.
#' @inheritParams renderUI
#' @param execOnResize If `FALSE` (the default), then when a plot is
#' resized, Shiny will *replay* the plot drawing commands with
#' [grDevices::replayPlot()] instead of re-executing `expr`.
@@ -58,15 +58,18 @@
#' interactive R Markdown document.
#' @export
renderPlot <- function(expr, width = 'auto', height = 'auto', res = 72, ...,
alt = "Plot object",
alt = NA,
env = parent.frame(), quoted = FALSE,
execOnResize = FALSE, outputArgs = list()
) {
expr <- get_quosure(expr, env, quoted)
# This ..stacktraceon is matched by a ..stacktraceoff.. when plotFunc
# is called
func <- quoToFunction(expr, "renderPlot", ..stacktraceon = TRUE)
func <- installExprFunction(
expr, "func", env, quoted,
label = "renderPlot",
# This ..stacktraceon is matched by a ..stacktraceoff.. when plotFunc
# is called
..stacktraceon = TRUE
)
args <- list(...)
@@ -184,15 +187,15 @@ renderPlot <- function(expr, width = 'auto', height = 'auto', res = 72, ...,
outputFunc,
renderFunc,
outputArgs,
cacheHint = list(userExpr = get_expr(expr), res = res)
cacheHint = list(userExpr = installedFuncExpr(func), res = res)
)
class(markedFunc) <- c("shiny.renderPlot", class(markedFunc))
markedFunc
}
resizeSavedPlot <- function(name, session, result, width, height, alt, pixelratio, res, ...) {
if (result$img$width == width && result$img$height == height &&
result$pixelratio == pixelratio && result$res == res) {
if (isTRUE(result$img$width == width && result$img$height == height &&
result$pixelratio == pixelratio && result$res == res)) {
return(result)
}
@@ -212,7 +215,7 @@ resizeSavedPlot <- function(name, session, result, width, height, alt, pixelrati
src = session$fileUrl(name, outfile, contentType = "image/png"),
width = width,
height = height,
alt = alt,
alt = result$alt,
coordmap = coordmap,
error = attr(coordmap, "error", exact = TRUE)
)
@@ -288,6 +291,7 @@ drawPlot <- function(name, session, func, width, height, alt, pixelratio, res, .
recordedPlot = grDevices::recordPlot(),
coordmap = getCoordmap(value, width*pixelratio, height*pixelratio, res*pixelratio),
pixelratio = pixelratio,
alt = if (anyNA(alt)) getAltText(value) else alt,
res = res
)
}
@@ -302,10 +306,10 @@ drawPlot <- function(name, session, func, width, height, alt, pixelratio, res, .
),
function(result) {
result$img <- dropNulls(list(
src = session$fileUrl(name, outfile, contentType='image/png'),
src = session$fileUrl(name, outfile, contentType = 'image/png'),
width = width,
height = height,
alt = alt,
alt = result$alt,
coordmap = result$coordmap,
# Get coordmap error message if present
error = attr(result$coordmap, "error", exact = TRUE)
@@ -339,6 +343,24 @@ custom_print.ggplot <- function(x) {
), class = "ggplot_build_gtable")
}
# Infer alt text description from renderPlot() value
# (currently just ggplot2 is supported)
getAltText <- function(x, default = "Plot object") {
# Since, inside renderPlot(), custom_print.ggplot()
# overrides print.ggplot, this class indicates a ggplot()
if (!inherits(x, "ggplot_build_gtable")) {
return(default)
}
# ggplot2::get_alt_text() was added in v3.3.4
# https://github.com/tidyverse/ggplot2/pull/4482
get_alt <- getNamespace("ggplot2")$get_alt_text
if (!is.function(get_alt)) {
return(default)
}
alt <- paste(get_alt(x$build), collapse = " ")
if (nzchar(alt)) alt else default
}
# The coordmap extraction functions below return something like the examples
# below. For base graphics:
# plot(mtcars$wt, mtcars$mpg)
@@ -590,7 +612,7 @@ getGgplotCoordmap <- function(p, width, height, res) {
find_panel_info <- function(b) {
# Structure of ggplot objects changed after 2.1.0. After 2.2.1, there was a
# an API for extracting the necessary information.
ggplot_ver <- utils::packageVersion("ggplot2")
ggplot_ver <- get_package_version("ggplot2")
if (ggplot_ver > "2.2.1") {
find_panel_info_api(b)

View File

@@ -42,9 +42,7 @@
#' (i.e. they either evaluate to `NA` or `NaN`).
#' @param ... Arguments to be passed through to [xtable::xtable()]
#' and [xtable::print.xtable()].
#' @param env The environment in which to evaluate `expr`.
#' @param quoted Is `expr` a quoted expression (with `quote()`)?
#' This is useful if you want to save an expression in a variable.
#' @inheritParams renderUI
#' @param outputArgs A list of arguments to be passed through to the
#' implicit call to [tableOutput()] when `renderTable` is
#' used in an interactive R Markdown document.
@@ -74,8 +72,7 @@ renderTable <- function(expr, striped = FALSE, hover = FALSE,
env = parent.frame(), quoted = FALSE,
outputArgs=list())
{
expr <- get_quosure(expr, env, quoted)
func <- quoToFunction(expr, "renderTable")
func <- installExprFunction(expr, "func", env, quoted, label = "renderTable")
if (!is.function(spacing)) spacing <- match.arg(spacing)

View File

@@ -23,10 +23,10 @@
#' @examples
#' ## Only run this example in interactive R sessions
#' if (interactive()) {
#' runUrl('https://github.com/rstudio/shiny_example/archive/master.tar.gz')
#' runUrl('https://github.com/rstudio/shiny_example/archive/main.tar.gz')
#'
#' # Can run an app from a subdirectory in the archive
#' runUrl("https://github.com/rstudio/shiny_example/archive/master.zip",
#' runUrl("https://github.com/rstudio/shiny_example/archive/main.zip",
#' subdir = "inst/shinyapp/")
#' }
runUrl <- function(url, filetype = NULL, subdir = NULL, destdir = NULL, ...) {
@@ -121,7 +121,8 @@ runGist <- function(gist, destdir = NULL, ...) {
#' @param username GitHub username. If `repo` is of the form
#' `"username/repo"`, `username` will be taken from `repo`.
#' @param ref Desired git reference. Could be a commit, tag, or branch name.
#' Defaults to `"master"`.
#' Defaults to `"HEAD"`, which means the default branch on GitHub, typically
#' `"main"` or `"master"`.
#' @export
#' @examples
#' ## Only run this example in interactive R sessions
@@ -133,7 +134,7 @@ runGist <- function(gist, destdir = NULL, ...) {
#' runGitHub("shiny_example", "rstudio", subdir = "inst/shinyapp/")
#' }
runGitHub <- function(repo, username = getOption("github.user"),
ref = "master", subdir = NULL, destdir = NULL, ...) {
ref = "HEAD", subdir = NULL, destdir = NULL, ...) {
if (grepl('/', repo)) {
res <- strsplit(repo, '/')[[1]]

View File

@@ -22,10 +22,13 @@
#' @param port The TCP port that the application should listen on. If the
#' `port` is not specified, and the `shiny.port` option is set (with
#' `options(shiny.port = XX)`), then that port will be used. Otherwise,
#' use a random port.
#' use a random port between 3000:8000, excluding ports that are blocked
#' by Google Chrome for being considered unsafe: 3659, 4045, 5060,
#' 5061, 6000, 6566, 6665:6669 and 6697. Up to twenty random
#' ports will be tried.
#' @param launch.browser If true, the system's default web browser will be
#' launched automatically after the app is started. Defaults to true in
#' interactive sessions only. This value of this parameter can also be a
#' interactive sessions only. The value of this parameter can also be a
#' function to call with the application's URL.
#' @param host The IPv4 address that the application should listen on. Defaults
#' to the `shiny.host` option, if set, or `"127.0.0.1"` if not. See
@@ -301,7 +304,8 @@ runApp <- function(appDir=getwd(),
# Reject ports in this range that are considered unsafe by Chrome
# http://superuser.com/questions/188058/which-ports-are-considered-unsafe-on-chrome
# https://github.com/rstudio/shiny/issues/1784
if (!port %in% c(3659, 4045, 6000, 6665:6669, 6697)) {
# https://chromium.googlesource.com/chromium/src.git/+/refs/heads/main/net/base/port_util.cc
if (!port %in% c(3659, 4045, 5060, 5061, 6000, 6566, 6665:6669, 6697)) {
break
}
}
@@ -463,7 +467,7 @@ runExample <- function(example=NA,
launch.browser = getOption('shiny.launch.browser', interactive()),
host=getOption('shiny.host', '127.0.0.1'),
display.mode=c("auto", "normal", "showcase")) {
examplesDir <- system.file('examples', package='shiny')
examplesDir <- system_file('examples', package='shiny')
dir <- resolve(examplesDir, example)
if (is.null(dir)) {
if (is.na(example)) {

View File

@@ -5,7 +5,6 @@
#' value. The returned value will be used for the test snapshot.
#' @param session A Shiny session object.
#'
#' @keywords internal
#' @export
setSerializer <- function(inputId, fun, session = getDefaultReactiveDomain()) {
if (is.null(session)) {

View File

@@ -1,5 +1,9 @@
# Create a map for input handlers and register the defaults.
inputHandlers <- Map$new()
# Create a Map object for input handlers and register the defaults.
# This is assigned in .onLoad time.
inputHandlers <- NULL
on_load({
inputHandlers <- Map$new()
})
#' Register an Input Handler
#'
@@ -41,12 +45,12 @@ inputHandlers <- Map$new()
#' })
#'
#' ## On the Javascript side, the associated input binding must have a corresponding getType method:
#' getType: function(el) {
#' return "mypackage.validint";
#' }
#' # getType: function(el) {
#' # return "mypackage.validint";
#' # }
#'
#' }
#' @seealso [removeInputHandler()]
#' @seealso [removeInputHandler()] [applyInputHandlers()]
#' @export
registerInputHandler <- function(type, fun, force=FALSE){
if (inputHandlers$containsKey(type) && !force){
@@ -125,115 +129,117 @@ applyInputHandlers <- function(inputs, shinysession = getDefaultReactiveDomain()
inputs
}
on_load({
# Takes a list-of-lists and returns a matrix. The lists
# must all be the same length. NULL is replaced by NA.
registerInputHandler("shiny.matrix", function(data, ...) {
if (length(data) == 0)
return(matrix(nrow=0, ncol=0))
# Takes a list-of-lists and returns a matrix. The lists
# must all be the same length. NULL is replaced by NA.
registerInputHandler("shiny.matrix", function(data, ...) {
if (length(data) == 0)
return(matrix(nrow=0, ncol=0))
m <- matrix(unlist(lapply(data, function(x) {
sapply(x, function(y) {
ifelse(is.null(y), NA, y)
})
})), nrow = length(data[[1]]), ncol = length(data))
return(m)
})
registerInputHandler("shiny.number", function(val, ...){
ifelse(is.null(val), NA, val)
})
registerInputHandler("shiny.password", function(val, shinysession, name) {
# Mark passwords as not serializable
setSerializer(name, serializerUnserializable)
val
})
registerInputHandler("shiny.date", function(val, ...){
# First replace NULLs with NA, then convert to Date vector
datelist <- ifelse(lapply(val, is.null), NA, val)
res <- NULL
tryCatch({
res <- as.Date(unlist(datelist))
},
error = function(e) {
# It's possible for client to send a string like "99999-01-01", which
# as.Date can't handle.
warning(e$message)
res <<- as.Date(rep(NA, length(datelist)))
}
)
res
})
registerInputHandler("shiny.datetime", function(val, ...){
# First replace NULLs with NA, then convert to POSIXct vector
times <- lapply(val, function(x) {
if (is.null(x)) NA
else x
m <- matrix(unlist(lapply(data, function(x) {
sapply(x, function(y) {
ifelse(is.null(y), NA, y)
})
})), nrow = length(data[[1]]), ncol = length(data))
return(m)
})
as.POSIXct(unlist(times), origin = "1970-01-01", tz = "UTC")
})
registerInputHandler("shiny.action", function(val, shinysession, name) {
# mark up the action button value with a special class so we can recognize it later
class(val) <- c(class(val), "shinyActionButtonValue")
val
})
registerInputHandler("shiny.file", function(val, shinysession, name) {
# This function is only used when restoring a Shiny fileInput. When a file is
# uploaded the usual way, it takes a different code path and won't hit this
# function.
if (is.null(val))
return(NULL)
# The data will be a named list of lists; convert to a data frame.
val <- as.data.frame(lapply(val, unlist), stringsAsFactors = FALSE)
# `val$datapath` should be a filename without a path, for security reasons.
if (basename(val$datapath) != val$datapath) {
stop("Invalid '/' found in file input path.")
}
# Prepend the persistent dir
oldfile <- file.path(getCurrentRestoreContext()$dir, val$datapath)
# Copy the original file to a new temp dir, so that a restored session can't
# modify the original.
newdir <- file.path(tempdir(), createUniqueId(12))
dir.create(newdir)
val$datapath <- file.path(newdir, val$datapath)
file.copy(oldfile, val$datapath)
# Need to mark this input value with the correct serializer. When a file is
# uploaded the usual way (instead of being restored), this occurs in
# session$`@uploadEnd`.
setSerializer(name, serializerFileInput)
snapshotPreprocessInput(name, snapshotPreprocessorFileInput)
val
})
# to be used with !!!answer
registerInputHandler("shiny.symbolList", function(val, ...) {
if (is.null(val)) {
list()
} else {
lapply(val, as.symbol)
}
})
# to be used with !!answer
registerInputHandler("shiny.symbol", function(val, ...) {
if (is.null(val) || identical(val, "")) {
NULL
} else {
as.symbol(val)
}
registerInputHandler("shiny.number", function(val, ...){
ifelse(is.null(val), NA, val)
})
registerInputHandler("shiny.password", function(val, shinysession, name) {
# Mark passwords as not serializable
setSerializer(name, serializerUnserializable)
val
})
registerInputHandler("shiny.date", function(val, ...){
# First replace NULLs with NA, then convert to Date vector
datelist <- ifelse(lapply(val, is.null), NA, val)
res <- NULL
tryCatch({
res <- as.Date(unlist(datelist))
},
error = function(e) {
# It's possible for client to send a string like "99999-01-01", which
# as.Date can't handle.
warning(e$message)
res <<- as.Date(rep(NA, length(datelist)))
}
)
res
})
registerInputHandler("shiny.datetime", function(val, ...){
# First replace NULLs with NA, then convert to POSIXct vector
times <- lapply(val, function(x) {
if (is.null(x)) NA
else x
})
as.POSIXct(unlist(times), origin = "1970-01-01", tz = "UTC")
})
registerInputHandler("shiny.action", function(val, shinysession, name) {
# mark up the action button value with a special class so we can recognize it later
class(val) <- c("shinyActionButtonValue", class(val))
val
})
registerInputHandler("shiny.file", function(val, shinysession, name) {
# This function is only used when restoring a Shiny fileInput. When a file is
# uploaded the usual way, it takes a different code path and won't hit this
# function.
if (is.null(val))
return(NULL)
# The data will be a named list of lists; convert to a data frame.
val <- as.data.frame(lapply(val, unlist), stringsAsFactors = FALSE)
# `val$datapath` should be a filename without a path, for security reasons.
if (basename(val$datapath) != val$datapath) {
stop("Invalid '/' found in file input path.")
}
# Prepend the persistent dir
oldfile <- file.path(getCurrentRestoreContext()$dir, val$datapath)
# Copy the original file to a new temp dir, so that a restored session can't
# modify the original.
newdir <- file.path(tempdir(), createUniqueId(12))
dir.create(newdir)
val$datapath <- file.path(newdir, val$datapath)
file.copy(oldfile, val$datapath)
# Need to mark this input value with the correct serializer. When a file is
# uploaded the usual way (instead of being restored), this occurs in
# session$`@uploadEnd`.
setSerializer(name, serializerFileInput)
snapshotPreprocessInput(name, snapshotPreprocessorFileInput)
val
})
# to be used with !!!answer
registerInputHandler("shiny.symbolList", function(val, ...) {
if (is.null(val)) {
list()
} else {
lapply(val, as.symbol)
}
})
# to be used with !!answer
registerInputHandler("shiny.symbol", function(val, ...) {
if (is.null(val) || identical(val, "")) {
NULL
} else {
as.symbol(val)
}
})
})

View File

@@ -1,7 +1,12 @@
#' @include server-input-handlers.R
appsByToken <- Map$new()
appsNeedingFlush <- Map$new()
appsByToken <- NULL
appsNeedingFlush <- NULL
on_load({
appsByToken <- Map$new()
appsNeedingFlush <- Map$new()
})
# Provide a character representation of the WS that can be used
# as a key in a Map.
@@ -29,7 +34,7 @@ registerClient <- function(client) {
#' Define Server Functionality
#'
#' @description \lifecycle{superseded}
#' @description `r lifecycle::badge("superseded")`
#'
#' @description Defines the server-side logic of the Shiny application. This generally
#' involves creating functions that map user inputs to various kinds of output.
@@ -49,7 +54,7 @@ registerClient <- function(client) {
#' optional `session` parameter, which is used when greater control is
#' needed.
#'
#' See the [tutorial](https://rstudio.github.io/shiny/tutorial/) for more
#' See the [tutorial](https://shiny.rstudio.com/tutorial/) for more
#' on how to write a server function.
#'
#' @param func The server function for this application. See the details section
@@ -122,13 +127,16 @@ decodeMessage <- function(data) {
return(mainMessage)
}
autoReloadCallbacks <- Callbacks$new()
autoReloadCallbacks <- NULL
on_load({
autoReloadCallbacks <- Callbacks$new()
})
createAppHandlers <- function(httpHandlers, serverFuncSource) {
appvars <- new.env()
appvars$server <- NULL
sys.www.root <- system.file('www', package='shiny')
sys.www.root <- system_file('www', package='shiny')
# This value, if non-NULL, must be present on all HTTP and WebSocket
# requests as the Shiny-Shared-Secret header or else access will be
@@ -331,7 +339,7 @@ argsForServerFunc <- function(serverFunc, session) {
getEffectiveBody <- function(func) {
if (is.null(func))
NULL
else if (isS4(func) && class(func) == "functionWithTrace")
else if (isS4(func) && inherits(func, "functionWithTrace"))
body(func@original)
else
body(func)
@@ -385,7 +393,7 @@ startApp <- function(appObj, port, host, quiet) {
list(
# Always handle /session URLs dynamically, even if / is a static path.
"session" = excludeStaticPath(),
"shared" = system.file(package = "shiny", "www", "shared")
"shared" = system_file(package = "shiny", "www", "shared")
),
.globals$resourcePaths
)

View File

@@ -94,6 +94,10 @@ getShinyOption <- function(name, default = NULL) {
#' numbers to JSON format to send to the client web browser.}
#' \item{shiny.launch.browser (defaults to `interactive()`)}{A boolean which controls the default behavior
#' when an app is run. See [runApp()] for more information.}
#' \item{shiny.mathjax.url (defaults to `"https://mathjax.rstudio.com/latest/MathJax.js"`)}{
#' The URL that should be used to load MathJax, via [withMathJax()].}
#' \item{shiny.mathjax.config (defaults to `"config=TeX-AMS-MML_HTMLorMML"`)}{The querystring
#' used to load MathJax, via [withMathJax()].}
#' \item{shiny.maxRequestSize (defaults to 5MB)}{This is a number which specifies the maximum
#' web request size, which serves as a size limit for file uploads.}
#' \item{shiny.minified (defaults to `TRUE`)}{By default
@@ -125,6 +129,9 @@ getShinyOption <- function(name, default = NULL) {
#' console.}
#' \item{shiny.testmode (defaults to `FALSE`)}{If `TRUE`, then various features for testing Shiny
#' applications are enabled.}
#' \item{shiny.snapshotsortc (defaults to `FALSE`)}{If `TRUE`, test snapshot keys
#' for \pkg{shinytest} will be sorted consistently using the C locale. Snapshots
#' retrieved by \pkg{shinytest2} will always sort using the C locale.}
#' \item{shiny.trace (defaults to `FALSE`)}{Print messages sent between the R server and the web
#' browser client to the R console. This is useful for debugging. Possible
#' values are `"send"` (only print messages sent to the client),
@@ -133,9 +140,10 @@ getShinyOption <- function(name, default = NULL) {
#' messages).}
#' \item{shiny.autoload.r (defaults to `TRUE`)}{If `TRUE`, then the R/
#' of a shiny app will automatically be sourced.}
#' \item{shiny.usecairo (defaults to `TRUE`)}{This is used to disable graphical rendering by the
#' Cairo package, if it is installed. See [plotPNG()] for more
#' information.}
#' \item{shiny.useragg (defaults to `TRUE`)}{Set to `FALSE` to prevent PNG rendering via the
#' ragg package. See [plotPNG()] for more information.}
#' \item{shiny.usecairo (defaults to `TRUE`)}{Set to `FALSE` to prevent PNG rendering via the
#' Cairo package. See [plotPNG()] for more information.}
#' \item{shiny.devmode (defaults to `NULL`)}{Option to enable Shiny Developer Mode. When set,
#' different default `getOption(key)` values will be returned. See [devmode()] for more details.}
### Not documenting as 'shiny.devmode.verbose' is for niche use only
@@ -178,7 +186,7 @@ getShinyOption <- function(name, default = NULL) {
#' @aliases shiny-options
#' @export
shinyOptions <- function(...) {
newOpts <- list(...)
newOpts <- list2(...)
if (length(newOpts) > 0) {
# If we're within a session, modify at the session level.

View File

@@ -2,7 +2,7 @@
## usethis namespace: start
## usethis namespace: end
#' @importFrom lifecycle deprecated
#' @importFrom lifecycle deprecated is_present
#' @importFrom grDevices dev.set dev.cur
#' @importFrom fastmap fastmap
#' @importFrom promises %...!%
@@ -11,11 +11,13 @@
#' promise promise_resolve promise_reject is.promising
#' as.promise
#' @importFrom rlang
#' quo enquo as_function get_expr get_env new_function enquos
#' quo enquo enquo0 as_function get_expr get_env new_function enquos
#' eval_tidy expr pairlist2 new_quosure enexpr as_quosure is_quosure inject
#' quo_set_env quo_set_expr quo_get_expr
#' enquos0 zap_srcref %||% is_na
#' is_false
#' is_false list2
#' missing_arg is_missing maybe_missing
#' quo_is_missing fn_fmls<- fn_body fn_body<-
#' @importFrom ellipsis
#' check_dots_empty check_dots_unnamed
#' @import htmltools

View File

@@ -33,8 +33,12 @@ createUniqueId <- function(bytes, prefix = "", suffix = "") {
}
toJSON <- function(x, ..., dataframe = "columns", null = "null", na = "null",
auto_unbox = TRUE, digits = getOption("shiny.json.digits", 16),
use_signif = TRUE, force = TRUE, POSIXt = "ISO8601", UTC = TRUE,
auto_unbox = TRUE,
# Shiny has had a legacy value of 16 significant digits
# We can use `I(16)` mixed with the default behavior in jsonlite's `use_signif=`
# https://github.com/jeroen/jsonlite/commit/728efa9
digits = getOption("shiny.json.digits", I(16)), use_signif = is(digits, "AsIs"),
force = TRUE, POSIXt = "ISO8601", UTC = TRUE,
rownames = FALSE, keep_vec_names = TRUE, strict_atomic = TRUE) {
if (strict_atomic) {
@@ -185,9 +189,11 @@ workerId <- local({
#' session is actually connected.
#' }
#' \item{request}{
#' An environment that implements the Rook specification for HTTP requests.
#' This is the request that was used to initiate the websocket connection
#' (as opposed to the request that downloaded the web page for the app).
#' An environment that implements the [Rook
#' specification](https://github.com/jeffreyhorner/Rook#the-environment) for
#' HTTP requests. This is the request that was used to initiate the websocket
#' connection (as opposed to the request that downloaded the web page for the
#' app).
#' }
#' \item{userData}{
#' An environment for app authors and module/package authors to store whatever
@@ -403,7 +409,7 @@ ShinySession <- R6Class(
sendMessage = function(...) {
# This function is a wrapper for $write
msg <- list(...)
if (anyUnnamed(msg)) {
if (any_unnamed(msg)) {
stop("All arguments to sendMessage must be named.")
}
private$write(toJSON(msg))
@@ -478,6 +484,35 @@ ShinySession <- R6Class(
# "json" unless requested otherwise. The only other valid value is
# "rds".
format <- params$format %||% "json"
# Machines can test their snapshot under different locales.
# R CMD check runs under the `C` locale.
# However, before this parameter, existing snapshots were most likely not
# under the `C` locale is would cause failures. This parameter allows
# users to opt-in to the `C` locale.
# From ?sort:
# However, there are some caveats with the radix sort:
# If x is a character vector, all elements must share the
# same encoding. Only UTF-8 (including ASCII) and Latin-1
# encodings are supported. Collation always follows the "C"
# locale.
# {shinytest2} will always set `sortC=1`
# {shinytest} does not have `sortC` functionality.
# Users should set `options(shiny.snapshotsortc = TRUE)` within their app.
# The sortingMethod should always be `radix` going forward.
sortMethod <-
if (!is.null(params$sortC)) {
if (params$sortC != "1") {
stop("The `sortC` parameter can only be `1` or not supplied")
}
"radix"
} else {
# Allow users to set an option for {shinytest2}.
if (isTRUE(getShinyOption("snapshotsortc", default = FALSE))) {
"radix"
} else {
"auto"
}
}
values <- list()
@@ -520,7 +555,7 @@ ShinySession <- R6Class(
}
)
values$input <- sortByName(values$input)
values$input <- sortByName(values$input, method = sortMethod)
}
if (!is.null(params$output)) {
@@ -548,7 +583,7 @@ ShinySession <- R6Class(
}
)
values$output <- sortByName(values$output)
values$output <- sortByName(values$output, method = sortMethod)
}
if (!is.null(params$export)) {
@@ -569,7 +604,7 @@ ShinySession <- R6Class(
)
}
values$export <- sortByName(values$export)
values$export <- sortByName(values$export, method = sortMethod)
}
# Make sure input, output, and export are all named lists (at this
@@ -825,7 +860,7 @@ ShinySession <- R6Class(
dots <- eval(substitute(alist(...)))
}
if (anyUnnamed(dots))
if (any_unnamed(dots))
stop("exportTestValues: all arguments must be named.")
names(dots) <- ns(names(dots))
@@ -913,7 +948,7 @@ ShinySession <- R6Class(
# Copy `values` from scopeState to state, adding namespace
if (length(scopeState$values) != 0) {
if (anyUnnamed(scopeState$values)) {
if (any_unnamed(scopeState$values)) {
stop("All scope values in must be named.")
}
@@ -1114,7 +1149,12 @@ ShinySession <- R6Class(
structure(list(), class = "try-error", condition = cond)
} else if (inherits(cond, "shiny.output.cancel")) {
structure(list(), class = "cancel-output")
} else if (inherits(cond, "shiny.silent.error")) {
} else if (cnd_inherits(cond, "shiny.silent.error")) {
# The error condition might have been chained by
# foreign code, e.g. dplyr. Find the original error.
while (!inherits(cond, "shiny.silent.error")) {
cond <- cond$parent
}
# Don't let shiny.silent.error go through the normal stop
# path of try, because we don't want it to print. But we
# do want to try to return the same looking result so that
@@ -1701,7 +1741,7 @@ ShinySession <- R6Class(
dots <- eval(substitute(alist(...)))
}
if (anyUnnamed(dots))
if (any_unnamed(dots))
stop("exportTestValues: all arguments must be named.")
# Create a named list where each item is a list with an expression and
@@ -1714,7 +1754,7 @@ ShinySession <- R6Class(
},
getTestSnapshotUrl = function(input = TRUE, output = TRUE, export = TRUE,
format = "json") {
format = "json", sortC = FALSE) {
reqString <- function(group, value) {
if (isTRUE(value))
paste0(group, "=1")
@@ -1728,6 +1768,7 @@ ShinySession <- R6Class(
reqString("input", input),
reqString("output", output),
reqString("export", export),
reqString("sortC", sortC),
paste0("format=", format),
sep = "&"
)
@@ -2127,18 +2168,6 @@ ShinySession <- R6Class(
})
}
}
),
active = list(
session = function() {
shinyDeprecated(
"0.11.1", "shinysession$session",
details = paste0(
"Attempted to access deprecated shinysession$session object. ",
"Please just access the shinysession object directly."
)
)
self
}
)
)
@@ -2175,7 +2204,7 @@ ShinySession <- R6Class(
if (getOption("shiny.allowoutputreads", FALSE)) {
.subset2(x, 'impl')$getOutput(name)
} else {
rlang::abort(paste0("Can't read output '", output, "'"))
rlang::abort(paste0("Can't read output '", name, "'"))
}
}

View File

@@ -193,7 +193,7 @@ shinyAppDir_serverR <- function(appDir, options=list()) {
staticPaths <- list()
}
fallbackWWWDir <- system.file("www-dir", package = "shiny")
fallbackWWWDir <- system_file("www-dir", package = "shiny")
serverSource <- cachedFuncWithFile(appDir, "server.R", case.sensitive = FALSE,
function(serverR) {
@@ -286,7 +286,7 @@ shinyAppDir_serverR <- function(appDir, options=list()) {
#
# The return value is a function that halts monitoring when called.
initAutoReloadMonitor <- function(dir) {
if (!getOption("shiny.autoreload", FALSE)) {
if (!get_devmode_option("shiny.autoreload", FALSE)) {
return(function(){})
}
@@ -339,7 +339,7 @@ initAutoReloadMonitor <- function(dir) {
#' @param appDir The application directory. If `appDir` is `NULL` or
#' not supplied, the nearest enclosing directory that is a Shiny app, starting
#' with the current directory, is used.
#' @param renv The environmeny in which the files in the `R/` directory should
#' @param renv The environment in which the files in the `R/` directory should
#' be evaluated.
#' @param globalrenv The environment in which `global.R` should be evaluated. If
#' `NULL`, `global.R` will not be evaluated at all.
@@ -455,7 +455,7 @@ shinyAppDir_appR <- function(fileName, appDir, options=list())
staticPaths <- list()
}
fallbackWWWDir <- system.file("www-dir", package = "shiny")
fallbackWWWDir <- system_file("www-dir", package = "shiny")
oldwd <- NULL
monitorHandle <- NULL

View File

@@ -14,7 +14,11 @@ NULL
#' # now we can just write "static" content without withMathJax()
#' div("more math here $$\\sqrt{2}$$")
withMathJax <- function(...) {
path <- 'https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'
path <- paste0(
getOption("shiny.mathjax.url", "https://mathjax.rstudio.com/latest/MathJax.js"),
"?",
getOption("shiny.mathjax.config", "config=TeX-AMS-MML_HTMLorMML")
)
tagList(
tags$head(
singleton(tags$script(src = path, type = 'text/javascript'))
@@ -39,7 +43,7 @@ renderPage <- function(ui, showcase=0, testMode=FALSE) {
# Put the body into the default template
ui <- htmlTemplate(
system.file("template", "default.html", package = "shiny"),
system_file("template", "default.html", package = "shiny"),
lang = lang,
body = ui,
# this template is a complete HTML document
@@ -47,48 +51,59 @@ renderPage <- function(ui, showcase=0, testMode=FALSE) {
)
}
jquery <- function() {
version <- getOption("shiny.jquery.version", 3)
if (version == 3) {
return(htmlDependency(
"jquery", version_jquery,
c(href = "shared"),
script = "jquery.min.js"
))
}
if (version == 1) {
return(htmlDependency(
"jquery", "1.12.4",
c(href = "shared/legacy"),
script = "jquery.min.js"
))
}
stop("Unsupported version of jQuery: ", version)
}
shiny_deps <- c(
list(jquery()),
list(jqueryDependency()),
shinyDependencies()
)
if (testMode) {
# Add code injection listener if in test mode
shiny_deps[[length(shiny_deps) + 1]] <-
htmlDependency("shiny-testmode", shinyPackageVersion(),
c(href="shared"), script = "shiny-testmode.js")
htmlDependency(
"shiny-testmode",
get_package_version("shiny"),
src = "www/shared",
package = "shiny",
script = "shiny-testmode.js",
all_files = FALSE
)
}
html <- renderDocument(ui, shiny_deps, processDep = createWebDependency)
enc2utf8(paste(collapse = "\n", html))
}
jqueryDependency <- function() {
version <- getOption("shiny.jquery.version", 3)
if (version == 3) {
return(htmlDependency(
"jquery", version_jquery,
src = "www/shared",
package = "shiny",
script = "jquery.min.js",
all_files = FALSE
))
}
if (version == 1) {
return(htmlDependency(
"jquery", "1.12.4",
src = "www/shared/legacy",
package = "shiny",
script = "jquery.min.js",
all_files = FALSE
))
}
stop("Unsupported version of jQuery: ", version)
}
shinyDependencies <- function() {
list(
bslib::bs_dependency_defer(shinyDependencyCSS),
htmlDependency(
name = "shiny-javascript",
version = shinyPackageVersion(),
src = c(href = "shared"),
version = get_package_version("shiny"),
src = "www/shared",
package = "shiny",
script =
if (isTRUE(
get_devmode_option(
@@ -98,24 +113,27 @@ shinyDependencies <- function() {
))
"shiny.min.js"
else
"shiny.js"
"shiny.js",
all_files = FALSE
)
)
}
shinyDependencyCSS <- function(theme) {
version <- shinyPackageVersion()
version <- get_package_version("shiny")
if (!is_bs_theme(theme)) {
return(htmlDependency(
name = "shiny-css",
version = version,
src = c(href = "shared"),
stylesheet = "shiny.min.css"
src = "www/shared",
package = "shiny",
stylesheet = "shiny.min.css",
all_files = FALSE
))
}
scss_home <- system.file("www/shared/shiny_scss", package = "shiny")
scss_home <- system_file("www/shared/shiny_scss", package = "shiny")
scss_files <- file.path(scss_home, c("bootstrap.scss", "shiny.scss"))
scss_files <- lapply(scss_files, sass::sass_file)
@@ -130,7 +148,7 @@ shinyDependencyCSS <- function(theme) {
#' Create a Shiny UI handler
#'
#' @description \lifecycle{superseded}
#' @description `r lifecycle::badge("superseded")`
#'
#' @description Historically this function was used in ui.R files to register a user
#' interface with Shiny. It is no longer required as of Shiny 0.10; simply

View File

@@ -2,12 +2,23 @@ utils::globalVariables('func', add = TRUE)
#' Mark a function as a render function
#'
#' `r lifecycle::badge("superseded")` Please use [`createRenderFunction()`] to
#' support async execution. (Shiny 1.1.0)
#'
#' Should be called by implementers of `renderXXX` functions in order to mark
#' their return values as Shiny render functions, and to provide a hint to Shiny
#' regarding what UI function is most commonly used with this type of render
#' function. This can be used in R Markdown documents to create complete output
#' widgets out of just the render function.
#'
#' Note that it is generally preferable to use [createRenderFunction()] instead
#' of `markRenderFunction()`. It essentially wraps up the user-provided
#' expression in the `transform` function passed to it, then passes the resulting
#' function to `markRenderFunction()`. It also provides a simpler calling
#' interface. There may be cases where `markRenderFunction()` must be used instead of
#' [createRenderFunction()] -- for example, when the `transform` parameter of
#' [createRenderFunction()] is not flexible enough for your needs.
#'
#' @param uiFunc A function that renders Shiny UI. Must take a single argument:
#' an output ID.
#' @param renderFunc A function that is suitable for assigning to a Shiny output
@@ -37,7 +48,7 @@ utils::globalVariables('func', add = TRUE)
#' is able to serve JS and CSS resources.
#' @return The `renderFunc` function, with annotations.
#'
#' @seealso [createRenderFunction()], [quoToFunction()]
#' @seealso [createRenderFunction()]
#' @export
markRenderFunction <- function(
uiFunc,
@@ -47,6 +58,12 @@ markRenderFunction <- function(
cacheWriteHook = NULL,
cacheReadHook = NULL
) {
# (Do not emit warning for superseded code, "since theres no risk if you keep using it")
# # This method is called by the superseding function, createRenderFunction().
# if (in_devmode()) {
# shinyDeprecated("1.1.0", "markRenderFunction()", "createRenderFunction()")
# }
force(renderFunc)
# a mutable object that keeps track of whether `useRenderFunction` has been
@@ -94,6 +111,7 @@ markRenderFunction <- function(
# For everything else, do nothing.
cacheHint <- lapply(cacheHint, function(x) {
if (is.function(x)) formalsAndBody(x)
else if (is_quosure(x)) zap_srcref(quo_get_expr(x))
else if (is.language(x)) zap_srcref(x)
else x
})
@@ -133,10 +151,27 @@ print.shiny.render.function <- function(x, ...) {
cat_line("<shiny.render.function>")
}
#' Implement render functions
#' Implement custom render functions
#'
#' This function is a wrapper for [markRenderFunction()] which provides support
#' for async computation via promises.
#' Developer-facing utilities for implementing a custom `renderXXX()` function.
#' Before using these utilities directly, consider using the [`htmlwidgets`
#' package](http://www.htmlwidgets.org/develop_intro.html) to implement custom
#' outputs (i.e., custom `renderXXX()`/`xxxOutput()` functions). That said,
#' these utilities can be used more directly if a full-blown htmlwidget isn't
#' needed and/or the user-supplied reactive expression needs to be wrapped in
#' additional call(s).
#'
#' To implement a custom `renderXXX()` function, essentially 2 things are needed:
#' 1. Capture the user's reactive expression as a function.
#' * New `renderXXX()` functions can use `quoToFunction()` for this, but
#' already existing `renderXXX()` functions that contain `env` and `quoted`
#' parameters may want to continue using `installExprFunction()` for better
#' legacy support (see examples).
#' 2. Flag the resulting function (from 1) as a Shiny rendering function and
#' also provide a UI container for displaying the result of the rendering
#' function.
#' * `createRenderFunction()` is currently recommended (instead of
#' [markRenderFunction()]) for this step (see examples).
#'
#' @param func A function without parameters, that returns user data. If the
#' returned value is a promise, then the render function will proceed in async
@@ -153,16 +188,24 @@ print.shiny.render.function <- function(x, ...) {
#' @return An annotated render function, ready to be assigned to an
#' `output` slot.
#'
#' @seealso [quoToFunction()], [markRenderFunction()].
#'
#' @examples
#' # A very simple render function
#' renderTriple <- function(x) {
#' x <- substitute(x)
#' if (!rlang::is_quosure(x)) {
#' x <- rlang::new_quosure(x, env = parent.frame())
#' }
#' func <- quoToFunction(x, "renderTriple")
#' # A custom render function that repeats the supplied value 3 times
#' renderTriple <- function(expr) {
#' # Wrap user-supplied reactive expression into a function
#' func <- quoToFunction(rlang::enquo0(expr))
#'
#' createRenderFunction(
#' func,
#' transform = function(value, session, name, ...) {
#' paste(rep(value, 3), collapse=", ")
#' },
#' outputFunc = textOutput
#' )
#' }
#'
#' # For better legacy support, consider using installExprFunction() over quoToFunction()
#' renderTripleLegacy <- function(expr, env = parent.frame(), quoted = FALSE) {
#' func <- installExprFunction(expr, "func", env, quoted)
#'
#' createRenderFunction(
#' func,
@@ -174,10 +217,38 @@ print.shiny.render.function <- function(x, ...) {
#' }
#'
#' # Test render function from the console
#' a <- 1
#' r <- renderTriple({ a + 1 })
#' a <- 2
#' reactiveConsole(TRUE)
#'
#' v <- reactiveVal("basic")
#' r <- renderTriple({ v() })
#' r()
#' #> [1] "basic, basic, basic"
#'
#' # User can supply quoted code via rlang::quo(). Note that evaluation of the
#' # expression happens when r2() is invoked, not when r2 is created.
#' q <- rlang::quo({ v() })
#' r2 <- rlang::inject(renderTriple(!!q))
#' v("rlang")
#' r2()
#' #> [1] "rlang, rlang, rlang"
#'
#' # Supplying quoted code without rlang::quo() requires installExprFunction()
#' expr <- quote({ v() })
#' r3 <- renderTripleLegacy(expr, quoted = TRUE)
#' v("legacy")
#' r3()
#' #> [1] "legacy, legacy, legacy"
#'
#' # The legacy approach also supports with quosures (env is ignored in this case)
#' q <- rlang::quo({ v() })
#' r4 <- renderTripleLegacy(q, quoted = TRUE)
#' v("legacy-rlang")
#' r4()
#' #> [1] "legacy-rlang, legacy-rlang, legacy-rlang"
#'
#' # Turn off reactivity in the console
#' reactiveConsole(FALSE)
#'
#' @export
createRenderFunction <- function(
func,
@@ -316,9 +387,7 @@ markOutputAttrs <- function(renderFunc, snapshotExclude = NULL,
#' the output, see [plotPNG()].
#'
#' @param expr An expression that returns a list.
#' @param env The environment in which to evaluate `expr`.
#' @param quoted Is `expr` a quoted expression (with `quote()`)? This
#' is useful if you want to save an expression in a variable.
#' @inheritParams renderUI
#' @param deleteFile Should the file in `func()$src` be deleted after
#' it is sent to the client browser? Generally speaking, if the image is a
#' temp file generated within `func`, then this should be `TRUE`;
@@ -397,11 +466,10 @@ markOutputAttrs <- function(renderFunc, snapshotExclude = NULL,
#'
#' shinyApp(ui, server)
#' }
renderImage <- function(expr, env=parent.frame(), quoted=FALSE,
renderImage <- function(expr, env = parent.frame(), quoted = FALSE,
deleteFile, outputArgs=list())
{
expr <- get_quosure(expr, env, quoted)
func <- quoToFunction(expr, "renderImage")
func <- installExprFunction(expr, "func", env, quoted, label = "renderImage")
# missing() must be used directly within the function with the given arg
if (missing(deleteFile)) {
@@ -523,9 +591,7 @@ isTemp <- function(path, tempDir = tempdir(), mustExist) {
#' function return [invisible()].
#'
#' @param expr An expression to evaluate.
#' @param env The environment in which to evaluate `expr`. For expert use only.
#' @param quoted Is `expr` a quoted expression (with `quote()`)? This
#' is useful if you want to save an expression in a variable.
#' @inheritParams renderUI
#' @param width Width of printed output.
#' @param outputArgs A list of arguments to be passed through to the implicit
#' call to [verbatimTextOutput()] or [textOutput()] when the functions are
@@ -536,8 +602,7 @@ isTemp <- function(path, tempDir = tempdir(), mustExist) {
renderPrint <- function(expr, env = parent.frame(), quoted = FALSE,
width = getOption('width'), outputArgs=list())
{
expr <- get_quosure(expr, env, quoted)
func <- quoToFunction(expr, "renderPrint")
func <- installExprFunction(expr, "func", env, quoted, label = "renderPrint")
# Set a promise domain that sets the console width
# and captures output
@@ -569,7 +634,7 @@ renderPrint <- function(expr, env = parent.frame(), quoted = FALSE,
outputArgs,
cacheHint = list(
label = "renderPrint",
origUserExpr = get_expr(expr)
origUserExpr = installedFuncExpr(func)
)
)
}
@@ -619,11 +684,10 @@ createRenderPrintPromiseDomain <- function(width) {
#' element.
#' @export
#' @rdname renderPrint
renderText <- function(expr, env=parent.frame(), quoted=FALSE,
renderText <- function(expr, env = parent.frame(), quoted = FALSE,
outputArgs=list(), sep=" ") {
expr <- get_quosure(expr, env, quoted)
func <- quoToFunction(expr, "renderText")
func <- installExprFunction(expr, "func", env, quoted, label = "renderText")
createRenderFunction(
func,
@@ -644,9 +708,13 @@ renderText <- function(expr, env=parent.frame(), quoted=FALSE,
#'
#' @param expr An expression that returns a Shiny tag object, [HTML()],
#' or a list of such objects.
#' @param env The environment in which to evaluate `expr`.
#' @param quoted Is `expr` a quoted expression (with `quote()`)? This
#' is useful if you want to save an expression in a variable.
#' @template param-env
#' @templateVar x expr
#' @templateVar env env
#' @templateVar quoted quoted
#' @template param-quoted
#' @templateVar x expr
#' @templateVar quoted quoted
#' @param outputArgs A list of arguments to be passed through to the implicit
#' call to [uiOutput()] when `renderUI` is used in an
#' interactive R Markdown document.
@@ -675,8 +743,7 @@ renderText <- function(expr, env=parent.frame(), quoted=FALSE,
renderUI <- function(expr, env = parent.frame(), quoted = FALSE,
outputArgs = list())
{
expr <- get_quosure(expr, env, quoted)
func <- quoToFunction(expr, "renderUI")
func <- installExprFunction(expr, "func", env, quoted, label = "renderUI")
createRenderFunction(
func,
@@ -711,9 +778,9 @@ renderUI <- function(expr, env = parent.frame(), quoted = FALSE,
#' function.)
#' @param contentType A string of the download's
#' [content type](https://en.wikipedia.org/wiki/Internet_media_type), for
#' example `"text/csv"` or `"image/png"`. If `NULL` or
#' `NA`, the content type will be guessed based on the filename
#' extension, or `application/octet-stream` if the extension is unknown.
#' example `"text/csv"` or `"image/png"`. If `NULL`, the content type
#' will be guessed based on the filename extension, or
#' `application/octet-stream` if the extension is unknown.
#' @param outputArgs A list of arguments to be passed through to the implicit
#' call to [downloadButton()] when `downloadHandler` is used
#' in an interactive R Markdown document.
@@ -743,7 +810,7 @@ renderUI <- function(expr, env = parent.frame(), quoted = FALSE,
#' shinyApp(ui, server)
#' }
#' @export
downloadHandler <- function(filename, content, contentType=NA, outputArgs=list()) {
downloadHandler <- function(filename, content, contentType=NULL, outputArgs=list()) {
renderFunc <- function(shinysession, name, ...) {
shinysession$registerDownload(name, filename, contentType, content)
}
@@ -755,6 +822,10 @@ downloadHandler <- function(filename, content, contentType=NA, outputArgs=list()
#' Table output with the JavaScript DataTables library
#'
#' @description
#' `r lifecycle::badge("superseded")` Please use
#' \href{https://rstudio.github.io/DT/shiny.html}{\code{DT::renderDataTable()}}.
#' (Shiny 0.11.1)
#'
#' Makes a reactive version of the given function that returns a data frame (or
#' matrix), which will be rendered with the [DataTables](https://datatables.net)
#' library. Paging, searching, filtering, and sorting can be done on the R side
@@ -829,8 +900,7 @@ renderDataTable <- function(expr, options = NULL, searchDelay = 500,
)
}
expr <- get_quosure(expr, env, quoted)
func <- quoToFunction(expr, "renderDataTable")
func <- installExprFunction(expr, "func", env, quoted, label = "renderDataTable")
renderFunc <- function(shinysession, name, ...) {
if (is.function(options)) options <- options()
@@ -883,7 +953,7 @@ renderDataTable <- function(expr, options = NULL, searchDelay = 500,
DT10Names <- function() {
rbind(
utils::read.table(
system.file('www/shared/datatables/upgrade1.10.txt', package = 'shiny'),
system_file('www/shared/datatables/upgrade1.10.txt', package = 'shiny'),
stringsAsFactors = FALSE
),
c('aoColumns', 'Removed') # looks like an omission on the upgrade guide
@@ -918,67 +988,3 @@ checkDT9 <- function(options) {
names(options)[i] <- nms10
options
}
# Deprecated functions ------------------------------------------------------
#' Deprecated reactive functions
#'
#' @description \lifecycle{superseded}
#'
#' @name deprecatedReactives
#' @keywords internal
NULL
#' Plot output (deprecated)
#'
#' `reactivePlot` has been replaced by [renderPlot()].
#' @param func A function.
#' @param width Width.
#' @param height Height.
#' @param ... Other arguments to pass on.
#' @rdname deprecatedReactives
#' @export
reactivePlot <- function(func, width='auto', height='auto', ...) {
shinyDeprecated("0.4.0", "reactivePlot()", "renderPlot()")
renderPlot({ func() }, width=width, height=height, ...)
}
#' Table output (deprecated)
#'
#' `reactiveTable` has been replaced by [renderTable()].
#' @rdname deprecatedReactives
#' @export
reactiveTable <- function(func, ...) {
shinyDeprecated("0.4.0", "reactiveTable()", "renderTable()")
renderTable({ func() })
}
#' Print output (deprecated)
#'
#' `reactivePrint` has been replaced by [renderPrint()].
#' @rdname deprecatedReactives
#' @export
reactivePrint <- function(func) {
shinyDeprecated("0.4.0", "reactivePrint()", "renderPrint()")
renderPrint({ func() })
}
#' UI output (deprecated)
#'
#' `reactiveUI` has been replaced by [renderUI()].
#' @rdname deprecatedReactives
#' @export
reactiveUI <- function(func) {
shinyDeprecated("0.4.0", "reactiveUI()", "renderUI()")
renderUI({ func() })
}
#' Text output (deprecated)
#'
#' `reactiveText` has been replaced by [renderText()].
#' @rdname deprecatedReactives
#' @export
reactiveText <- function(func) {
shinyDeprecated("0.4.0", "reactiveText()", "renderText()")
renderText({ func() })
}

View File

@@ -32,26 +32,40 @@ licenseLink <- function(licenseName) {
showcaseHead <- function() {
deps <- list(
htmlDependency("jqueryui", "1.12.1", c(href="shared/jqueryui"),
script = "jquery-ui.min.js"),
htmlDependency("showdown", "0.3.1", c(href="shared/showdown/compressed"),
script = "showdown.js"),
htmlDependency("highlight.js", "6.2", c(href="shared/highlight"),
script = "highlight.pack.js")
jqueryuiDependency(),
htmlDependency(
"showdown",
"0.3.1",
src = "www/shared/showdown/compressed",
package="shiny",
script = "showdown.js"
),
htmlDependency(
"highlight.js",
"6.2",
src = "www/shared/highlight",
package="shiny",
script = "highlight.pack.js",
stylesheet = "rstudio.css"
),
htmlDependency(
"showcase",
"0.1.0",
src = "www/shared",
package = "shiny",
script = "shiny-showcase.js",
stylesheet = "shiny-showcase.css",
all_files = FALSE
)
)
mdfile <- file.path.ci(getwd(), 'Readme.md')
html <- with(tags, tagList(
script(src="shared/shiny-showcase.js"),
link(rel="stylesheet", type="text/css",
href="shared/highlight/rstudio.css"),
link(rel="stylesheet", type="text/css",
href="shared/shiny-showcase.css"),
html <- tagList(
if (file.exists(mdfile))
script(type="text/markdown", id="showcase-markdown-content",
tags$script(type="text/markdown", id="showcase-markdown-content",
paste(readUTF8(mdfile), collapse="\n"))
else ""
))
)
return(attachDependencies(html, deps))
}
@@ -83,7 +97,7 @@ navTabsHelper <- function(files, prefix = "") {
with(tags,
li(class=if (tolower(file) %in% c("app.r", "server.r")) "active" else "",
a(href=paste("#", gsub(".", "_", file, fixed=TRUE), "_code", sep=""),
"data-toggle"="tab", paste0(prefix, file)))
"data-toggle"="tab", "data-bs-toggle"="tab", paste0(prefix, file)))
)
})
}
@@ -92,7 +106,7 @@ navTabsDropdown <- function(files) {
if (length(files) > 0) {
with(tags,
li(role="presentation", class="dropdown",
a(class="dropdown-toggle", `data-toggle`="dropdown", href="#",
a(class="dropdown-toggle", `data-toggle`="dropdown", `data-bs-toggle`="dropdown", href="#",
role="button", `aria-haspopup`="true", `aria-expanded`="false",
"www", span(class="caret")
),
@@ -134,7 +148,7 @@ showcaseCodeTabs <- function(codeLicense) {
a(id="showcase-code-position-toggle",
class="btn btn-default btn-sm",
onclick="toggleCodePosition()",
icon("level-up"),
icon("level-up-alt"),
"show with app"),
ul(class="nav nav-tabs",
navTabsHelper(rFiles),

190
R/staticimports.R Normal file
View File

@@ -0,0 +1,190 @@
# Generated by staticimports; do not edit by hand.
# ======================================================================
# Imported from pkg:staticimports
# ======================================================================
# Given a vector, return TRUE if any elements are named, FALSE otherwise.
# For zero-length vectors, always return FALSE.
any_named <- function(x) {
if (length(x) == 0) return(FALSE)
nms <- names(x)
!is.null(nms) && any(nzchar(nms))
}
# Given a vector, return TRUE if any elements are unnamed, FALSE otherwise.
# For zero-length vectors, always return FALSE.
any_unnamed <- function(x) {
if (length(x) == 0) return(FALSE)
nms <- names(x)
is.null(nms) || !all(nzchar(nms))
}
# Borrowed from pkgload:::dev_meta, with some modifications.
# Returns TRUE if `pkg` was loaded with `devtools::load_all()`.
devtools_loaded <- function(pkg) {
ns <- .getNamespace(pkg)
if (is.null(ns) || is.null(ns$.__DEVTOOLS__)) {
return(FALSE)
}
TRUE
}
get_package_version <- function(pkg) {
# `utils::packageVersion()` can be slow, so first try the fast path of
# checking if the package is already loaded.
ns <- .getNamespace(pkg)
if (is.null(ns)) {
utils::packageVersion(pkg)
} else {
as.package_version(ns$.__NAMESPACE__.$spec[["version"]])
}
}
is_installed <- function(pkg, version = NULL) {
installed <- isNamespaceLoaded(pkg) || nzchar(system_file_cached(package = pkg))
if (is.null(version)) {
return(installed)
}
installed && isTRUE(get_package_version(pkg) >= version)
}
# Simplified version rlang:::s3_register() that just uses
# warning() instead of rlang::warn() when registration fails
# https://github.com/r-lib/rlang/blob/main/R/compat-s3-register.R
s3_register <- function(generic, class, method = NULL) {
stopifnot(is.character(generic), length(generic) == 1)
stopifnot(is.character(class), length(class) == 1)
pieces <- strsplit(generic, "::")[[1]]
stopifnot(length(pieces) == 2)
package <- pieces[[1]]
generic <- pieces[[2]]
caller <- parent.frame()
get_method_env <- function() {
top <- topenv(caller)
if (isNamespace(top)) {
asNamespace(environmentName(top))
} else {
caller
}
}
get_method <- function(method, env) {
if (is.null(method)) {
get(paste0(generic, ".", class), envir = get_method_env())
} else {
method
}
}
register <- function(...) {
envir <- asNamespace(package)
# Refresh the method each time, it might have been updated by
# `devtools::load_all()`
method_fn <- get_method(method)
stopifnot(is.function(method_fn))
# Only register if generic can be accessed
if (exists(generic, envir)) {
registerS3method(generic, class, method_fn, envir = envir)
} else {
warning(
"Can't find generic `", generic, "` in package ", package,
" register S3 method. Do you need to update ", package,
" to the latest version?", call. = FALSE
)
}
}
# Always register hook in case package is later unloaded & reloaded
setHook(packageEvent(package, "onLoad"), function(...) {
register()
})
# Avoid registration failures during loading (pkgload or regular).
# Check that environment is locked because the registering package
# might be a dependency of the package that exports the generic. In
# that case, the exports (and the generic) might not be populated
# yet (#1225).
if (isNamespaceLoaded(package) && environmentIsLocked(asNamespace(package))) {
register()
}
invisible()
}
# Borrowed from pkgload::shim_system.file, with some modifications. This behaves
# like `system.file()`, except that (1) for packages loaded with
# `devtools::load_all()`, it will return the path to files in the package's
# inst/ directory, and (2) for other packages, the directory lookup is cached.
# Also, to keep the implementation simple, it doesn't support specification of
# lib.loc or mustWork.
system_file <- function(..., package = "base") {
if (!devtools_loaded(package)) {
return(system_file_cached(..., package = package))
}
if (!is.null(names(list(...)))) {
stop("All arguments other than `package` must be unnamed.")
}
# If package was loaded with devtools (the package loaded with load_all),
# also search for files under inst/, and don't cache the results (it seems
# more likely that the package path will change during the development
# process)
pkg_path <- find.package(package)
# First look in inst/
files_inst <- file.path(pkg_path, "inst", ...)
present_inst <- file.exists(files_inst)
# For any files that weren't present in inst/, look in the base path
files_top <- file.path(pkg_path, ...)
present_top <- file.exists(files_top)
# Merge them together. Here are the different possible conditions, and the
# desired result. NULL means to drop that element from the result.
#
# files_inst: /inst/A /inst/B /inst/C /inst/D
# present_inst: T T F F
# files_top: /A /B /C /D
# present_top: T F T F
# result: /inst/A /inst/B /C NULL
#
files <- files_top
files[present_inst] <- files_inst[present_inst]
# Drop cases where not present in either location
files <- files[present_inst | present_top]
if (length(files) == 0) {
return("")
}
# Make sure backslashes are replaced with slashes on Windows
normalizePath(files, winslash = "/")
}
# A wrapper for `system.file()`, which caches the package path because
# `system.file()` can be slow. If a package is not installed, the result won't
# be cached.
system_file_cached <- local({
pkg_dir_cache <- character()
function(..., package = "base") {
if (!is.null(names(list(...)))) {
stop("All arguments other than `package` must be unnamed.")
}
not_cached <- is.na(match(package, names(pkg_dir_cache)))
if (not_cached) {
pkg_dir <- system.file(package = package)
if (nzchar(pkg_dir)) {
pkg_dir_cache[[package]] <<- pkg_dir
}
} else {
pkg_dir <- pkg_dir_cache[[package]]
}
file.path(pkg_dir, ...)
}
})

View File

@@ -423,6 +423,23 @@ updateSliderInput <- function(session = getDefaultReactiveDomain(), inputId, lab
{
validate_session_object(session)
if (!is.null(value)) {
if (!is.null(min) && !is.null(max)) {
# Validate value/min/max together if all three are provided
tryCatch(
validate_slider_value(min, max, value, "updateSliderInput"),
error = function(err) warning(conditionMessage(err), call. = FALSE)
)
} else if (length(value) < 1 || length(value) > 2 || any(is.na(value))) {
# Otherwise ensure basic assumptions about value are met
warning(
"In updateSliderInput(): value must be a single value or a length-2 ",
"vector and cannot contain NA values.",
call. = FALSE
)
}
}
# If no min/max/value is provided, we won't know the
# type, and this will return an empty string
dataType <- getSliderType(min, max, value)

View File

@@ -51,60 +51,199 @@ formalsAndBody <- function(x) {
}
# This function is to be called from functions like `reactive()`, `observe()`,
# and the various render functions. It handles the following cases:
# - The typical case where x is an unquoted expression, and `env` and `quoted`
# are not used.
# - New-style metaprogramming cases, where rlang::inject() is used to inline a
# quosure into the AST, as in `inject(reactive(!!x))`.
# - Old-style metaprogramming cases, where `env` and/or `quoted` are used.
#
# Much of the complexity is handling old-style metaprogramming cases. The code
# in this function is more complicated because it needs to look at unevaluated
# expressions in the _calling_ function. If this code were put directly in the
# calling function, it would look like this:
#
# if (!missing(env) || !missing(quoted)) {
# deprecatedEnvQuotedMessage()
# if (!quoted) x <- substitute(x)
# x <- new_quosure(x, env)
#
# } else {
# x <- substitute(x)
# if (!is_quosure(x)) {
# x <- new_quosure(x, env = parent.frame())
# }
# }
#
# In the future, the calling functions will not need to have the `env` and
# `quoted` arguments -- `rlang::inject()` and quosures can be used instead.
# Instead of using this function, `get_quosure()`, the caller can instead use
# just the following code:
#
# x <- substitute(x)
# if (!is_quosure(x)) {
# x <- new_quosure(x, env = parent.frame())
# }
#
get_quosure <- function(x, env, quoted) {
if (!eval(substitute(missing(env)), parent.frame()) ||
!eval(substitute(missing(quoted)), parent.frame()))
{
deprecatedEnvQuotedMessage()
if (!quoted) {
x <- eval(substitute(substitute(x)), parent.frame())
}
x <- new_quosure(x, env)
#' @describeIn createRenderFunction convert a quosure to a function.
#' @param q Quosure of the expression `x`. When capturing expressions to create
#' your quosure, it is recommended to use [`enquo0()`] to not unquote the
#' object too early. See [`enquo0()`] for more details.
#' @inheritParams installExprFunction
#' @export
quoToFunction <- function(
q,
label = sys.call(-1)[[1]],
..stacktraceon = FALSE
) {
func <- quoToSimpleFunction(as_quosure(q))
wrapFunctionLabel(func, updateFunctionLabel(label), ..stacktraceon = ..stacktraceon, dots = FALSE)
}
} else {
x <- eval(substitute(substitute(x)), parent.frame())
# At this point, x can be a quosure if rlang::inject() is used, but the
# typical case is that x is not a quosure.
if (!is_quosure(x)) {
x <- new_quosure(x, env = parent.frame(2L))
updateFunctionLabel <- function(label) {
badFnName <- "anonymous"
if (all(is.language(label))) {
# Prevent immediately invoked functions like as.language(a()())
if (is.language(label) && length(label) > 1) {
return(badFnName)
}
label <- deparse(label, width.cutoff = 500L)
}
label <- as.character(label)
# Prevent function calls that are over one line; (Assignments are hard to perform)
# Prevent immediately invoked functions like "a()()"
if (length(label) > 1 || grepl("(", label, fixed = TRUE)) {
return(badFnName)
}
if (label == "NULL") {
return(badFnName)
}
label
}
quoToSimpleFunction <- function(q) {
# Should not use `new_function(list(), get_expr(q), get_env(q))` as extra logic
# is done by rlang to convert the quosure to a function within `as_function(q)`
fun <- as_function(q)
# If the quosure is empty, then the returned function can not be called.
# https://github.com/r-lib/rlang/issues/1244
if (quo_is_missing(q)) {
fn_body(fun) <- quote({})
}
x
# `as_function()` returns a function that takes `...`. We need one that takes no
# args.
fn_fmls(fun) <- list()
fun
}
#' Convert an expression to a function
#'
#' `r lifecycle::badge("superseded")` Please use [`installExprFunction()`] for a better
#' debugging experience (Shiny 0.8.0). If the `expr` and `quoted` parameters are not needed, please see
#' [`quoToFunction()`] (Shiny 1.6.0).
#'
#' Similar to [installExprFunction()] but doesn't register debug hooks.
#'
#' @param expr A quoted or unquoted expression, or a quosure.
#' @param env The desired environment for the function. Defaults to the
#' calling environment two steps back.
#' @param quoted Is the expression quoted?
#' @seealso [`installExprFunction()`] for the modern approach to converting an expression to a function
#' @export
#' @keywords internal
exprToFunction <- function(expr, env = parent.frame(), quoted = FALSE) {
# If `expr` is a raw quosure, must say `quoted = TRUE`; (env is ignored)
# If `inject()` a quosure, env is ignored, and quoted should be FALSE (aka ignored).
# Make article of usage
# * (by joe)
if (!quoted) {
expr <- eval(substitute(substitute(expr)), parent.frame())
}
# MUST call with `quoted = TRUE` as exprToQuo() will not reach high enough
q <- exprToQuo(expr, env, quoted = TRUE)
# MUST call `as_function()`. Can NOT call `new_function()`
# rlang has custom logic for handling converting a quosure to a function
quoToSimpleFunction(q)
}
# For internal use only; External users should be using `exprToFunction()` or `installExprFunction()`
# MUST be the exact same logic as `exprToFunction()`, but without the `quoToSimpleFunction()` call
exprToQuo <- function(expr, env = parent.frame(), quoted = FALSE) {
if (!quoted) {
expr <- eval(substitute(substitute(expr)), parent.frame())
}
q <-
if (is_quosure(expr)) {
# inject()ed quosure
# do nothing
expr
} else if (is.language(expr) || rlang::is_atomic(expr) || is.null(expr)) {
# Most common case...
new_quosure(expr, env = env)
} else {
stop("Don't know how to convert '", class(expr)[1], "' to a function; a quosure or quoted expression was expected")
}
q
}
#' @describeIn createRenderFunction converts a user's reactive `expr` into a
#' function that's assigned to a `name` in the `assign.env`.
#'
#' @param name The name the function should be given
#' @param eval.env The desired environment for the function. Defaults to the
#' calling environment two steps back.
#' @param assign.env The environment in which the function should be assigned.
#' @param label A label for the object to be shown in the debugger. Defaults to
#' the name of the calling function.
#' @param wrappedWithLabel,..stacktraceon Advanced use only. For stack manipulation purposes; see
#' [stacktrace()].
#' @inheritParams exprToFunction
#' @export
installExprFunction <- function(expr, name, eval.env = parent.frame(2),
quoted = FALSE,
assign.env = parent.frame(1),
label = sys.call(-1)[[1]],
wrappedWithLabel = TRUE,
..stacktraceon = FALSE) {
if (!quoted) {
quoted <- TRUE
expr <- eval(substitute(substitute(expr)), parent.frame())
}
func <- exprToFunction(expr, eval.env, quoted)
if (length(label) > 1) {
# Just in case the deparsed code is more complicated than we imagine. If we
# have a label with length > 1 it causes warnings in wrapFunctionLabel.
label <- paste0(label, collapse = "\n")
}
wrappedWithLabel <- isTRUE(wrappedWithLabel)
if (wrappedWithLabel) {
func <- wrapFunctionLabel(func, updateFunctionLabel(label), ..stacktraceon = ..stacktraceon, dots = FALSE)
}
assign(name, func, envir = assign.env)
if (!wrappedWithLabel) {
registerDebugHook(name, assign.env, label)
}
invisible(func)
}
# Utility function for creating a debugging label, given an expression.
# `expr` is a quoted expression.
# `function_name` is the name of the calling function.
# `label` is an optional user-provided label. If NULL, it will be inferred.
exprToLabel <- function(expr, function_name, label = NULL) {
srcref <- attr(expr, "srcref", exact = TRUE)
if (is.null(label)) {
label <- rexprSrcrefToLabel(
srcref[[1]],
simpleExprToFunction(expr, function_name)
)
}
if (length(srcref) >= 2) attr(label, "srcref") <- srcref[[2]]
attr(label, "srcfile") <- srcFileOfRef(srcref[[1]])
label
}
simpleExprToFunction <- function(expr, function_name) {
sprintf('%s(%s)', function_name, paste(deparse(expr), collapse='\n'))
}
installedFuncExpr <- function(func) {
fn_body(attr(func, "wrappedFunc", exact = TRUE))
}
funcToLabelBody <- function(func) {
paste(deparse(installedFuncExpr(func)), collapse='\n')
}
funcToLabel <- function(func, functionLabel, label = NULL) {
if (!is.null(label)) return(label)
sprintf(
'%s(%s)',
functionLabel,
funcToLabelBody(func)
)
}
quoToLabelBody <- function(q) {
paste(deparse(quo_get_expr(q)), collapse='\n')
}
quoToLabel <- function(q, functionLabel, label = NULL) {
if (!is.null(label)) return(label)
sprintf(
'%s(%s)',
functionLabel,
quoToLabelBody(q)
)
}

271
R/utils.R
View File

@@ -2,6 +2,11 @@
#' @include map.R
NULL
# @staticimports pkg:staticimports
# is_installed get_package_version system_file
# s3_register
# any_named any_unnamed
#' Make a random number generator repeatable
#'
#' Given a function that generates random data, returns a wrapped version of
@@ -126,34 +131,6 @@ dropNullsOrEmpty <- function(x) {
x[!vapply(x, nullOrEmpty, FUN.VALUE=logical(1))]
}
# Given a vector/list, return TRUE if any elements are named, FALSE otherwise.
anyNamed <- function(x) {
# Zero-length vector
if (length(x) == 0) return(FALSE)
nms <- names(x)
# List with no name attribute
if (is.null(nms)) return(FALSE)
# List with name attribute; check for any ""
any(nzchar(nms))
}
# Given a vector/list, return TRUE if any elements are unnamed, FALSE otherwise.
anyUnnamed <- function(x) {
# Zero-length vector
if (length(x) == 0) return(FALSE)
nms <- names(x)
# List with no name attribute
if (is.null(nms)) return(TRUE)
# List with name attribute; check for any ""
any(!nzchar(nms))
}
# Given a vector/list, returns a named vector/list (the labels will be blank).
asNamed <- function(x) {
@@ -173,7 +150,7 @@ empty_named_list <- function() {
# name as elements in a, the element in a is dropped. Also, if there are any
# duplicated names in a or b, only the last one with that name is kept.
mergeVectors <- function(a, b) {
if (anyUnnamed(a) || anyUnnamed(b)) {
if (any_unnamed(a) || any_unnamed(b)) {
stop("Vectors must be either NULL or have names for all elements")
}
@@ -185,15 +162,27 @@ mergeVectors <- function(a, b) {
# Sort a vector by the names of items. If there are multiple items with the
# same name, preserve the original order of those items. For empty
# vectors/lists/NULL, return the original value.
sortByName <- function(x) {
if (anyUnnamed(x))
sortByName <- function(x, method = "auto") {
if (any_unnamed(x))
stop("All items must be named")
# Special case for empty vectors/lists, and NULL
if (length(x) == 0)
return(x)
x[order(names(x))]
# Must provide consistent sort order
# https://github.com/rstudio/shinytest/issues/409
# Using a flag in the snapshot url to determine the method
# `method="radix"` uses `C` locale, which is consistent across platforms
# Even if two platforms share `en_us.UTF-8`, they may not sort consistently
# https://blog.zhimingwang.org/macos-lc_collate-hunt
# (macOS) $ LC_ALL=en_US.UTF-8 sort <<<$'python-dev\npython3-dev'
# python-dev
# python3-dev
# (Linux) $ LC_ALL=en_US.UTF-8 sort <<<$'python-dev\npython3-dev'
# python3-dev
# python-dev
x[order(names(x), method = method)]
}
# Sort a vector. If a character vector, sort using C locale, which is consistent
@@ -404,164 +393,6 @@ getContentType <- function(file, defaultType = 'application/octet-stream') {
mime::guess_type(file, unknown = defaultType, subtype = subtype)
}
# Create a zero-arg function from a quoted expression and environment
# @examples
# makeFunction(body=quote(print(3)))
makeFunction <- function(args = pairlist(), body, env = parent.frame()) {
eval(call("function", args, body), env)
}
#' Convert an expression to a function
#'
#' This is to be called from another function, because it will attempt to get
#' an unquoted expression from two calls back. Note: as of Shiny 1.6.0, it is
#' recommended to use [quoToFunction()] instead.
#'
#' If expr is a quoted expression, then this just converts it to a function.
#' If expr is a function, then this simply returns expr (and prints a
#' deprecation message).
#' If expr was a non-quoted expression from two calls back, then this will
#' quote the original expression and convert it to a function.
#
#' @param expr A quoted or unquoted expression, or a function.
#' @param env The desired environment for the function. Defaults to the
#' calling environment two steps back.
#' @param quoted Is the expression quoted?
#'
#' @examples
#' # Example of a new renderer, similar to renderText
#' # This is something that toolkit authors will do
#' renderTriple <- function(expr, env=parent.frame(), quoted=FALSE) {
#' # Convert expr to a function
#' func <- shiny::exprToFunction(expr, env, quoted)
#'
#' function() {
#' value <- func()
#' paste(rep(value, 3), collapse=", ")
#' }
#' }
#'
#'
#' # Example of using the renderer.
#' # This is something that app authors will do.
#' values <- reactiveValues(A="text")
#'
#' \dontrun{
#' # Create an output object
#' output$tripleA <- renderTriple({
#' values$A
#' })
#' }
#'
#' # At the R console, you can experiment with the renderer using isolate()
#' tripleA <- renderTriple({
#' values$A
#' })
#'
#' isolate(tripleA())
#' # "text, text, text"
#' @export
exprToFunction <- function(expr, env=parent.frame(), quoted=FALSE) {
if (!quoted) {
expr <- eval(substitute(substitute(expr)), parent.frame())
}
# expr is a quoted expression
makeFunction(body=expr, env=env)
}
#' Install an expression as a function
#'
#' Installs an expression in the given environment as a function, and registers
#' debug hooks so that breakpoints may be set in the function. Note: as of
#' Shiny 1.6.0, it is recommended to use [quoToFunction()] instead.
#'
#' This function can replace `exprToFunction` as follows: we may use
#' `func <- exprToFunction(expr)` if we do not want the debug hooks, or
#' `installExprFunction(expr, "func")` if we do. Both approaches create a
#' function named `func` in the current environment.
#'
#' @seealso Wraps [exprToFunction()]; see that method's documentation
#' for more documentation and examples.
#'
#' @param expr A quoted or unquoted expression
#' @param name The name the function should be given
#' @param eval.env The desired environment for the function. Defaults to the
#' calling environment two steps back.
#' @param quoted Is the expression quoted?
#' @param assign.env The environment in which the function should be assigned.
#' @param label A label for the object to be shown in the debugger. Defaults to
#' the name of the calling function.
#' @param wrappedWithLabel,..stacktraceon Advanced use only. For stack manipulation purposes; see
#' [stacktrace()].
#' @export
installExprFunction <- function(expr, name, eval.env = parent.frame(2),
quoted = FALSE,
assign.env = parent.frame(1),
label = deparse(sys.call(-1)[[1]]),
wrappedWithLabel = TRUE,
..stacktraceon = FALSE) {
if (!quoted) {
quoted <- TRUE
expr <- eval(substitute(substitute(expr)), parent.frame())
}
func <- exprToFunction(expr, eval.env, quoted)
if (length(label) > 1) {
# Just in case the deparsed code is more complicated than we imagine. If we
# have a label with length > 1 it causes warnings in wrapFunctionLabel.
label <- paste0(label, collapse = "\n")
}
if (wrappedWithLabel) {
func <- wrapFunctionLabel(func, label, ..stacktraceon = ..stacktraceon)
} else {
registerDebugHook(name, assign.env, label)
}
assign(name, func, envir = assign.env)
}
#' Convert a quosure to a function for a Shiny render function
#'
#' This takes a quosure and label, and wraps them into a function that should be
#' passed to [createRenderFunction()] or [markRenderFunction()].
#'
#' This function was added in Shiny 1.6.0. Previously, it was recommended to use
#' [installExprFunction()] or [exprToFunction()] in render functions, but now we
#' recommend using [quoToFunction()], because it does not require `env` and
#' `quoted` arguments -- that information is captured by quosures provided by
#' \pkg{rlang}.
#'
#' @param q A quosure.
#' @inheritParams installExprFunction
#' @seealso [createRenderFunction()] for example usage.
#'
#' @export
quoToFunction <- function(q, label, ..stacktraceon = FALSE) {
q <- as_quosure(q)
# Use new_function() instead of as_function(), because as_function() adds an
# extra parent environment. (This may not actually be a problem, though.)
func <- new_function(NULL, get_expr(q), get_env(q))
wrapFunctionLabel(func, label, ..stacktraceon = ..stacktraceon)
}
# Utility function for creating a debugging label, given an expression.
# `expr` is a quoted expression.
# `function_name` is the name of the calling function.
# `label` is an optional user-provided label. If NULL, it will be inferred.
exprToLabel <- function(expr, function_name, label = NULL) {
srcref <- attr(expr, "srcref", exact = TRUE)
if (is.null(label)) {
label <- rexprSrcrefToLabel(
srcref[[1]],
sprintf('%s(%s)', function_name, paste(deparse(expr), collapse = '\n'))
)
}
if (length(srcref) >= 2) attr(label, "srcref") <- srcref[[2]]
attr(label, "srcfile") <- srcFileOfRef(srcref[[1]])
label
}
#' Parse a GET query string from a URL
#'
#' Returns a named list of key-value pairs.
@@ -653,7 +484,7 @@ shinyCallingHandlers <- function(expr) {
withCallingHandlers(captureStackTraces(expr),
error = function(e) {
# Don't intercept shiny.silent.error (i.e. validation errors)
if (inherits(e, "shiny.silent.error"))
if (cnd_inherits(e, "shiny.silent.error"))
return()
handle <- getOption('shiny.error')
@@ -1158,7 +989,7 @@ reactiveStop <- function(message = "", class = NULL) {
#'
#' ui <- fluidPage(
#' checkboxGroupInput('in1', 'Check some letters', choices = head(LETTERS)),
#' selectizeInput('in2', 'Select a state', choices = state.name),
#' selectizeInput('in2', 'Select a state', choices = c("", state.name)),
#' plotOutput('plot')
#' )
#'
@@ -1176,7 +1007,7 @@ reactiveStop <- function(message = "", class = NULL) {
#'
#' }
validate <- function(..., errorClass = character(0)) {
results <- sapply(list(...), function(x) {
results <- sapply(list2(...), function(x) {
# Detect NULL or NA
if (is.null(x))
return(NA_character_)
@@ -1596,21 +1427,31 @@ dateYMD <- function(date = NULL, argName = "value") {
# function which calls the original function using the specified name. This can
# be helpful for profiling, because the specified name will show up on the stack
# trace.
wrapFunctionLabel <- function(func, name, ..stacktraceon = FALSE) {
wrapFunctionLabel <- function(func, name, ..stacktraceon = FALSE, dots = TRUE) {
if (name == "name" || name == "func" || name == "relabelWrapper") {
stop("Invalid name for wrapFunctionLabel: ", name)
}
assign(name, func, environment())
registerDebugHook(name, environment(), name)
if (..stacktraceon) {
# We need to wrap the `...` in `!!quote(...)` so that R CMD check won't
# complain about "... may be used in an incorrect context"
body <- expr({ ..stacktraceon..((!!name)(!!quote(...))) })
if (isTRUE(dots)) {
if (..stacktraceon) {
# We need to wrap the `...` in `!!quote(...)` so that R CMD check won't
# complain about "... may be used in an incorrect context"
body <- expr({ ..stacktraceon..((!!name)(!!quote(...))) })
} else {
body <- expr({ (!!name)(!!quote(...)) })
}
relabelWrapper <- new_function(pairlist2(... =), body, environment())
} else {
body <- expr({ (!!name)(!!quote(...)) })
# Same logic as when `dots = TRUE`, but without the `...`
if (..stacktraceon) {
body <- expr({ ..stacktraceon..((!!name)()) })
} else {
body <- expr({ (!!name)() })
}
relabelWrapper <- new_function(list(), body, environment())
}
relabelWrapper <- new_function(pairlist2(... =), body, environment())
# Preserve the original function that was passed in; is used for caching.
attr(relabelWrapper, "wrappedFunc") <- func
@@ -1864,24 +1705,20 @@ findEnclosingApp <- function(path = ".") {
}
}
# Check if a package is installed, and if version is specified,
# that we have at least that version
is_available <- function(package, version = NULL) {
installed <- nzchar(system.file(package = package))
if (is.null(version)) {
return(installed)
}
installed && isTRUE(utils::packageVersion(package) >= version)
# Until `rlang::cnd_inherits()` is on CRAN
cnd_inherits <- function(cnd, class) {
cnd_some(cnd, ~ inherits(.x, class))
}
cnd_some <- function(.cnd, .p, ...) {
.p <- rlang::as_function(.p)
# cached version of utils::packageVersion("shiny")
shinyPackageVersion <- local({
version <- NULL
function() {
if (is.null(version)) {
version <<- utils::packageVersion("shiny")
while (rlang::is_condition(.cnd)) {
if (.p(.cnd, ...)) {
return(TRUE)
}
version
.cnd <- .cnd$parent
}
})
FALSE
}

View File

@@ -0,0 +1,2 @@
# Generated by tools/updateBootstrapDatepicker.R; do not edit by hand
version_bs_date_picker <- "1.9.0"

View File

@@ -0,0 +1,2 @@
# Generated by tools/updateIonRangeSlider.R; do not edit by hand
version_ion_range_slider <- "2.3.1"

2
R/version_jqueryui.R Normal file
View File

@@ -0,0 +1,2 @@
# Generated by tools/updatejQueryUI.R; do not edit by hand
version_jqueryui <- "1.13.2"

2
R/version_selectize.R Normal file
View File

@@ -0,0 +1,2 @@
# Generated by tools/updateSelectize.R; do not edit by hand
version_selectize <- "0.12.4"

2
R/version_strftime.R Normal file
View File

@@ -0,0 +1,2 @@
# Generated by tools/updateStrftime.R; do not edit by hand
version_strftime <- "0.9.2"

View File

@@ -2,7 +2,7 @@
<!-- badges: start -->
[![CRAN](https://www.r-pkg.org/badges/version/shiny)](https://CRAN.R-project.org/package=shiny)
[![R build status](https://github.com/rstudio/shiny/workflows/R-CMD-check/badge.svg)](https://github.com/rstudio/shiny/actions)
[![R build status](https://github.com/rstudio/shiny/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/rstudio/shiny/actions)
[![RStudio community](https://img.shields.io/badge/community-shiny-blue?style=social&logo=rstudio&logoColor=75AADB)](https://community.rstudio.com/new-topic?category=shiny&tags=shiny)
<!-- badges: end -->
@@ -16,7 +16,7 @@ Easily build rich and productive interactive web apps in R &mdash; no HTML/CSS/J
* A prebuilt set of highly sophisticated, customizable, and easy-to-use widgets (e.g., plots, tables, sliders, dropdowns, date pickers, and more).
* An attractive default look based on [Bootstrap](https://getbootstrap.com/) which can also be easily customized with the [bslib](https://github.com/rstudio/bslib) package or avoided entirely with more direct R bindings to HTML/CSS/JavaScript.
* Seamless integration with [R Markdown](https://shiny.rstudio.com/articles/interactive-docs.html), making it easy to embed numerous applications natively within a larger dynamic document.
* Tools for improving and monitoring performance, including native support for [async programming](https://blog.rstudio.com/2018/06/26/shiny-1-1-0/), [caching](https://talks.cpsievert.me/20201117), [load testing](https://rstudio.github.io/shinyloadtest/), and [more](https://support.rstudio.com/hc/en-us/articles/231874748-Scaling-and-Performance-Tuning-in-RStudio-Connect).
* Tools for improving and monitoring performance, including native support for [async programming](https://posit.co/blog/shiny-1-1-0/), [caching](https://talks.cpsievert.me/20201117), [load testing](https://rstudio.github.io/shinyloadtest/), and more.
* [Modules](https://shiny.rstudio.com/articles/modules.html): a framework for reducing code duplication and complexity.
* An ability to [bookmark application state](https://shiny.rstudio.com/articles/bookmarking-state.html) and/or [generate code to reproduce output(s)](https://github.com/rstudio/shinymeta).
* A rich ecosystem of extension packages for more [custom widgets](http://www.htmlwidgets.org/), [input validation](https://github.com/rstudio/shinyvalidate), [unit testing](https://github.com/rstudio/shinytest), and more.
@@ -45,16 +45,24 @@ For more examples and inspiration, check out the [Shiny User Gallery](https://sh
For help with learning fundamental Shiny programming concepts, check out the [Mastering Shiny](https://mastering-shiny.org/) book and the [Shiny Tutorial](https://shiny.rstudio.com/tutorial/). The former is currently more up-to-date with modern Shiny features, whereas the latter takes a deeper, more visual, dive into fundamental concepts.
## Join the conversation
If you want to chat about Shiny, meet other developers, or help us decide what to work on next, [join us on Discord](https://discord.gg/yMGCamUMnS).
## Getting Help
To ask a question about Shiny, please use the [RStudio Community website](https://community.rstudio.com/new-topic?category=shiny&tags=shiny).
To ask a question about Shiny, please use the [RStudio Community website](https://community.rstudio.com/new-topic?category=shiny&tags=shiny).
For bug reports, please use the [issue tracker](https://github.com/rstudio/shiny/issues) and also keep in mind that by [writing a good bug report](https://github.com/rstudio/shiny/wiki/Writing-Good-Bug-Reports), you're more likely to get help with your problem.
For bug reports, please use the [issue tracker](https://github.com/rstudio/shiny/issues) and also keep in mind that by [writing a good bug report](https://github.com/rstudio/shiny/wiki/Writing-Good-Bug-Reports), you're more likely to get help with your problem.
## Contributing
We welcome contributions to the **shiny** package. Please see our [CONTRIBUTING.md](https://github.com/rstudio/shiny/blob/master/.github/CONTRIBUTING.md) file for detailed guidelines of how to contribute.
We welcome contributions to the **shiny** package. Please see our [CONTRIBUTING.md](https://github.com/rstudio/shiny/blob/main/.github/CONTRIBUTING.md) file for detailed guidelines of how to contribute.
## License
The shiny package as a whole is licensed under the GPLv3. See the [LICENSE](LICENSE) file for more details.
## R version support
Shiny is supported on the latest release version of R, as well as the previous four minor release versions of R. For example, if the latest release R version is 4.1, then that version is supported, as well as 4.0, 3.6, 3.5, and 3.4.

View File

@@ -5,7 +5,7 @@
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": "3.9"
"corejs": "3.12"
}
]
],

View File

@@ -1,2 +0,0 @@
library(shinytest)
expect_pass(testApp("../", suffix = osName()))

View File

@@ -1,12 +0,0 @@
app <- ShinyDriver$new("../../")
app$snapshotInit("mytest")
app$snapshot()
{{
if (isTRUE(module)) {
'
app$setInputs(`examplemodule1-button` = "click")
app$setInputs(`examplemodule1-button` = "click")
app$snapshot()'
}
}}

View File

@@ -1,9 +1 @@
library(testthat)
test_dir(
"./testthat",
# Run in the app's environment containing all support methods.
env = shiny::loadSupport(),
# Display the regular progress output and throw an error if any test error is found
reporter = c("progress", "fail")
)
shinytest2::test_app()

View File

@@ -0,0 +1,2 @@
# Load application support files into testing environment
shinytest2::load_app_env()

View File

@@ -14,5 +14,4 @@ if (isTRUE(rdir)) {
expect_equal(output$sequence, "1 2 3 4 5 6 7 8 9 10 11 12")
'
}
}}
})
}}})

View File

@@ -0,0 +1,18 @@
library(shinytest2)
test_that("Initial snapshot values are consistent", {
app <- AppDriver$new(name = "init")
app$expect_values()
}){{
if (isTRUE(module)) {
HTML('
test_that("Module values are consistent", {
app <- AppDriver$new(name = "mod")
app$click("examplemodule1-button")
app$click("examplemodule1-button")
app$expect_values()
})')
}
}}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 730 KiB

View File

@@ -1,801 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<metadata>
Created by FontForge 20200314 at Wed Jan 13 11:57:54 2021
By Robert Madole
Copyright (c) Font Awesome
</metadata>
<!-- Font Awesome Free 5.15.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><defs>
<font id="FontAwesome5Free-Regular" horiz-adv-x="512" >
<font-face
font-family="Font Awesome 5 Free Regular"
font-weight="400"
font-stretch="normal"
units-per-em="512"
panose-1="2 0 5 3 0 0 0 0 0 0"
ascent="448"
descent="-64"
bbox="-0.0663408 -64.0662 640.004 448.1"
underline-thickness="25"
underline-position="-50"
unicode-range="U+0020-F5C8"
/>
<missing-glyph />
<glyph glyph-name="heart" unicode="&#xf004;"
d="M458.4 383.7c75.2998 -63.4004 64.0996 -166.601 10.5996 -221.3l-175.4 -178.7c-10 -10.2002 -23.2998 -15.7998 -37.5996 -15.7998c-14.2002 0 -27.5996 5.69922 -37.5996 15.8994l-175.4 178.7c-53.5996 54.7002 -64.5996 157.9 10.5996 221.2
c57.8008 48.7002 147.101 41.2998 202.4 -15c55.2998 56.2998 144.6 63.5996 202.4 15zM434.8 196.2c36.2002 36.8994 43.7998 107.7 -7.2998 150.8c-38.7002 32.5996 -98.7002 27.9004 -136.5 -10.5996l-35 -35.7002l-35 35.7002
c-37.5996 38.2998 -97.5996 43.1992 -136.5 10.5c-51.2002 -43.1006 -43.7998 -113.5 -7.2998 -150.7l175.399 -178.7c2.40039 -2.40039 4.40039 -2.40039 6.80078 0z" />
<glyph glyph-name="star" unicode="&#xf005;" horiz-adv-x="576"
d="M528.1 276.5c26.2002 -3.7998 36.7002 -36.0996 17.7002 -54.5996l-105.7 -103l25 -145.5c4.5 -26.3008 -23.1992 -45.9004 -46.3994 -33.7002l-130.7 68.7002l-130.7 -68.7002c-23.2002 -12.2998 -50.8994 7.39941 -46.3994 33.7002l25 145.5l-105.7 103
c-19 18.5 -8.5 50.7998 17.7002 54.5996l146.1 21.2998l65.2998 132.4c11.7998 23.8994 45.7002 23.5996 57.4004 0l65.2998 -132.4zM388.6 135.7l100.601 98l-139 20.2002l-62.2002 126l-62.2002 -126l-139 -20.2002l100.601 -98l-23.7002 -138.4l124.3 65.2998
l124.3 -65.2998z" />
<glyph glyph-name="user" unicode="&#xf007;" horiz-adv-x="448"
d="M313.6 144c74.2002 0 134.4 -60.2002 134.4 -134.4v-25.5996c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v25.5996c0 74.2002 60.2002 134.4 134.4 134.4c28.7998 0 42.5 -16 89.5996 -16s60.9004 16 89.5996 16zM400 -16v25.5996
c0 47.6006 -38.7998 86.4004 -86.4004 86.4004c-14.6992 0 -37.8994 -16 -89.5996 -16c-51.2998 0 -75 16 -89.5996 16c-47.6006 0 -86.4004 -38.7998 -86.4004 -86.4004v-25.5996h352zM224 160c-79.5 0 -144 64.5 -144 144s64.5 144 144 144s144 -64.5 144 -144
s-64.5 -144 -144 -144zM224 400c-52.9004 0 -96 -43.0996 -96 -96s43.0996 -96 96 -96s96 43.0996 96 96s-43.0996 96 -96 96z" />
<glyph glyph-name="clock" unicode="&#xf017;"
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM317.8 96.4004l-84.8994 61.6992
c-3.10059 2.30078 -4.90039 5.90039 -4.90039 9.7002v164.2c0 6.59961 5.40039 12 12 12h32c6.59961 0 12 -5.40039 12 -12v-141.7l66.7998 -48.5996c5.40039 -3.90039 6.5 -11.4004 2.60059 -16.7998l-18.8008 -25.9004c-3.89941 -5.2998 -11.3994 -6.5 -16.7998 -2.59961z
" />
<glyph glyph-name="list-alt" unicode="&#xf022;"
d="M464 416c26.5098 0 48 -21.4902 48 -48v-352c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h416zM458 16c3.31152 0 6 2.68848 6 6v340c0 3.31152 -2.68848 6 -6 6h-404c-3.31152 0 -6 -2.68848 -6 -6v-340
c0 -3.31152 2.68848 -6 6 -6h404zM416 108v-24c0 -6.62695 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h200c6.62695 0 12 -5.37305 12 -12zM416 204v-24c0 -6.62695 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37305 -12 12
v24c0 6.62695 5.37305 12 12 12h200c6.62695 0 12 -5.37305 12 -12zM416 300v-24c0 -6.62695 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h200c6.62695 0 12 -5.37305 12 -12zM164 288c0 -19.8818 -16.1182 -36 -36 -36
s-36 16.1182 -36 36s16.1182 36 36 36s36 -16.1182 36 -36zM164 192c0 -19.8818 -16.1182 -36 -36 -36s-36 16.1182 -36 36s16.1182 36 36 36s36 -16.1182 36 -36zM164 96c0 -19.8818 -16.1182 -36 -36 -36s-36 16.1182 -36 36s16.1182 36 36 36s36 -16.1182 36 -36z" />
<glyph glyph-name="flag" unicode="&#xf024;"
d="M336.174 368c35.4668 0 73.0195 12.6914 108.922 28.1797c31.6406 13.6514 66.9043 -9.65723 66.9043 -44.1162v-239.919c0 -16.1953 -8.1543 -31.3057 -21.7129 -40.1631c-26.5762 -17.3643 -70.0693 -39.9814 -128.548 -39.9814c-68.6084 0 -112.781 32 -161.913 32
c-56.5674 0 -89.957 -11.2803 -127.826 -28.5566v-83.4434c0 -8.83691 -7.16309 -16 -16 -16h-16c-8.83691 0 -16 7.16309 -16 16v406.438c-14.3428 8.2998 -24 23.7979 -24 41.5615c0 27.5693 23.2422 49.71 51.2012 47.8965
c22.9658 -1.49023 41.8662 -19.4717 44.4805 -42.3379c0.213867 -1.83398 0.308594 -3.65918 0.308594 -5.5498c0 -5.30273 -0.860352 -10.4053 -2.4502 -15.1768c22.418 8.68555 49.4199 15.168 80.7207 15.168c68.6084 0 112.781 -32 161.913 -32zM464 112v240
c-31.5059 -14.6338 -84.5547 -32 -127.826 -32c-59.9111 0 -101.968 32 -161.913 32c-41.4365 0 -80.4766 -16.5879 -102.261 -32v-232c31.4473 14.5967 84.4648 24 127.826 24c59.9111 0 101.968 -32 161.913 -32c41.4365 0 80.4775 16.5879 102.261 32z" />
<glyph glyph-name="bookmark" unicode="&#xf02e;" horiz-adv-x="384"
d="M336 448c26.5098 0 48 -21.4902 48 -48v-464l-192 112l-192 -112v464c0 26.5098 21.4902 48 48 48h288zM336 19.5703v374.434c0 3.31348 -2.68555 5.99609 -6 5.99609h-276c-3.31152 0 -6 -2.68848 -6 -6v-374.43l144 84z" />
<glyph glyph-name="image" unicode="&#xf03e;"
d="M464 384c26.5098 0 48 -21.4902 48 -48v-288c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h416zM458 48c3.31152 0 6 2.68848 6 6v276c0 3.31152 -2.68848 6 -6 6h-404c-3.31152 0 -6 -2.68848 -6 -6v-276
c0 -3.31152 2.68848 -6 6 -6h404zM128 296c22.0908 0 40 -17.9092 40 -40s-17.9092 -40 -40 -40s-40 17.9092 -40 40s17.9092 40 40 40zM96 96v48l39.5137 39.5146c4.6875 4.68652 12.2852 4.68652 16.9717 0l39.5146 -39.5146l119.514 119.515
c4.6875 4.68652 12.2852 4.68652 16.9717 0l87.5146 -87.5146v-80h-320z" />
<glyph glyph-name="edit" unicode="&#xf044;" horiz-adv-x="576"
d="M402.3 103.1l32 32c5 5 13.7002 1.5 13.7002 -5.69922v-145.4c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h273.5c7.09961 0 10.7002 -8.59961 5.7002 -13.7002l-32 -32c-1.5 -1.5 -3.5 -2.2998 -5.7002 -2.2998h-241.5v-352h352
v113.5c0 2.09961 0.799805 4.09961 2.2998 5.59961zM558.9 304.9l-262.601 -262.601l-90.3994 -10c-26.2002 -2.89941 -48.5 19.2002 -45.6006 45.6006l10 90.3994l262.601 262.601c22.8994 22.8994 59.8994 22.8994 82.6992 0l43.2002 -43.2002
c22.9004 -22.9004 22.9004 -60 0.100586 -82.7998zM460.1 274l-58.0996 58.0996l-185.8 -185.899l-7.2998 -65.2998l65.2998 7.2998zM524.9 353.7l-43.2002 43.2002c-4.10059 4.09961 -10.7998 4.09961 -14.7998 0l-30.9004 -30.9004l58.0996 -58.0996l30.9004 30.8994
c4 4.2002 4 10.7998 -0.0996094 14.9004z" />
<glyph glyph-name="times-circle" unicode="&#xf057;"
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM357.8 254.2l-62.2002 -62.2002l62.2002 -62.2002
c4.7002 -4.7002 4.7002 -12.2998 0 -17l-22.5996 -22.5996c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-62.2002 62.2002l-62.2002 -62.2002c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-22.5996 22.5996c-4.7002 4.7002 -4.7002 12.2998 0 17l62.2002 62.2002l-62.2002 62.2002
c-4.7002 4.7002 -4.7002 12.2998 0 17l22.5996 22.5996c4.7002 4.7002 12.2998 4.7002 17 0l62.2002 -62.2002l62.2002 62.2002c4.7002 4.7002 12.2998 4.7002 17 0l22.5996 -22.5996c4.7002 -4.7002 4.7002 -12.2998 0 -17z" />
<glyph glyph-name="check-circle" unicode="&#xf058;"
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 392c-110.549 0 -200 -89.4678 -200 -200c0 -110.549 89.4678 -200 200 -200c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200z
M396.204 261.733c4.66699 -4.70508 4.63672 -12.3037 -0.0673828 -16.9717l-172.589 -171.204c-4.70508 -4.66797 -12.3027 -4.63672 -16.9697 0.0683594l-90.7812 91.5156c-4.66797 4.70605 -4.63672 12.3047 0.0683594 16.9717l22.7188 22.5361
c4.70508 4.66699 12.3027 4.63574 16.9697 -0.0693359l59.792 -60.2773l141.353 140.216c4.70508 4.66797 12.3027 4.6377 16.9697 -0.0673828z" />
<glyph glyph-name="question-circle" unicode="&#xf059;"
d="M256 440c136.957 0 248 -111.083 248 -248c0 -136.997 -111.043 -248 -248 -248s-248 111.003 -248 248c0 136.917 111.043 248 248 248zM256 -8c110.569 0 200 89.4697 200 200c0 110.529 -89.5088 200 -200 200c-110.528 0 -200 -89.5049 -200 -200
c0 -110.569 89.4678 -200 200 -200zM363.244 247.2c0 -67.0518 -72.4209 -68.084 -72.4209 -92.8633v-6.33691c0 -6.62695 -5.37305 -12 -12 -12h-45.6475c-6.62695 0 -12 5.37305 -12 12v8.65918c0 35.7451 27.1006 50.0342 47.5791 61.5156
c17.5615 9.84473 28.3242 16.541 28.3242 29.5791c0 17.2461 -21.999 28.6934 -39.7842 28.6934c-23.1885 0 -33.8936 -10.9775 -48.9424 -29.9697c-4.05664 -5.11914 -11.46 -6.07031 -16.666 -2.12402l-27.8232 21.0986
c-5.10742 3.87207 -6.25098 11.0654 -2.64453 16.3633c23.627 34.6934 53.7217 54.1846 100.575 54.1846c49.0713 0 101.45 -38.3037 101.45 -88.7998zM298 80c0 -23.1592 -18.8408 -42 -42 -42s-42 18.8408 -42 42s18.8408 42 42 42s42 -18.8408 42 -42z" />
<glyph glyph-name="eye" unicode="&#xf06e;" horiz-adv-x="576"
d="M288 304c0.114258 0 0.240234 -0.0175781 0.354492 -0.0175781c61.6543 0 111.71 -50.0557 111.71 -111.71s-50.0557 -111.71 -111.71 -111.71s-111.71 50.0557 -111.71 111.71c0 10.7422 1.51953 21.1328 4.35547 30.9678
c7.95898 -4.52637 17.2129 -7.17188 27 -7.24023c30.9072 0 56 25.0928 56 56c-0.0683594 9.78711 -2.71387 19.041 -7.24023 27c9.88379 3.07617 20.3896 4.83008 31.2402 5zM572.52 206.6c2.21387 -4.37793 3.46094 -9.38965 3.46094 -14.626
c0 -5.2373 -1.24707 -10.1855 -3.46094 -14.5635c-54.1992 -105.771 -161.59 -177.41 -284.52 -177.41s-230.29 71.5898 -284.52 177.4c-2.21387 4.37793 -3.46094 9.38965 -3.46094 14.626c0 5.2373 1.24707 10.1855 3.46094 14.5635
c54.1992 105.771 161.59 177.41 284.52 177.41s230.29 -71.5898 284.52 -177.4zM288 48c98.6602 0 189.1 55 237.93 144c-48.8398 89 -139.27 144 -237.93 144s-189.09 -55 -237.93 -144c48.8398 -89 139.279 -144 237.93 -144z" />
<glyph glyph-name="eye-slash" unicode="&#xf070;" horiz-adv-x="640"
d="M634 -23c3.66895 -2.93262 6.00391 -7.45117 6.00391 -12.5088c0 -3.7832 -1.31543 -7.26074 -3.51367 -10.001l-10 -12.4902c-2.93359 -3.66309 -7.44824 -5.99414 -12.502 -5.99414c-3.77637 0 -7.25 1.31152 -9.98828 3.50391l-598 467.49
c-3.66895 2.93262 -6.00391 7.45117 -6.00391 12.5088c0 3.7832 1.31543 7.26074 3.51367 10.001l10 12.4902c2.93359 3.66309 7.44824 5.99414 12.502 5.99414c3.77637 0 7.25 -1.31152 9.98828 -3.50391zM296.79 301.53c7.51172 1.60254 15.2266 2.45508 23.21 2.46973
c60.4805 0 109.36 -47.9102 111.58 -107.85zM343.21 82.46c-7.51367 -1.59375 -15.2285 -2.44336 -23.21 -2.45996c-60.4697 0 -109.35 47.9102 -111.58 107.84zM320 336c-19.8799 0 -39.2803 -2.7998 -58.2197 -7.09961l-46.4102 36.29
c32.9199 11.8096 67.9297 18.8096 104.63 18.8096c122.93 0 230.29 -71.5898 284.57 -177.4c2.21289 -4.37793 3.45996 -9.38965 3.45996 -14.626c0 -5.2373 -1.24707 -10.1855 -3.45996 -14.5635c-14.1924 -27.5625 -31.9229 -52.6689 -52.9004 -75.1104l-37.7402 29.5
c17.2305 18.0527 31.9385 38.1318 44 60.2002c-48.8398 89 -139.279 144 -237.93 144zM320 48c19.8896 0 39.2803 2.7998 58.2197 7.08984l46.4102 -36.2803c-32.9199 -11.7598 -67.9297 -18.8096 -104.63 -18.8096c-122.92 0 -230.28 71.5898 -284.51 177.4
c-2.21387 4.37793 -3.46094 9.38965 -3.46094 14.626c0 5.2373 1.24707 10.1855 3.46094 14.5635c14.1885 27.5586 31.916 52.6621 52.8896 75.1006l37.7402 -29.5c-17.249 -18.0469 -31.9727 -38.1221 -44.0498 -60.1904c48.8496 -89 139.279 -144 237.93 -144z" />
<glyph glyph-name="calendar-alt" unicode="&#xf073;" horiz-adv-x="448"
d="M148 160h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12zM256 172c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40
c6.59961 0 12 -5.40039 12 -12v-40zM352 172c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM256 76c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40
c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM160 76c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM352 76c0 -6.59961 -5.40039 -12 -12 -12h-40
c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM448 336v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40
c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="comment" unicode="&#xf075;"
d="M256 416c141.4 0 256 -93.0996 256 -208s-114.6 -208 -256 -208c-32.7998 0 -64 5.2002 -92.9004 14.2998c-29.0996 -20.5996 -77.5996 -46.2998 -139.1 -46.2998c-9.59961 0 -18.2998 5.7002 -22.0996 14.5c-3.80078 8.7998 -2 19 4.59961 26
c0.5 0.400391 31.5 33.7998 46.4004 73.2002c-33 35.0996 -52.9004 78.7002 -52.9004 126.3c0 114.9 114.6 208 256 208zM256 48c114.7 0 208 71.7998 208 160s-93.2998 160 -208 160s-208 -71.7998 -208 -160c0 -42.2002 21.7002 -74.0996 39.7998 -93.4004
l20.6006 -21.7998l-10.6006 -28.0996c-5.5 -14.5 -12.5996 -28.1006 -19.8994 -40.2002c23.5996 7.59961 43.1992 18.9004 57.5 29l19.5 13.7998l22.6992 -7.2002c25.3008 -8 51.7002 -12.0996 78.4004 -12.0996z" />
<glyph glyph-name="folder" unicode="&#xf07b;"
d="M464 320c26.5098 0 48 -21.4902 48 -48v-224c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h146.74c8.49023 0 16.6299 -3.37012 22.6299 -9.37012l54.6299 -54.6299h192zM464 48v224h-198.62
c-8.49023 0 -16.6299 3.37012 -22.6299 9.37012l-54.6299 54.6299h-140.12v-288h416z" />
<glyph glyph-name="folder-open" unicode="&#xf07c;" horiz-adv-x="576"
d="M527.9 224c37.6992 0 60.6992 -41.5 40.6992 -73.4004l-79.8994 -128c-8.7998 -14.0996 -24.2002 -22.5996 -40.7002 -22.5996h-400c-26.5 0 -48 21.5 -48 48v288c0 26.5 21.5 48 48 48h160l64 -64h160c26.5 0 48 -21.5 48 -48v-48h47.9004zM48 330v-233.4l62.9004 104.2
c8.69922 14.4004 24.2998 23.2002 41.0996 23.2002h280v42c0 3.2998 -2.7002 6 -6 6h-173.9l-64 64h-134.1c-3.2998 0 -6 -2.7002 -6 -6zM448 48l80 128h-378.8l-77.2002 -128h376z" />
<glyph glyph-name="chart-bar" unicode="&#xf080;"
d="M396.8 96c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v230.4c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-230.4c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004zM204.8 96
c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v198.4c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-198.4c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004zM300.8 96
c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v134.4c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-134.4c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004zM496 48c8.83984 0 16 -7.16016 16 -16v-16
c0 -8.83984 -7.16016 -16 -16 -16h-464c-17.6699 0 -32 14.3301 -32 32v336c0 8.83984 7.16016 16 16 16h16c8.83984 0 16 -7.16016 16 -16v-320h448zM108.8 96c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v70.4004c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004
c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-70.4004c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004z" />
<glyph glyph-name="comments" unicode="&#xf086;" horiz-adv-x="576"
d="M532 61.7998c15.2998 -30.7002 37.4004 -54.5 37.7998 -54.7998c6.2998 -6.7002 8 -16.5 4.40039 -25c-3.7002 -8.5 -12 -14 -21.2002 -14c-53.5996 0 -96.7002 20.2998 -125.2 38.7998c-19 -4.39941 -39 -6.7998 -59.7998 -6.7998
c-86.2002 0 -159.9 40.4004 -191.3 97.7998c-9.7002 1.2002 -19.2002 2.7998 -28.4004 4.90039c-28.5 -18.6006 -71.7002 -38.7998 -125.2 -38.7998c-9.19922 0 -17.5996 5.5 -21.1992 14c-3.7002 8.5 -1.90039 18.2998 4.39941 25
c0.400391 0.399414 22.4004 24.1992 37.7002 54.8994c-27.5 27.2002 -44 61.2002 -44 98.2002c0 88.4004 93.0996 160 208 160c86.2998 0 160.3 -40.5 191.8 -98.0996c99.7002 -11.8008 176.2 -77.9004 176.2 -157.9c0 -37.0996 -16.5 -71.0996 -44 -98.2002zM139.2 154.1
l19.7998 -4.5c16 -3.69922 32.5 -5.59961 49 -5.59961c86.7002 0 160 51.2998 160 112s-73.2998 112 -160 112s-160 -51.2998 -160 -112c0 -28.7002 16.2002 -50.5996 29.7002 -64l24.7998 -24.5l-15.5 -31.0996c-2.59961 -5.10059 -5.2998 -10.1006 -8 -14.8008
c14.5996 5.10059 29 12.3008 43.0996 21.4004zM498.3 96c13.5 13.4004 29.7002 35.2998 29.7002 64c0 49.2002 -48.2998 91.5 -112.7 106c0.299805 -3.2998 0.700195 -6.59961 0.700195 -10c0 -80.9004 -78 -147.5 -179.3 -158.3
c29.0996 -29.6006 77.2998 -49.7002 131.3 -49.7002c16.5 0 33 1.90039 49 5.59961l19.9004 4.60059l17.0996 -11.1006c14.0996 -9.09961 28.5 -16.2998 43.0996 -21.3994c-2.69922 4.7002 -5.39941 9.7002 -8 14.7998l-15.5 31.0996z" />
<glyph glyph-name="star-half" unicode="&#xf089;" horiz-adv-x="576"
d="M288 62.7002v-54.2998l-130.7 -68.6006c-23.3994 -12.2998 -50.8994 7.60059 -46.3994 33.7002l25 145.5l-105.7 103c-19 18.5 -8.5 50.7998 17.7002 54.5996l146.1 21.2002l65.2998 132.4c5.90039 11.8994 17.2998 17.7998 28.7002 17.7998v-68.0996l-62.2002 -126
l-139 -20.2002l100.601 -98l-23.7002 -138.4z" />
<glyph glyph-name="lemon" unicode="&#xf094;"
d="M484.112 420.111c28.1221 -28.123 35.9434 -68.0039 19.0215 -97.0547c-23.0576 -39.584 50.1436 -163.384 -82.3311 -295.86c-132.301 -132.298 -256.435 -59.3594 -295.857 -82.3291c-29.0459 -16.917 -68.9219 -9.11426 -97.0576 19.0205
c-28.1221 28.1221 -35.9434 68.0029 -19.0215 97.0547c23.0566 39.5859 -50.1436 163.386 82.3301 295.86c132.308 132.309 256.407 59.3496 295.862 82.332c29.0498 16.9219 68.9307 9.09863 97.0537 -19.0234zM461.707 347.217
c13.5166 23.2031 -27.7578 63.7314 -50.4883 50.4912c-66.6025 -38.7939 -165.646 45.5898 -286.081 -74.8457c-120.444 -120.445 -36.0449 -219.472 -74.8447 -286.08c-13.542 -23.2471 27.8145 -63.6953 50.4932 -50.4883
c66.6006 38.7949 165.636 -45.5996 286.076 74.8428c120.444 120.445 36.0449 219.472 74.8447 286.08zM291.846 338.481c1.37012 -10.96 -6.40332 -20.957 -17.3643 -22.3271c-54.8467 -6.85547 -135.779 -87.7871 -142.636 -142.636
c-1.37305 -10.9883 -11.3984 -18.7334 -22.3262 -17.3643c-10.9609 1.37012 -18.7344 11.3652 -17.3643 22.3262c9.16211 73.2852 104.167 168.215 177.364 177.364c10.9531 1.36816 20.9561 -6.40234 22.3262 -17.3633z" />
<glyph glyph-name="credit-card" unicode="&#xf09d;" horiz-adv-x="576"
d="M527.9 416c26.5996 0 48.0996 -21.5 48.0996 -48v-352c0 -26.5 -21.5 -48 -48.0996 -48h-479.801c-26.5996 0 -48.0996 21.5 -48.0996 48v352c0 26.5 21.5 48 48.0996 48h479.801zM54.0996 368c-3.2998 0 -6 -2.7002 -6 -6v-42h479.801v42c0 3.2998 -2.7002 6 -6 6
h-467.801zM521.9 16c3.2998 0 6 2.7002 6 6v170h-479.801v-170c0 -3.2998 2.7002 -6 6 -6h467.801zM192 116v-40c0 -6.59961 -5.40039 -12 -12 -12h-72c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h72c6.59961 0 12 -5.40039 12 -12zM384 116v-40
c0 -6.59961 -5.40039 -12 -12 -12h-136c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h136c6.59961 0 12 -5.40039 12 -12z" />
<glyph glyph-name="hdd" unicode="&#xf0a0;" horiz-adv-x="576"
d="M567.403 212.358c5.59668 -8.04688 8.59668 -17.6113 8.59668 -27.4121v-136.946c0 -26.5098 -21.4902 -48 -48 -48h-480c-26.5098 0 -48 21.4902 -48 48v136.946c0 10.167 3.19531 19.6465 8.59668 27.4121l105.08 151.053
c8.67383 12.4678 23.0791 20.5889 39.4043 20.5889h269.838c16.3252 0 30.7305 -8.12109 39.4043 -20.5889zM153.081 336l-77.9131 -112h425.664l-77.9131 112h-269.838zM528 48v128h-480v-128h480zM496 112c0 -17.6729 -14.3271 -32 -32 -32s-32 14.3271 -32 32
s14.3271 32 32 32s32 -14.3271 32 -32zM400 112c0 -17.6729 -14.3271 -32 -32 -32s-32 14.3271 -32 32s14.3271 32 32 32s32 -14.3271 32 -32z" />
<glyph glyph-name="hand-point-right" unicode="&#xf0a4;"
d="M428.8 310.4c45.0996 0 83.2002 -38.1016 83.2002 -83.2002c0 -45.6162 -37.7646 -83.2002 -83.2002 -83.2002h-35.6475c-1.71387 -7.70605 -4.43555 -15.2051 -7.92969 -22.0645c2.50586 -22.0059 -3.50293 -44.9775 -15.9844 -62.791
c-1.14062 -52.4863 -37.3984 -91.1445 -99.9404 -91.1445h-21.2988c-60.0635 0 -98.5117 40 -127.2 40h-2.67871c-5.74707 -4.95215 -13.5361 -8 -22.1201 -8h-64c-17.6729 0 -32 12.8936 -32 28.7998v230.4c0 15.9062 14.3271 28.7998 32 28.7998h64.001
c8.58398 0 16.373 -3.04785 22.1201 -8h2.67871c6.96387 0 14.8623 6.19336 30.1816 23.6689l0.128906 0.148438l0.130859 0.145508c8.85645 9.93652 18.1162 20.8398 25.8506 33.2529c18.7051 30.2471 30.3936 78.7842 75.707 78.7842c56.9277 0 92 -35.2861 92 -83.2002
c0 -0.0283203 0 0.0361328 0 0.0078125c0 -7.66602 -0.748047 -15.1582 -2.17578 -22.4072h86.1768zM428.8 192c18.9756 0 35.2002 16.2246 35.2002 35.2002c0 18.7002 -16.7754 35.2002 -35.2002 35.2002h-158.399c0 17.3242 26.3994 35.1992 26.3994 70.3994
c0 26.4004 -20.625 35.2002 -44 35.2002c-8.79395 0 -20.4443 -32.7119 -34.9258 -56.0996c-9.07422 -14.5752 -19.5244 -27.2256 -30.7988 -39.875c-16.1094 -18.374 -33.8359 -36.6328 -59.0752 -39.5967v-176.753c42.79 -3.7627 74.5088 -39.6758 120 -39.6758h21.2988
c40.5244 0 57.124 22.1973 50.6006 61.3252c14.6113 8.00098 24.1514 33.9785 12.9248 53.625c19.3652 18.2246 17.7871 46.3809 4.9502 61.0498h91.0254zM88 64c0 13.2549 -10.7451 24 -24 24s-24 -10.7451 -24 -24s10.7451 -24 24 -24s24 10.7451 24 24z" />
<glyph glyph-name="hand-point-left" unicode="&#xf0a5;"
d="M0 227.2c0 45.0986 38.1006 83.2002 83.2002 83.2002h86.1758c-1.3623 6.91016 -2.17578 14.374 -2.17578 22.3994c0 47.9141 35.0723 83.2002 92 83.2002c45.3135 0 57.002 -48.5371 75.7061 -78.7852c7.73438 -12.4121 16.9951 -23.3154 25.8506 -33.2529
l0.130859 -0.145508l0.128906 -0.148438c15.3213 -17.4746 23.2197 -23.668 30.1836 -23.668h2.67871c5.74707 4.95215 13.5361 8 22.1201 8h64c17.6729 0 32 -12.8936 32 -28.7998v-230.4c0 -15.9062 -14.3271 -28.7998 -32 -28.7998h-64
c-8.58398 0 -16.373 3.04785 -22.1201 8h-2.67871c-28.6885 0 -67.1367 -40 -127.2 -40h-21.2988c-62.542 0 -98.8008 38.6582 -99.9404 91.1445c-12.4814 17.8135 -18.4922 40.7852 -15.9844 62.791c-3.49414 6.85938 -6.21582 14.3584 -7.92969 22.0645h-35.6465
c-45.4355 0 -83.2002 37.584 -83.2002 83.2002zM48 227.2c0 -18.9756 16.2246 -35.2002 35.2002 -35.2002h91.0244c-12.8369 -14.6689 -14.415 -42.8252 4.9502 -61.0498c-11.2256 -19.6465 -1.68652 -45.624 12.9248 -53.625
c-6.52246 -39.1279 10.0771 -61.3252 50.6016 -61.3252h21.2988c45.4912 0 77.21 35.9131 120 39.6768v176.752c-25.2393 2.96289 -42.9658 21.2227 -59.0752 39.5967c-11.2744 12.6494 -21.7246 25.2998 -30.7988 39.875
c-14.4814 23.3877 -26.1318 56.0996 -34.9258 56.0996c-23.375 0 -44 -8.7998 -44 -35.2002c0 -35.2002 26.3994 -53.0752 26.3994 -70.3994h-158.399c-18.4248 0 -35.2002 -16.5 -35.2002 -35.2002zM448 88c-13.2549 0 -24 -10.7451 -24 -24s10.7451 -24 24 -24
s24 10.7451 24 24s-10.7451 24 -24 24z" />
<glyph glyph-name="hand-point-up" unicode="&#xf0a6;" horiz-adv-x="448"
d="M105.6 364.8c0 45.0996 38.1016 83.2002 83.2002 83.2002c45.6162 0 83.2002 -37.7646 83.2002 -83.2002v-35.6465c7.70605 -1.71387 15.2051 -4.43555 22.0645 -7.92969c22.0059 2.50684 44.9775 -3.50293 62.791 -15.9844
c52.4863 -1.14062 91.1445 -37.3984 91.1445 -99.9404v-21.2988c0 -60.0635 -40 -98.5117 -40 -127.2v-2.67871c4.95215 -5.74707 8 -13.5361 8 -22.1201v-64c0 -17.6729 -12.8936 -32 -28.7998 -32h-230.4c-15.9062 0 -28.7998 14.3271 -28.7998 32v64
c0 8.58398 3.04785 16.373 8 22.1201v2.67871c0 6.96387 -6.19336 14.8623 -23.6689 30.1816l-0.148438 0.128906l-0.145508 0.130859c-9.93652 8.85645 -20.8398 18.1162 -33.2529 25.8506c-30.2471 18.7051 -78.7842 30.3936 -78.7842 75.707
c0 56.9277 35.2861 92 83.2002 92c0.0283203 0 -0.0361328 0 -0.0078125 0c7.66602 0 15.1582 -0.748047 22.4072 -2.17578v86.1768zM224 364.8c0 18.9756 -16.2246 35.2002 -35.2002 35.2002c-18.7002 0 -35.2002 -16.7754 -35.2002 -35.2002v-158.399
c-17.3242 0 -35.1992 26.3994 -70.3994 26.3994c-26.4004 0 -35.2002 -20.625 -35.2002 -44c0 -8.79395 32.7119 -20.4443 56.0996 -34.9258c14.5752 -9.07422 27.2256 -19.5244 39.875 -30.7988c18.374 -16.1094 36.6328 -33.8359 39.5967 -59.0752h176.753
c3.7627 42.79 39.6758 74.5088 39.6758 120v21.2988c0 40.5244 -22.1973 57.124 -61.3252 50.6006c-8.00098 14.6113 -33.9785 24.1514 -53.625 12.9248c-18.2246 19.3652 -46.3809 17.7871 -61.0498 4.9502v91.0254zM352 24c-13.2549 0 -24 -10.7451 -24 -24
s10.7451 -24 24 -24s24 10.7451 24 24s-10.7451 24 -24 24z" />
<glyph glyph-name="hand-point-down" unicode="&#xf0a7;" horiz-adv-x="448"
d="M188.8 -64c-45.0986 0 -83.2002 38.1006 -83.2002 83.2002v86.1758c-6.91016 -1.3623 -14.374 -2.17578 -22.3994 -2.17578c-47.9141 0 -83.2002 35.0723 -83.2002 92c0 45.3135 48.5371 57.002 78.7852 75.707c12.4121 7.73438 23.3154 16.9951 33.2529 25.8506
l0.145508 0.130859l0.148438 0.128906c17.4746 15.3213 23.668 23.2197 23.668 30.1836v2.67871c-4.95215 5.74707 -8 13.5361 -8 22.1201v64c0 17.6729 12.8936 32 28.7998 32h230.4c15.9062 0 28.7998 -14.3271 28.7998 -32v-64.001
c0 -8.58398 -3.04785 -16.373 -8 -22.1201v-2.67871c0 -28.6885 40 -67.1367 40 -127.2v-21.2988c0 -62.542 -38.6582 -98.8008 -91.1445 -99.9404c-17.8135 -12.4814 -40.7852 -18.4922 -62.791 -15.9844c-6.85938 -3.49414 -14.3584 -6.21582 -22.0645 -7.92969v-35.6465
c0 -45.4355 -37.584 -83.2002 -83.2002 -83.2002zM188.8 -16c18.9756 0 35.2002 16.2246 35.2002 35.2002v91.0244c14.6689 -12.8369 42.8252 -14.415 61.0498 4.9502c19.6465 -11.2256 45.624 -1.68652 53.625 12.9248c39.1279 -6.52246 61.3252 10.0771 61.3252 50.6016
v21.2988c0 45.4912 -35.9131 77.21 -39.6768 120h-176.752c-2.96289 -25.2393 -21.2227 -42.9658 -39.5967 -59.0752c-12.6494 -11.2744 -25.2998 -21.7246 -39.875 -30.7988c-23.3877 -14.4814 -56.0996 -26.1318 -56.0996 -34.9258c0 -23.375 8.7998 -44 35.2002 -44
c35.2002 0 53.0752 26.3994 70.3994 26.3994v-158.399c0 -18.4248 16.5 -35.2002 35.2002 -35.2002zM328 384c0 -13.2549 10.7451 -24 24 -24s24 10.7451 24 24s-10.7451 24 -24 24s-24 -10.7451 -24 -24z" />
<glyph glyph-name="copy" unicode="&#xf0c5;" horiz-adv-x="448"
d="M433.941 382.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-80v-48c0 -26.5098 -21.4902 -48 -48 -48h-224c-26.5098 0 -48 21.4902 -48 48v320c0 26.5098 21.4902 48 48 48h80v48c0 26.5098 21.4902 48 48 48
h172.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM266 -16c3.31152 0 6 2.68848 6 6v42h-96c-26.5098 0 -48 21.4902 -48 48v224h-74c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM394 80c3.31152 0 6 2.68848 6 6v202h-88
c-13.2549 0 -24 10.7451 -24 24v88h-106c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM400 336v9.63184c0 1.65527 -0.670898 3.15723 -1.75684 4.24316l-48.3682 48.3682c-1.12598 1.125 -2.65234 1.75684 -4.24316 1.75684h-9.63184v-64h64z" />
<glyph glyph-name="save" unicode="&#xf0c7;" horiz-adv-x="448"
d="M433.941 318.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h268.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM272 368h-128v-80h128v80z
M394 16c3.31152 0 6 2.68848 6 6v259.632c0 1.65527 -0.670898 3.15723 -1.75684 4.24316l-78.2432 78.2432v-100.118c0 -13.2549 -10.7451 -24 -24 -24h-176c-13.2549 0 -24 10.7451 -24 24v104h-42c-3.31152 0 -6 -2.68848 -6 -6v-340c0 -3.31152 2.68848 -6 6 -6h340z
M224 216c48.5234 0 88 -39.4766 88 -88s-39.4766 -88 -88 -88s-88 39.4766 -88 88s39.4766 88 88 88zM224 88c22.0557 0 40 17.9443 40 40s-17.9443 40 -40 40s-40 -17.9443 -40 -40s17.9443 -40 40 -40z" />
<glyph glyph-name="square" unicode="&#xf0c8;" horiz-adv-x="448"
d="M400 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h352zM394 16c3.2998 0 6 2.7002 6 6v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340z" />
<glyph glyph-name="envelope" unicode="&#xf0e0;"
d="M464 384c26.5098 0 48 -21.4902 48 -48v-288c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h416zM464 336h-416v-40.8047c22.4248 -18.2627 58.1797 -46.6602 134.587 -106.49
c16.834 -13.2422 50.2051 -45.0762 73.4131 -44.7012c23.2119 -0.371094 56.5723 31.4541 73.4131 44.7012c76.4189 59.8389 112.165 88.2305 134.587 106.49v40.8047zM48 48h416v185.601c-22.915 -18.252 -55.4189 -43.8691 -104.947 -82.6523
c-22.5439 -17.748 -60.3359 -55.1787 -103.053 -54.9473c-42.9277 -0.231445 -81.2051 37.75 -103.062 54.9551c-49.5293 38.7842 -82.0244 64.3945 -104.938 82.6455v-185.602z" />
<glyph glyph-name="lightbulb" unicode="&#xf0eb;" horiz-adv-x="352"
d="M176 368c8.83984 0 16 -7.16016 16 -16s-7.16016 -16 -16 -16c-35.2803 0 -64 -28.7002 -64 -64c0 -8.83984 -7.16016 -16 -16 -16s-16 7.16016 -16 16c0 52.9404 43.0596 96 96 96zM96.0596 -11.1699l-0.0400391 43.1797h159.961l-0.0507812 -43.1797
c-0.00976562 -3.13965 -0.939453 -6.21973 -2.67969 -8.83984l-24.5098 -36.8398c-2.95996 -4.45996 -7.95996 -7.14062 -13.3203 -7.14062h-78.8496c-5.35059 0 -10.3506 2.68066 -13.3203 7.14062l-24.5098 36.8398c-1.75 2.62012 -2.68066 5.68945 -2.68066 8.83984z
M176 448c97.2002 0 176 -78.7998 176 -176c0 -44.3701 -16.4502 -84.8496 -43.5498 -115.79c-16.6406 -18.9795 -42.7402 -58.79 -52.4199 -92.1602v-0.0498047h-48v0.0996094c0.00488281 4.98145 0.790039 9.78809 2.21973 14.3008
c5.67969 17.9893 22.9902 64.8496 62.0996 109.46c20.4102 23.29 31.6504 53.1699 31.6504 84.1396c0 70.5801 -57.4199 128 -128 128c-68.2803 0 -128.15 -54.3604 -127.95 -128c0.0898438 -30.9902 11.0703 -60.71 31.6104 -84.1396
c39.3496 -44.9004 56.5801 -91.8604 62.1699 -109.67c1.42969 -4.56055 2.13965 -9.30078 2.15039 -14.0703v-0.120117h-48v0.0595703c-9.68066 33.3604 -35.7803 73.1709 -52.4209 92.1602c-27.1094 30.9307 -43.5596 71.4102 -43.5596 115.78
c0 93.0303 73.7197 176 176 176z" />
<glyph glyph-name="bell" unicode="&#xf0f3;" horiz-adv-x="448"
d="M439.39 85.71c6 -6.44043 8.66016 -14.1602 8.61035 -21.71c-0.0996094 -16.4004 -12.9805 -32 -32.0996 -32h-383.801c-19.1191 0 -31.9893 15.5996 -32.0996 32c-0.0498047 7.5498 2.61035 15.2598 8.61035 21.71c19.3193 20.7598 55.4697 51.9902 55.4697 154.29
c0 77.7002 54.4795 139.9 127.939 155.16v20.8398c0 17.6699 14.3203 32 31.9805 32s31.9805 -14.3301 31.9805 -32v-20.8398c73.46 -15.2598 127.939 -77.46 127.939 -155.16c0 -102.3 36.1504 -133.53 55.4697 -154.29zM67.5303 80h312.939
c-21.2197 27.96 -44.4199 74.3203 -44.5293 159.42c0 0.200195 0.0595703 0.379883 0.0595703 0.580078c0 61.8604 -50.1396 112 -112 112s-112 -50.1396 -112 -112c0 -0.200195 0.0595703 -0.379883 0.0595703 -0.580078
c-0.109375 -85.0898 -23.3096 -131.45 -44.5293 -159.42zM224 -64c-35.3203 0 -63.9697 28.6504 -63.9697 64h127.939c0 -35.3496 -28.6494 -64 -63.9697 -64z" />
<glyph glyph-name="hospital" unicode="&#xf0f8;" horiz-adv-x="448"
d="M128 204v40c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-40c0 -6.62695 -5.37305 -12 -12 -12h-40c-6.62695 0 -12 5.37305 -12 12zM268 192c-6.62695 0 -12 5.37305 -12 12v40c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-40
c0 -6.62695 -5.37305 -12 -12 -12h-40zM192 108c0 -6.62695 -5.37305 -12 -12 -12h-40c-6.62695 0 -12 5.37305 -12 12v40c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-40zM268 96c-6.62695 0 -12 5.37305 -12 12v40c0 6.62695 5.37305 12 12 12h40
c6.62695 0 12 -5.37305 12 -12v-40c0 -6.62695 -5.37305 -12 -12 -12h-40zM448 -28v-36h-448v36c0 6.62695 5.37305 12 12 12h19.5v378.965c0 11.6172 10.7451 21.0352 24 21.0352h88.5v40c0 13.2549 10.7451 24 24 24h112c13.2549 0 24 -10.7451 24 -24v-40h88.5
c13.2549 0 24 -9.41797 24 -21.0352v-378.965h19.5c6.62695 0 12 -5.37305 12 -12zM79.5 -15h112.5v67c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-67h112.5v351h-64.5v-24c0 -13.2549 -10.7451 -24 -24 -24h-112c-13.2549 0 -24 10.7451 -24 24v24
h-64.5v-351zM266 384h-26v26c0 3.31152 -2.68848 6 -6 6h-20c-3.31152 0 -6 -2.68848 -6 -6v-26h-26c-3.31152 0 -6 -2.68848 -6 -6v-20c0 -3.31152 2.68848 -6 6 -6h26v-26c0 -3.31152 2.68848 -6 6 -6h20c3.31152 0 6 2.68848 6 6v26h26c3.31152 0 6 2.68848 6 6v20
c0 3.31152 -2.68848 6 -6 6z" />
<glyph glyph-name="plus-square" unicode="&#xf0fe;" horiz-adv-x="448"
d="M352 208v-32c0 -6.59961 -5.40039 -12 -12 -12h-88v-88c0 -6.59961 -5.40039 -12 -12 -12h-32c-6.59961 0 -12 5.40039 -12 12v88h-88c-6.59961 0 -12 5.40039 -12 12v32c0 6.59961 5.40039 12 12 12h88v88c0 6.59961 5.40039 12 12 12h32c6.59961 0 12 -5.40039 12 -12
v-88h88c6.59961 0 12 -5.40039 12 -12zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340
c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="circle" unicode="&#xf111;"
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200z" />
<glyph glyph-name="smile" unicode="&#xf118;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM332 135.4c8.5 10.1992 23.7002 11.5 33.7998 3.09961c10.2002 -8.5 11.6006 -23.5996 3.10059 -33.7998
c-30 -36 -74.1006 -56.6006 -120.9 -56.6006s-90.9004 20.6006 -120.9 56.6006c-8.39941 10.2002 -7.09961 25.2998 3.10059 33.7998c10.0996 8.40039 25.2998 7.09961 33.7998 -3.09961c20.7998 -25.1006 51.5 -39.4004 84 -39.4004s63.2002 14.4004 84 39.4004z" />
<glyph glyph-name="frown" unicode="&#xf119;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM248 144c40.2002 0 78 -17.7002 103.8 -48.5996c8.40039 -10.2002 7.10059 -25.3008 -3.09961 -33.8008
c-10.7002 -8.7998 -25.7002 -6.59961 -33.7998 3.10059c-16.6006 20 -41 31.3994 -66.9004 31.3994s-50.2998 -11.5 -66.9004 -31.3994c-8.5 -10.2002 -23.5996 -11.5 -33.7998 -3.10059c-10.2002 8.5 -11.5996 23.6006 -3.09961 33.8008
c25.7998 30.8994 63.5996 48.5996 103.8 48.5996z" />
<glyph glyph-name="meh" unicode="&#xf11a;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM336 128c13.2002 0 24 -10.7998 24 -24s-10.7998 -24 -24 -24h-176c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24h176z
" />
<glyph glyph-name="keyboard" unicode="&#xf11c;" horiz-adv-x="576"
d="M528 384c26.5098 0 48 -21.4902 48 -48v-288c0 -26.5098 -21.4902 -48 -48 -48h-480c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h480zM536 48v288c0 4.41113 -3.58887 8 -8 8h-480c-4.41113 0 -8 -3.58887 -8 -8v-288c0 -4.41113 3.58887 -8 8 -8
h480c4.41113 0 8 3.58887 8 8zM170 178c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM266 178c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28
c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM362 178c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM458 178c0 -6.62695 -5.37305 -12 -12 -12h-28
c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM122 96c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM506 96
c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM122 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28
c6.62695 0 12 -5.37305 12 -12v-28zM218 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM314 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28
c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM410 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM506 260c0 -6.62695 -5.37305 -12 -12 -12h-28
c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM408 102c0 -6.62695 -5.37305 -12 -12 -12h-216c-6.62695 0 -12 5.37305 -12 12v16c0 6.62695 5.37305 12 12 12h216c6.62695 0 12 -5.37305 12 -12v-16z" />
<glyph glyph-name="calendar" unicode="&#xf133;" horiz-adv-x="448"
d="M400 384c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12
v-52h48zM394 -16c3.2998 0 6 2.7002 6 6v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340z" />
<glyph glyph-name="play-circle" unicode="&#xf144;"
d="M371.7 210c16.3994 -9.2002 16.3994 -32.9004 0 -42l-176 -101c-15.9004 -8.7998 -35.7002 2.59961 -35.7002 21v208c0 18.5 19.9004 29.7998 35.7002 21zM504 192c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248s248 -111 248 -248zM56 192
c0 -110.5 89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200z" />
<glyph glyph-name="minus-square" unicode="&#xf146;" horiz-adv-x="448"
d="M108 164c-6.59961 0 -12 5.40039 -12 12v32c0 6.59961 5.40039 12 12 12h232c6.59961 0 12 -5.40039 12 -12v-32c0 -6.59961 -5.40039 -12 -12 -12h-232zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h352
c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="check-square" unicode="&#xf14a;" horiz-adv-x="448"
d="M400 416c26.5098 0 48 -21.4902 48 -48v-352c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h352zM400 16v352h-352v-352h352zM364.136 257.724l-172.589 -171.204
c-4.70508 -4.66699 -12.3027 -4.63672 -16.9697 0.0683594l-90.7812 91.5156c-4.66699 4.70508 -4.63672 12.3037 0.0693359 16.9717l22.7188 22.5361c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0693359l59.792 -60.2773l141.353 140.217
c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0683594l22.5361 -22.7178c4.66699 -4.70605 4.63672 -12.3047 -0.0683594 -16.9717z" />
<glyph glyph-name="share-square" unicode="&#xf14d;" horiz-adv-x="576"
d="M561.938 289.94c18.75 -18.7402 18.75 -49.1406 0 -67.8809l-143.998 -144c-29.9727 -29.9727 -81.9404 -9.05273 -81.9404 33.9404v53.7998c-101.266 -7.83691 -99.625 -31.6406 -84.1104 -78.7598c14.2285 -43.0889 -33.4736 -79.248 -71.0195 -55.7402
c-51.6924 32.3057 -84.8701 83.0635 -84.8701 144.76c0 39.3408 12.2197 72.7402 36.3301 99.3008c19.8398 21.8398 47.7402 38.4697 82.9102 49.4199c36.7295 11.4395 78.3096 16.1094 120.76 17.9893v57.1982c0 42.9355 51.9258 63.9541 81.9404 33.9404zM384 112l144 144
l-144 144v-104.09c-110.86 -0.90332 -240 -10.5166 -240 -119.851c0 -52.1396 32.79 -85.6094 62.3096 -104.06c-39.8174 120.65 48.999 141.918 177.69 143.84v-103.84zM408.74 27.5068c7.4375 2.125 14.5508 5.30566 20.9736 9.30273
c7.97656 4.95215 18.2861 -0.825195 18.2861 -10.2139v-42.5957c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h132c6.62695 0 12 -5.37305 12 -12v-4.48633c0 -4.91699 -2.9873 -9.36914 -7.56934 -11.1514
c-13.7021 -5.33105 -26.3955 -11.5371 -38.0498 -18.585c-1.82715 -1.11523 -3.98633 -1.76953 -6.28027 -1.77734h-86.1006c-3.31152 0 -6 -2.68848 -6 -6v-340c0 -3.31152 2.68848 -6 6 -6h340c3.31152 0 6 2.68848 6 6v25.9658c0 5.37012 3.5791 10.0596 8.74023 11.541z
" />
<glyph glyph-name="compass" unicode="&#xf14e;" horiz-adv-x="496"
d="M347.94 318.14c16.6592 7.61035 33.8096 -9.54004 26.1992 -26.1992l-65.9697 -144.341c-3.19238 -6.9834 -8.78613 -12.5771 -15.7695 -15.7695l-144.341 -65.9697c-16.6592 -7.61035 -33.8096 9.5498 -26.1992 26.1992l65.9697 144.341
c3.19238 6.9834 8.78613 12.5771 15.7695 15.7695zM270.58 169.42c12.4697 12.4697 12.4697 32.6904 0 45.1602s-32.6904 12.4697 -45.1602 0s-12.4697 -32.6904 0 -45.1602s32.6904 -12.4697 45.1602 0zM248 440c136.97 0 248 -111.03 248 -248s-111.03 -248 -248 -248
s-248 111.03 -248 248s111.03 248 248 248zM248 -8c110.28 0 200 89.7197 200 200s-89.7197 200 -200 200s-200 -89.7197 -200 -200s89.7197 -200 200 -200z" />
<glyph glyph-name="caret-square-down" unicode="&#xf150;" horiz-adv-x="448"
d="M125.1 240h197.801c10.6992 0 16.0996 -13 8.5 -20.5l-98.9004 -98.2998c-4.7002 -4.7002 -12.2002 -4.7002 -16.9004 0l-98.8994 98.2998c-7.7002 7.5 -2.2998 20.5 8.39941 20.5zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="caret-square-up" unicode="&#xf151;" horiz-adv-x="448"
d="M322.9 144h-197.801c-10.6992 0 -16.0996 13 -8.5 20.5l98.9004 98.2998c4.7002 4.7002 12.2002 4.7002 16.9004 0l98.8994 -98.2998c7.7002 -7.5 2.2998 -20.5 -8.39941 -20.5zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="caret-square-right" unicode="&#xf152;" horiz-adv-x="448"
d="M176 93.0996v197.801c0 10.6992 13 16.0996 20.5 8.5l98.2998 -98.9004c4.7002 -4.7002 4.7002 -12.2002 0 -16.9004l-98.2998 -98.8994c-7.5 -7.7002 -20.5 -2.2998 -20.5 8.39941zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="file" unicode="&#xf15b;" horiz-adv-x="384"
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416z" />
<glyph glyph-name="file-alt" unicode="&#xf15c;" horiz-adv-x="384"
d="M288 200v-28c0 -6.59961 -5.40039 -12 -12 -12h-168c-6.59961 0 -12 5.40039 -12 12v28c0 6.59961 5.40039 12 12 12h168c6.59961 0 12 -5.40039 12 -12zM276 128c6.59961 0 12 -5.40039 12 -12v-28c0 -6.59961 -5.40039 -12 -12 -12h-168c-6.59961 0 -12 5.40039 -12 12
v28c0 6.59961 5.40039 12 12 12h168zM384 316.1v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996l83.9004 -83.9004c9 -8.90039 14.0996 -21.2002 14.0996 -33.9004z
M256 396.1v-76.0996h76.0996zM336 -16v288h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416h288z" />
<glyph glyph-name="thumbs-up" unicode="&#xf164;"
d="M466.27 161.31c4.6748 -22.6465 0.864258 -44.5371 -8.98926 -62.9893c2.95898 -23.8682 -4.02148 -48.5654 -17.3398 -66.9902c-0.954102 -55.9072 -35.8232 -95.3301 -112.94 -95.3301c-7 0 -15 0.00976562 -22.2197 0.00976562
c-102.742 0 -133.293 38.9395 -177.803 39.9404c-3.56934 -13.7764 -16.085 -23.9502 -30.9775 -23.9502h-64c-17.6729 0 -32 14.3271 -32 32v240c0 17.6729 14.3271 32 32 32h98.7598c19.1455 16.9531 46.0137 60.6533 68.7598 83.4004
c13.667 13.667 10.1533 108.6 71.7607 108.6c57.5801 0 95.2695 -31.9355 95.2695 -104.73c0 -18.4092 -3.92969 -33.7295 -8.84961 -46.5391h36.4795c48.6025 0 85.8203 -41.5654 85.8203 -85.5801c0 -19.1504 -4.95996 -34.9902 -13.7305 -49.8408zM404.52 107.48
c21.5811 20.3838 18.6992 51.0645 5.21094 65.6191c9.44922 0 22.3594 18.9102 22.2695 37.8105c-0.0898438 18.9102 -16.71 37.8203 -37.8203 37.8203h-103.989c0 37.8193 28.3594 55.3691 28.3594 94.5391c0 23.75 0 56.7305 -47.2695 56.7305
c-18.9102 -18.9102 -9.45996 -66.1797 -37.8203 -94.54c-26.5596 -26.5703 -66.1797 -97.46 -94.54 -97.46h-10.9199v-186.17c53.6113 0 100.001 -37.8203 171.64 -37.8203h37.8203c35.5117 0 60.8203 17.1201 53.1201 65.9004
c15.2002 8.16016 26.5 36.4395 13.9395 57.5703zM88 16c0 13.2549 -10.7451 24 -24 24s-24 -10.7451 -24 -24s10.7451 -24 24 -24s24 10.7451 24 24z" />
<glyph glyph-name="thumbs-down" unicode="&#xf165;"
d="M466.27 222.69c8.77051 -14.8506 13.7305 -30.6904 13.7305 -49.8408c0 -44.0146 -37.2178 -85.5801 -85.8203 -85.5801h-36.4795c4.91992 -12.8096 8.84961 -28.1299 8.84961 -46.5391c0 -72.7949 -37.6895 -104.73 -95.2695 -104.73
c-61.6074 0 -58.0938 94.9326 -71.7607 108.6c-22.7461 22.7471 -49.6133 66.4473 -68.7598 83.4004h-7.05176c-5.5332 -9.56152 -15.8662 -16 -27.708 -16h-64c-17.6729 0 -32 14.3271 -32 32v240c0 17.6729 14.3271 32 32 32h64c8.11328 0 15.5146 -3.02539 21.1553 -8
h10.8447c40.9971 0 73.1953 39.9902 176.78 39.9902c7.21973 0 15.2197 0.00976562 22.2197 0.00976562c77.1172 0 111.986 -39.4229 112.94 -95.3301c13.3184 -18.4248 20.2979 -43.1221 17.3398 -66.9902c9.85352 -18.4521 13.6641 -40.3428 8.98926 -62.9893zM64 152
c13.2549 0 24 10.7451 24 24s-10.7451 24 -24 24s-24 -10.7451 -24 -24s10.7451 -24 24 -24zM394.18 135.27c21.1104 0 37.7305 18.9102 37.8203 37.8203c0.0898438 18.9004 -12.8203 37.8105 -22.2695 37.8105c13.4883 14.5547 16.3701 45.2354 -5.21094 65.6191
c12.5605 21.1309 1.26074 49.4102 -13.9395 57.5703c7.7002 48.7803 -17.6084 65.9004 -53.1201 65.9004h-37.8203c-71.6387 0 -118.028 -37.8203 -171.64 -37.8203v-186.17h10.9199c28.3604 0 67.9805 -70.8896 94.54 -97.46
c28.3604 -28.3604 18.9102 -75.6299 37.8203 -94.54c47.2695 0 47.2695 32.9805 47.2695 56.7305c0 39.1699 -28.3594 56.7197 -28.3594 94.5391h103.989z" />
<glyph glyph-name="sun" unicode="&#xf185;"
d="M494.2 226.1c11.2002 -7.59961 17.7998 -20.0996 17.8994 -33.6992c0 -13.4004 -6.69922 -26 -17.7998 -33.5l-59.7998 -40.5l13.7002 -71c2.5 -13.2002 -1.60059 -26.8008 -11.1006 -36.3008s-22.8994 -13.7998 -36.2998 -11.0996l-70.8994 13.7002l-40.4004 -59.9004
c-7.5 -11.0996 -20.0996 -17.7998 -33.5 -17.7998s-26 6.7002 -33.5 17.9004l-40.4004 59.8994l-70.7998 -13.7002c-13.3994 -2.59961 -26.7998 1.60059 -36.2998 11.1006s-13.7002 23.0996 -11.0996 36.2998l13.6992 71l-59.7998 40.5
c-11.0996 7.5 -17.7998 20 -17.7998 33.5s6.59961 26 17.7998 33.5996l59.7998 40.5l-13.6992 71c-2.60059 13.2002 1.59961 26.7002 11.0996 36.3008c9.5 9.59961 23 13.6992 36.2998 11.1992l70.7998 -13.6992l40.4004 59.8994c15.0996 22.2998 51.9004 22.2998 67 0
l40.4004 -59.8994l70.8994 13.6992c13 2.60059 26.6006 -1.59961 36.2002 -11.0996c9.5 -9.59961 13.7002 -23.2002 11.0996 -36.4004l-13.6992 -71zM381.3 140.5l76.7998 52.0996l-76.7998 52l17.6006 91.1006l-91 -17.6006l-51.9004 76.9004l-51.7998 -76.7998
l-91 17.5996l17.5996 -91.2002l-76.7998 -52l76.7998 -52l-17.5996 -91.1992l90.8994 17.5996l51.9004 -77l51.9004 76.9004l91 -17.6006zM256 296c57.2998 0 104 -46.7002 104 -104s-46.7002 -104 -104 -104s-104 46.7002 -104 104s46.7002 104 104 104zM256 136
c30.9004 0 56 25.0996 56 56s-25.0996 56 -56 56s-56 -25.0996 -56 -56s25.0996 -56 56 -56z" />
<glyph glyph-name="moon" unicode="&#xf186;"
d="M279.135 -64c-141.424 0 -256 114.64 -256 256c0 141.425 114.641 256 256 256c16.0342 -0.00292969 31.5078 -1.46875 46.7354 -4.27734c44.0205 -8.13086 53.7666 -66.8691 15.0215 -88.9189c-41.374 -23.5439 -67.4336 -67.4121 -67.4336 -115.836
c0 -83.5234 75.9238 -146.475 158.272 -130.792c43.6904 8.32129 74.5186 -42.5693 46.248 -77.4004c-47.8613 -58.9717 -120.088 -94.7754 -198.844 -94.7754zM279.135 400c-114.875 0 -208 -93.125 -208 -208s93.125 -208 208 -208
c65.2314 0 123.439 30.0361 161.575 77.0244c-111.611 -21.2568 -215.252 64.0957 -215.252 177.943c0 67.5127 36.9326 126.392 91.6934 157.555c-12.3271 2.27637 -25.0312 3.47754 -38.0166 3.47754z" />
<glyph glyph-name="caret-square-left" unicode="&#xf191;" horiz-adv-x="448"
d="M272 290.9v-197.801c0 -10.6992 -13 -16.0996 -20.5 -8.5l-98.2998 98.9004c-4.7002 4.7002 -4.7002 12.2002 0 16.9004l98.2998 98.8994c7.5 7.7002 20.5 2.2998 20.5 -8.39941zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="dot-circle" unicode="&#xf192;"
d="M256 392c-110.549 0 -200 -89.4678 -200 -200c0 -110.549 89.4678 -200 200 -200c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200zM256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248z
M256 272c44.1826 0 80 -35.8174 80 -80s-35.8174 -80 -80 -80s-80 35.8174 -80 80s35.8174 80 80 80z" />
<glyph glyph-name="building" unicode="&#xf1ad;" horiz-adv-x="448"
d="M128 300v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12zM268 288c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40
c0 -6.59961 -5.40039 -12 -12 -12h-40zM140 192c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40zM268 192c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40
c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40zM192 108c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM268 96c-6.59961 0 -12 5.40039 -12 12v40
c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40zM448 -28v-36h-448v36c0 6.59961 5.40039 12 12 12h19.5v440c0 13.2998 10.7002 24 24 24h337c13.2998 0 24 -10.7002 24 -24v-440h19.5
c6.59961 0 12 -5.40039 12 -12zM79.5 -15h112.5v67c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-67h112.5v414l-288.5 1z" />
<glyph glyph-name="file-pdf" unicode="&#xf1c1;" horiz-adv-x="384"
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM298.2 127.7c10.5 -10.5 8 -38.7002 -17.5 -38.7002c-14.7998 0 -36.9004 6.7998 -55.7998 17c-21.6006 -3.59961 -46 -12.7002 -68.4004 -20.0996c-50.0996 -86.4004 -79.4004 -47 -76.0996 -31.2002
c4 20 31 35.8994 51 46.2002c10.5 18.3994 25.3994 50.5 35.3994 74.3994c-7.39941 28.6006 -11.3994 51 -7 67.1006c4.7998 17.6992 38.4004 20.2998 42.6006 -5.90039c4.69922 -15.4004 -1.5 -39.9004 -5.40039 -56c8.09961 -21.2998 19.5996 -35.7998 36.7998 -46.2998
c17.4004 2.2002 52.2002 5.5 64.4004 -6.5zM100.1 49.9004c0 -0.700195 11.4004 4.69922 30.4004 35c-5.90039 -5.5 -25.2998 -21.3008 -30.4004 -35zM181.7 240.5c-2.5 0 -2.60059 -26.9004 1.7998 -40.7998c4.90039 8.7002 5.59961 40.7998 -1.7998 40.7998zM157.3 103.9
c15.9004 6.09961 34 14.8994 54.7998 19.1992c-11.1992 8.30078 -21.7998 20.4004 -30.0996 35.5c-6.7002 -17.6992 -15 -37.7998 -24.7002 -54.6992zM288.9 108.9c3.59961 2.39941 -2.2002 10.3994 -37.3008 7.7998c32.3008 -13.7998 37.3008 -7.7998 37.3008 -7.7998z" />
<glyph glyph-name="file-word" unicode="&#xf1c2;" horiz-adv-x="384"
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM268.1 192v0.200195h15.8008c7.7998 0 13.5 -7.2998 11.5996 -14.9004c-4.2998 -17 -13.7002 -54.0996 -34.5 -136c-1.2998 -5.39941 -6.09961 -9.09961 -11.5996 -9.09961h-24.7002
c-5.5 0 -10.2998 3.7998 -11.6006 9.09961c-5.2998 20.9004 -17.7998 71 -17.8994 71.4004l-2.90039 17.2998c-0.5 -5.2998 -1.5 -11.0996 -3 -17.2998l-17.8994 -71.4004c-1.30078 -5.39941 -6.10059 -9.09961 -11.6006 -9.09961h-25.2002
c-5.59961 0 -10.3994 3.7002 -11.6992 9.09961c-6.5 26.5 -25.2002 103.4 -33.2002 136c-1.7998 7.5 3.89941 14.7998 11.7002 14.7998h16.7998c5.7998 0 10.7002 -4.09961 11.7998 -9.69922c5 -25.7002 18.4004 -93.8008 19.0996 -99
c0.300781 -1.7002 0.400391 -3.10059 0.5 -4.2002c0.800781 7.5 0.400391 4.7002 24.8008 103.7c1.39941 5.2998 6.19922 9.09961 11.6992 9.09961h13.3008c5.59961 0 10.3994 -3.7998 11.6992 -9.2002c23.9004 -99.7002 22.8008 -94.3994 23.6006 -99.5
c0.299805 -1.7002 0.5 -3.09961 0.700195 -4.2998c0.599609 8.09961 0.399414 5.7998 21 103.5c1.09961 5.5 6 9.5 11.6992 9.5z" />
<glyph glyph-name="file-excel" unicode="&#xf1c3;" horiz-adv-x="384"
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM260 224c9.2002 0 15 -10 10.2998 -18c-16 -27.5 -45.5996 -76.9004 -46.2998 -78l46.4004 -78c4.59961 -8 -1.10059 -18 -10.4004 -18h-28.7998c-4.40039 0 -8.5 2.40039 -10.6006 6.2998
c-22.6992 41.7998 -13.6992 27.5 -28.5996 57.7002c-5.59961 -12.7002 -6.90039 -17.7002 -28.5996 -57.7002c-2.10059 -3.89941 -6.10059 -6.2998 -10.5 -6.2998h-28.9004c-9.2998 0 -15.0996 10 -10.4004 18l46.3008 78l-46.3008 78c-4.59961 8 1.10059 18 10.4004 18
h28.9004c4.39941 0 8.5 -2.40039 10.5996 -6.2998c21.7002 -40.4004 14.7002 -28.6006 28.5996 -57.7002c6.40039 15.2998 10.6006 24.5996 28.6006 57.7002c2.09961 3.89941 6.09961 6.2998 10.5 6.2998h28.7998z" />
<glyph glyph-name="file-powerpoint" unicode="&#xf1c4;" horiz-adv-x="384"
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM120 44v168c0 6.59961 5.40039 12 12 12h69.2002c36.7002 0 62.7998 -27 62.7998 -66.2998c0 -74.2998 -68.7002 -66.5 -95.5 -66.5v-47.2002c0 -6.59961 -5.40039 -12 -12 -12h-24.5c-6.59961 0 -12 5.40039 -12 12z
M168.5 131.4h23c7.90039 0 13.9004 2.39941 18.0996 7.19922c8.5 9.80078 8.40039 28.5 0.100586 37.8008c-4.10059 4.59961 -9.90039 7 -17.4004 7h-23.8994v-52h0.0996094z" />
<glyph glyph-name="file-image" unicode="&#xf1c5;" horiz-adv-x="384"
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM80 32v64l39.5 39.5c4.7002 4.7002 12.2998 4.7002 17 0l39.5 -39.5l87.5 87.5c4.7002 4.7002 12.2998 4.7002 17 0l23.5 -23.5v-128h-224zM128 272c26.5 0 48 -21.5 48 -48s-21.5 -48 -48 -48s-48 21.5 -48 48
s21.5 48 48 48z" />
<glyph glyph-name="file-archive" unicode="&#xf1c6;" horiz-adv-x="384"
d="M128.3 288h32v-32h-32v32zM192.3 384v-32h-32v32h32zM128.3 352h32v-32h-32v32zM192.3 320v-32h-32v32h32zM369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1
c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM256 396.1v-76.0996h76.0996zM336 -16v288h-104c-13.2998 0 -24 10.7002 -24 24v104h-48.2998v-16h-32v16h-79.7002v-416h288zM194.2 182.3l17.2998 -87.7002c6.40039 -32.3994 -18.4004 -62.5996 -51.5 -62.5996
c-33.2002 0 -58 30.4004 -51.4004 62.9004l19.7002 97.0996v32h32v-32h22.1006c5.7998 0 10.6992 -4.09961 11.7998 -9.7002zM160.3 57.9004c17.9004 0 32.4004 12.0996 32.4004 27c0 14.8994 -14.5 27 -32.4004 27c-17.8994 0 -32.3994 -12.1006 -32.3994 -27
c0 -14.9004 14.5 -27 32.3994 -27zM192.3 256v-32h-32v32h32z" />
<glyph glyph-name="file-audio" unicode="&#xf1c7;" horiz-adv-x="384"
d="M369.941 350.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM332.118 320
l-76.1182 76.1182v-76.1182h76.1182zM48 -16h288v288h-104c-13.2549 0 -24 10.7451 -24 24v104h-160v-416zM192 60.0244c0 -10.6914 -12.9258 -16.0459 -20.4854 -8.48535l-35.5146 35.9746h-28c-6.62695 0 -12 5.37305 -12 12v56c0 6.62695 5.37305 12 12 12h28
l35.5146 36.9473c7.56055 7.56055 20.4854 2.20605 20.4854 -8.48535v-135.951zM233.201 107.154c9.05078 9.29688 9.05957 24.1328 0.000976562 33.4385c-22.1494 22.752 12.2344 56.2461 34.3945 33.4814c27.1982 -27.9404 27.2119 -72.4443 0.000976562 -100.401
c-21.793 -22.3857 -56.9463 10.3154 -34.3965 33.4814z" />
<glyph glyph-name="file-video" unicode="&#xf1c8;" horiz-adv-x="384"
d="M369.941 350.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM332.118 320
l-76.1182 76.1182v-76.1182h76.1182zM48 -16h288v288h-104c-13.2549 0 -24 10.7451 -24 24v104h-160v-416zM276.687 195.303c10.0049 10.0049 27.3135 2.99707 27.3135 -11.3135v-111.976c0 -14.2939 -17.2959 -21.332 -27.3135 -11.3135l-52.6865 52.6738v-37.374
c0 -11.0459 -8.9541 -20 -20 -20h-104c-11.0459 0 -20 8.9541 -20 20v104c0 11.0459 8.9541 20 20 20h104c11.0459 0 20 -8.9541 20 -20v-37.374z" />
<glyph glyph-name="file-code" unicode="&#xf1c9;" horiz-adv-x="384"
d="M149.9 98.9004c3.5 -3.30078 3.69922 -8.90039 0.399414 -12.4004l-17.3994 -18.5996c-1.60059 -1.80078 -4 -2.80078 -6.40039 -2.80078c-2.2002 0 -4.40039 0.900391 -6 2.40039l-57.7002 54.0996c-3.7002 3.40039 -3.7002 9.30078 0 12.8008l57.7002 54.0996
c3.40039 3.2998 9 3.2002 12.4004 -0.400391l17.3994 -18.5996l0.200195 -0.200195c3.2002 -3.59961 2.7998 -9.2002 -0.799805 -12.3994l-32.7998 -28.9004l32.7998 -28.9004zM369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288
c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM256 396.1v-76.0996h76.0996zM336 -16v288h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416h288zM209.6 234l24.4004 -7
c4.7002 -1.2998 7.40039 -6.2002 6 -10.9004l-54.7002 -188.199c-1.2998 -4.60059 -6.2002 -7.40039 -10.8994 -6l-24.4004 7.09961c-4.7002 1.2998 -7.40039 6.2002 -6 10.9004l54.7002 188.1c1.39941 4.7002 6.2002 7.40039 10.8994 6zM234.1 157.1
c-3.5 3.30078 -3.69922 8.90039 -0.399414 12.4004l17.3994 18.5996c3.30078 3.60059 8.90039 3.7002 12.4004 0.400391l57.7002 -54.0996c3.7002 -3.40039 3.7002 -9.30078 0 -12.8008l-57.7002 -54.0996c-3.5 -3.2998 -9.09961 -3.09961 -12.4004 0.400391
l-17.3994 18.5996l-0.200195 0.200195c-3.2002 3.59961 -2.7998 9.2002 0.799805 12.3994l32.7998 28.9004l-32.7998 28.9004z" />
<glyph glyph-name="life-ring" unicode="&#xf1cd;"
d="M256 -56c-136.967 0 -248 111.033 -248 248s111.033 248 248 248s248 -111.033 248 -248s-111.033 -248 -248 -248zM152.602 20.7197c63.2178 -38.3184 143.579 -38.3184 206.797 0l-53.4111 53.4111c-31.8467 -13.5215 -68.168 -13.5059 -99.9746 0zM336 192
c0 44.1123 -35.8877 80 -80 80s-80 -35.8877 -80 -80s35.8877 -80 80 -80s80 35.8877 80 80zM427.28 88.6016c38.3184 63.2178 38.3184 143.579 0 206.797l-53.4111 -53.4111c13.5215 -31.8467 13.5049 -68.168 0 -99.9746zM359.397 363.28
c-63.2168 38.3184 -143.578 38.3184 -206.796 0l53.4111 -53.4111c31.8457 13.5215 68.167 13.5049 99.9736 0zM84.7197 295.398c-38.3184 -63.2178 -38.3184 -143.579 0 -206.797l53.4111 53.4111c-13.5215 31.8467 -13.5059 68.168 0 99.9746z" />
<glyph glyph-name="paper-plane" unicode="&#xf1d8;"
d="M440 441.5c34.5996 19.9004 77.5996 -8.7998 71.5 -48.9004l-59.4004 -387.199c-2.2998 -14.5 -11.0996 -27.3008 -23.8994 -34.5c-7.2998 -4.10059 -15.4004 -6.2002 -23.6006 -6.2002c-6.19922 0 -12.3994 1.2002 -18.2998 3.59961l-111.899 46.2002l-43.8008 -59.0996
c-27.3994 -36.9004 -86.5996 -17.8008 -86.5996 28.5996v84.4004l-114.3 47.2998c-36.7998 15.0996 -40.1006 66 -5.7002 85.8994zM192 -16l36.5996 49.5l-36.5996 15.0996v-64.5996zM404.6 12.7002l59.4004 387.3l-416 -240l107.8 -44.5996l211.5 184.3
c14.2002 12.2998 34.4004 -5.7002 23.7002 -21.2002l-140.2 -202.3z" />
<glyph glyph-name="futbol" unicode="&#xf1e3;" horiz-adv-x="496"
d="M483.8 268.6c42.2998 -130.199 -29 -270.1 -159.2 -312.399c-25.5 -8.2998 -51.2998 -12.2002 -76.6992 -12.2002c-104.5 0 -201.7 66.5996 -235.7 171.4c-42.2998 130.199 29 270.1 159.2 312.399c25.5 8.2998 51.2998 12.2002 76.6992 12.2002
c104.5 0 201.7 -66.5996 235.7 -171.4zM409.3 74.9004c6.10059 8.39941 12.1006 16.8994 16.7998 26.1992c14.3008 28.1006 21.5 58.5 21.7002 89.2002l-38.8994 36.4004l-71.1006 -22.1006l-24.3994 -75.1992l43.6992 -60.9004zM409.3 310.3
c-24.5 33.4004 -58.7002 58.4004 -97.8994 71.4004l-47.4004 -26.2002v-73.7998l64.2002 -46.5l70.7002 22zM184.9 381.6c-39.9004 -13.2998 -73.5 -38.5 -97.8008 -71.8994l10.1006 -52.5l70.5996 -22l64.2002 46.5v73.7998zM139 68.5l43.5 61.7002l-24.2998 74.2998
l-71.1006 22.2002l-39 -36.4004c0.5 -55.7002 23.4004 -95.2002 37.8008 -115.3zM187.2 1.5c64.0996 -20.4004 115.5 -1.7998 121.7 0l22.3994 48.0996l-44.2998 61.7002h-78.5996l-43.6006 -61.7002z" />
<glyph glyph-name="newspaper" unicode="&#xf1ea;" horiz-adv-x="576"
d="M552 384c13.2549 0 24 -10.7451 24 -24v-336c0 -13.2549 -10.7451 -24 -24 -24h-496c-30.9277 0 -56 25.0723 -56 56v272c0 13.2549 10.7451 24 24 24h42.752c6.60547 18.623 24.3896 32 45.248 32h440zM48 56c0 -4.41113 3.58887 -8 8 -8s8 3.58887 8 8v248h-16v-248z
M528 48v288h-416v-280c0 -2.7168 -0.204102 -5.38574 -0.578125 -8h416.578zM172 168c-6.62695 0 -12 5.37305 -12 12v96c0 6.62695 5.37305 12 12 12h136c6.62695 0 12 -5.37305 12 -12v-96c0 -6.62695 -5.37305 -12 -12 -12h-136zM200 248v-40h80v40h-80zM160 108v24
c0 6.62695 5.37305 12 12 12h136c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-136c-6.62695 0 -12 5.37305 -12 12zM352 108v24c0 6.62695 5.37305 12 12 12h104c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-104
c-6.62695 0 -12 5.37305 -12 12zM352 252v24c0 6.62695 5.37305 12 12 12h104c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-104c-6.62695 0 -12 5.37305 -12 12zM352 180v24c0 6.62695 5.37305 12 12 12h104c6.62695 0 12 -5.37305 12 -12v-24
c0 -6.62695 -5.37305 -12 -12 -12h-104c-6.62695 0 -12 5.37305 -12 12z" />
<glyph glyph-name="bell-slash" unicode="&#xf1f6;" horiz-adv-x="640"
d="M633.99 -23.0195c6.91016 -5.52051 8.01953 -15.5908 2.5 -22.4902l-10 -12.4902c-5.53027 -6.88965 -15.5898 -8.00977 -22.4902 -2.49023l-598 467.51c-6.90039 5.52051 -8.01953 15.5908 -2.49023 22.4902l10 12.4902
c5.52051 6.90039 15.5898 8.00977 22.4902 2.49023zM163.53 80h182.84l61.3994 -48h-279.659c-19.1201 0 -31.9902 15.5996 -32.1006 32c-0.0498047 7.5498 2.61035 15.2598 8.61035 21.71c18.3701 19.7402 51.5703 49.6904 54.8398 140.42l45.4697 -35.5498
c-6.91992 -54.7803 -24.6895 -88.5498 -41.3994 -110.58zM320 352c-23.3496 0 -45 -7.17969 -62.9404 -19.4004l-38.1699 29.8408c19.6807 15.7793 43.1104 27.3096 69.1299 32.7197v20.8398c0 17.6699 14.3203 32 31.9805 32s31.9805 -14.3301 31.9805 -32v-20.8398
c73.46 -15.2598 127.939 -77.46 127.939 -155.16c0 -41.3604 6.03027 -70.7197 14.3398 -92.8496l-59.5293 46.54c-1.63086 13.96 -2.77051 28.8896 -2.79004 45.7295c0 0.200195 0.0595703 0.379883 0.0595703 0.580078c0 61.8604 -50.1396 112 -112 112zM320 -64
c-35.3203 0 -63.9697 28.6504 -63.9697 64h127.939c0 -35.3496 -28.6494 -64 -63.9697 -64z" />
<glyph glyph-name="copyright" unicode="&#xf1f9;"
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 -8c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200c-110.549 0 -200 -89.4688 -200 -200c0 -110.549 89.4678 -200 200 -200z
M363.351 93.0645c-9.61328 -9.71289 -45.5293 -41.3965 -104.064 -41.3965c-82.4297 0 -140.484 61.4248 -140.484 141.567c0 79.1514 60.2754 139.4 139.763 139.4c55.5303 0 88.7373 -26.6201 97.5928 -34.7783c2.37793 -2.1875 3.86914 -5.3252 3.86914 -8.80762
c0 -2.39746 -0.717773 -4.64258 -1.93359 -6.51465l-18.1543 -28.1133c-3.8418 -5.9502 -11.9668 -7.28223 -17.499 -2.9209c-8.5957 6.77637 -31.8145 22.5381 -61.708 22.5381c-48.3037 0 -77.916 -35.3301 -77.916 -80.082c0 -41.5889 26.8877 -83.6924 78.2764 -83.6924
c32.6572 0 56.8428 19.0391 65.7266 27.2256c5.26953 4.85645 13.5957 4.03906 17.8193 -1.73828l19.8652 -27.1699c1.45996 -1.98145 2.32422 -4.42969 2.32422 -7.07715c0 -3.28809 -1.32422 -6.2793 -3.47656 -8.44043z" />
<glyph glyph-name="closed-captioning" unicode="&#xf20a;"
d="M464 384c26.5 0 48 -21.5 48 -48v-288c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v288c0 26.5 21.5 48 48 48h416zM458 48c3.2998 0 6 2.7002 6 6v276c0 3.2998 -2.7002 6 -6 6h-404c-3.2998 0 -6 -2.7002 -6 -6v-276c0 -3.2998 2.7002 -6 6 -6h404z
M246.9 133.7c1.69922 -2.40039 1.5 -5.60059 -0.5 -7.7002c-53.6006 -56.7998 -172.801 -32.0996 -172.801 67.9004c0 97.2998 121.7 119.5 172.5 70.0996c2.10059 -2 2.5 -3.2002 1 -5.7002l-17.5 -30.5c-1.89941 -3.09961 -6.19922 -4 -9.09961 -1.7002
c-40.7998 32 -94.5996 14.9004 -94.5996 -31.1992c0 -48 51 -70.5 92.1992 -32.6006c2.80078 2.5 7.10059 2.10059 9.2002 -0.899414zM437.3 133.7c1.7002 -2.40039 1.5 -5.60059 -0.5 -7.7002c-53.5996 -56.9004 -172.8 -32.0996 -172.8 67.9004
c0 97.2998 121.7 119.5 172.5 70.0996c2.09961 -2 2.5 -3.2002 1 -5.7002l-17.5 -30.5c-1.90039 -3.09961 -6.2002 -4 -9.09961 -1.7002c-40.8008 32 -94.6006 14.9004 -94.6006 -31.1992c0 -48 51 -70.5 92.2002 -32.6006c2.7998 2.5 7.09961 2.10059 9.2002 -0.899414z
" />
<glyph glyph-name="object-group" unicode="&#xf247;"
d="M500 320h-12v-256h12c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v12h-320v-12c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h12v256h-12
c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-12h320v12c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12zM448 384v-32h32v32h-32zM32 384v-32h32v32h-32zM64 0v32
h-32v-32h32zM480 0v32h-32v-32h32zM440 64v256h-12c-6.62695 0 -12 5.37305 -12 12v12h-320v-12c0 -6.62695 -5.37305 -12 -12 -12h-12v-256h12c6.62695 0 12 -5.37305 12 -12v-12h320v12c0 6.62695 5.37305 12 12 12h12zM404 256c6.62695 0 12 -5.37207 12 -12v-168
c0 -6.62793 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37207 -12 12v52h-84c-6.62695 0 -12 5.37207 -12 12v168c0 6.62793 5.37305 12 12 12h200c6.62695 0 12 -5.37207 12 -12v-52h84zM136 280v-112h144v112h-144zM376 104v112h-56v-76
c0 -6.62793 -5.37305 -12 -12 -12h-76v-24h144z" />
<glyph glyph-name="object-ungroup" unicode="&#xf248;" horiz-adv-x="576"
d="M564 224h-12v-160h12c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v12h-224v-12c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h12v24h-88v-12
c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h12v160h-12c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-12h224v12c0 6.62695 5.37305 12 12 12h72
c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-12v-24h88v12c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12zM352 384v-32h32v32h-32zM352 128v-32h32v32h-32zM64 96v32h-32v-32h32zM64 352v32
h-32v-32h32zM96 136h224v12c0 6.62695 5.37305 12 12 12h12v160h-12c-6.62695 0 -12 5.37305 -12 12v12h-224v-12c0 -6.62695 -5.37305 -12 -12 -12h-12v-160h12c6.62695 0 12 -5.37305 12 -12v-12zM224 0v32h-32v-32h32zM504 64v160h-12c-6.62695 0 -12 5.37305 -12 12v12
h-88v-88h12c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v12h-88v-24h12c6.62695 0 12 -5.37305 12 -12v-12h224v12c0 6.62695 5.37305 12 12 12h12zM544 0v32h-32v-32h32zM544 256v32h-32v-32h32z" />
<glyph glyph-name="sticky-note" unicode="&#xf249;" horiz-adv-x="448"
d="M448 99.8936c0 -13.2451 -5.37012 -25.252 -14.0586 -33.9404l-83.8828 -83.8818c-8.68848 -8.68848 -20.6943 -14.0596 -33.9404 -14.0596h-268.118c-26.5098 0 -48 21.4902 -48 48v351.988c0 26.5098 21.4902 48 48 48h352c26.5098 0 48 -21.4902 48 -48v-268.106z
M320 19.8936l76.1182 76.1182h-76.1182v-76.1182zM400 368h-352v-351.988h224v104c0 13.2549 10.7451 24 24 24h104v223.988z" />
<glyph glyph-name="clone" unicode="&#xf24d;"
d="M464 448c26.5098 0 48 -21.4902 48 -48v-320c0 -26.5098 -21.4902 -48 -48 -48h-48v-48c0 -26.5098 -21.4902 -48 -48 -48h-320c-26.5098 0 -48 21.4902 -48 48v320c0 26.5098 21.4902 48 48 48h48v48c0 26.5098 21.4902 48 48 48h320zM362 -16c3.31152 0 6 2.68848 6 6
v42h-224c-26.5098 0 -48 21.4902 -48 48v224h-42c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h308zM458 80c3.31152 0 6 2.68848 6 6v308c0 3.31152 -2.68848 6 -6 6h-308c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h308z" />
<glyph glyph-name="hourglass" unicode="&#xf254;" horiz-adv-x="384"
d="M368 400c0 -80.0996 -31.8984 -165.619 -97.1797 -208c64.9912 -42.1934 97.1797 -127.436 97.1797 -208h4c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-360c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h4
c0 80.0996 31.8994 165.619 97.1797 208c-64.9912 42.1934 -97.1797 127.436 -97.1797 208h-4c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h360c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-4zM64 400
c0 -101.621 57.3066 -184 128 -184s128 82.3799 128 184h-256zM320 -16c0 101.62 -57.3076 184 -128 184s-128 -82.3799 -128 -184h256z" />
<glyph glyph-name="hand-rock" unicode="&#xf255;"
d="M408.864 368.948c48.8213 20.751 103.136 -15.0723 103.136 -67.9111v-114.443c0 -15.3955 -3.08887 -30.3906 -9.18262 -44.5674l-42.835 -99.6562c-4.99707 -11.625 -3.98242 -18.8574 -3.98242 -42.3701c0 -17.6729 -14.3271 -32 -32 -32h-252
c-17.6729 0 -32 14.3271 -32 32c0 27.3301 1.1416 29.2012 -3.11035 32.9033l-97.71 85.0811c-24.8994 21.6797 -39.1797 52.8926 -39.1797 85.6338v56.9531c0 47.4277 44.8457 82.0215 91.0459 71.1807c1.96094 55.751 63.5107 87.8262 110.671 60.8057
c29.1895 31.0713 78.8604 31.4473 108.334 -0.0214844c32.7051 18.6846 76.4121 10.3096 98.8135 -23.5879zM464 186.594v114.445c0 34.29 -52 33.8232 -52 0.676758c0 -8.83594 -7.16309 -16 -16 -16h-7c-8.83691 0 -16 7.16406 -16 16v26.751
c0 34.457 -52 33.707 -52 0.676758v-27.4287c0 -8.83594 -7.16309 -16 -16 -16h-7c-8.83691 0 -16 7.16406 -16 16v40.4658c0 34.3525 -52 33.8115 -52 0.677734v-41.1436c0 -8.83594 -7.16406 -16 -16 -16h-7c-8.83594 0 -16 7.16406 -16 16v26.751
c0 34.4023 -52 33.7744 -52 0.676758v-116.571c0 -8.83105 -7.17773 -15.9961 -16.0078 -15.9961c-4.0166 0 -7.68848 1.48242 -10.499 3.92969l-7 6.09473c-3.37012 2.93457 -5.49316 7.25293 -5.49316 12.0674v41.2275c0 34.2148 -52 33.8857 -52 0.677734v-56.9531
c0 -18.8555 8.27441 -36.874 22.7002 -49.4365l97.71 -85.0801c12.4502 -10.8398 19.5898 -26.4463 19.5898 -42.8164v-10.2861h220v7.07617c0 13.21 2.65332 26.0791 7.88281 38.25l42.835 99.6553c3.37891 7.82715 5.28223 16.501 5.28223 25.5625v0.0498047z" />
<glyph glyph-name="hand-paper" unicode="&#xf256;" horiz-adv-x="448"
d="M372.57 335.359c39.9062 5.63281 75.4297 -25.7393 75.4297 -66.3594v-131.564c-0.00292969 -15.7393 -1.80566 -30.9482 -5.19531 -45.666l-30.1836 -130.958c-3.34668 -14.5234 -16.2783 -24.8125 -31.1816 -24.8125h-222.897
c-10.7539 0 -20.2588 5.28613 -26.0615 13.4316l-119.97 168.415c-21.2441 29.8203 -14.8047 71.3574 14.5498 93.1533c18.7754 13.9395 42.1309 16.2979 62.083 8.87109v126.13c0 44.0547 41.125 75.5439 82.4053 64.9834c23.8926 48.1963 92.3535 50.2471 117.982 0.74707
c42.5186 11.1445 83.0391 -21.9346 83.0391 -65.5469v-10.8242zM399.997 137.437l-0.00195312 131.563c0 24.9492 -36.5703 25.5508 -36.5703 -0.691406v-76.3086c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v154.184
c0 25.501 -36.5703 26.3633 -36.5703 0.691406v-154.875c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v188.309c0 25.501 -36.5703 26.3545 -36.5703 0.691406v-189c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16
v153.309c0 25.501 -36.5713 26.3359 -36.5713 0.691406v-206.494c0 -15.5703 -20.0352 -21.9092 -29.0303 -9.2832l-27.1279 38.0791c-14.3711 20.1709 -43.833 -2.33496 -29.3945 -22.6045l115.196 -161.697h201.92l27.3252 118.551
c2.63086 11.417 3.96484 23.1553 3.96484 34.8857z" />
<glyph glyph-name="hand-scissors" unicode="&#xf257;"
d="M256 -32c-44.9561 0 -77.3428 43.2627 -64.0244 85.8535c-21.6484 13.71 -34.0156 38.7617 -30.3408 65.0068h-87.6348c-40.8037 0 -74 32.8105 -74 73.1406c0 40.3291 33.1963 73.1396 74 73.1396l94 -9.14062l-78.8496 18.6787
c-38.3076 14.7422 -57.04 57.4707 -41.9424 95.1123c15.0303 37.4736 57.7549 55.7803 95.6416 41.2012l144.929 -55.7568c24.9551 30.5566 57.8086 43.9932 92.2178 24.7324l97.999 -54.8525c20.9746 -11.7393 34.0049 -33.8457 34.0049 -57.6904v-205.702
c0 -30.7422 -21.4404 -57.5576 -51.7979 -64.5537l-118.999 -27.4268c-4.97168 -1.14648 -10.0889 -1.72949 -15.2031 -1.72949zM256 16.0127l70 -0.000976562c1.52441 0 2.99707 0.174805 4.42285 0.501953l119.001 27.4277
c8.58203 1.97754 14.5762 9.29102 14.5762 17.7812v205.701c0 6.4873 -3.62109 12.542 -9.44922 15.8047l-98 54.8545c-8.13965 4.55566 -18.668 2.61914 -24.4873 -4.50781l-21.7646 -26.6475c-2.93457 -3.59375 -7.40332 -5.87305 -12.4004 -5.87305
c-2.02246 0 -3.95703 0.375977 -5.73828 1.06152l-166.549 64.0908c-32.6543 12.5664 -50.7744 -34.5771 -19.2227 -46.7168l155.357 -59.7852c6 -2.30859 10.2539 -8.12402 10.2539 -14.9326v-11.6328c0 -8.83691 -7.16309 -16 -16 -16h-182
c-34.375 0 -34.4297 -50.2803 0 -50.2803h182c8.83691 0 16 -7.16309 16 -16v-6.85645c0 -8.83691 -7.16309 -16 -16 -16h-28c-25.1221 0 -25.1592 -36.5674 0 -36.5674h28c8.83691 0 16 -7.16211 16 -16v-6.85547c0 -8.83691 -7.16309 -16 -16 -16
c-25.1201 0 -25.1602 -36.5674 0 -36.5674z" />
<glyph glyph-name="hand-lizard" unicode="&#xf258;" horiz-adv-x="576"
d="M556.686 157.458c12.6357 -19.4863 19.3145 -42.0615 19.3145 -65.2871v-124.171h-224v71.582l-99.751 38.7871c-2.7832 1.08203 -5.70996 1.63086 -8.69727 1.63086h-131.552c-30.8789 0 -56 25.1211 -56 56c0 48.5234 39.4766 88 88 88h113.709l18.333 48h-196.042
c-44.1123 0 -80 35.8877 -80 80v8c0 30.8779 25.1211 56 56 56h293.917c24.5 0 47.084 -12.2725 60.4111 -32.8291zM528 16v76.1709c0 0.0166016 -0.0439453 0.106445 -0.0439453 0.12207c0 14.3945 -4.24219 27.8057 -11.5439 39.0498l-146.358 225.715
c-4.44336 6.85254 -11.9707 10.9424 -20.1367 10.9424h-293.917c-4.41113 0 -8 -3.58887 -8 -8v-8c0 -17.6445 14.3555 -32 32 -32h213.471c25.2021 0 42.626 -25.293 33.6299 -48.8457l-24.5518 -64.2812c-7.05371 -18.4658 -25.0732 -30.873 -44.8398 -30.873h-113.709
c-22.0557 0 -40 -17.9443 -40 -40c0 -4.41113 3.58887 -8 8 -8h131.552c0.0175781 0 0.0712891 -0.0273438 0.0888672 -0.0273438c9.16992 0 17.9404 -1.72461 26.0039 -4.86621l99.752 -38.7881c18.5898 -7.22852 30.6035 -24.7881 30.6035 -44.7363v-23.582h128z" />
<glyph glyph-name="hand-spock" unicode="&#xf259;"
d="M501.03 331.824c6.92773 -11.1826 10.9697 -24.4053 10.9697 -38.5146c0 -5.92676 -0.706055 -11.6885 -2.03809 -17.208l-57.623 -241.963c-13.2236 -56.1904 -63.707 -98.1387 -123.908 -98.1387h-0.352539h-107.455
c-0.0761719 0 -0.193359 0.00195312 -0.270508 0.00195312c-40.9248 0 -78.1475 15.9814 -105.761 42.0391l-91.3652 85.9766c-14.3076 13.4434 -23.2246 32.5547 -23.2246 53.7168c0 19.5254 7.61035 37.2861 20.0254 50.4766
c5.31836 5.66406 29.875 29.3926 68.1152 21.8477l-24.3594 82.1973c-1.97363 6.64844 -2.97656 13.6836 -2.97656 20.9688c0 38.6953 29.8926 70.4639 67.8262 73.4531c-0.246094 2.45117 -0.34082 4.85547 -0.34082 7.37207c0 34.4199 23.585 63.376 55.4619 71.5752
c43.248 10.9785 80.5645 -17.7012 89.6602 -53.0723l13.6836 -53.207l4.64648 22.6602c6.99023 33.5186 36.6826 58.8037 72.2373 58.916c8.73438 0 56.625 -3.26953 70.7383 -54.0801c15.0664 0.710938 46.9199 -3.50977 66.3105 -35.0176zM463.271 287.219
c7.86914 32.9844 -42.1211 45.2695 -50.0859 11.9219l-24.8008 -104.146c-4.38867 -18.4141 -31.7783 -11.8926 -28.0557 6.2168l28.5479 139.166c7.39844 36.0703 -43.3076 45.0703 -50.1182 11.9629l-31.791 -154.971
c-3.54883 -17.3086 -28.2832 -18.0469 -32.7109 -0.804688l-47.3262 184.035c-8.43359 32.8105 -58.3691 20.2676 -49.8652 -12.8359l42.4414 -165.039c4.81641 -18.7207 -23.3711 -26.9121 -28.9648 -8.00781l-31.3438 105.779
c-9.6875 32.6465 -59.1191 18.2578 -49.3867 -14.625l36.0137 -121.539c6.59375 -22.2441 10.1777 -45.7803 10.1777 -70.1523c0 -6.54297 -8.05664 -10.9355 -13.4824 -5.82617l-51.123 48.1074c-24.7852 23.4082 -60.0527 -14.1875 -35.2793 -37.4902l91.3691 -85.9805
c19.0469 -17.9736 44.75 -28.998 72.9795 -28.998h0.157227h107.455c0.0732422 0 0.138672 0.0429688 0.212891 0.0429688c37.5791 0 69.1016 26.1416 77.3564 61.2168z" />
<glyph glyph-name="hand-pointer" unicode="&#xf25a;" horiz-adv-x="448"
d="M358.182 268.639c43.1934 16.6348 89.8184 -15.7949 89.8184 -62.6387v-84c-0.000976562 -5.24023 -0.600586 -10.3037 -1.72754 -15.2041l-27.4297 -118.999c-6.98242 -30.2969 -33.7549 -51.7969 -64.5566 -51.7969h-178.286
c-21.2588 0 -41.3682 10.4102 -53.791 27.8457l-109.699 154.001c-21.2432 29.8193 -14.8047 71.3574 14.5498 93.1523c18.8115 13.9658 42.1748 16.2822 62.083 8.87207v161.129c0 36.9443 29.7363 67 66.2861 67s66.2861 -30.0557 66.2861 -67v-73.6338
c20.4131 2.85742 41.4678 -3.94238 56.5947 -19.6289c27.1934 12.8467 60.3799 5.66992 79.8721 -19.0986zM80.9854 168.303c-14.4004 20.2119 -43.8008 -2.38281 -29.3945 -22.6055l109.712 -154c3.43457 -4.81934 8.92871 -7.69727 14.6973 -7.69727h178.285
c8.49219 0 15.8037 5.99414 17.7822 14.5762l27.4297 119.001c0.333008 1.44629 0.501953 2.93457 0.501953 4.42285v84c0 25.1602 -36.5713 25.1211 -36.5713 0c0 -8.83594 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16406 -16 16v21
c0 25.1602 -36.5713 25.1201 -36.5713 0v-21c0 -8.83594 -7.16309 -16 -16 -16h-6.85938c-8.83691 0 -16 7.16406 -16 16v35c0 25.1602 -36.5703 25.1201 -36.5703 0v-35c0 -8.83594 -7.16309 -16 -16 -16h-6.85742c-8.83691 0 -16 7.16406 -16 16v175
c0 25.1602 -36.5713 25.1201 -36.5713 0v-241.493c0 -15.5703 -20.0352 -21.9092 -29.0303 -9.2832zM176.143 48v96c0 8.83691 6.26855 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16zM251.571 48v96
c0 8.83691 6.26758 16 14 16h6c7.73145 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26855 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16zM327 48v96c0 8.83691 6.26758 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6
c-7.73242 0 -14 7.16309 -14 16z" />
<glyph glyph-name="hand-peace" unicode="&#xf25b;" horiz-adv-x="448"
d="M362.146 256.024c42.5908 13.3184 85.8535 -19.0684 85.8535 -64.0244l-0.0117188 -70.001c-0.000976562 -5.24023 -0.600586 -10.3027 -1.72949 -15.2031l-27.4268 -118.999c-6.99707 -30.3564 -33.8105 -51.7969 -64.5547 -51.7969h-205.702
c-23.8447 0 -45.9502 13.0303 -57.6904 34.0059l-54.8525 97.999c-19.2607 34.4092 -5.82422 67.2617 24.7324 92.2178l-55.7568 144.928c-14.5791 37.8867 3.72754 80.6113 41.2012 95.6416c37.6406 15.0977 80.3691 -3.63477 95.1123 -41.9424l18.6787 -78.8496
l-9.14062 94c0 40.8037 32.8096 74 73.1396 74s73.1406 -33.1963 73.1406 -74v-87.6348c26.2451 3.6748 51.2959 -8.69238 65.0068 -30.3408zM399.987 122l-0.000976562 70c0 25.1602 -36.5674 25.1201 -36.5674 0c0 -8.83691 -7.16309 -16 -16 -16h-6.85547
c-8.83789 0 -16 7.16309 -16 16v28c0 25.1592 -36.5674 25.1221 -36.5674 0v-28c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v182c0 34.4297 -50.2803 34.375 -50.2803 0v-182c0 -8.83691 -7.16309 -16 -16 -16h-11.6328
c-6.80859 0 -12.624 4.25391 -14.9326 10.2539l-59.7842 155.357c-12.1396 31.5518 -59.2842 13.4326 -46.7168 -19.2227l64.0898 -166.549c0.685547 -1.78125 1.07812 -3.71875 1.07812 -5.74121c0 -4.99707 -2.2959 -9.46289 -5.88965 -12.3975l-26.6475 -21.7646
c-7.12695 -5.81934 -9.06445 -16.3467 -4.50781 -24.4873l54.8535 -98c3.26367 -5.82812 9.31934 -9.44922 15.8057 -9.44922h205.701c8.49121 0 15.8037 5.99414 17.7812 14.5762l27.4277 119.001c0.333008 1.44629 0.501953 2.93457 0.501953 4.42285z" />
<glyph glyph-name="registered" unicode="&#xf25d;"
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 -8c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200c-110.549 0 -200 -89.4688 -200 -200c0 -110.549 89.4678 -200 200 -200z
M366.442 73.791c4.40332 -7.99219 -1.37012 -17.791 -10.5107 -17.791h-42.8096c-0.00488281 0 -0.000976562 -0.0126953 -0.00585938 -0.0126953c-4.58594 0 -8.57422 2.58301 -10.5869 6.37305l-47.5156 89.3027h-31.958v-83.6631c0 -6.61719 -5.38281 -12 -12 -12
h-38.5674c-6.61719 0 -12 5.38281 -12 12v248.304c0 6.61719 5.38281 12 12 12h78.667c71.251 0 101.498 -32.749 101.498 -85.252c0 -31.6123 -15.2148 -59.2969 -39.4824 -73.1758c3.02148 -4.61719 0.225586 0.199219 53.2715 -96.085zM256.933 208.094
c20.9131 0 32.4307 11.5186 32.4316 32.4316c0 19.5752 -6.5127 31.709 -38.9297 31.709h-27.377v-64.1406h33.875z" />
<glyph glyph-name="calendar-plus" unicode="&#xf271;" horiz-adv-x="448"
d="M336 156v-24c0 -6.59961 -5.40039 -12 -12 -12h-76v-76c0 -6.59961 -5.40039 -12 -12 -12h-24c-6.59961 0 -12 5.40039 -12 12v76h-76c-6.59961 0 -12 5.40039 -12 12v24c0 6.59961 5.40039 12 12 12h76v76c0 6.59961 5.40039 12 12 12h24c6.59961 0 12 -5.40039 12 -12
v-76h76c6.59961 0 12 -5.40039 12 -12zM448 336v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40
c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="calendar-minus" unicode="&#xf272;" horiz-adv-x="448"
d="M124 120c-6.59961 0 -12 5.40039 -12 12v24c0 6.59961 5.40039 12 12 12h200c6.59961 0 12 -5.40039 12 -12v-24c0 -6.59961 -5.40039 -12 -12 -12h-200zM448 336v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52
c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="calendar-times" unicode="&#xf273;" horiz-adv-x="448"
d="M311.7 73.2998l-17 -17c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-53.7002 53.7998l-53.7002 -53.6992c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-17 17c-4.7002 4.69922 -4.7002 12.2998 0 17l53.7002 53.6992l-53.7002 53.7002c-4.7002 4.7002 -4.7002 12.2998 0 17
l17 17c4.7002 4.7002 12.2998 4.7002 17 0l53.7002 -53.7002l53.7002 53.7002c4.7002 4.7002 12.2998 4.7002 17 0l17 -17c4.7002 -4.7002 4.7002 -12.2998 0 -17l-53.7998 -53.7998l53.6992 -53.7002c4.80078 -4.7002 4.80078 -12.2998 0.100586 -17zM448 336v-352
c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10
v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="calendar-check" unicode="&#xf274;" horiz-adv-x="448"
d="M400 384c26.5098 0 48 -21.4902 48 -48v-352c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h48v52c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-52h128v52c0 6.62695 5.37305 12 12 12h40
c6.62695 0 12 -5.37305 12 -12v-52h48zM394 -16c3.31152 0 6 2.68848 6 6v298h-352v-298c0 -3.31152 2.68848 -6 6 -6h340zM341.151 184.65l-142.31 -141.169c-4.70508 -4.66699 -12.3027 -4.6377 -16.9707 0.0673828l-75.0908 75.6992
c-4.66699 4.70508 -4.6377 12.3027 0.0673828 16.9707l22.7197 22.5361c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0693359l44.1035 -44.4609l111.072 110.182c4.70508 4.66699 12.3027 4.63672 16.9707 -0.0683594l22.5361 -22.7178
c4.66699 -4.70508 4.63672 -12.3027 -0.0683594 -16.9697z" />
<glyph glyph-name="map" unicode="&#xf279;" horiz-adv-x="576"
d="M560.02 416c8.4502 0 15.9805 -6.83008 15.9805 -16.0195v-346.32c0 -13.4707 -8.32422 -24.9951 -20.1201 -29.71l-151.83 -52.8105c-6.23242 -2.02832 -12.9023 -3.12305 -19.8076 -3.12305c-7.07324 0 -13.8799 1.15039 -20.2422 3.27344l-172 60.71l-170.05 -62.8398
c-1.99023 -0.790039 -4 -1.16016 -5.95996 -1.16016c-8.45996 0 -15.9902 6.83008 -15.9902 16.0195v346.32c0.00292969 13.4697 8.32617 24.9932 20.1201 29.71l151.83 52.8105c6.43945 2.08984 13.1201 3.13965 19.8096 3.13965
c7.06641 -0.00292969 13.8789 -1.16602 20.2402 -3.28027l172 -60.7197h0.00976562l170.05 62.8398c1.98047 0.790039 4 1.16016 5.95996 1.16016zM224 357.58v-285.97l128 -45.1904v285.97zM48 29.9502l127.36 47.0801l0.639648 0.229492v286.2l-128 -44.5303v-288.979z
M528 65.0801v288.97l-127.36 -47.0693l-0.639648 -0.240234v-286.19z" />
<glyph glyph-name="comment-alt" unicode="&#xf27a;"
d="M448 448c35.2998 0 64 -28.7002 64 -64v-288c0 -35.2998 -28.7002 -64 -64 -64h-144l-124.9 -93.5996c-2.19922 -1.7002 -4.69922 -2.40039 -7.09961 -2.40039c-6.2002 0 -12 4.90039 -12 12v84h-96c-35.2998 0 -64 28.7002 -64 64v288c0 35.2998 28.7002 64 64 64h384z
M464 96v288c0 8.7998 -7.2002 16 -16 16h-384c-8.7998 0 -16 -7.2002 -16 -16v-288c0 -8.7998 7.2002 -16 16 -16h144v-60l67.2002 50.4004l12.7998 9.59961h160c8.7998 0 16 7.2002 16 16z" />
<glyph glyph-name="pause-circle" unicode="&#xf28b;"
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM352 272v-160c0 -8.7998 -7.2002 -16 -16 -16h-48
c-8.7998 0 -16 7.2002 -16 16v160c0 8.7998 7.2002 16 16 16h48c8.7998 0 16 -7.2002 16 -16zM240 272v-160c0 -8.7998 -7.2002 -16 -16 -16h-48c-8.7998 0 -16 7.2002 -16 16v160c0 8.7998 7.2002 16 16 16h48c8.7998 0 16 -7.2002 16 -16z" />
<glyph glyph-name="stop-circle" unicode="&#xf28d;"
d="M504 192c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248s248 -111 248 -248zM56 192c0 -110.5 89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200zM352 272v-160c0 -8.7998 -7.2002 -16 -16 -16h-160
c-8.7998 0 -16 7.2002 -16 16v160c0 8.7998 7.2002 16 16 16h160c8.7998 0 16 -7.2002 16 -16z" />
<glyph glyph-name="handshake" unicode="&#xf2b5;" horiz-adv-x="640"
d="M519.2 320.1h120.8v-255.699h-64c-17.5 0 -31.7998 14.1992 -31.9004 31.6992h-57.8994c-1.7998 -8.19922 -5.2998 -16.0996 -10.9004 -23l-26.2002 -32.2998c-15.7998 -19.3994 -41.8994 -25.5 -64 -16.7998c-13.5 -16.5996 -30.5996 -24 -48.7998 -24
c-15.0996 0 -28.5996 5.09961 -41.0996 15.9004c-31.7998 -21.9004 -74.7002 -21.3008 -105.601 3.7998l-84.5996 76.3994h-9.09961c-0.100586 -17.5 -14.3008 -31.6992 -31.9004 -31.6992h-64v255.699h118l47.5996 47.6006c10.5 10.3994 24.8008 16.2998 39.6006 16.2998
h226.8c15.4326 0 29.4326 -6.22168 39.5996 -16.2998zM48 96.4004c8.7998 0 16 7.09961 16 16c0 8.7998 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.80078 7.2002 -16 16 -16zM438 103.3c2.7002 3.40039 2.2002 8.5 -1.2002 11.2998l-108.2 87.8008l-8.19922 -7.5
c-40.3008 -36.8008 -86.7002 -11.8008 -101.5 4.39941c-26.7002 29 -25 74.4004 4.39941 101.3l38.7002 35.5h-56.7002c-2 -0.799805 -3.7002 -1.5 -5.7002 -2.2998l-61.6992 -61.5996h-41.9004v-128.101h27.7002l97.2998 -88
c16.0996 -13.0996 41.4004 -10.5 55.2998 6.60059l15.6006 19.2002l36.7998 -31.5c3 -2.40039 12 -4.90039 18 2.39941l30 36.5l23.8994 -19.3994c3.5 -2.80078 8.5 -2.2002 11.3008 1.19922zM544 144.1v128h-44.7002l-61.7002 61.6006
c-1.39941 1.5 -3.39941 2.2998 -5.5 2.2998l-83.6992 -0.200195c-10 0 -19.6006 -3.7002 -27 -10.5l-65.6006 -60.0996c-9.7002 -8.7998 -10.5 -24 -1.2002 -33.9004c8.90039 -9.39941 25.1006 -8.7002 34.6006 0l55.2002 50.6006c6.5 5.89941 16.5996 5.5 22.5996 -1
l10.9004 -11.7002c6 -6.5 5.5 -16.6006 -1 -22.6006l-12.5 -11.3994l102.699 -83.4004c2.80078 -2.2998 5.40039 -4.89941 7.7002 -7.7002h69.2002zM592 96.4004c8.7998 0 16 7.09961 16 16c0 8.7998 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.80078 7.2002 -16 16 -16z
" />
<glyph glyph-name="envelope-open" unicode="&#xf2b6;"
d="M494.586 283.484c10.6523 -8.80762 17.4141 -22.1064 17.4141 -36.9932v-262.491c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v262.515c0 14.9355 6.80469 28.2705 17.5146 37.0771c4.08008 3.35449 110.688 89.0996 135.15 108.549
c22.6992 18.1426 60.1299 55.8594 103.335 55.8594c43.4365 0 81.2314 -38.1914 103.335 -55.8594c23.5283 -18.707 130.554 -104.773 135.251 -108.656zM464 -10v253.632c0 0.00195312 0.00390625 0.000976562 0.00390625 0.00292969
c0 1.88184 -0.869141 3.56152 -2.22754 4.66016c-15.8633 12.8232 -108.793 87.5752 -132.366 106.316c-17.5527 14.0195 -49.7168 45.3887 -73.4102 45.3887c-23.6016 0 -55.2451 -30.8799 -73.4102 -45.3887c-23.5713 -18.7393 -116.494 -93.4795 -132.364 -106.293
c-1.40918 -1.13965 -2.22559 -2.85254 -2.22559 -4.66504v-253.653c0 -3.31152 2.68848 -6 6 -6h404c3.31152 0 6 2.68848 6 6zM432.009 177.704c4.24902 -5.15918 3.46484 -12.7949 -1.74512 -16.9814c-28.9746 -23.2822 -59.2734 -47.5967 -70.9287 -56.8623
c-22.6992 -18.1436 -60.1299 -55.8604 -103.335 -55.8604c-43.4521 0 -81.2871 38.2373 -103.335 55.8604c-11.2793 8.9668 -41.7441 33.4131 -70.9268 56.8643c-5.20996 4.1875 -5.99316 11.8223 -1.74512 16.9814l15.2578 18.5283
c4.17773 5.07227 11.6572 5.84277 16.7793 1.72559c28.6182 -23.001 58.5654 -47.0352 70.5596 -56.5713c17.5527 -14.0195 49.7168 -45.3887 73.4102 -45.3887c23.6016 0 55.2461 30.8799 73.4102 45.3887c11.9941 9.53516 41.9434 33.5703 70.5625 56.5684
c5.12207 4.11621 12.6016 3.3457 16.7783 -1.72656z" />
<glyph glyph-name="address-book" unicode="&#xf2b9;" horiz-adv-x="448"
d="M436 288h-20v-64h20c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-20v-64h20c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-20v-48c0 -26.5 -21.5 -48 -48 -48h-320c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48
h320c26.5 0 48 -21.5 48 -48v-48h20c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12zM368 -16v416h-320v-416h320zM208 192c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64zM118.4 64
c-12.4004 0 -22.4004 8.59961 -22.4004 19.2002v19.2002c0 31.7998 30.0996 57.5996 67.2002 57.5996c11.3994 0 17.8994 -8 44.7998 -8c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996v-19.2002c0 -10.6006 -10 -19.2002 -22.4004 -19.2002
h-179.199z" />
<glyph glyph-name="address-card" unicode="&#xf2bb;" horiz-adv-x="576"
d="M528 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-480c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h480zM528 16v352h-480v-352h480zM208 192c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64z
M118.4 64c-12.4004 0 -22.4004 8.59961 -22.4004 19.2002v19.2002c0 31.7998 30.0996 57.5996 67.2002 57.5996c11.3994 0 17.8994 -8 44.7998 -8c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996v-19.2002
c0 -10.6006 -10 -19.2002 -22.4004 -19.2002h-179.199zM360 128c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 192c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112
c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 256c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112z" />
<glyph glyph-name="user-circle" unicode="&#xf2bd;" horiz-adv-x="496"
d="M248 344c53 0 96 -43 96 -96s-43 -96 -96 -96s-96 43 -96 96s43 96 96 96zM248 200c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8
c49.7002 0 95.0996 18.2998 130.1 48.4004c-14.8994 23 -40.3994 38.5 -69.5996 39.5c-20.7998 -6.5 -40.5996 -9.60059 -60.5 -9.60059s-39.7002 3.2002 -60.5 9.60059c-29.2002 -0.900391 -54.7002 -16.5 -69.5996 -39.5c35 -30.1006 80.3994 -48.4004 130.1 -48.4004z
M410.7 76.0996c23.3994 32.7002 37.2998 72.7002 37.2998 115.9c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200c0 -43.2002 13.9004 -83.2002 37.2998 -115.9c24.5 31.4004 62.2002 51.9004 105.101 51.9004c10.1992 0 26.0996 -9.59961 57.5996 -9.59961
c31.5996 0 47.4004 9.59961 57.5996 9.59961c43 0 80.7002 -20.5 105.101 -51.9004z" />
<glyph glyph-name="id-badge" unicode="&#xf2c1;" horiz-adv-x="384"
d="M336 448c26.5 0 48 -21.5 48 -48v-416c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48h288zM336 -16v416h-288v-416h288zM144 336c-8.7998 0 -16 7.2002 -16 16s7.2002 16 16 16h96c8.7998 0 16 -7.2002 16 -16s-7.2002 -16 -16 -16
h-96zM192 160c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64zM102.4 32c-12.4004 0 -22.4004 8.59961 -22.4004 19.2002v19.2002c0 31.7998 30.0996 57.5996 67.2002 57.5996c11.3994 0 17.8994 -8 44.7998 -8
c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996v-19.2002c0 -10.6006 -10 -19.2002 -22.4004 -19.2002h-179.199z" />
<glyph glyph-name="id-card" unicode="&#xf2c2;" horiz-adv-x="576"
d="M528 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-480c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h480zM528 16v288h-480v-288h32.7998c-1 4.5 -0.799805 -3.59961 -0.799805 22.4004c0 31.7998 30.0996 57.5996 67.2002 57.5996
c11.3994 0 17.8994 -8 44.7998 -8c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996c0 -26 0.0996094 -17.9004 -0.799805 -22.4004h224.8zM360 96c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16
c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 160c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 224c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112
c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM192 128c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64z" />
<glyph glyph-name="window-maximize" unicode="&#xf2d0;"
d="M464 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h416zM464 22v234h-416v-234c0 -3.2998 2.7002 -6 6 -6h404c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="window-minimize" unicode="&#xf2d1;"
d="M480 -32h-448c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32h448c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32z" />
<glyph glyph-name="window-restore" unicode="&#xf2d2;"
d="M464 448c26.5 0 48 -21.5 48 -48v-320c0 -26.5 -21.5 -48 -48 -48h-48v-48c0 -26.5 -21.5 -48 -48 -48h-320c-26.5 0 -48 21.5 -48 48v320c0 26.5 21.5 48 48 48h48v48c0 26.5 21.5 48 48 48h320zM368 -16v208h-320v-208h320zM464 80v320h-320v-48h224
c26.5 0 48 -21.5 48 -48v-224h48z" />
<glyph glyph-name="snowflake" unicode="&#xf2dc;" horiz-adv-x="448"
d="M440.1 92.7998c7.60059 -4.39941 10.1006 -14.2002 5.5 -21.7002l-7.89941 -13.8994c-4.40039 -7.7002 -14 -10.2998 -21.5 -5.90039l-39.2002 23l9.09961 -34.7002c2.30078 -8.5 -2.69922 -17.2998 -11.0996 -19.5996l-15.2002 -4.09961
c-8.39941 -2.30078 -17.0996 2.7998 -19.2998 11.2998l-21.2998 81l-71.9004 42.2002v-84.5l58.2998 -59.3008c6.10059 -6.19922 6.10059 -16.3994 0 -22.5996l-11.0996 -11.2998c-6.09961 -6.2002 -16.0996 -6.2002 -22.2002 0l-24.8994 25.3994v-46.0996
c0 -8.7998 -7 -16 -15.7002 -16h-15.7002c-8.7002 0 -15.7002 7.2002 -15.7002 16v45.9004l-24.8994 -25.4004c-6.10059 -6.2002 -16.1006 -6.2002 -22.2002 0l-11.1006 11.2998c-6.09961 6.2002 -6.09961 16.4004 0 22.6006l58.3008 59.2998v84.5l-71.9004 -42.2002
l-21.2998 -81c-2.2998 -8.5 -10.9004 -13.5996 -19.2998 -11.2998l-15.2002 4.09961c-8.40039 2.2998 -13.2998 11.1006 -11.1006 19.6006l9.10059 34.6992l-39.2002 -23c-7.5 -4.39941 -17.2002 -1.7998 -21.5 5.90039l-7.90039 13.9004
c-4.2998 7.69922 -1.69922 17.5 5.80078 21.8994l39.1992 23l-34.0996 9.2998c-8.40039 2.30078 -13.2998 11.1006 -11.0996 19.6006l4.09961 15.5c2.2998 8.5 10.9004 13.5996 19.2998 11.2998l79.7002 -21.7002l71.9004 42.2002l-71.9004 42.2002l-79.7002 -21.7002
c-8.39941 -2.2998 -17.0996 2.7998 -19.2998 11.2998l-4.09961 15.5c-2.30078 8.5 2.69922 17.2998 11.0996 19.6006l34.0996 9.09961l-39.1992 23c-7.60059 4.5 -10.1006 14.2002 -5.80078 21.9004l7.90039 13.8994c4.40039 7.7002 14 10.2998 21.5 5.90039l39.2002 -23
l-9.10059 34.7002c-2.2998 8.5 2.7002 17.2998 11.1006 19.5996l15.2002 4.09961c8.39941 2.30078 17.0996 -2.7998 19.2998 -11.2998l21.2998 -81l71.9004 -42.2002v84.5l-58.3008 59.3008c-6.09961 6.19922 -6.09961 16.3994 0 22.5996l11.5 11.2998
c6.10059 6.2002 16.1006 6.2002 22.2002 0l24.9004 -25.3994v46.0996c0 8.7998 7 16 15.7002 16h15.6992c8.7002 0 15.7002 -7.2002 15.7002 -16v-45.9004l24.9004 25.4004c6.09961 6.2002 16.0996 6.2002 22.2002 0l11.0996 -11.2998
c6.09961 -6.2002 6.09961 -16.4004 0 -22.6006l-58.2998 -59.2998v-84.5l71.8994 42.2002l21.3008 81c2.2998 8.5 10.8994 13.5996 19.2998 11.2998l15.2002 -4.09961c8.39941 -2.2998 13.2998 -11.1006 11.0996 -19.6006l-9.09961 -34.6992l39.1992 23
c7.5 4.39941 17.2002 1.7998 21.5 -5.90039l7.90039 -13.9004c4.2998 -7.69922 1.7002 -17.5 -5.7998 -21.8994l-39.2002 -23l34.0996 -9.2998c8.40039 -2.30078 13.3008 -11.1006 11.1006 -19.6006l-4.10059 -15.5c-2.2998 -8.5 -10.8994 -13.5996 -19.2998 -11.2998
l-79.7002 21.7002l-71.8994 -42.2002l71.7998 -42.2002l79.7002 21.7002c8.39941 2.2998 17.0996 -2.7998 19.2998 -11.2998l4.09961 -15.5c2.30078 -8.5 -2.69922 -17.2998 -11.0996 -19.6006l-34.0996 -9.2998z" />
<glyph glyph-name="trash-alt" unicode="&#xf2ed;" horiz-adv-x="448"
d="M268 32c-6.62305 0 -12 5.37695 -12 12v216c0 6.62305 5.37695 12 12 12h24c6.62305 0 12 -5.37695 12 -12v-216c0 -6.62305 -5.37695 -12 -12 -12h-24zM432 368c8.83105 0 16 -7.16895 16 -16v-16c0 -8.83105 -7.16895 -16 -16 -16h-16v-336
c0 -26.4922 -21.5078 -48 -48 -48h-288c-26.4922 0 -48 21.5078 -48 48v336h-16c-8.83105 0 -16 7.16895 -16 16v16c0 8.83105 7.16895 16 16 16h82.4102l34.0195 56.7002c8.39258 13.9844 23.6777 23.2998 41.1602 23.2998h100.82
c0.0078125 0 -0.015625 0.0517578 -0.0078125 0.0517578c17.4824 0 32.7949 -9.36719 41.1875 -23.3516l34 -56.7002h82.4102zM171.84 397.09l-17.4502 -29.0898h139.221l-17.46 29.0898c-1.0498 1.74707 -2.95898 2.91016 -5.14355 2.91016h-0.00683594h-94
c-0.00585938 0 -0.00683594 0.00683594 -0.0126953 0.00683594c-2.18457 0 -4.09766 -1.16992 -5.14746 -2.91699zM368 -16v336h-288v-336h288zM156 32c-6.62305 0 -12 5.37695 -12 12v216c0 6.62305 5.37695 12 12 12h24c6.62305 0 12 -5.37695 12 -12v-216
c0 -6.62305 -5.37695 -12 -12 -12h-24z" />
<glyph glyph-name="images" unicode="&#xf302;" horiz-adv-x="576"
d="M480 32v-16c0 -26.5098 -21.4902 -48 -48 -48h-384c-26.5098 0 -48 21.4902 -48 48v256c0 26.5098 21.4902 48 48 48h16v-48h-10c-3.31152 0 -6 -2.68848 -6 -6v-244c0 -3.31152 2.68848 -6 6 -6h372c3.31152 0 6 2.68848 6 6v10h48zM522 368h-372
c-3.31152 0 -6 -2.68848 -6 -6v-244c0 -3.31152 2.68848 -6 6 -6h372c3.31152 0 6 2.68848 6 6v244c0 3.31152 -2.68848 6 -6 6zM528 416c26.5098 0 48 -21.4902 48 -48v-256c0 -26.5098 -21.4902 -48 -48 -48h-384c-26.5098 0 -48 21.4902 -48 48v256
c0 26.5098 21.4902 48 48 48h384zM264 304c0 -22.0908 -17.9092 -40 -40 -40s-40 17.9092 -40 40s17.9092 40 40 40s40 -17.9092 40 -40zM192 208l39.5146 39.5146c4.68652 4.68652 12.2842 4.68652 16.9717 0l39.5137 -39.5146l103.515 103.515
c4.68652 4.68652 12.2842 4.68652 16.9717 0l71.5137 -71.5146v-80h-288v48z" />
<glyph glyph-name="clipboard" unicode="&#xf328;" horiz-adv-x="384"
d="M336 384c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h80c0 35.2998 28.7002 64 64 64s64 -28.7002 64 -64h80zM192 408c-13.2998 0 -24 -10.7002 -24 -24s10.7002 -24 24 -24s24 10.7002 24 24
s-10.7002 24 -24 24zM336 -10v340c0 3.2998 -2.7002 6 -6 6h-42v-36c0 -6.59961 -5.40039 -12 -12 -12h-168c-6.59961 0 -12 5.40039 -12 12v36h-42c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h276c3.2998 0 6 2.7002 6 6z" />
<glyph glyph-name="arrow-alt-circle-down" unicode="&#xf358;"
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM224 308c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-116
h67c10.7002 0 16.0996 -12.9004 8.5 -20.5l-99 -99c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-99 99c-7.5 7.59961 -2.2002 20.5 8.5 20.5h67v116z" />
<glyph glyph-name="arrow-alt-circle-left" unicode="&#xf359;"
d="M8 192c0 137 111 248 248 248s248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248zM456 192c0 110.5 -89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200s200 89.5 200 200zM384 212v-40c0 -6.59961 -5.40039 -12 -12 -12h-116v-67
c0 -10.7002 -12.9004 -16 -20.5 -8.5l-99 99c-4.7002 4.7002 -4.7002 12.2998 0 17l99 99c7.59961 7.59961 20.5 2.2002 20.5 -8.5v-67h116c6.59961 0 12 -5.40039 12 -12z" />
<glyph glyph-name="arrow-alt-circle-right" unicode="&#xf35a;"
d="M504 192c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248s248 -111 248 -248zM56 192c0 -110.5 89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200zM128 172v40c0 6.59961 5.40039 12 12 12h116v67
c0 10.7002 12.9004 16 20.5 8.5l99 -99c4.7002 -4.7002 4.7002 -12.2998 0 -17l-99 -99c-7.59961 -7.59961 -20.5 -2.2002 -20.5 8.5v67h-116c-6.59961 0 -12 5.40039 -12 12z" />
<glyph glyph-name="arrow-alt-circle-up" unicode="&#xf35b;"
d="M256 -56c-137 0 -248 111 -248 248s111 248 248 248s248 -111 248 -248s-111 -248 -248 -248zM256 392c-110.5 0 -200 -89.5 -200 -200s89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200zM276 64h-40c-6.59961 0 -12 5.40039 -12 12v116h-67
c-10.7002 0 -16 12.9004 -8.5 20.5l99 99c4.7002 4.7002 12.2998 4.7002 17 0l99 -99c7.59961 -7.59961 2.2002 -20.5 -8.5 -20.5h-67v-116c0 -6.59961 -5.40039 -12 -12 -12z" />
<glyph glyph-name="gem" unicode="&#xf3a5;" horiz-adv-x="576"
d="M464 448c4.09961 0 7.7998 -2 10.0996 -5.40039l99.9004 -147.199c2.90039 -4.40039 2.59961 -10.1006 -0.700195 -14.2002l-276 -340.8c-4.7998 -5.90039 -13.7998 -5.90039 -18.5996 0l-276 340.8c-3.2998 4 -3.60059 9.7998 -0.700195 14.2002l100 147.199
c2.2002 3.40039 6 5.40039 10 5.40039h352zM444.7 400h-56.7998l51.6992 -96h68.4004zM242.6 400l-51.5996 -96h194l-51.7002 96h-90.7002zM131.3 400l-63.2998 -96h68.4004l51.6992 96h-56.7998zM88.2998 256l119.7 -160l-68.2998 160h-51.4004zM191.2 256l96.7998 -243.3
l96.7998 243.3h-193.6zM368 96l119.6 160h-51.3994z" />
<glyph glyph-name="money-bill-alt" unicode="&#xf3d1;" horiz-adv-x="640"
d="M320 304c53.0195 0 96 -50.1396 96 -112c0 -61.8701 -43 -112 -96 -112c-53.0195 0 -96 50.1504 -96 112c0 61.8604 42.9805 112 96 112zM360 136v16c0 4.41992 -3.58008 8 -8 8h-16v88c0 4.41992 -3.58008 8 -8 8h-13.5801
c-4.91113 0 -9.50586 -1.49316 -13.3096 -4.03027l-15.3301 -10.2197c-2.15332 -1.43262 -3.55957 -3.88379 -3.55957 -6.66113c0 -1.6377 0.493164 -3.16113 1.33887 -4.42871l8.88086 -13.3105c1.43164 -2.15234 3.88379 -3.55957 6.66113 -3.55957
c1.6377 0 3.16016 0.494141 4.42871 1.33984l0.469727 0.310547v-55.4404h-16c-4.41992 0 -8 -3.58008 -8 -8v-16c0 -4.41992 3.58008 -8 8 -8h64c4.41992 0 8 3.58008 8 8zM608 384c17.6699 0 32 -14.3301 32 -32v-320c0 -17.6699 -14.3301 -32 -32 -32h-576
c-17.6699 0 -32 14.3301 -32 32v320c0 17.6699 14.3301 32 32 32h576zM592 112v160c-35.3496 0 -64 28.6504 -64 64h-416c0 -35.3496 -28.6504 -64 -64 -64v-160c35.3496 0 64 -28.6504 64 -64h416c0 35.3496 28.6504 64 64 64z" />
<glyph glyph-name="window-close" unicode="&#xf410;"
d="M464 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h416zM464 22v340c0 3.2998 -2.7002 6 -6 6h-404c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h404c3.2998 0 6 2.7002 6 6z
M356.5 253.4l-61.4004 -61.4004l61.4004 -61.4004c4.59961 -4.59961 4.59961 -12.0996 0 -16.7998l-22.2998 -22.2998c-4.60059 -4.59961 -12.1006 -4.59961 -16.7998 0l-61.4004 61.4004l-61.4004 -61.4004c-4.59961 -4.59961 -12.0996 -4.59961 -16.7998 0
l-22.2998 22.2998c-4.59961 4.60059 -4.59961 12.1006 0 16.7998l61.4004 61.4004l-61.4004 61.4004c-4.59961 4.59961 -4.59961 12.0996 0 16.7998l22.2998 22.2998c4.60059 4.59961 12.1006 4.59961 16.7998 0l61.4004 -61.4004l61.4004 61.4004
c4.59961 4.59961 12.0996 4.59961 16.7998 0l22.2998 -22.2998c4.7002 -4.60059 4.7002 -12.1006 0 -16.7998z" />
<glyph glyph-name="comment-dots" unicode="&#xf4ad;"
d="M144 240c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM256 240c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM368 240c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32
s-32 14.2998 -32 32s14.2998 32 32 32zM256 416c141.4 0 256 -93.0996 256 -208s-114.6 -208 -256 -208c-32.7998 0 -64 5.2002 -92.9004 14.2998c-29.0996 -20.5996 -77.5996 -46.2998 -139.1 -46.2998c-9.59961 0 -18.2998 5.7002 -22.0996 14.5
c-3.80078 8.7998 -2 19 4.59961 26c0.5 0.400391 31.5 33.7998 46.4004 73.2002c-33 35.0996 -52.9004 78.7002 -52.9004 126.3c0 114.9 114.6 208 256 208zM256 48c114.7 0 208 71.7998 208 160s-93.2998 160 -208 160s-208 -71.7998 -208 -160
c0 -42.2002 21.7002 -74.0996 39.7998 -93.4004l20.6006 -21.7998l-10.6006 -28.0996c-5.5 -14.5 -12.5996 -28.1006 -19.8994 -40.2002c23.5996 7.59961 43.1992 18.9004 57.5 29l19.5 13.7998l22.6992 -7.2002c25.3008 -8 51.7002 -12.0996 78.4004 -12.0996z" />
<glyph glyph-name="smile-wink" unicode="&#xf4da;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM365.8 138.4c10.2002 -8.5 11.6006 -23.6006 3.10059 -33.8008
c-30 -36 -74.1006 -56.5996 -120.9 -56.5996s-90.9004 20.5996 -120.9 56.5996c-8.39941 10.2002 -7.09961 25.3008 3.10059 33.8008c10.0996 8.39941 25.2998 7.09961 33.7998 -3.10059c20.7998 -25.0996 51.5 -39.3994 84 -39.3994s63.2002 14.3994 84 39.3994
c8.5 10.2002 23.5996 11.6006 33.7998 3.10059zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 268c25.7002 0 55.9004 -16.9004 59.7002 -42.0996c1.7998 -11.1006 -11.2998 -18.2002 -19.7998 -10.8008l-9.5 8.5
c-14.8008 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5c-8.30078 -7.39941 -21.5 -0.399414 -19.8008 10.8008c4 25.1992 34.2002 42.0996 59.9004 42.0996z" />
<glyph glyph-name="angry" unicode="&#xf556;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM248 136c33.5996 0 65.2002 -14.7998 86.7998 -40.5996
c8.40039 -10.2002 7.10059 -25.3008 -3.09961 -33.8008c-10.6006 -8.89941 -25.7002 -6.69922 -33.7998 3c-24.8008 29.7002 -75 29.7002 -99.8008 0c-8.5 -10.1992 -23.5996 -11.5 -33.7998 -3s-11.5996 23.6006 -3.09961 33.8008
c21.5996 25.7998 53.2002 40.5996 86.7998 40.5996zM200 208c0 -17.7002 -14.2998 -32.0996 -32 -32.0996s-32 14.2998 -32 32c0 6.19922 2.2002 11.6992 5.2998 16.5996l-28.2002 8.5c-12.6992 3.7998 -19.8994 17.2002 -16.0996 29.9004
c3.7998 12.6992 17.0996 20 29.9004 16.0996l80 -24c12.6992 -3.7998 19.8994 -17.2002 16.0996 -29.9004c-3.09961 -10.3994 -12.7002 -17.0996 -23 -17.0996zM399 262.9c3.7998 -12.7002 -3.40039 -26.1006 -16.0996 -29.8008l-28.2002 -8.5
c3.09961 -4.89941 5.2998 -10.3994 5.2998 -16.5996c0 -17.7002 -14.2998 -32 -32 -32s-32 14.2998 -32 32c-10.2998 0 -19.9004 6.7002 -23 17.0996c-3.7998 12.7002 3.40039 26.1006 16.0996 29.9004l80 24c12.8008 3.7998 26.1006 -3.40039 29.9004 -16.0996z" />
<glyph glyph-name="dizzy" unicode="&#xf567;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM214.2 209.9
c-7.90039 -7.90039 -20.5 -7.90039 -28.4004 -0.200195l-17.7998 17.7998l-17.7998 -17.7998c-7.7998 -7.7998 -20.5 -7.7998 -28.2998 0c-7.80078 7.7998 -7.80078 20.5 0 28.2998l17.8994 17.9004l-17.8994 17.8994c-7.80078 7.7998 -7.80078 20.5 0 28.2998
c7.7998 7.80078 20.5 7.80078 28.2998 0l17.7998 -17.7998l17.9004 17.9004c7.7998 7.7998 20.5 7.7998 28.2998 0s7.7998 -20.5 0 -28.2998l-17.9004 -17.9004l17.9004 -17.7998c7.7998 -7.7998 7.7998 -20.5 0 -28.2998zM374.2 302.1
c7.7002 -7.7998 7.7002 -20.3994 0 -28.1992l-17.9004 -17.9004l17.7998 -18c7.80078 -7.7998 7.80078 -20.5 0 -28.2998c-7.7998 -7.7998 -20.5 -7.7998 -28.2998 0l-17.7998 17.7998l-17.7998 -17.7998c-7.7998 -7.7998 -20.5 -7.7998 -28.2998 0
c-7.80078 7.7998 -7.80078 20.5 0 28.2998l17.8994 17.9004l-17.8994 17.8994c-7.80078 7.7998 -7.80078 20.5 0 28.2998c7.7998 7.80078 20.5 7.80078 28.2998 0l17.7998 -17.7998l17.9004 17.7998c7.7998 7.80078 20.5 7.80078 28.2998 0zM248 176
c35.2998 0 64 -28.7002 64 -64s-28.7002 -64 -64 -64s-64 28.7002 -64 64s28.7002 64 64 64z" />
<glyph glyph-name="flushed" unicode="&#xf579;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM344 304c44.2002 0 80 -35.7998 80 -80s-35.7998 -80 -80 -80
s-80 35.7998 -80 80s35.7998 80 80 80zM344 176c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM344 248c13.2998 0 24 -10.7002 24 -24s-10.7002 -24 -24 -24s-24 10.7002 -24 24s10.7002 24 24 24zM232 224c0 -44.2002 -35.7998 -80 -80 -80
s-80 35.7998 -80 80s35.7998 80 80 80s80 -35.7998 80 -80zM152 176c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM152 248c13.2998 0 24 -10.7002 24 -24s-10.7002 -24 -24 -24s-24 10.7002 -24 24s10.7002 24 24 24zM312 104
c13.2002 0 24 -10.7998 24 -24s-10.7998 -24 -24 -24h-128c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24h128z" />
<glyph glyph-name="frown-open" unicode="&#xf57a;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM200 240c0 -17.7002 -14.2998 -32 -32 -32s-32 14.2998 -32 32
s14.2998 32 32 32s32 -14.2998 32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM248 160c35.5996 0 88.7998 -21.2998 95.7998 -61.2002c2 -11.7998 -9.09961 -21.5996 -20.5 -18.0996
c-31.2002 9.59961 -59.3994 15.2998 -75.2998 15.2998s-44.0996 -5.7002 -75.2998 -15.2998c-11.5 -3.40039 -22.5 6.2998 -20.5 18.0996c7 39.9004 60.2002 61.2002 95.7998 61.2002z" />
<glyph glyph-name="grimace" unicode="&#xf57f;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM344 192c26.5 0 48 -21.5 48 -48v-32c0 -26.5 -21.5 -48 -48 -48h-192c-26.5 0 -48 21.5 -48 48v32c0 26.5 21.5 48 48 48
h192zM176 96v24h-40v-8c0 -8.7998 7.2002 -16 16 -16h24zM176 136v24h-24c-8.7998 0 -16 -7.2002 -16 -16v-8h40zM240 96v24h-48v-24h48zM240 136v24h-48v-24h48zM304 96v24h-48v-24h48zM304 136v24h-48v-24h48zM360 112v8h-40v-24h24c8.7998 0 16 7.2002 16 16zM360 136v8
c0 8.7998 -7.2002 16 -16 16h-24v-24h40z" />
<glyph glyph-name="grin" unicode="&#xf580;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.9004 -123.3 80c-1.7002 9.90039 7.7998 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32z" />
<glyph glyph-name="grin-alt" unicode="&#xf581;" horiz-adv-x="496"
d="M200.3 200c-7.5 -11.4004 -24.5996 -12 -32.7002 0c-12.3994 18.7002 -15.1992 37.2998 -15.6992 56c0.599609 18.7002 3.2998 37.2998 15.6992 56c7.60059 11.4004 24.7002 12 32.7002 0c12.4004 -18.7002 15.2002 -37.2998 15.7002 -56
c-0.599609 -18.7002 -3.2998 -37.2998 -15.7002 -56zM328.3 200c-7.5 -11.4004 -24.5996 -12 -32.7002 0c-12.3994 18.7002 -15.1992 37.2998 -15.6992 56c0.599609 18.7002 3.2998 37.2998 15.6992 56c7.60059 11.4004 24.7002 12 32.7002 0
c12.4004 -18.7002 15.2002 -37.2998 15.7002 -56c-0.599609 -18.7002 -3.2998 -37.2998 -15.7002 -56zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200
s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.8008 -123.3 80c-1.7002 10 7.7998 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006
s79.7002 4.7998 105.6 13.1006z" />
<glyph glyph-name="grin-beam" unicode="&#xf582;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.9004 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM117.7 216.3c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998
c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996
l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002zM277.7 216.3c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998
c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002z" />
<glyph glyph-name="grin-beam-sweat" unicode="&#xf583;" horiz-adv-x="496"
d="M440 288c-29.5 0 -53.2998 26.2998 -53.2998 58.7002c0 25 31.7002 75.5 46.2002 97.2998c3.5 5.2998 10.5996 5.2998 14.1992 0c14.5 -21.7998 46.2002 -72.2998 46.2002 -97.2998c0 -32.4004 -23.7998 -58.7002 -53.2998 -58.7002zM248 48
c-51.9004 0 -115.3 32.9004 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-8 -47.0996 -71.3994 -80 -123.3 -80zM378.3 216.3
c-3.09961 -0.899414 -7.2002 0.100586 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998
c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998zM483.6 269.2c8 -24.2998 12.4004 -50.2002 12.4004 -77.2002c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248
c45.7002 0 88.4004 -12.5996 125.2 -34.2002c-10.9004 -21.5996 -15.5 -36.2002 -17.2002 -45.7002c-31.2002 20.1006 -68.2002 31.9004 -108 31.9004c-110.3 0 -200 -89.7002 -200 -200s89.7002 -200 200 -200s200 89.7002 200 200
c0 22.5 -3.90039 44.0996 -10.7998 64.2998c0.399414 0 21.7998 -2.7998 46.3994 12.9004zM168 258.6c-12.2998 0 -23.7998 -7.7998 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998
c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996z" />
<glyph glyph-name="grin-hearts" unicode="&#xf584;" horiz-adv-x="496"
d="M353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.8008 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM200.8 192.3
l-70.2002 18.1006c-20.3994 5.2998 -31.8994 27 -24.1992 47.1992c6.69922 17.7002 26.6992 26.7002 44.8994 22l7.10059 -1.89941l2 7.09961c5.09961 18.1006 22.8994 30.9004 41.5 27.9004c21.3994 -3.40039 34.3994 -24.2002 28.7998 -44.5l-19.4004 -69.9004
c-1.2998 -4.5 -6 -7.2002 -10.5 -6zM389.6 257.6c7.7002 -20.1992 -3.7998 -41.7998 -24.1992 -47.0996l-70.2002 -18.2002c-4.60059 -1.2002 -9.2998 1.5 -10.5 6l-19.4004 69.9004c-5.59961 20.2998 7.40039 41.0996 28.7998 44.5c18.7002 3 36.5 -9.7998 41.5 -27.9004
l2 -7.09961l7.10059 1.89941c18.2002 4.7002 38.2002 -4.39941 44.8994 -22zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200
s89.7002 -200 200 -200z" />
<glyph glyph-name="grin-squint" unicode="&#xf585;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.9004 -123.3 80c-1.7002 9.90039 7.7998 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM118.9 184.2c-3.80078 4.39941 -3.90039 11 -0.100586 15.5l33.6006 40.2998
l-33.6006 40.2998c-3.7002 4.5 -3.7002 11 0.100586 15.5c3.89941 4.40039 10.1992 5.5 15.2998 2.5l80 -48c3.59961 -2.2002 5.7998 -6.09961 5.7998 -10.2998s-2.2002 -8.09961 -5.7998 -10.2998l-80 -48c-5.40039 -3.2002 -11.7002 -1.7002 -15.2998 2.5zM361.8 181.7
l-80 48c-3.59961 2.2002 -5.7998 6.09961 -5.7998 10.2998s2.2002 8.09961 5.7998 10.2998l80 48c5.10059 2.90039 11.5 1.90039 15.2998 -2.5c3.80078 -4.5 3.90039 -11 0.100586 -15.5l-33.6006 -40.2998l33.6006 -40.2998c3.7002 -4.5 3.7002 -11 -0.100586 -15.5
c-3.59961 -4.2002 -9.89941 -5.7002 -15.2998 -2.5z" />
<glyph glyph-name="grin-squint-tears" unicode="&#xf586;"
d="M117.1 63.9004c6.30078 0.899414 11.7002 -4.5 10.9004 -10.9004c-3.7002 -25.7998 -13.7002 -84 -30.5996 -100.9c-22 -21.8994 -57.9004 -21.5 -80.3008 0.900391c-22.3994 22.4004 -22.7998 58.4004 -0.899414 80.2998
c16.8994 16.9004 75.0996 26.9004 100.899 30.6006zM75.9004 105.6c-19.6006 -3.89941 -35.1006 -8.09961 -47.3008 -12.1992c-39.2998 90.5996 -22.0996 199.899 52 274c48.5 48.3994 111.9 72.5996 175.4 72.5996c38.9004 0 77.7998 -9.2002 113.2 -27.4004
c-4 -12.1992 -8.2002 -28 -12 -48.2998c-30.4004 17.9004 -65 27.7002 -101.2 27.7002c-53.4004 0 -103.6 -20.7998 -141.4 -58.5996c-61.5996 -61.5 -74.2998 -153.4 -38.6992 -227.801zM428.2 293.2c20.2998 3.89941 36.2002 8 48.5 12
c47.8994 -93.2002 32.8994 -210.5 -45.2002 -288.601c-48.5 -48.3994 -111.9 -72.5996 -175.4 -72.5996c-33.6992 0 -67.2998 7 -98.6992 20.5996c4.19922 12.2002 8.2998 27.7002 12.1992 47.2002c26.6006 -12.7998 55.9004 -19.7998 86.4004 -19.7998
c53.4004 0 103.6 20.7998 141.4 58.5996c65.6992 65.7002 75.7998 166 30.7998 242.601zM394.9 320.1c-6.30078 -0.899414 -11.7002 4.5 -10.9004 10.9004c3.7002 25.7998 13.7002 84 30.5996 100.9c22 21.8994 57.9004 21.5 80.3008 -0.900391
c22.3994 -22.4004 22.7998 -58.4004 0.899414 -80.2998c-16.8994 -16.9004 -75.0996 -26.9004 -100.899 -30.6006zM207.9 211.8c3 -3 4.19922 -7.2998 3.19922 -11.5l-22.5996 -90.5c-1.40039 -5.39941 -6.2002 -9.09961 -11.7002 -9.09961h-0.899414
c-5.80078 0.5 -10.5 5.09961 -11 10.8994l-4.80078 52.3008l-52.2998 4.7998c-5.7998 0.5 -10.3994 5.2002 -10.8994 11c-0.400391 5.89941 3.39941 11.2002 9.09961 12.5996l90.5 22.7002c4.2002 1 8.40039 -0.200195 11.4004 -3.2002zM247.6 236.9
c-0.0996094 0 -6.39941 -1.80078 -11.3994 3.19922c-3 3 -4.2002 7.30078 -3.2002 11.4004l22.5996 90.5c1.40039 5.7002 7 9.2002 12.6006 9.09961c5.7998 -0.5 10.5 -5.09961 11 -10.8994l4.7998 -52.2998l52.2998 -4.80078c5.7998 -0.5 10.4004 -5.19922 10.9004 -11
c0.399414 -5.89941 -3.40039 -11.1992 -9.10059 -12.5996zM299.6 148.4c29.1006 29.0996 53 59.5996 65.3008 83.7998c4.89941 9.2998 17.5996 9.89941 23.3994 1.7002c27.7002 -38.9004 6.10059 -106.9 -30.5996 -143.7s-104.8 -58.2998 -143.7 -30.6006
c-8.2998 5.90039 -7.5 18.6006 1.7002 23.4004c24.2002 12.5 54.7998 36.2998 83.8994 65.4004z" />
<glyph glyph-name="grin-stars" unicode="&#xf587;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.8008 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM125.7 200.9l6.09961 34.8994l-25.3994 24.6006
c-4.60059 4.59961 -1.90039 12.2998 4.2998 13.1992l34.8994 5l15.5 31.6006c2.90039 5.7998 11 5.7998 13.9004 0l15.5 -31.6006l34.9004 -5c6.19922 -1 8.7998 -8.69922 4.2998 -13.1992l-25.4004 -24.6006l6 -34.8994c1 -6.2002 -5.39941 -11 -11 -7.90039
l-31.2998 16.2998l-31.2998 -16.2998c-5.60059 -3.09961 -12 1.7002 -11 7.90039zM385.4 273.6c6.19922 -1 8.89941 -8.59961 4.39941 -13.1992l-25.3994 -24.6006l6 -34.8994c1 -6.2002 -5.40039 -11 -11 -7.90039l-31.3008 16.2998l-31.2998 -16.2998
c-5.59961 -3.09961 -12 1.7002 -11 7.90039l6 34.8994l-25.3994 24.6006c-4.60059 4.59961 -1.90039 12.2998 4.2998 13.1992l34.8994 5l15.5 31.6006c2.90039 5.7998 11 5.7998 13.9004 0l15.5 -31.6006z" />
<glyph glyph-name="grin-tears" unicode="&#xf588;" horiz-adv-x="640"
d="M117.1 191.9c6.30078 0.899414 11.7002 -4.5 10.9004 -10.9004c-3.7002 -25.7998 -13.7002 -84 -30.5996 -100.9c-22 -21.8994 -57.9004 -21.5 -80.3008 0.900391c-22.3994 22.4004 -22.7998 58.4004 -0.899414 80.2998c16.8994 16.9004 75.0996 26.9004 100.899 30.6006
zM623.8 161.3c21.9004 -21.8994 21.5 -57.8994 -0.799805 -80.2002c-22.4004 -22.3994 -58.4004 -22.7998 -80.2998 -0.899414c-16.9004 16.8994 -26.9004 75.0996 -30.6006 100.899c-0.899414 6.30078 4.5 11.7002 10.8008 10.8008
c25.7998 -3.7002 84 -13.7002 100.899 -30.6006zM497.2 99.5996c12.3994 -37.2998 25.0996 -43.7998 28.2998 -46.5c-44.5996 -65.7998 -120 -109.1 -205.5 -109.1s-160.9 43.2998 -205.5 109.1c3.09961 2.60059 15.7998 9.10059 28.2998 46.5
c33.4004 -63.8994 100.3 -107.6 177.2 -107.6s143.8 43.7002 177.2 107.6zM122.7 223.5c-2.40039 0.299805 -5 2.5 -49.5 -6.90039c12.3994 125.4 118.1 223.4 246.8 223.4s234.4 -98 246.8 -223.5c-44.2998 9.40039 -47.3994 7.2002 -49.5 7
c-15.2002 95.2998 -97.7998 168.5 -197.3 168.5s-182.1 -73.2002 -197.3 -168.5zM320 48c-51.9004 0 -115.3 32.9004 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996s79.7002 4.7998 105.6 13.0996
c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-8 -47.0996 -71.3994 -80 -123.3 -80zM450.3 216.3c-3.09961 -0.899414 -7.2002 0.100586 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17
c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998zM240 258.6
c-12.2998 0 -23.7998 -7.7998 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004
c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996z" />
<glyph glyph-name="grin-tongue" unicode="&#xf589;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM312 40h0.0996094v43.7998l-17.6992 8.7998c-15.1006 7.60059 -31.5 -1.69922 -34.9004 -16.5l-2.7998 -12.0996c-2.10059 -9.2002 -15.2002 -9.2002 -17.2998 0
l-2.80078 12.0996c-3.39941 14.8008 -19.8994 24 -34.8994 16.5l-17.7002 -8.7998v-42.7998c0 -35.2002 28 -64.5 63.0996 -65c35.8008 -0.5 64.9004 28.4004 64.9004 64zM340.2 14.7002c64 33.3994 107.8 100.3 107.8 177.3c0 110.3 -89.7002 200 -200 200
s-200 -89.7002 -200 -200c0 -77 43.7998 -143.9 107.8 -177.3c-2.2002 8.09961 -3.7998 16.5 -3.7998 25.2998v43.5c-14.2002 12.4004 -24.4004 27.5 -27.2998 44.5c-1.7002 10 7.7998 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996
s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-2.89941 -17 -13.0996 -32.0996 -27.2998 -44.5v-43.5c0 -8.7998 -1.59961 -17.2002 -3.7998 -25.2998zM168 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32
s14.2998 32 32 32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z" />
<glyph glyph-name="grin-tongue-squint" unicode="&#xf58a;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM312 40h0.0996094v43.7998l-17.6992 8.7998c-15.1006 7.60059 -31.5 -1.69922 -34.9004 -16.5l-2.7998 -12.0996c-2.10059 -9.2002 -15.2002 -9.2002 -17.2998 0
l-2.80078 12.0996c-3.39941 14.8008 -19.8994 24 -34.8994 16.5l-17.7002 -8.7998v-42.7998c0 -35.2002 28 -64.5 63.0996 -65c35.8008 -0.5 64.9004 28.4004 64.9004 64zM340.2 14.7002c64 33.3994 107.8 100.3 107.8 177.3c0 110.3 -89.7002 200 -200 200
s-200 -89.7002 -200 -200c0 -77 43.7998 -143.9 107.8 -177.3c-2.2002 8.09961 -3.7998 16.5 -3.7998 25.2998v43.5c-14.2002 12.4004 -24.4004 27.5 -27.2998 44.5c-1.7002 10 7.7998 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996
s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-2.89941 -17 -13.0996 -32.0996 -27.2998 -44.5v-43.5c0 -8.7998 -1.59961 -17.2002 -3.7998 -25.2998zM377.1 295.8c3.80078 -4.39941 3.90039 -11 0.100586 -15.5l-33.6006 -40.2998
l33.6006 -40.2998c3.7002 -4.5 3.7002 -11 -0.100586 -15.5c-3.59961 -4.2002 -9.89941 -5.7002 -15.2998 -2.5l-80 48c-3.59961 2.2002 -5.7998 6.09961 -5.7998 10.2998s2.2002 8.09961 5.7998 10.2998l80 48c5 3 11.5 1.90039 15.2998 -2.5zM214.2 250.3
c3.59961 -2.2002 5.7998 -6.09961 5.7998 -10.2998s-2.2002 -8.09961 -5.7998 -10.2998l-80 -48c-5.40039 -3.2002 -11.7002 -1.7002 -15.2998 2.5c-3.80078 4.5 -3.90039 11 -0.100586 15.5l33.6006 40.2998l-33.6006 40.2998c-3.7002 4.5 -3.7002 11 0.100586 15.5
c3.89941 4.5 10.2998 5.5 15.2998 2.5z" />
<glyph glyph-name="grin-tongue-wink" unicode="&#xf58b;" horiz-adv-x="496"
d="M152 268c25.7002 0 55.9004 -16.9004 59.7998 -42.0996c0.799805 -5 -1.7002 -10 -6.09961 -12.4004c-5.7002 -3.09961 -11.2002 -0.599609 -13.7002 1.59961l-9.5 8.5c-14.7998 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5
c-3.7998 -3.39941 -9.2998 -4 -13.7002 -1.59961c-4.39941 2.40039 -6.89941 7.40039 -6.09961 12.4004c3.89941 25.1992 34.0996 42.0996 59.7998 42.0996zM328 320c44.2002 0 80 -35.7998 80 -80s-35.7998 -80 -80 -80s-80 35.7998 -80 80s35.7998 80 80 80zM328 192
c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM328 264c13.2998 0 24 -10.7002 24 -24s-10.7002 -24 -24 -24s-24 10.7002 -24 24s10.7002 24 24 24zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248z
M312 40h0.0996094v43.7998l-17.6992 8.7998c-15.1006 7.60059 -31.5 -1.69922 -34.9004 -16.5l-2.7998 -12.0996c-2.10059 -9.2002 -15.2002 -9.2002 -17.2998 0l-2.80078 12.0996c-3.39941 14.8008 -19.8994 24 -34.8994 16.5l-17.7002 -8.7998v-42.7998
c0 -35.2002 28 -64.5 63.0996 -65c35.8008 -0.5 64.9004 28.4004 64.9004 64zM340.2 14.7002c64 33.3994 107.8 100.3 107.8 177.3c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200c0 -77 43.7998 -143.9 107.8 -177.3
c-2.2002 8.09961 -3.7998 16.5 -3.7998 25.2998v43.5c-14.2002 12.4004 -24.4004 27.5 -27.2998 44.5c-1.7002 10 7.7998 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998
c-2.89941 -17 -13.0996 -32.0996 -27.2998 -44.5v-43.5c0 -8.7998 -1.59961 -17.2002 -3.7998 -25.2998z" />
<glyph glyph-name="grin-wink" unicode="&#xf58c;" horiz-adv-x="496"
d="M328 268c25.6904 0 55.8799 -16.9199 59.8701 -42.1201c1.72949 -11.0898 -11.3506 -18.2695 -19.8301 -10.8398l-9.5498 8.47949c-14.8105 13.1904 -46.1602 13.1904 -60.9707 0l-9.5498 -8.47949c-8.33008 -7.40039 -21.5801 -0.379883 -19.8301 10.8398
c3.98047 25.2002 34.1699 42.1201 59.8604 42.1201zM168 208c-17.6699 0 -32 14.3301 -32 32s14.3301 32 32 32s32 -14.3301 32 -32s-14.3301 -32 -32 -32zM353.55 143.36c10.04 3.13965 19.3906 -5.4502 17.71 -15.3408
c-7.92969 -47.1494 -71.3193 -80.0195 -123.26 -80.0195s-115.33 32.8701 -123.26 80.0195c-1.69043 9.9707 7.76953 18.4707 17.71 15.3408c25.9297 -8.31055 64.3994 -13.0605 105.55 -13.0605s79.6201 4.75977 105.55 13.0605zM248 440c136.97 0 248 -111.03 248 -248
s-111.03 -248 -248 -248s-248 111.03 -248 248s111.03 248 248 248zM248 -8c110.28 0 200 89.7197 200 200s-89.7197 200 -200 200s-200 -89.7197 -200 -200s89.7197 -200 200 -200z" />
<glyph glyph-name="kiss" unicode="&#xf596;" horiz-adv-x="496"
d="M168 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM304 140c0 -13 -13.4004 -27.2998 -35.0996 -36.4004c21.7998 -8.69922 35.1992 -23 35.1992 -36c0 -19.1992 -28.6992 -41.5 -71.5 -44h-0.5
c-3.69922 0 -7 2.60059 -7.7998 6.2002c-0.899414 3.7998 1.10059 7.7002 4.7002 9.2002l17 7.2002c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.2002c-6 2.59961 -5.7002 12.3994 0 14.7998l17 7.2002
c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.19922c-3.59961 1.5 -5.59961 5.40039 -4.7002 9.2002c0.799805 3.7998 4.40039 6.60059 8.2002 6.2002c42.7002 -2.5 71.5 -24.7998 71.5 -44zM248 440c137 0 248 -111 248 -248
s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z
" />
<glyph glyph-name="kiss-beam" unicode="&#xf597;" horiz-adv-x="496"
d="M168 296c23.7998 0 52.7002 -29.2998 55.7998 -71.4004c0.299805 -3.7998 -2 -7.19922 -5.59961 -8.2998c-3.10059 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996c-12.3008 0 -23.8008 -7.89941 -31.5 -21.5996l-9.5 -17
c-1.80078 -3.2002 -5.80078 -4.7002 -9.30078 -3.7002c-3.59961 1.10059 -5.89941 4.60059 -5.59961 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8
c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM304 140c0 -13 -13.4004 -27.2998 -35.0996 -36.4004c21.7998 -8.69922 35.1992 -23 35.1992 -36c0 -19.1992 -28.6992 -41.5 -71.5 -44h-0.5
c-3.69922 0 -7 2.60059 -7.7998 6.2002c-0.899414 3.7998 1.10059 7.7002 4.7002 9.2002l17 7.2002c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.2002c-6 2.59961 -5.7002 12.3994 0 14.7998l17 7.2002
c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.19922c-3.59961 1.5 -5.59961 5.40039 -4.7002 9.2002c0.799805 3.7998 4.40039 6.60059 8.2002 6.2002c42.7002 -2.5 71.5 -24.7998 71.5 -44zM328 296
c23.7998 0 52.7002 -29.2998 55.7998 -71.4004c0.299805 -3.7998 -2 -7.19922 -5.59961 -8.2998c-3.10059 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996c-12.3008 0 -23.8008 -7.89941 -31.5 -21.5996l-9.5 -17
c-1.80078 -3.2002 -5.80078 -4.7002 -9.30078 -3.7002c-3.59961 1.10059 -5.89941 4.60059 -5.59961 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004z" />
<glyph glyph-name="kiss-wink-heart" unicode="&#xf598;" horiz-adv-x="504"
d="M304 139.5c0 -13 -13.4004 -27.2998 -35.0996 -36.4004c21.7998 -8.69922 35.1992 -23 35.1992 -36c0 -19.1992 -28.6992 -41.5 -71.5 -44h-0.5c-3.69922 0 -7 2.60059 -7.7998 6.2002c-0.899414 3.7998 1.10059 7.7002 4.7002 9.2002l17 7.2002
c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.2002c-6 2.59961 -5.7002 12.3994 0 14.7998l17 7.2002c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.19922c-3.59961 1.5 -5.59961 5.40039 -4.7002 9.2002
c0.799805 3.7998 4.40039 6.60059 8.2002 6.2002c42.7002 -2.5 71.5 -24.7998 71.5 -44zM374.5 223c-14.7998 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5c-2.5 -2.2998 -7.90039 -4.7002 -13.7002 -1.59961c-4.39941 2.39941 -6.89941 7.39941 -6.09961 12.3994
c3.89941 25.2002 34.2002 42.1006 59.7998 42.1006s55.7998 -16.9004 59.7998 -42.1006c0.799805 -5 -1.7002 -10 -6.09961 -12.3994c-4.40039 -2.40039 -9.90039 -1.7002 -13.7002 1.59961zM136 239.5c0 17.7002 14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32
s-32 14.2998 -32 32zM501.1 45.5c9.2002 -23.9004 -4.39941 -49.4004 -28.5 -55.7002l-83 -21.5c-5.39941 -1.39941 -10.8994 1.7998 -12.3994 7.10059l-22.9004 82.5996c-6.59961 24 8.7998 48.5996 34 52.5996c22 3.5 43.1006 -11.5996 49 -33l2.2998 -8.39941
l8.40039 2.2002c21.5996 5.59961 45.0996 -5.10059 53.0996 -25.9004zM334 11.7002c17.7002 -64 10.9004 -39.5 13.4004 -46.7998c-30.5 -13.4004 -64 -20.9004 -99.4004 -20.9004c-137 0 -248 111 -248 248s111 248 248 248s248 -111 247.9 -248
c0 -31.7998 -6.2002 -62.0996 -17.1006 -90c-6 1.5 -12.2002 2.7998 -18.5996 2.90039c-5.60059 9.69922 -13.6006 17.5 -22.6006 23.8994c6.7002 19.9004 10.4004 41.1006 10.4004 63.2002c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200
c30.7998 0 59.9004 7.2002 86 19.7002z" />
<glyph glyph-name="laugh" unicode="&#xf599;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM328 224c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM168 224
c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM362.4 160c8.19922 0 14.5 -7 13.5 -15c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
<glyph glyph-name="laugh-beam" unicode="&#xf59a;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM328 296c23.7998 0 52.7002 -29.2998 55.7998 -71.4004c0.700195 -8.5 -10.7998 -11.8994 -14.8994 -4.5
l-9.5 17c-7.7002 13.7002 -19.2002 21.6006 -31.5 21.6006c-12.3008 0 -23.8008 -7.90039 -31.5 -21.6006l-9.5 -17c-4.10059 -7.39941 -15.6006 -4.09961 -14.9004 4.5c3.2998 42.1006 32.2002 71.4004 56 71.4004zM127 220.1c-4.2002 -7.39941 -15.7002 -4 -15.0996 4.5
c3.2998 42.1006 32.1992 71.4004 56 71.4004c23.7998 0 52.6992 -29.2998 56 -71.4004c0.699219 -8.5 -10.8008 -11.8994 -14.9004 -4.5l-9.5 17c-7.7002 13.7002 -19.2002 21.6006 -31.5 21.6006s-23.7998 -7.90039 -31.5 -21.6006zM362.4 160c8.19922 0 14.5 -7 13.5 -15
c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
<glyph glyph-name="laugh-squint" unicode="&#xf59b;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM343.6 252l33.6006 -40.2998c8.59961 -10.4004 -3.90039 -24.7998 -15.4004 -18l-80 48
c-7.7998 4.7002 -7.7998 15.8994 0 20.5996l80 48c11.6006 6.7998 24 -7.7002 15.4004 -18zM134.2 193.7c-11.6006 -6.7998 -24.1006 7.59961 -15.4004 18l33.6006 40.2998l-33.6006 40.2998c-8.59961 10.2998 3.7998 24.9004 15.4004 18l80 -48
c7.7998 -4.7002 7.7998 -15.8994 0 -20.5996zM362.4 160c8.19922 0 14.5 -7 13.5 -15c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
<glyph glyph-name="laugh-wink" unicode="&#xf59c;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM328 284c25.7002 0 55.9004 -16.9004 59.7002 -42.0996c1.7998 -11.1006 -11.2998 -18.2002 -19.7998 -10.8008
l-9.5 8.5c-14.8008 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5c-8.30078 -7.39941 -21.5 -0.399414 -19.8008 10.8008c4 25.1992 34.2002 42.0996 59.9004 42.0996zM168 224c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32z
M362.4 160c8.19922 0 14.5 -7 13.5 -15c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
<glyph glyph-name="meh-blank" unicode="&#xf5a4;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32
s-32 14.2998 -32 32s14.2998 32 32 32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z" />
<glyph glyph-name="meh-rolling-eyes" unicode="&#xf5a5;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM336 296c39.7998 0 72 -32.2002 72 -72s-32.2002 -72 -72 -72
s-72 32.2002 -72 72s32.2002 72 72 72zM336 184c22.0996 0 40 17.9004 40 40c0 13.5996 -7.2998 25.0996 -17.7002 32.2998c1 -2.59961 1.7002 -5.39941 1.7002 -8.2998c0 -13.2998 -10.7002 -24 -24 -24s-24 10.7002 -24 24c0 3 0.700195 5.7002 1.7002 8.2998
c-10.4004 -7.2002 -17.7002 -18.7002 -17.7002 -32.2998c0 -22.0996 17.9004 -40 40 -40zM232 224c0 -39.7998 -32.2002 -72 -72 -72s-72 32.2002 -72 72s32.2002 72 72 72s72 -32.2002 72 -72zM120 224c0 -22.0996 17.9004 -40 40 -40s40 17.9004 40 40
c0 13.5996 -7.2998 25.0996 -17.7002 32.2998c1 -2.59961 1.7002 -5.39941 1.7002 -8.2998c0 -13.2998 -10.7002 -24 -24 -24s-24 10.7002 -24 24c0 3 0.700195 5.7002 1.7002 8.2998c-10.4004 -7.2002 -17.7002 -18.7002 -17.7002 -32.2998zM312 96
c13.2002 0 24 -10.7998 24 -24s-10.7998 -24 -24 -24h-128c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24h128z" />
<glyph glyph-name="sad-cry" unicode="&#xf5b3;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM392 53.5996c34.5996 35.9004 56 84.7002 56 138.4c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200c0 -53.7002 21.4004 -102.4 56 -138.4v114.4
c0 13.2002 10.7998 24 24 24s24 -10.7998 24 -24v-151.4c28.5 -15.5996 61.2002 -24.5996 96 -24.5996s67.5 9 96 24.5996v151.4c0 13.2002 10.7998 24 24 24s24 -10.7998 24 -24v-114.4zM205.8 213.5c-5.7998 -3.2002 -11.2002 -0.700195 -13.7002 1.59961l-9.5 8.5
c-14.7998 13.2002 -46.1992 13.2002 -61 0l-9.5 -8.5c-3.7998 -3.39941 -9.2998 -4 -13.6992 -1.59961c-4.40039 2.40039 -6.90039 7.40039 -6.10059 12.4004c3.90039 25.1992 34.2002 42.0996 59.7998 42.0996c25.6006 0 55.8008 -16.9004 59.8008 -42.0996
c0.799805 -5 -1.7002 -10 -6.10059 -12.4004zM344 268c25.7002 0 55.9004 -16.9004 59.7998 -42.0996c0.799805 -5 -1.7002 -10 -6.09961 -12.4004c-5.7002 -3.09961 -11.2002 -0.599609 -13.7002 1.59961l-9.5 8.5c-14.7998 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5
c-3.7998 -3.39941 -9.2002 -4 -13.7002 -1.59961c-4.39941 2.40039 -6.89941 7.40039 -6.09961 12.4004c3.89941 25.1992 34.0996 42.0996 59.7998 42.0996zM248 176c30.9004 0 56 -28.7002 56 -64s-25.0996 -64 -56 -64s-56 28.7002 -56 64s25.0996 64 56 64z" />
<glyph glyph-name="sad-tear" unicode="&#xf5b4;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM256 144c38.0996 0 74 -16.7998 98.5 -46.0996
c8.5 -10.2002 7.09961 -25.3008 -3.09961 -33.8008c-10.6006 -8.7998 -25.7002 -6.69922 -33.8008 3.10059c-15.2998 18.2998 -37.7998 28.7998 -61.5996 28.7998c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM162.4 173.2c2.7998 3.7002 8.39941 3.7002 11.1992 0c11.4004 -15.2998 36.4004 -50.6006 36.4004 -68.1006
c0 -22.6992 -18.7998 -41.0996 -42 -41.0996s-42 18.4004 -42 41.0996c0 17.5 25 52.8008 36.4004 68.1006z" />
<glyph glyph-name="smile-beam" unicode="&#xf5b8;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM332 135.4c8.5 10.1992 23.5996 11.5 33.7998 3.09961
c10.2002 -8.5 11.6006 -23.5996 3.10059 -33.7998c-30 -36 -74.1006 -56.6006 -120.9 -56.6006s-90.9004 20.6006 -120.9 56.6006c-8.39941 10.2002 -7.09961 25.2998 3.10059 33.7998c10.2002 8.40039 25.2998 7.09961 33.7998 -3.09961
c20.7998 -25.1006 51.5 -39.4004 84 -39.4004s63.2002 14.4004 84 39.4004zM136.5 237l-9.5 -17c-1.90039 -3.2002 -5.90039 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004
c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996zM328 296c23.7998 0 52.7002 -29.2998 56 -71.4004
c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002
c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004z" />
<glyph glyph-name="surprise" unicode="&#xf5c2;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM248 168c35.2998 0 64 -28.7002 64 -64s-28.7002 -64 -64 -64
s-64 28.7002 -64 64s28.7002 64 64 64zM200 240c0 -17.7002 -14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z" />
<glyph glyph-name="tired" unicode="&#xf5c8;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM377.1 295.8c3.80078 -4.39941 3.90039 -11 0.100586 -15.5
l-33.6006 -40.2998l33.6006 -40.2998c3.7998 -4.5 3.7002 -11 -0.100586 -15.5c-3.5 -4.10059 -9.89941 -5.7002 -15.2998 -2.5l-80 48c-3.59961 2.2002 -5.7998 6.09961 -5.7998 10.2998s2.2002 8.09961 5.7998 10.2998l80 48c5 2.90039 11.5 1.90039 15.2998 -2.5z
M220 240c0 -4.2002 -2.2002 -8.09961 -5.7998 -10.2998l-80 -48c-5.40039 -3.2002 -11.7998 -1.60059 -15.2998 2.5c-3.80078 4.5 -3.90039 11 -0.100586 15.5l33.6006 40.2998l-33.6006 40.2998c-3.7998 4.5 -3.7002 11 0.100586 15.5
c3.7998 4.40039 10.2998 5.5 15.2998 2.5l80 -48c3.59961 -2.2002 5.7998 -6.09961 5.7998 -10.2998zM248 176c45.4004 0 100.9 -38.2998 107.8 -93.2998c1.5 -11.9004 -7 -21.6006 -15.5 -17.9004c-22.7002 9.7002 -56.2998 15.2002 -92.2998 15.2002
s-69.5996 -5.5 -92.2998 -15.2002c-8.60059 -3.7002 -17 6.10059 -15.5 17.9004c6.89941 55 62.3994 93.2998 107.8 93.2998z" />
</font>
</defs></svg>

Before

Width:  |  Height:  |  Size: 141 KiB

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