[#16329] QR code variants (#17221)

* Rename wallet-user-avatar's `:color` prop to `:customization-color`
* Refactor QR code component and implement all variants
  - Improve preview screen
* Update QR code usages
* Remove `status-im2.common.qr-code-viewer.view/qr-code-view` component
to keep only one implementation.
* Remove the node dependency:
  "qrcode": "^1.4.1"
This commit is contained in:
Ulises Manuel 2023-10-08 17:42:58 -06:00 committed by GitHub
parent 4dc834b079
commit 1abd1e9420
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 332 additions and 244 deletions

View File

@ -35,7 +35,6 @@
"functional-red-black-tree": "^1.0.1",
"i18n-js": "^3.3.0",
"node-libs-react-native": "^1.2.1",
"qrcode": "^1.4.1",
"react": "18.0.0",
"react-dom": "18.0.0",
"react-native": "0.69.10",

View File

@ -35,7 +35,7 @@
:indicator-size status indicator outer radius, set to nil or 0 when no indicator
:indicator-border `indicator-size`-`indicator-border` is the inner radius
:indicator-color color for status indicator
:theme :light or :dark
:theme :light or :dark
:background-color intials avatar background color
:color intials avatar text color
:size intials avatar radius

View File

@ -28,11 +28,11 @@
(defn wallet-user-avatar
"params, first name, last name, color, size
and if it's dark or not!"
[{:keys [f-name l-name color size]
:or {f-name "John"
l-name "Doe"
color :red
size :x-large}}]
[{:keys [f-name l-name customization-color size]
:or {f-name "John"
l-name "Doe"
customization-color :red
size :x-large}}]
(let [circle-size (size circle-sizes)
small? (= size :small)
f-name-initial (-> f-name
@ -41,8 +41,8 @@
l-name-initial (-> l-name
string/upper-case
(subs 0 1))
circle-color (colors/custom-color color 50 20)
text-color (colors/custom-color-by-theme color 50 60)]
circle-color (colors/custom-color customization-color 50 20)
text-color (colors/custom-color-by-theme customization-color 50 60)]
[rn/view
{:style {:width circle-size
:height circle-size

View File

@ -1,14 +1,44 @@
(ns quo2.components.share.qr-code.style
(:require [quo2.foundations.colors :as colors]))
(def container
{:flex-direction :row
:justify-content :center})
(defn container
[size]
(if size
{:width size
:height size}
{:flex 1}))
(defn image
[width height]
{:width width
:height height
(def avatar-overlay
{:position :absolute
:top 0
:right 0
:left 0
:bottom 0
:justify-content :center
:align-items :center})
(defn qr-image
[size]
{:width (or size "100%")
:height (or size "100%")
:background-color colors/white-opa-70
:border-radius 12
:aspect-ratio 1})
(def ^:private avatar-container-common
{:width 68
:height 68
:justify-content :center
:align-items :center
:background-color colors/white})
(def avatar-container-circular
(assoc avatar-container-common :border-radius 33))
(def avatar-container-rounded
(assoc avatar-container-common :border-radius 16))
(def community-logo-image
{:width 64
:height 64
:border-radius 32})

View File

@ -1,12 +1,76 @@
(ns quo2.components.share.qr-code.view
(:require [quo2.components.share.qr-code.style :as style]
(:require [quo2.components.avatars.account-avatar.view :as account-avatar]
[quo2.components.avatars.channel-avatar.view :as channel-avatar]
[quo2.components.avatars.user-avatar.view :as user-avatar]
[quo2.components.avatars.wallet-user-avatar :as wallet-avatar]
[quo2.components.share.qr-code.style :as style]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]))
(defn qr-code
[{:keys [source width height]}]
[rn/view
{:style style/container}
(defn- avatar-image
[{avatar-type :avatar
:as props}]
[rn/view {:style style/avatar-overlay}
[rn/view
{:style (if (= avatar-type :wallet-account)
style/avatar-container-rounded
style/avatar-container-circular)}
(case avatar-type
:profile
[user-avatar/user-avatar
(assoc props
:size :size-64
:status-indicator? false
:online? false
:ring? false)]
:wallet-account
[account-avatar/view (assoc props :size :size-64 :type :default)]
:community
[rn/image
{:style style/community-logo-image
:source (:picture props)}]
:channel
[channel-avatar/view (assoc props :locked? nil :size :size-64)]
:saved-address
[wallet-avatar/wallet-user-avatar (assoc props :size :size-64)]
nil)]])
(defn view
"Receives a URL to show a QR code with an avatar (optional) over it.
Parameters:
- qr-image-uri: A valid uri representing the QR code to display using `fast-image`
- size: if not provided, the QR code image will grow according to its parent
- avatar: Type of the avatar, defaults to `:none` and it can be:
`:profile`, `:wallet-account`, `:community`, `:channel` or `:saved-address`
Depending on the type selected, different properties are accepted:
`:profile`:
- profile-picture
- full-name
- customization-color
`:wallet-account`
- emoji
- customization-color
`:community`
- picture
`:channel`
- emoji
- customization-color
`:saved-address`
- f-name
- l-name
- customization-color"
[{:keys [avatar size qr-image-uri]
:or {avatar :none}
:as props}]
[rn/view {:style (style/container size)}
[fast-image/fast-image
{:source source
:style (style/image width height)}]])
{:style (style/qr-image size)
:source {:uri qr-image-uri}}]
(when-not (= avatar :none)
[avatar-image props])])

View File

@ -8,15 +8,11 @@
[react-native.core :as rn]))
(defn view
[{:keys [source link-title
url-on-press url-on-long-press qr-url share-on-press]}]
[{:keys [qr-image-uri link-title url-on-press url-on-long-press qr-url share-on-press]}]
[blur/ios-view
{:style style/qr-code-container
:blur-type :light}
[qr-code/qr-code
{:source source
:width "100%"
:height 311}]
[qr-code/view {:qr-image-uri qr-image-uri}]
[rn/view {:style style/profile-address-container}
[rn/view {:style style/profile-address-column}
[text/text

View File

@ -335,7 +335,7 @@
(def settings-item quo2.components.settings.settings-item.view/view)
;;;; Share
(def qr-code quo2.components.share.qr-code.view/qr-code)
(def qr-code quo2.components.share.qr-code.view/view)
(def share-qr-code quo2.components.share.share-qr-code.view/view)
;;;; SWITCHER

View File

@ -19,7 +19,7 @@
[status-im.utils.gfycat.core :as gfy]
[status-im.utils.universal-links.utils :as universal-links]
[status-im.utils.utils :as utils]
[status-im2.common.qr-code-viewer.view :as qr-code-viewer]
[status-im2.common.qr-codes.view :as qr-codes]
[status-im2.config :as config]
[utils.i18n :as i18n])
(:require-macros [status-im.utils.views :as views]))
@ -32,7 +32,9 @@
[react/view {:on-layout #(reset! width (-> ^js % .-nativeEvent .-layout .-width))}
[react/view {:style {:padding-top 16 :padding-horizontal 16}}
(when @width
[qr-code-viewer/qr-code-view (- @width 32) address])
[qr-codes/qr-code
{:url address
:size (- @width 32)}])
(when ens-name
[react/view
[copyable-text/copyable-text-view

View File

@ -4,10 +4,10 @@
[reagent.core :as reagent]
[utils.ethereum.eip.eip55 :as eip55]
[status-im.ethereum.eip681 :as eip681]
[utils.i18n :as i18n]
[status-im.ui.components.copyable-text :as copyable-text]
[status-im2.common.qr-code-viewer.view :as qr-code-viewer]
[status-im.ui.components.react :as react])
[status-im.ui.components.react :as react]
[status-im2.common.qr-codes.view :as qr-codes]
[utils.i18n :as i18n])
(:require-macros [status-im.utils.views :as views]))
(views/defview share-address
@ -18,9 +18,9 @@
[react/view {:on-layout #(reset! width (-> ^js % .-nativeEvent .-layout .-width))}
[react/view {:style {:padding-top 16 :padding-horizontal 16}}
(when @width
[qr-code-viewer/qr-code-view
(- @width 32)
(eip681/generate-uri address {:chain-id chain-id})])
[qr-codes/qr-code
{:url (eip681/generate-uri address {:chain-id chain-id})
:size (- @width 32)}])
[copyable-text/copyable-text-view
{:label :t/ethereum-address
:container-style {:margin-top 12 :margin-bottom 4}

View File

@ -1,15 +0,0 @@
(ns status-im2.common.qr-code-viewer.style
(:require [quo2.foundations.colors :as colors]))
(def qr-code-padding 16)
(defn qr-code-container
[width]
{:align-self :center
:width width
:height width
:padding-horizontal 16
:background-color colors/white
:align-items :center
:justify-content :center
:border-radius 8})

View File

@ -1,31 +0,0 @@
(ns status-im2.common.qr-code-viewer.view
(:require ["qrcode" :as qr-code-js]
[cljs-bean.core :as bean]
[reagent.core :as reagent]
[status-im2.common.qr-code-viewer.style :as style]
[react-native.core :as rn]
[react-native.svg :as svg]))
(defn qr-code
[{:keys [size value]}]
(let [uri (reagent/atom nil)]
(.toString
qr-code-js
value
(bean/->js {:margin 0 :width size})
#(reset! uri %2))
(fn []
(when @uri
[svg/svgxml {:xml @uri :width size :height size}]))))
(defn qr-code-view
"Qr Code view including the frame.
Note: `size` includes frame with `style/qr-code-padding.`"
[size value]
(when (and size value)
[rn/view
{:style (style/qr-code-container size)
:accessibility-label :qr-code-image}
[qr-code
{:value value
:size (- size (* style/qr-code-padding 2))}]]))

View File

@ -0,0 +1,37 @@
(ns status-im2.common.qr-codes.view
(:require [quo2.core :as quo]
[utils.image-server :as image-server]
[utils.re-frame :as rf]))
(defn qr-code
"Receives a URL to show a QR code with an avatar (optional) over it.
Parameters:
- url: String to transform to QR
- size: if not provided, the QR code image will grow according to its parent
- avatar: Type of the avatar, defaults to `:none` and it can be:
`:profile`, `:wallet-account`, `:community`, `:channel` or `:saved-address`
Depending on the type selected, different properties are accepted:
`:profile`:
- profile-picture
- full-name
- customization-color
`:wallet-account`
- emoji
- customization-color
`:community`
- picture
`:channel`
- emoji
- customization-color
`:saved-address`
- f-name
- l-name
- customization-color"
[{:keys [url size] :as props}]
(let [qr-media-server-uri (image-server/get-qr-image-uri-for-any-url
{:url url
:port (rf/sub [:mediaserver/port])
:qr-size (or 400 (int size))
:error-level :highest})]
[quo/qr-code (assoc props :qr-image-uri qr-media-server-uri)]))

View File

@ -18,14 +18,14 @@
{:key :size-64}
{:key :x-large
:value "X Large"}]}
(preview/customization-color-option {:key :color})])
(preview/customization-color-option {:key :customization-color})])
(defn view
[]
(let [state (reagent/atom {:first-name "empty"
:last-name "name"
:size :x-large
:color :indigo})]
(let [state (reagent/atom {:first-name "empty"
:last-name "name"
:size :x-large
:customization-color :indigo})]
(fn []
[preview/preview-container {:state state :descriptor descriptor}
[quo/wallet-user-avatar @state]])))

View File

@ -392,7 +392,7 @@
{:name :section-label
:component section-label/preview}]
:share [{:name :qr-code
:component qr-code/preview-qr-code}
:component qr-code/preview}
{:name :share-qr-code
:component share-qr-code/preview-share-qr-code}]
:switchers [{:name :group-messaging-card

View File

@ -1,55 +1,104 @@
(ns status-im2.contexts.quo-preview.share.qr-code
(:require [react-native.core :as rn]
[quo2.core :as quo]
[utils.image-server :as image-server]
[utils.re-frame :as rf]
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
[status-im2.common.resources :as resources]
[status-im2.contexts.quo-preview.preview :as preview]
[utils.image-server :as image-server]
[utils.re-frame :as rf]))
(def descriptor
[{:label "URL For QR"
:key :text
:type :text}
{:label "Error Correction Level:"
:key :error-correction-level
[{:key :url
:type :text}
{:key :avatar
:type :select
:options [{:key :low
:value "Low"}
{:key :medium
:value "Medium"}
{:key :quart
:value "Quart"}
{:key :highest
:value "Highest"}]}])
:options [{:key :none}
{:key :profile}
{:key :wallet-account}
{:key :community}
{:key :channel}
{:key :saved-address}]}
{:key :size
:type :select
:options [{:key 250} {:key 311} {:key 350}]}])
(defn preview-qr-code
(def profile-descriptor
[{:key :profile-picture
:type :select
:options [{:key (resources/get-mock-image :user-picture-male5)
:value "User"}
{:key nil
:value "None"}]}
(preview/customization-color-option)
{:key :full-name
:type :text}])
(def wallet-account-descriptor
[{:key :emoji
:type :select
:options [{:key "🍒"}
{:key "🐧"}
{:key "🍨"}]}
(preview/customization-color-option)])
(def channel-descriptor
[{:key :emoji
:type :select
:options [{:key "🍒"}
{:key "🐧"}
{:key "🍨"}]}
(preview/customization-color-option)])
(def saved-address-descriptor
[{:key :f-name
:type :text}
{:key :l-name
:type :text}
(preview/customization-color-option)])
(defn preview
[]
(let [state (reagent/atom {:text "https://status.im"
:error-correction-level :highest})
text (reagent/cursor state [:text])
error-correction-level (reagent/cursor state [:error-correction-level])
media-server-uri (reagent/atom "")]
(let [media-server-port (rf/sub [:mediaserver/port])
state (reagent/atom
{:url "https://join.status.im/status"
:size 250
:avatar :none
:profile-picture (resources/get-mock-image :user-picture-male5)
:customization-color :army
:full-name "Full Name"
:emoji "🍒"
:picture (resources/get-mock-image :community-logo)
:f-name "First Name"
:l-name "Last Name"})]
(fn []
(reset! media-server-uri (image-server/get-qr-image-uri-for-any-url
{:url @text
:port (rf/sub [:mediaserver/port])
:error-level @error-correction-level
:qr-size 250}))
[preview/preview-container
{:state state
:descriptor descriptor}
[rn/view {:style {:padding-bottom 150}}
[rn/view {:style {:flex 1}}]
[rn/view
{:style {:padding-vertical 60
:flex-direction :row
:justify-content :center}}
[rn/view
[quo/qr-code
{:source {:uri @media-server-uri}
:height 250
:width 250}]
(let [qr-media-server-uri (image-server/get-qr-image-uri-for-any-url
{:url (:url @state)
:qr-size (:size @state)
:port media-server-port
:error-level :highest})]
[preview/preview-container
{:component-container-style {:flex 1
:justify-content :center
:align-items :center
:margin-vertical 12}
:state state
:descriptor (concat descriptor
(case (:avatar @state)
:profile profile-descriptor
:wallet-account wallet-account-descriptor
:channel channel-descriptor
:saved-address saved-address-descriptor
nil))}
[quo/qr-code
(cond-> @state
:always
(assoc :qr-image-uri qr-media-server-uri)
[rn/view
[rn/text {:style {:padding 20 :flex-shrink 1}} "Media server url -> "
@media-server-uri]]]]]])))
;; `:channel` variant receives colors as hex strings instead of keywords
(= (:avatar @state) :channel)
(update :customization-color colors/custom-color 60))]
[rn/view {:style {:margin 12}}
[quo/text "URL:"]
[quo/text (:url @state)]]]))))

View File

@ -1,10 +1,10 @@
(ns status-im2.contexts.quo-preview.share.share-qr-code
(:require [react-native.core :as rn]
[quo2.core :as quo]
(:require [quo2.core :as quo]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]
[status-im2.common.resources :as resources]
[reagent.core :as reagent]))
[utils.image-server :as image-server]
[utils.re-frame :as rf]))
(def descriptor
[{:label "URL"
@ -20,23 +20,28 @@
:link-title "Link to profile"
:url "status.app/u/zQ34e1zlOdas0pKnvrweeedsasas12adjie8"})]
(fn []
[preview/preview-container
{:state state
:descriptor descriptor}
[rn/view {:style {:padding-bottom 150}}
[rn/view {:style {:flex 1}}]
[rn/view
{:style {:padding-vertical 60
:justify-content :center}}
[preview/blur-view
{:show-blur-background? true
:height 600
:blur-view-props {:padding-top 20
:padding-horizontal 20}}
[quo/share-qr-code
{:source (resources/get-mock-image :qr-code)
:link-title (:link-title @state)
:url-on-press #(js/alert "url pressed")
:url-on-long-press #(js/alert "url long pressed")
:share-on-press #(js/alert "share pressed")
:qr-url (:url @state)}]]]]])))
(let [qr-media-server-uri (image-server/get-qr-image-uri-for-any-url
{:url (:url @state)
:port (rf/sub [:mediaserver/port])
:qr-size 300
:error-level :highest})]
[preview/preview-container
{:state state
:descriptor descriptor}
[rn/view {:style {:padding-bottom 150}}
[rn/view {:style {:flex 1}}]
[rn/view
{:style {:padding-vertical 60
:justify-content :center}}
[preview/blur-view
{:show-blur-background? true
:height 600
:blur-view-props {:padding-top 20
:padding-horizontal 20}}
[quo/share-qr-code
{:qr-image-uri qr-media-server-uri
:link-title (:link-title @state)
:url-on-press #(js/alert "url pressed")
:url-on-long-press #(js/alert "url long pressed")
:share-on-press #(js/alert "share pressed")
:qr-url (:url @state)}]]]]]))))

View File

@ -1,17 +1,19 @@
(ns status-im2.contexts.shell.share.view
(:require [utils.i18n :as i18n]
(:require [clojure.string :as string]
[quo2.core :as quo]
[react-native.core :as rn]
[status-im2.contexts.shell.share.style :as style]
[utils.re-frame :as rf]
[reagent.core :as reagent]
[quo2.foundations.colors :as colors]
[react-native.blur :as blur]
[status-im.ui.components.list-selection :as list-selection]
[utils.image-server :as image-server]
[react-native.core :as rn]
[react-native.navigation :as navigation]
[clojure.string :as string]
[reagent.core :as reagent]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.ui.components.list-selection :as list-selection]
[status-im2.common.qr-codes.view :as qr-codes]
[status-im2.contexts.shell.share.style :as style]
[utils.address :as address]
[utils.i18n :as i18n]
[utils.image-server :as image-server]
[utils.re-frame :as rf]
[react-native.platform :as platform]))
(defn header
@ -43,27 +45,24 @@
(defn profile-tab
[window-width]
(let [{:keys [emoji-hash
compressed-key
key-uid]} (rf/sub [:profile/profile])
port (rf/sub [:mediaserver/port])
emoji-hash-string (string/join emoji-hash)
(let [{:keys [emoji-hash compressed-key customization-color display-name]
:as profile} (rf/sub [:profile/profile])
qr-size (int (- window-width 64))
profile-url (str image-server/status-profile-base-url compressed-key)
profile-photo-uri (:uri (multiaccounts/displayed-photo profile))
abbreviated-url (address/get-abbreviated-profile-url
image-server/status-profile-base-url-without-https
compressed-key)
profile-url (str image-server/status-profile-base-url compressed-key)
source-uri (image-server/get-account-qr-image-uri
{:key-uid key-uid
:public-key compressed-key
:port port
:qr-size qr-size})]
emoji-hash-string (string/join emoji-hash)]
[:<>
[rn/view {:style style/qr-code-container}
[quo/qr-code
{:source {:uri source-uri}
:width qr-size
:height qr-size}]
[qr-codes/qr-code
{:url profile-url
:size qr-size
:avatar :profile
:full-name display-name
:customization-color customization-color
:profile-picture profile-photo-uri}]
[rn/view {:style style/profile-address-container}
[rn/view {:style style/profile-address-column}
[quo/text

View File

@ -3,11 +3,11 @@
[quo2.foundations.colors :as colors]
[react-native.clipboard :as clipboard]
[react-native.core :as rn]
[status-im2.common.qr-code-viewer.view :as qr-code-viewer]
[react-native.hooks :as hooks]
[reagent.core :as reagent]
[status-im2.common.qr-codes.view :as qr-codes]
[status-im2.common.resources :as resources]
[status-im2.common.standard-authentication.standard-auth.view :as standard-auth]
[react-native.hooks :as hooks]
[status-im2.contexts.syncing.setup-syncing.style :as style]
[status-im2.contexts.syncing.utils :as sync-utils]
[utils.datetime :as datetime]
@ -76,12 +76,14 @@
(i18n/label :t/setup-syncing)]]
[rn/view {:style style/qr-container}
(if (sync-utils/valid-connection-string? @code)
[rn/view {:style {:margin-horizontal 12}}
[qr-code-viewer/qr-code-view 311 @code]]
[quo/qr-code
{:source (resources/get-image :qr-code)
:height 220
:width "100%"}])
[qr-codes/qr-code {:url @code}]
[rn/view {:style {:flex-direction :row}}
[rn/image
{:source (resources/get-image :qr-code)
:style {:width "100%"
:background-color colors/white-opa-70
:border-radius 12
:aspect-ratio 1}}]])
(when (sync-utils/valid-connection-string? @code)
[rn/view
{:style style/valid-cs-container}

View File

@ -3580,25 +3580,7 @@ bser@2.1.1:
dependencies:
node-int64 "^0.4.0"
buffer-alloc-unsafe@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==
buffer-alloc@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec"
integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==
dependencies:
buffer-alloc-unsafe "^1.1.0"
buffer-fill "^1.0.0"
buffer-fill@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
buffer-from@^1.0.0, buffer-from@^1.1.1:
buffer-from@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
@ -3617,14 +3599,6 @@ buffer@^4.3.0, buffer@^4.9.1:
ieee754 "^1.1.4"
isarray "^1.0.0"
buffer@^5.4.3:
version "5.6.0"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786"
integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==
dependencies:
base64-js "^1.0.2"
ieee754 "^1.1.4"
buffer@^5.5.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
@ -4527,11 +4501,6 @@ diffie-hellman@^5.0.0:
miller-rabin "^4.0.0"
randombytes "^2.0.0"
dijkstrajs@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.1.tgz#d3cd81221e3ea40742cfcde556d4e99e98ddc71b"
integrity sha1-082BIh4+pAdCz83lVtTpnpjdxxs=
dom-serializer@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53"
@ -5984,11 +5953,6 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
isarray@^2.0.1:
version "2.0.5"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@ -8485,7 +8449,7 @@ plist@^3.0.2:
base64-js "^1.5.1"
xmlbuilder "^15.1.1"
pngjs@^3.3.0, pngjs@^3.4.0:
pngjs@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
@ -8701,19 +8665,6 @@ pupa@^2.1.1:
dependencies:
escape-goat "^2.0.0"
qrcode@^1.4.1:
version "1.4.4"
resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.4.tgz#f0c43568a7e7510a55efc3b88d9602f71963ea83"
integrity sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q==
dependencies:
buffer "^5.4.3"
buffer-alloc "^1.2.0"
buffer-from "^1.1.1"
dijkstrajs "^1.0.1"
isarray "^2.0.1"
pngjs "^3.3.0"
yargs "^13.2.4"
query-string@^6.13.5:
version "6.14.1"
resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a"
@ -11075,7 +11026,7 @@ yargs-parser@^21.1.1:
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
yargs@^13.2.2, yargs@^13.2.4:
yargs@^13.2.2:
version "13.3.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd"
integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==