diff --git a/go.mod b/go.mod index 472e6d593df..ef77bf3cb54 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,12 @@ module github.com/ray-project/kuberay go 1.24.0 require ( + github.com/alibabacloud-go/tea v1.3.10 + github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible + github.com/aliyun/credentials-go v1.4.7 github.com/dustinkirkland/golang-petname v0.0.0-20240428194347-eebcea082ee0 github.com/elazarl/go-bindata-assetfs v1.0.1 + github.com/fsnotify/fsnotify v1.8.0 github.com/go-logr/logr v1.4.3 github.com/go-logr/zerologr v1.2.3 github.com/golang/mock v1.6.0 @@ -12,6 +16,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 + github.com/hpcloud/tail v1.0.0 github.com/novln/docker-parser v1.0.0 github.com/onsi/ginkgo/v2 v2.23.4 github.com/onsi/gomega v1.37.0 @@ -20,6 +25,7 @@ require ( github.com/ray-project/kuberay/ray-operator v0.0.0 github.com/rs/cors v1.11.1 github.com/rs/zerolog v1.34.0 + github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.9.1 github.com/spf13/pflag v1.0.6 github.com/stretchr/testify v1.10.0 @@ -42,6 +48,7 @@ require ( require ( github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect + github.com/alibabacloud-go/debug v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -51,7 +58,6 @@ require ( github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/fatih/camelcase v1.0.0 // indirect - github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect @@ -105,7 +111,10 @@ require ( golang.org/x/tools v0.31.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/fsnotify.v1 v1.4.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.33.1 // indirect k8s.io/apiserver v0.33.1 // indirect diff --git a/go.sum b/go.sum index dddab9f7e86..0d0025cde32 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,17 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg6 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= +github.com/alibabacloud-go/debug v1.0.0/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc= +github.com/alibabacloud-go/debug v1.0.1 h1:MsW9SmUtbb1Fnt3ieC6NNZi6aEwrXfDksD4QA6GSbPg= +github.com/alibabacloud-go/debug v1.0.1/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc= +github.com/alibabacloud-go/tea v1.2.2/go.mod h1:CF3vOzEMAG+bR4WOql8gc2G9H3EkH3ZLAQdpmpXMgwk= +github.com/alibabacloud-go/tea v1.3.10 h1:J0Ke8iMyoxX2daj90hdPr1QgfxJnhR8SOflB910o/Dk= +github.com/alibabacloud-go/tea v1.3.10/go.mod h1:A560v/JTQ1n5zklt2BEpurJzZTI8TUT+Psg2drWlxRg= +github.com/alibabacloud-go/tea-utils/v2 v2.0.7/go.mod h1:qxn986l+q33J5VkialKMqT/TTs3E+U9MJpd001iWQ9I= +github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g= +github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/aliyun/credentials-go v1.4.7 h1:T17dLqEtPUFvjDRRb5giVvLh6dFT8IcNFJJb7MeyCxw= +github.com/aliyun/credentials-go v1.4.7/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -16,6 +27,7 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= +github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -87,6 +99,7 @@ github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63Kqpo github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -108,6 +121,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jarcoal/httpmock v1.4.0 h1:BvhqnH0JAYbNudL2GMJKgOHe2CtKlzJ/5rWKyp+hc2k= @@ -158,6 +173,7 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/novln/docker-parser v1.0.0 h1:PjEBd9QnKixcWczNGyEdfUrP6GR0YUilAqG7Wksg3uc= github.com/novln/docker-parser v1.0.0/go.mod h1:oCeM32fsoUwkwByB5wVjsrsVQySzPWkl3JdlTn1txpE= github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus= @@ -196,6 +212,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= @@ -219,6 +237,7 @@ github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= @@ -246,6 +265,12 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -254,6 +279,11 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -262,7 +292,16 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -274,6 +313,11 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -284,18 +328,44 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= @@ -310,6 +380,10 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU= golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -338,12 +412,19 @@ google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9x google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/go.work b/go.work new file mode 100644 index 00000000000..3790d17069b --- /dev/null +++ b/go.work @@ -0,0 +1,3 @@ +go 1.25.1 + +use ./historyserver diff --git a/go.work.sum b/go.work.sum new file mode 100644 index 00000000000..ce58082c962 --- /dev/null +++ b/go.work.sum @@ -0,0 +1,34 @@ +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/historyserver/Dockerfile b/historyserver/Dockerfile new file mode 100644 index 00000000000..5a068d6011d --- /dev/null +++ b/historyserver/Dockerfile @@ -0,0 +1,32 @@ +ARG TARGETOS +ARG TARGETARCH + +FROM --platform=$BUILDPLATFORM golang:1.25.1 as builder +ENV GOPROXY=https://goproxy.cn,direct +ARG BUILD_RAYSERVER_DASHBOARD + +RUN if [ "$BUILD_RAYSERVER_DASHBOARD" = "yes" ] ; then \ + curl -o install.sh https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh && chmod +x install.sh && ./install.sh && /bin/bash -c "source $HOME/.nvm/nvm.sh && nvm install 14 && nvm use 14" ;\ +else \ + echo "$BUILD_RAYSERVER_DASHBOARD not yes, no need install nvm"; \ +fi + +WORKDIR /historyserver +COPY . . + +RUN if [ "$BUILD_RAYSERVER_DASHBOARD" = "yes" ] ; then \ + /bin/bash -c "source $HOME/.nvm/nvm.sh && cd dashboard/ray/client && npm ci && npm run build" ;\ +else \ + mkdir -p dashboard/ray/client/build ;\ + echo "do not npm run build"; \ +fi + +RUN make build GOOS=${TARGETOS} GOARCH=${TARGETARCH} + +FROM ubuntu:22.04 + +RUN apt-get update && apt-get upgrade -y && rm -rf /var/cache/apt/ && apt-get install -y ca-certificates + +COPY --from=builder /historyserver/output/bin/historyserver /usr/local/bin/historyserver +COPY --from=builder /historyserver/output/bin/collector /usr/local/bin/collector +COPY --from=builder /historyserver/dashboard/ray/client/build /dashboard/ray/build \ No newline at end of file diff --git a/historyserver/Makefile b/historyserver/Makefile new file mode 100644 index 00000000000..c36bda2b5d2 --- /dev/null +++ b/historyserver/Makefile @@ -0,0 +1,140 @@ +# Image URL to use all building/pushing image targets +GOLANGCILINT_VERSION ?= v1.59.0 +GOBIN := $(shell go env GOPATH)/bin +GOBIN_GOLANGCILINT := $(GOBIN)/golangci-lint + +DOCKERBUILDER_INSTANCE=historyserver +OUT_DIR=output +BIN_DIR=$(OUT_DIR)/bin +BINARY_NAME=historyserver +BINARY_NAME_COLLECTOR=collector + +# Setting SHELL to bash allows bash commands to be executed by recipes. +# Options are set to exit when a recipe line exits non-zero or a piped command fails. +SHELL = /usr/bin/env bash -o pipefail +BUILD_TIMESTAMP = $(shell date -u +"%Y-%m-%dT%H:%M:%SZ") +COMMIT_SHORT ?= $(shell git rev-parse --short HEAD) +BRANCH ?= $(shell git branch --show-current) +VERSION ?= $(shell git describe --tags --long|awk -F '-' '{print $$1"."$$2"-"$$3""}') + +PACKAGE = gitlab.alibaba-inc.com/eml/historyserver + +GO_LDFLAGS := -extldflags "-static" +# GO_LDFLAGS += -w -s # Drop debugging symbols. +GO_LDFLAGS += -X $(PACKAGE)/pkg.Version=$(VERSION) \ + -X $(PACKAGE)/pkg.CommitID=$(COMMIT_SHORT) \ + -X $(PACKAGE)/pkg.BuildDate=$(BUILD_TIMESTAMP) \ + -X $(PACKAGE)/pkg.Branch=$(BRANCH) +GO_BUILD_FLAGS := -ldflags '$(GO_LDFLAGS)' + +GOOS ?= darwin +GOARCH ?= amd64 + +.PHONY: all + +all: build + +.PHONY: clean +clean: + rm -rf $(OUT_DIR) + +.PHONY: build +build: buildcollector buildhistoryserver + +.PHONY: buildcollector +#build: mod alllint test +buildcollector: mod + @echo "" + @echo "go build ..." + CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) go build -v $(GO_BUILD_FLAGS) -o $(BIN_DIR)/$(BINARY_NAME_COLLECTOR) ./cmd/collector/main.go + +.PHONY: buildhistoryserver +#build: mod alllint test +buildhistoryserver: mod + @echo "" + @echo "go build ..." + CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) go build -v $(GO_BUILD_FLAGS) -o $(BIN_DIR)/$(BINARY_NAME) ./cmd/historyserver/main.go + +.PHONY: simplebuild +simplebuild: + @echo "" + @echo "go build ..." + CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) go build -v $(GO_BUILD_FLAGS) -o $(BIN_DIR)/$(BINARY_NAME) + +.PHONY: mod +mod: + go mod tidy + +.PHONY: localimage +localimage: dockerbuilder_instance + docker buildx build -t historyserver:laster --platform linux/amd64 . --load + +.PHONY: dockerbuilder_instance +dockerbuilder_instance: + @docker buildx use $(DOCKERBUILDER_INSTANCE) || docker buildx create --name $(DOCKERBUILDER_INSTANCE) + docker buildx use $(DOCKERBUILDER_INSTANCE) + +# Run tests +.PHONY: test +test: + go test -v ./pkg/... ./cmd/... + +.PHONY: alllint +alllint: todolist issuelint ## Run go lint against code. + +.PHONY: issuelint +issuelint: install-golint + @echo "" + @echo "-------------------- show issues info, if has issuse, return error --------------------" + $(GOBIN_GOLANGCILINT) run -v --print-resources-usage -c .golangci.yaml + +.PHONY: todolist +todolist: install-golint ## Run go lint against code. + @echo "" + @echo "-------------------- only show TODO list info --------------------" + $(GOBIN_GOLANGCILINT) run --print-resources-usage -c .golangci.info.yaml --enable-only godox + @echo "" + +install-golint: ## check golint if not exist install golint tools +ifneq ("$(wildcard $(GOBIN_GOLANGCILINT))","") +ifeq ($(shell $(GOBIN_GOLANGCILINT) version --format short), $(GOLANGCILINT_VERSION)) + @echo "golangci-lint version match" +else + @echo "golangci-lint version do not match" + @{ \ + set -e ;\ + echo 'installing golangci-lint-$(GOLANGCILINT_VERSION)' ;\ + go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCILINT_VERSION) ;\ + echo 'Successfully installed' ;\ + } +endif +else + @echo "golangci-lint not exist" + @{ \ + set -e ;\ + echo 'installing golangci-lint-$(GOLANGCILINT_VERSION)' ;\ + go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCILINT_VERSION) ;\ + echo 'Successfully installed' ;\ + } +endif + + + +# Generate manifests e.g. CRD, RBAC etc. +#manifests: controller-gen +# $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases + +# Generate code +#generate: controller-gen +# $(CONTROLLER_GEN) object:headerFile=./hack/boilerplate.go.txt paths=./api/... + + +# find or download controller-gen +# download controller-gen if necessary +#controller-gen: +#ifeq (, $(shell which controller-gen)) +# go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.0-beta.2 +#CONTROLLER_GEN=$(shell go env GOPATH)/bin/controller-gen +#else +#CONTROLLER_GEN=$(shell which controller-gen) +#endif diff --git a/historyserver/backend/collector/runtime/interface.go b/historyserver/backend/collector/runtime/interface.go new file mode 100644 index 00000000000..c956240285d --- /dev/null +++ b/historyserver/backend/collector/runtime/interface.go @@ -0,0 +1,5 @@ +package runtime + +type RayLogCollector interface { + Start(chan struct{}) +} diff --git a/historyserver/backend/collector/runtime/logcollector/collector.go b/historyserver/backend/collector/runtime/logcollector/collector.go new file mode 100644 index 00000000000..dff09b47569 --- /dev/null +++ b/historyserver/backend/collector/runtime/logcollector/collector.go @@ -0,0 +1,260 @@ +package logcollector + +import ( + "bytes" + "fmt" + "io" + "net/http" + "os" + "path" + "path/filepath" + "strings" + "time" + + "github.com/fsnotify/fsnotify" + "github.com/hpcloud/tail" + "github.com/ray-project/kuberay/historyserver/backend/collector/storage" + "github.com/ray-project/kuberay/historyserver/utils" + "github.com/sirupsen/logrus" +) + +type RayLogHandler struct { + EnableMeta bool + + RootDir string + LogDir string + SessionDir string + LogFiles chan string + // fill after start + MetaDir string + + RayClusterName string + RayClusterID string + RayNodeName string + + LogBatching int + PushInterval time.Duration + + HttpClient *http.Client + Writter storage.StorageWritter + + // key job id + JobResourcesUrlInfo map[string]*JobUrlInfo +} + +func (r *RayLogHandler) Start(stop chan struct{}) { + go r.Run(stop) +} + +func (r *RayLogHandler) Run(stop chan struct{}) error { + watchPath := r.LogDir + + watcher, err := fsnotify.NewWatcher() + if err != nil { + logrus.Fatalf("Create fsnotify NewWatcher error %v", err) + } + defer watcher.Close() + go r.WatchLogsLoops(watcher, watchPath, stop) + go r.PushLogsLoops(stop) + + if r.EnableMeta { + // Persist meta data + go r.PersistMetaLoop(stop) + } + + <-stop + logrus.Warnf("Receive stop single, so stop ray collector ") + return nil +} + +func (r *RayLogHandler) AddLogFile(absoluteLogPathName string) { + r.LogFiles <- absoluteLogPathName +} + +func (r *RayLogHandler) PushLog(absoluteLogPathName string) error { + // 判断文件是否存在 + // 计算相对路径 + absoluteLogPathName = strings.TrimSpace(absoluteLogPathName) + absoluteLogPathName = filepath.Clean(absoluteLogPathName) + + relativePath := strings.TrimPrefix(absoluteLogPathName, fmt.Sprintf("%s/", r.LogDir)) + // 分割相对路径为子目录和文件名 + // subdir events/aa/ + // filename a.txt + subdir, filename := filepath.Split(relativePath) + logDir := utils.GetLogDir(r.RootDir, r.RayClusterName, r.RayClusterID, r.RayNodeName) + if len(subdir) != 0 { + dirName := path.Join(logDir, subdir) + if err := r.Writter.CreateDirectory(dirName); err != nil { + logrus.Errorf("Failed to create directory '%s': %v", dirName, err) + return err + } + } + + objectName := path.Join(logDir, subdir, filename) + logrus.Infof("Begin to create and append oss object %s by absoluteLogPathName %s, oss subdir [%s] filename [%s] relativePath[%s]", + objectName, absoluteLogPathName, subdir, filename, relativePath) + + // utils.DeleteObject(r.OssBucket, objectName) + + // 从文件开始读, + // Go 1.20推荐使用 io.SeekEnd, 老版本可能需要改为os.SEEK_END + seek := &tail.SeekInfo{Offset: 0, Whence: io.SeekStart} + t, err := tail.TailFile(absoluteLogPathName, tail.Config{ + Follow: true, + Location: seek, + }) + if err != nil { + logrus.Errorf("Create TailFile %s error %v", absoluteLogPathName, err) + return err + } + + var nextPos int64 = 0 + + logrus.Infof("Begin to first append oss object %s ...", objectName) + nextPos, err = r.Writter.Append(objectName, strings.NewReader(""), nextPos) + if err != nil { + logrus.Errorf("First append object %s error %v", + objectName, + err) + return err + } + + lines := 0 + lastPush := time.Now() + buf := bytes.NewBufferString("") + for { + select { + case <-time.Tick(r.PushInterval): + if lines > 0 { + nextPos, err = r.Writter.Append(objectName, buf, nextPos) + if err != nil { + logrus.Errorf("Tail file %s to object %s error, append value: %v, nextPos %d error [%v]", + absoluteLogPathName, + objectName, + buf.String(), + nextPos, + err) + return err + } + + now := time.Now() + logrus.Infof("Tail file %s to object %s success, by interval, append value %s, lines %v, interval %v", + absoluteLogPathName, objectName, buf.String(), lines, now.Sub(lastPush).Seconds()) + + lastPush = now + lines = 0 + buf = bytes.NewBufferString("") + } + case line, ok := <-t.Lines: + if !ok { + logrus.Infof("channel for path %v is closed", absoluteLogPathName) + return nil + } + lines++ + buf.WriteString(line.Text + "\n") + if lines >= r.LogBatching { + nextPos, err = r.Writter.Append(objectName, buf, nextPos) + if err != nil { + logrus.Errorf("Tail file %s to object %s error, append value: %v, nextPos %d error [%v]", + absoluteLogPathName, + objectName, + buf.String(), + nextPos, + err) + return err + } + + now := time.Now() + logrus.Infof("Tail file %s to object %s success, by line count, append value %s, lines %v, interval %v", + absoluteLogPathName, objectName, buf.String(), lines, now.Sub(lastPush).Seconds()) + + lastPush = now + lines = 0 + buf = bytes.NewBufferString("") + } + } + } +} + +func (r *RayLogHandler) PushLogsLoops(stop chan struct{}) { + + if err := r.Writter.CreateDirectory(r.RootDir); err != nil { + logrus.Errorf("Failed to create oss root directory %s: %v", r.RootDir, err) + return + } + + for { + select { + case logfile := <-r.LogFiles: + go r.PushLog(logfile) + case <-stop: + logrus.Warnf("Receive stop signal, so return PushLogsLoop") + return + } + } +} + +func (r *RayLogHandler) WatchLogsLoops(watcher *fsnotify.Watcher, walkPath string, stop chan struct{}) { + // 监听当前目录 + if err := watcher.Add(walkPath); err != nil { + logrus.Fatalf("Watcher rootpath %s error %v", r.LogDir, err) + } + + err := filepath.Walk(walkPath, func(path string, info os.FileInfo, err error) error { + if err != nil { + logrus.Errorf("Walk path %s error %v", walkPath, err) + return err // 返回错误 + } + // 检查是否是文件 + if !info.IsDir() { + logrus.Infof("Walk find new file %s", path) // 输出文件路径 + go r.AddLogFile(path) + } else { + logrus.Infof("Walk find new dir %s", path) // 输出dir路径 + if err := watcher.Add(path); err != nil { + logrus.Fatalf("Watcher add %s error %v", r.LogDir, err) + } + } + return nil + }) + + if err != nil { + logrus.Errorf("Walk path %s error %++v", walkPath, err) + return + } + logrus.Infof("Walk path %s success", walkPath) + + for { + select { + case <-stop: + logrus.Warnf("Receive stop signal, so return watchFileLoops") + return + case event, ok := <-watcher.Events: + if !ok { + logrus.Warnf("Receive watcher events not ok") + return + } + if event.Op == fsnotify.Create { + name := event.Name + info, _ := os.Stat(name) + + // 判断是文件还是目录 + if !info.IsDir() { + logrus.Infof("Watch find: create a new file %s", name) + r.AddLogFile(name) + } else { + if err := watcher.Add(name); err != nil { + logrus.Fatalf("Watch add file %s error %v", name, err) + } + } + } + case _, ok := <-watcher.Errors: + if !ok { + close(stop) + logrus.Warnf("Watcher error, so return watchFileLoops") + return + } + } + } +} diff --git a/historyserver/backend/collector/runtime/logcollector/meta.go b/historyserver/backend/collector/runtime/logcollector/meta.go new file mode 100644 index 00000000000..bb14dae470f --- /dev/null +++ b/historyserver/backend/collector/runtime/logcollector/meta.go @@ -0,0 +1,276 @@ +package logcollector + +import ( + "bytes" + "crypto/md5" + "encoding/hex" + "encoding/json" + "fmt" + "io" + "path" + "time" + + "github.com/ray-project/kuberay/historyserver/utils" + "github.com/sirupsen/logrus" +) + +func (r *RayLogHandler) PersistMetaLoop(stop chan struct{}) { + clistDir := path.Clean(r.RootDir + "/" + "cluster_list") + if err := r.Writter.CreateDirectory(clistDir); err != nil { + logrus.Errorf("CreateDirectory %s error %v", clistDir, err) + return + } + + // + // r.RootDir/cluster_list + // | - RayClusterName_RayClusterId_SessionId_timeStamp + // | - RayClusterName_RayClusterId_SessionId_timeStamp + // r.RootDir/RayClusterName_RayClusterID_meta + // + now := time.Now() + timestamp := now.Unix() + createTime := now.UTC().Format(("2006-01-02T15:04:05Z")) + rayClusterInfo := map[string]interface{}{ + "rayClusterName": r.RayClusterName, + "rayClusterID": r.RayClusterID, + "sessionId": path.Base(r.SessionDir), + "createTimestamp": timestamp, + } + data, err := json.Marshal(rayClusterInfo) + if err != nil { + logrus.Errorf("Build cluster meta information error %v", err) + return + } + fileName := path.Clean(clistDir + "/" + r.RayClusterName + "#" + r.RayClusterID + "#" + path.Base(r.SessionDir) + "#" + fmt.Sprintf("%v", timestamp)) + if err := r.Writter.WriteFile(fileName, bytes.NewReader(data)); err != nil { + logrus.Errorf("CreateObjectIfNotExist %s error %v", fileName, err) + return + } + + if err := r.Writter.CreateDirectory(r.MetaDir); err != nil { + logrus.Errorf("CreateDirectory %s error %v", r.MetaDir, err) + return + } + + // persist basic info + clusterInfoData, err := json.MarshalIndent(&utils.ClusterInfo{ + CreateTime: createTime, + Name: r.RayClusterName, + SessionName: path.Base(r.SessionDir), + CreateTimeStamp: timestamp, + }, "", " ") + if err != nil { + logrus.Errorf("MarshalIndent error %v", err) + return + } + basicInfoFileName := path.Join(r.MetaDir, utils.OssMetaFile_BasicInfo) + logrus.Debugf("Begin to create oss object %s, value: %v ...", basicInfoFileName, string(clusterInfoData)) + if err := r.Writter.WriteFile(basicInfoFileName, bytes.NewReader(clusterInfoData)); err != nil { + logrus.Errorf("Failed to create object '%s': %v", basicInfoFileName, err) + return + } + logrus.Debugf("Create oss object %s success", basicInfoFileName) + + // 设置每隔秒执行一次 + ticker := time.NewTicker(5 * time.Second) + defer ticker.Stop() // 确保在终止时停止ticker + + for { + select { + case <-ticker.C: + if err := r.PersistMeta(); err != nil { + logrus.Errorf("Failed to persist meta: %v", err) + } + case <-stop: + logrus.Warnf("Receive stop signal, so return PushLogsLoop") + return + } + } +} +func (r *RayLogHandler) PersistMeta() error { + + logrus.Debugf("Begin to PersisMeta ...") + defer logrus.Debugf("End to PersisMeta ...") + + for _, metaurl := range metaCommonUrlInfo { + if _, err := r.PersisUrlInfo(metaurl); err != nil { + logrus.Errorf("PersisUrlInfo %s error %v", metaurl.Url, err) + // no need break or return + } + } + r.PersisMetaNodeSummary() + r.PersisMetaJobsSummary() + + return nil +} + +func (r *RayLogHandler) PersisUrlInfo(urlinfo *UrlInfo) ([]byte, error) { + + logrus.Debugf("Begin to request url %s to key file %s", urlinfo.Url, urlinfo.Key) + + resp, err := r.HttpClient.Get(urlinfo.Url) + if err != nil { + logrus.Errorf("request %s error %v", urlinfo.Url, err) + return nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + logrus.Errorf("request %s read body error %v", urlinfo.Url, err) + return nil, err + } + + md5Hash := md5.Sum(body) + md5Hex := hex.EncodeToString(md5Hash[:]) + if md5Hex == urlinfo.Hash { + logrus.Debugf("meta url %s respons data no change , no need persistent ", urlinfo.Url) + return body, nil + } else { + logrus.Debugf("meta url %s respons data has change , old hash is %s new is %s", urlinfo.Url, urlinfo.Hash, md5Hex) + urlinfo.Hash = md5Hex + } + + objectName := path.Join(r.MetaDir, urlinfo.Key) + logrus.Debugf("Begin to create oss object %s ...", objectName) + err = r.Writter.WriteFile(objectName, bytes.NewReader(body)) + if err != nil { + logrus.Errorf("Failed to create object '%s': %v", objectName, err) + return body, err + } + logrus.Debugf("Create oss object %s success", objectName) + return body, nil +} + +func (r *RayLogHandler) PersisMetaNodeSummary() { + body, err := r.PersisUrlInfo(NodeSummaryUrlInfo) + if err != nil { + logrus.Errorf("Failed to persist meta url %s: %v", NodeSummaryUrlInfo.Url, err) + return + } + + var reponData = map[string]interface{}{} + if err := json.Unmarshal(body, &reponData); err != nil { + logrus.Errorf("Ummarshal resp body error %v. key %s repons body %s", err, NodeSummaryUrlInfo.Key, reponData) + return + } + + data := reponData["data"].(map[string]interface{}) + summary := data["summary"].([]interface{}) + currentNodeIDS := make(map[string]struct{}, 0) + + for _, node := range summary { + nodeSummary := node.(map[string]interface{}) + rayletInfo := nodeSummary["raylet"].(map[string]interface{}) + nodeId := rayletInfo["nodeId"].(string) + currentNodeIDS[nodeId] = struct{}{} + } + + for oldnodeID, _ := range NodeUrlInfo { + if _, ok := currentNodeIDS[oldnodeID]; !ok { + delete(NodeUrlInfo, oldnodeID) + } + } + + for newnodeID, _ := range currentNodeIDS { + if _, ok := NodeUrlInfo[newnodeID]; !ok { + NodeUrlInfo[newnodeID] = make([]*UrlInfo, 0, 2) + + NodeUrlInfo[newnodeID] = append(NodeUrlInfo[newnodeID], + &UrlInfo{ + Key: fmt.Sprintf("%s%s", utils.OssMetaFile_Node_Prefix, newnodeID), + Url: fmt.Sprintf("http://localhost:8265/nodes/%s", newnodeID), + }) + NodeUrlInfo[newnodeID] = append(NodeUrlInfo[newnodeID], + &UrlInfo{ + Key: fmt.Sprintf("%s%s", utils.OssMetaFile_NodeLogs_Prefix, newnodeID), + Url: fmt.Sprintf("http://localhost:8265/api/v0/logs?node_id=%s", newnodeID), + }) + } + } + + for _, nodeUrlInfoList := range NodeUrlInfo { + for _, nodeUrlInfo := range nodeUrlInfoList { + if _, err := r.PersisUrlInfo(nodeUrlInfo); err != nil { + logrus.Errorf("Persisnode UrlInfo %s error %v", nodeUrlInfo.Url, err) + } + } + } + return +} + +func (r *RayLogHandler) PersisMetaJobsSummary() { + + body, err := r.PersisUrlInfo(JobsUrlInfo) + if err != nil { + logrus.Errorf("Failed to persist meta url %s: %v", JobsUrlInfo.Url, err) + return + } + var reponData = []interface{}{} + if err := json.Unmarshal(body, &reponData); err != nil { + logrus.Errorf("Ummarshal resp body error %v. key %s repons body %s", err, JobsUrlInfo.Key, reponData) + return + } + currentJobIDS := make(map[string]string, 0) + for _, jobinfo := range reponData { + job := jobinfo.(map[string]interface{}) + jobid, ok := job["job_id"].(string) + if !ok { + continue + } + status, statusOk := job["status"].(string) + if !statusOk { + continue + } + currentJobIDS[jobid] = status + } + + for jobID, status := range currentJobIDS { + if _, ok := r.JobResourcesUrlInfo[jobID]; !ok { + r.JobResourcesUrlInfo[jobID] = &JobUrlInfo{ + UrlInfos: []*UrlInfo{ + &UrlInfo{ + Key: fmt.Sprintf("%s%s", utils.OssMetaFile_JOBTASK_DETAIL_Prefix, jobID), + Url: fmt.Sprintf("http://localhost:8265/api/v0/tasks?detail=1&limit=10000&filter_keys=job_id&filter_predicates=%%3D&filter_values=%s", jobID), + }, + &UrlInfo{ + Key: fmt.Sprintf("%s%s", utils.OssMetaFile_JOBTASK_SUMMARIZE_BY_FUNC_NAME_Prefix, jobID), + Url: fmt.Sprintf("http://localhost:8265/api/v0/tasks/summarize?filter_keys=job_id&filter_predicates=%%3D&filter_values=%s", jobID), + }, + &UrlInfo{ + Key: fmt.Sprintf("%s%s", utils.OssMetaFile_JOBTASK_SUMMARIZE_BY_LINEAGE_Prefix, jobID), + Url: fmt.Sprintf("http://localhost:8265/api/v0/tasks/summarize?filter_keys=job_id&filter_predicates=%%3D&filter_values=%s&summary_by=lineage", jobID), + }, + &UrlInfo{ + Key: fmt.Sprintf("%s%s", utils.OssMetaFile_JOBDATASETS_Prefix, jobID), + Url: fmt.Sprintf("http://localhost:8265/api/data/datasets/%s", jobID), + }, + }, + Status: status, + } + } + } + + for jobID, taskurlsInfo := range r.JobResourcesUrlInfo { + if taskurlsInfo.StopPersist { + logrus.Debugf("JobID %s stop perisist, status is ", jobID, taskurlsInfo.Status) + continue + } + var hasError bool + for _, taskurl := range taskurlsInfo.UrlInfos { + if _, err := r.PersisUrlInfo(taskurl); err != nil { + logrus.Errorf("Persis task UrlInfo %s error %v", taskurl.Url, err) + // no need break + hasError = true + } + } + if taskurlsInfo.Status == JOBSTATUS_FAILED || + taskurlsInfo.Status == JOBSTATUS_STOPPED || + taskurlsInfo.Status == JOBSTATUS_SUCCEEDED { + if !hasError { + taskurlsInfo.StopPersist = true + } + } + } + + return +} diff --git a/historyserver/backend/collector/runtime/logcollector/util.go b/historyserver/backend/collector/runtime/logcollector/util.go new file mode 100644 index 00000000000..79476ab0040 --- /dev/null +++ b/historyserver/backend/collector/runtime/logcollector/util.go @@ -0,0 +1,84 @@ +package logcollector + +import "github.com/ray-project/kuberay/historyserver/utils" + +const ( + JOBSTATUS_PENDING = "PENDING" + JOBSTATUS_RUNNING = "RUNNING" + JOBSTATUS_STOPPED = "STOPPED" + JOBSTATUS_SUCCEEDED = "SUCCEEDED" + JOBSTATUS_FAILED = "FAILED" +) + +type MetaType string + +const ( + MetaTypeUrl = "URL" + MetaTypeFile = "FILE" + MetaTypeFileNames = "FILENAMES" +) + +type UrlInfo struct { + Key string + Url string + Hash string + Path string + Type string +} + +type JobUrlInfo struct { + UrlInfos []*UrlInfo + Status string + StopPersist bool +} + +var metaCommonUrlInfo = []*UrlInfo{ + &UrlInfo{ + Key: utils.OssMetaFile_ClusterStatus, + Url: "http://localhost:8265/api/cluster_status?format=1", + Type: MetaTypeUrl, + }, + &UrlInfo{ + Key: utils.OssMetaFile_LOGICAL_ACTORS, + Url: "http://localhost:8265/logical/actors", + Type: MetaTypeUrl, + }, + &UrlInfo{ + Key: utils.OssMetaFile_ALLTASKS_DETAIL, + // limit 最多 10000 + Url: "http://localhost:8265/api/v0/tasks?detail=1&limit=10000", + Type: MetaTypeUrl, + }, + + &UrlInfo{Key: utils.OssMetaFile_Applications, + Url: "http://localhost:8265/api/serve/applications/", + Type: MetaTypeUrl, + }, + + &UrlInfo{ + Key: utils.OssMetaFile_Events, + Url: "http://localhost:8265/events", + Type: MetaTypeUrl, + }, + &UrlInfo{ + Key: utils.OssMetaFile_PlacementGroups, + // limit 最多 10000 + Url: "http://localhost:8265/api/v0/placement_groups?detail=1&limit=10000", + Type: MetaTypeUrl, + }, +} + +var NodeSummaryUrlInfo = &UrlInfo{ + Key: utils.OssMetaFile_NodeSummaryKey, + Url: "http://localhost:8265/nodes?view=summary", + Type: MetaTypeUrl, +} + +// key is node id +var NodeUrlInfo = make(map[string][]*UrlInfo) + +var JobsUrlInfo = &UrlInfo{ + Key: utils.OssMetaFile_Jobs, + Url: "http://localhost:8265/api/jobs/", + Type: MetaTypeUrl, +} diff --git a/historyserver/backend/collector/runtime/runtime.go b/historyserver/backend/collector/runtime/runtime.go new file mode 100644 index 00000000000..e00916fbfab --- /dev/null +++ b/historyserver/backend/collector/runtime/runtime.go @@ -0,0 +1,46 @@ +package runtime + +import ( + "fmt" + "net/http" + "path" + "strings" + "time" + + "github.com/ray-project/kuberay/historyserver/backend/collector/runtime/logcollector" + "github.com/ray-project/kuberay/historyserver/backend/collector/storage" + "github.com/ray-project/kuberay/historyserver/backend/types" + "github.com/ray-project/kuberay/historyserver/utils" +) + +func NewCollector(config *types.RayCollectorConfig, writter storage.StorageWritter) RayLogCollector { + handler := logcollector.RayLogHandler{ + EnableMeta: config.Role == "Head", + LogFiles: make(chan string), + + RootDir: config.RootDir, + SessionDir: config.SessionDir, + + RayClusterName: config.RayClusterName, + RayClusterID: config.RayClusterID, + RayNodeName: config.RayNodeName, + + LogBatching: config.LogBatching, + PushInterval: config.PushInterval, + + HttpClient: &http.Client{ + Transport: &http.Transport{ + MaxIdleConns: 100, // 最大空闲连接数 + MaxIdleConnsPerHost: 20, // 每个主机的最大空闲连接数 + IdleConnTimeout: 90 * time.Second, // 空闲连接的超时时间 + }, + }, + Writter: writter, + } + logDir := strings.TrimSpace(path.Join(config.SessionDir, utils.RAY_SESSIONDIR_LOGDIR_NAME)) + handler.LogDir = logDir + rootMetaDir := fmt.Sprintf("%s/", path.Clean(path.Join(handler.RootDir, handler.RayClusterName+"_"+handler.RayClusterID, "meta"))) + handler.MetaDir = rootMetaDir + + return &handler +} diff --git a/historyserver/backend/collector/storage/aliyunoss/README.md b/historyserver/backend/collector/storage/aliyunoss/README.md new file mode 100644 index 00000000000..5414899b69b --- /dev/null +++ b/historyserver/backend/collector/storage/aliyunoss/README.md @@ -0,0 +1,11 @@ +This module is the collector for aliyunoss. + +Oss endpoint and oss bucket are read from /var/collector-config/data. + +Content in /var/collector-config/data should be in json format, like +`{"ossBucket": "", "ossEndpoint": ""}` + +Set `--runtime-class-name=aliyunoss` to enable this module. + +Currently this module can only be used in ack environment. Oidc must be +enabled for the cluster, and permission for write the oss must be granted. diff --git a/historyserver/backend/collector/storage/aliyunoss/config/types.go b/historyserver/backend/collector/storage/aliyunoss/config/types.go new file mode 100644 index 00000000000..d38e6c8c330 --- /dev/null +++ b/historyserver/backend/collector/storage/aliyunoss/config/types.go @@ -0,0 +1,59 @@ +// Package config is +/* +Copyright 2024 by the bingyu bingyu.zj@alibaba-inc.com Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config + +import ( + "k8s.io/apimachinery/pkg/util/sets" +) + +type EnterConfig struct { + Module string + ModuleExecBinary string + EnterOssExpireHour int + WatchLogDir string + EnableMeta bool +} + +type GlobalConfig struct { + OSSEndpoint string + OSSRegion string + OSSBucket string + OSSHistoryServerDir string +} + +type RayMetaHanderConfig struct { + GlobalConfig + RayClusterName string + RayClusterID string + OSSExpireHour int +} + +type RayHistoryServerConfig struct { + GlobalConfig + DashBoardDir string + + ArmsRegionId string + ACKClusterId string + WebAppId string + WebAppSecret string + LocalServiceName string + AllowedUID sets.Set[string] + AllowedAID sets.Set[string] + + MaxOssListLimit int +} diff --git a/historyserver/backend/collector/storage/aliyunoss/config/validate.go b/historyserver/backend/collector/storage/aliyunoss/config/validate.go new file mode 100644 index 00000000000..5a23cc7cb62 --- /dev/null +++ b/historyserver/backend/collector/storage/aliyunoss/config/validate.go @@ -0,0 +1,69 @@ +// Package config is +/* +Copyright 2024 by the zhangjie bingyu.zj@alibaba-inc.com Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package config + +import ( + "k8s.io/apimachinery/pkg/util/validation/field" +) + +// ValidateGlobalConfig is +func ValidateGlobalConfig(c *GlobalConfig, fldpath *field.Path) field.ErrorList { + var allErrs field.ErrorList + if len(c.OSSEndpoint) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.OSSEndpoint, "oss_endpoint must be set")) + } + if len(c.OSSRegion) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.OSSRegion, "oss_region must be set")) + } + if len(c.OSSBucket) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.OSSBucket, "oss_bucket must be set")) + } + if len(c.OSSHistoryServerDir) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.OSSHistoryServerDir, "oss_historyserver_root_dir must be set")) + } + + return allErrs +} + +// ValidateMetaHanderConfig is +func ValidateMetaHanderConfig(c *RayMetaHanderConfig, fldpath *field.Path) field.ErrorList { + var allErrs field.ErrorList + if len(c.RayClusterName) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.RayClusterName, "ray_cluster_name must be set")) + } + if len(c.RayClusterID) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.RayClusterID, "ray_cluster_id must be set")) + } + return allErrs +} +func ValidatRayHistoryServerConfig(c *RayHistoryServerConfig, fldpath *field.Path) field.ErrorList { + var allErrs field.ErrorList + if len(c.DashBoardDir) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.DashBoardDir, "dashboard-dir must be set")) + } + if len(c.LocalServiceName) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.LocalServiceName, "local_service_name must be set")) + } + if len(c.WebAppId) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.WebAppId, "webapp_id must be set")) + } + if len(c.WebAppSecret) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.WebAppSecret, "webapp_secret must be set")) + } + + return allErrs +} diff --git a/historyserver/backend/collector/storage/aliyunoss/ray/config.go b/historyserver/backend/collector/storage/aliyunoss/ray/config.go new file mode 100644 index 00000000000..4784f94e269 --- /dev/null +++ b/historyserver/backend/collector/storage/aliyunoss/ray/config.go @@ -0,0 +1,24 @@ +package ray + +import "github.com/ray-project/kuberay/historyserver/backend/types" + +type config struct { + types.RayCollectorConfig + + OSSEndpoint string + OSSBucket string +} + +func (c *config) complete(rcc *types.RayCollectorConfig, jd map[string]interface{}) { + c.RayCollectorConfig = *rcc + c.OSSBucket = jd["ossBucket"].(string) + c.OSSEndpoint = jd["ossEndpoint"].(string) +} + +func (c *config) completeHSConfig(rcc *types.RayHistoryServerConfig, jd map[string]interface{}) { + c.RayCollectorConfig = types.RayCollectorConfig{ + RootDir: rcc.RootDir, + } + c.OSSBucket = jd["ossBucket"].(string) + c.OSSEndpoint = jd["ossEndpoint"].(string) +} diff --git a/historyserver/backend/collector/storage/aliyunoss/ray/ray.go b/historyserver/backend/collector/storage/aliyunoss/ray/ray.go new file mode 100644 index 00000000000..5fc947391ae --- /dev/null +++ b/historyserver/backend/collector/storage/aliyunoss/ray/ray.go @@ -0,0 +1,209 @@ +// Package ray is +/* +Copyright 2024 by the zhangjie bingyu.zj@alibaba-inc.com Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package ray + +import ( + "bytes" + "fmt" + "io" + "net/http" + "path" + "path/filepath" + "sort" + "strconv" + "strings" + "time" + + "github.com/aliyun/aliyun-oss-go-sdk/oss" + "github.com/sirupsen/logrus" + + "github.com/ray-project/kuberay/historyserver/backend/collector/storage" + "github.com/ray-project/kuberay/historyserver/backend/collector/storage/aliyunoss/rrsa" + "github.com/ray-project/kuberay/historyserver/backend/types" + "github.com/ray-project/kuberay/historyserver/utils" +) + +type RayLogsHandler struct { + OssBucket *oss.Bucket + SessionDir string + OssRootDir string + LogDir string + LogFiles chan string + RayClusterName string + RayClusterID string + RayNodeName string + HttpClient *http.Client + + LogBatching int + PushInterval time.Duration +} + +func (r *RayLogsHandler) CreateDirectory(d string) error { + objectDir := fmt.Sprintf("%s/", path.Clean(d)) + + isExist, err := r.OssBucket.IsObjectExist(objectDir) + if err != nil { + logrus.Errorf("Failed to check if dirObject %s exists: %v", objectDir, err) + return err + } + if !isExist { + logrus.Infof("Begin to create oss dir %s ...", objectDir) + err = r.OssBucket.PutObject(objectDir, bytes.NewReader([]byte(""))) + if err != nil { + logrus.Errorf("Failed to create directory '%s': %v", objectDir, err) + return err + } + logrus.Infof("Create oss dir %s success", objectDir) + } + return nil +} + +func (r *RayLogsHandler) Append(file string, reader io.Reader, appendPosition int64) (nextPod int64, err error) { + return r.OssBucket.AppendObject(file, reader, appendPosition) +} + +func (r *RayLogsHandler) WriteFile(file string, reader io.Reader) error { + return r.OssBucket.PutObject(file, reader) +} + +func (r *RayLogsHandler) List() []utils.ClusterInfo { + // 初始的继续标记 + continueToken := "" + clusters := make(utils.ClusterInfoList, 0, 10) + logrus.Debugf("Prepare to get list clusters info ...") + + getClusters := func() { + for { + options := []oss.Option{ + oss.Prefix(path.Join(r.OssRootDir, "cluster_list") + "/"), + oss.ContinuationToken(continueToken), + oss.MaxKeys(100), + oss.Delimiter("/"), + } + + // 列举所有文件 + lsRes, err := r.OssBucket.ListObjectsV2(options...) + if err != nil { + logrus.Errorf("Failed to list objects from %s: %v", path.Join(r.OssRootDir, "cluster_list")+"/", err) + return + } + logrus.Infof("Returned objects in %v. length of lsRes.Objects: %v, length of lsRes.CommonPrefixes: %v", path.Join(r.OssRootDir, "cluster_list")+"/", len(lsRes.Objects), + len(lsRes.CommonPrefixes)) + for _, objects := range lsRes.Objects { + logrus.Infof("Process %++v", objects) + c := &utils.ClusterInfo{} + metas := strings.Split(objects.Key, "#") + if len(metas) < 4 { + continue + } + c.Name = path.Base(metas[0]) + "_" + metas[1] + c.SessionName = metas[2] + cs, _ := strconv.ParseInt(metas[3], 10, 64) + c.CreateTimeStamp = cs + t := time.Unix(cs, 0) + c.CreateTime = t.UTC().Format(("2006-01-02T15:04:05Z")) + clusters = append(clusters, *c) + } + if lsRes.IsTruncated { + continueToken = lsRes.NextContinuationToken + } else { + break + } + } + } + getClusters() + sort.Sort(clusters) + return clusters +} + +func (r *RayLogsHandler) GetContent(clusterId string, fileName string) io.Reader { + logrus.Infof("Prepare to get object %s info ...", fileName) + options := []oss.Option{} + body, err := r.OssBucket.GetObject(fileName, options...) + if err != nil { + logrus.Errorf("Failed to get object %s: %v", fileName, err) + return nil + } + defer body.Close() + + data, err := io.ReadAll(body) + if err != nil { + logrus.Errorf("Failed to read all data from object %s : %v", fileName, err) + return nil + } + return bytes.NewReader(data) +} + +func NewReader(c *types.RayHistoryServerConfig, jd map[string]interface{}) (storage.StorageReader, error) { + config := &config{} + config.completeHSConfig(c, jd) + + return New(config) +} + +func NewWritter(c *types.RayCollectorConfig, jd map[string]interface{}) (storage.StorageWritter, error) { + config := &config{} + config.complete(c, jd) + + return New(config) +} + +func New(c *config) (*RayLogsHandler, error) { + logrus.Infof("Begin to create oss client ...") + httpClient := &http.Client{ + Timeout: 5 * time.Second, // 设置超时时间 + } + provider, err := rrsa.NewOssProvider() + if err != nil { + logrus.Fatalf("Create rrsa provider error %v", err) + } + client, err := oss.New(c.OSSEndpoint, "", "", oss.HTTPClient(httpClient), oss.SetCredentialsProvider(provider)) + if err != nil { + logrus.Fatalf("Create oss client error %v", err) + } + logrus.Infof("Begin to create oss bucket %s ...", c.OSSBucket) + bucket, err := client.Bucket(c.OSSBucket) + if err != nil { + logrus.Fatalf("Create oss bucket instance error %v", err) + } + sessionDir := strings.TrimSpace(c.SessionDir) + sessionDir = filepath.Clean(sessionDir) + + logdir := strings.TrimSpace(path.Join(sessionDir, utils.RAY_SESSIONDIR_LOGDIR_NAME)) + logdir = filepath.Clean(logdir) + logrus.Infof("Clean logdir is %s", logdir) + + return &RayLogsHandler{ + OssBucket: bucket, + SessionDir: sessionDir, + OssRootDir: c.RootDir, + LogDir: logdir, + LogFiles: make(chan string, 100), + RayClusterName: c.RayClusterName, + RayClusterID: c.RayClusterID, + RayNodeName: c.RayNodeName, + HttpClient: &http.Client{ + Transport: &http.Transport{ + MaxIdleConns: 100, // 最大空闲连接数 + MaxIdleConnsPerHost: 20, // 每个主机的最大空闲连接数 + IdleConnTimeout: 90 * time.Second, // 空闲连接的超时时间 + }, + }, + LogBatching: c.LogBatching, + PushInterval: c.PushInterval, + }, nil +} diff --git a/historyserver/backend/collector/storage/aliyunoss/ray/ray_test.go b/historyserver/backend/collector/storage/aliyunoss/ray/ray_test.go new file mode 100644 index 00000000000..c72e3179e83 --- /dev/null +++ b/historyserver/backend/collector/storage/aliyunoss/ray/ray_test.go @@ -0,0 +1,62 @@ +// Package logs is +/* +Copyright 2024 by the zhangjie bingyu.zj@alibaba-inc.com Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package ray + +import ( + "os" + "path" + "path/filepath" + "strings" + "testing" + + "github.com/sirupsen/logrus" +) + +func TestTrim(t *testing.T) { + absoluteLogPathName := " /tmp/ray/test/LLogs/events///aa/a.txt " + logdir := "/tmp/ray/test/lLogs/" + + absoluteLogPathName = strings.TrimSpace(absoluteLogPathName) + absoluteLogPathName = filepath.Clean(absoluteLogPathName) + + logdir = strings.TrimSpace(logdir) + logdir = filepath.Clean(logdir) + + relativePath := strings.TrimPrefix(absoluteLogPathName, logdir+"/") + //relativePath := strings.TrimPrefix(absoluteLogPathName, logdir) + // 分割相对路径为子目录和文件名 + subdir, filename := filepath.Split(relativePath) + test_path_join := path.Join("aa./b/c/d", "e") + t.Logf("file [%s] logdir [%s] subdir %s filename %s", absoluteLogPathName, + logdir, subdir, filename) + t.Logf("test_path_join [%s]", test_path_join) +} + +func TestWalk(t *testing.T) { + watchPath := "/tmp/ray/test/LLogs/" + filepath.Walk(watchPath, func(path string, info os.FileInfo, err error) error { + if err != nil { + logrus.Errorf("Walk path error %v", err) + return err // 返回错误 + } + // 检查是否是文件 + if !info.IsDir() { + logrus.Infof("Find new file %s", path) // 输出文件路径 + } + return nil + }) +} diff --git a/historyserver/backend/collector/storage/aliyunoss/rrsa/credential.go b/historyserver/backend/collector/storage/aliyunoss/rrsa/credential.go new file mode 100644 index 00000000000..3f44e951269 --- /dev/null +++ b/historyserver/backend/collector/storage/aliyunoss/rrsa/credential.go @@ -0,0 +1,76 @@ +package rrsa + +import ( + "log" + + "github.com/alibabacloud-go/tea/tea" + "github.com/aliyun/aliyun-oss-go-sdk/oss" + "github.com/aliyun/credentials-go/credentials" +) + +func newCredential() (credentials.Credential, error) { + // https://www.alibabacloud.com/help/doc-detail/378661.html + credType := "oidc_role_arn" + cred, err := credentials.NewCredential(&credentials.Config{ + Type: &credType, + }) + return cred, err +} + +type Credentials struct { + AccessKeyId string + AccessKeySecret string + SecurityToken string +} + +func NewProvider() (credentials.Credential, error) { + return newCredential() +} + +func NewOssProvider() (*OssCredentialsProvider, error) { + cred, err := newCredential() + if err != nil { + return nil, err + } + return &OssCredentialsProvider{cred: cred}, nil +} + +type OssCredentialsProvider struct { + cred credentials.Credential +} + +func (c *Credentials) GetAccessKeyID() string { + return c.AccessKeyId +} + +func (c *Credentials) GetAccessKeySecret() string { + return c.AccessKeySecret +} + +func (c *Credentials) GetSecurityToken() string { + return c.SecurityToken +} + +func (p *OssCredentialsProvider) GetCredentials() oss.Credentials { + id, err := p.cred.GetAccessKeyId() + if err != nil { + log.Printf("get access key id failed: %+v", err) + return &Credentials{} + } + secret, err := p.cred.GetAccessKeySecret() + if err != nil { + log.Printf("get access key secret failed: %+v", err) + return &Credentials{} + } + token, err := p.cred.GetSecurityToken() + if err != nil { + log.Printf("get access security token failed: %+v", err) + return &Credentials{} + } + + return &Credentials{ + AccessKeyId: tea.StringValue(id), + AccessKeySecret: tea.StringValue(secret), + SecurityToken: tea.StringValue(token), + } +} diff --git a/historyserver/backend/collector/storage/interface.go b/historyserver/backend/collector/storage/interface.go new file mode 100644 index 00000000000..20a28dac6ab --- /dev/null +++ b/historyserver/backend/collector/storage/interface.go @@ -0,0 +1,25 @@ +package storage + +import ( + "io" + + "github.com/ray-project/kuberay/historyserver/utils" +) + +// StorageWriter is the interface for storage writer. +type StorageWritter interface { + CreateDirectory(path string) error + Append(file string, reader io.Reader, appendPosition int64) (nextPod int64, err error) + WriteFile(file string, reader io.Reader) error +} + +// HistoryServer create readers for each storage runtime +// Depends on the implementation of front end. +type StorageReader interface { + // need to return all available files from backend + List() []utils.ClusterInfo + // for log, pass filename to this func + // for metadata, fileName is generated by historyserver, which will obey the same rule as collector to make sure the historyserver can ready the right file. + // + GetContent(clusterId string, fileName string) io.Reader +} diff --git a/historyserver/backend/historyserver/reader.go b/historyserver/backend/historyserver/reader.go new file mode 100644 index 00000000000..b75feeaf78b --- /dev/null +++ b/historyserver/backend/historyserver/reader.go @@ -0,0 +1,137 @@ +package historyserver + +import ( + "encoding/json" + "io" + "net/http" + "os" + "path" + "path/filepath" + "sort" + + "github.com/emicklei/go-restful/v3" + "github.com/ray-project/kuberay/historyserver/utils" + "github.com/sirupsen/logrus" +) + +func (s *ServerHandler) listClusters(limit int) []utils.ClusterInfo { + // 初始的继续标记 + logrus.Debugf("Prepare to get list clusters info ...") + clusters := s.reader.List() + sort.Sort(utils.ClusterInfoList(clusters)) + if limit > 0 { + clusters = clusters[:limit] + } + return clusters +} + +func (s *ServerHandler) MetaKeyInfo(rayClusterNameID, key string) []byte { + baseObject := path.Join(utils.GetMetaDirByNameID(s.rootDir, rayClusterNameID), key) + logrus.Infof("Prepare to get object %s info ...", baseObject) + body := s.reader.GetContent(rayClusterNameID, baseObject) + data, err := io.ReadAll(body) + if err != nil { + logrus.Errorf("Failed to read all data from object %s : %v", baseObject, err) + return nil + } + return data +} + +func (s *ServerHandler) LogKeyInfo(rayClusterNameID, nodeID, key string, lines int64) []byte { + baseObject := path.Join(utils.GetLogDirByNameID(s.rootDir, rayClusterNameID, nodeID), key) + logrus.Infof("Prepare to get object %s info ...", baseObject) + body := s.reader.GetContent(rayClusterNameID, baseObject) + data, err := io.ReadAll(body) + if err != nil { + logrus.Errorf("Failed to read all data from object %s : %v", baseObject, err) + return nil + } + return data +} + +func (s *ServerHandler) staticFileHandler(req *restful.Request, resp *restful.Response) { + logrus.Infof("static parameters %++v", req.PathParameters()) + logrus.Infof("static request %++v", *req.Request) + // logrus.Infof("static query %++v", req.) + // Get the path parameter + path := req.PathParameter("path") + + // Construct the full path to the static directory + fullPath := filepath.Join(s.dashboardDir, "static", path) + logrus.Infof("staticFileHandler fullpath %s", fullPath) + + // Check if the full path exists + if _, err := os.Stat(fullPath); os.IsNotExist(err) { + resp.WriteErrorString(http.StatusNotFound, "File or directory not found") + logrus.Errorf("File or directory %s not found", fullPath) + return + } + + // Serve the file or directory + if isDir(fullPath) { + // List files in the directory + files, err := os.ReadDir(fullPath) + if err != nil { + resp.WriteErrorString(http.StatusInternalServerError, "Error reading directory") + logrus.Errorf("Error reading directory %s %s", fullPath, err) + return + } + resp.WriteAsJson(files) + } else { + // Serve the file + http.ServeFile(resp.ResponseWriter, req.Request, fullPath) + logrus.Infof("ServerFile %s", fullPath) + } +} + +func isDir(path string) bool { + fileInfo, err := os.Stat(path) + if err != nil { + return false + } + return fileInfo.IsDir() +} + +type grafanaHealthReturnMsg struct { + Result bool `json:"result"` + Msg string `json:"msg"` + Data grafanaData `json:"data"` +} + +type grafanaData struct { + GrafanaHost string `json:"grafanaHost"` + SessionName string `json:"sessionName"` + DashboardDatasource string `json:"dashboardDatasource"` + DashboardUids map[string]string `json:"dashboardUids"` +} + +func (h *ServerHandler) getGrafanaHealth(req *restful.Request, resp *restful.Response) { + data := grafanaData{ + GrafanaHost: "https://g.console.aliyun.com", + SessionName: req.Attribute(COOKIE_SESSION_NAME_KEY).(string), + DashboardDatasource: "Prometheus", + DashboardUids: map[string]string{ + "default": "ray_cluster", + "default_params": "orgId=1", + "serve": "ray_serve", + "serve_params": "orgId=1", + "data": "ray_data", + "data_params": "orgId=1", + "ray_serve_deployment": "ray_serve_deployment", + "ray_serve_deployment_params": "orgId=1", + }, + } + ret := grafanaHealthReturnMsg{ + Result: true, + Msg: "Grafana is Running", + Data: data, + } + retStr, err := json.Marshal(ret) + if err != nil { + logrus.Errorf("Error: %v, Value: %v", err, ret) + resp.WriteErrorString(400, err.Error()) + return + } + logrus.Info(string(retStr)) + resp.Write([]byte(retStr)) +} diff --git a/historyserver/backend/historyserver/router.go b/historyserver/backend/historyserver/router.go new file mode 100644 index 00000000000..7f7c23299af --- /dev/null +++ b/historyserver/backend/historyserver/router.go @@ -0,0 +1,453 @@ +package historyserver + +import ( + "encoding/json" + "fmt" + "net/http" + "os" + "path" + "strconv" + + "github.com/emicklei/go-restful/v3" + "github.com/ray-project/kuberay/historyserver/utils" + "github.com/sirupsen/logrus" +) + +const ( + COOKIE_CLUSTER_NAME_KEY = "cluster_name" + COOKIE_SESSION_NAME_KEY = "session_name" +) + +func routerClusters(s *ServerHandler) { + ws := new(restful.WebService) + defer restful.Add(ws) + + ws.Path("/clusters").Consumes(restful.MIME_JSON).Produces(restful.MIME_JSON) //.Filter(s.loginWrapper) + ws.Route(ws.GET("/").To(s.getClusters). + Doc("get all clusters"). + Writes([]string{})) +} + +func routerNodes(s *ServerHandler) { + ws := new(restful.WebService) + defer restful.Add(ws) + ws.Path("/nodes").Consumes(restful.MIME_JSON).Produces(restful.MIME_JSON) //.Filter(s.loginWrapper) + ws.Route(ws.GET("/").To(s.getNodes).Filter(s.CookieHandle). + Doc("get nodes for a given clusters").Param(ws.QueryParameter("view", "such as summary")). + Writes("")) + ws.Route(ws.GET("/{node_id}").To(s.getNode).Filter(s.CookieHandle). + Doc("get specifical nodes "). + Param(ws.PathParameter("node_id", "node_id")). + Writes("")) +} + +func routerEvents(s *ServerHandler) { + ws := new(restful.WebService) + defer restful.Add(ws) + ws.Path("/events").Consumes(restful.MIME_JSON).Produces(restful.MIME_JSON) //.Filter(s.loginWrapper) + ws.Route(ws.GET("/").To(s.getEvents).Filter(s.CookieHandle). + Doc("get events"). + Writes("")) +} + +func routerAPI(s *ServerHandler) { + ws := new(restful.WebService) + defer restful.Add(ws) + ws.Path("/api").Consumes(restful.MIME_JSON).Produces(restful.MIME_JSON) //.Filter(s.loginWrapper) + ws.Route(ws.GET("/cluster_status").To(s.getClusterStatus).Filter(s.CookieHandle). + Doc("get clusters status").Param(ws.QueryParameter("format", "such as 1")). + Writes("")) // 这里你可以替换为具体的返回类型 + ws.Route(ws.GET("/grafana_health").To(s.getGrafanaHealth).Filter(s.CookieHandle). + Doc("get grafana_health"). + Writes("")) // 这里你可以替换为具体的返回类型 + ws.Route(ws.GET("/prometheus_health").To(s.getPrometheusHealth).Filter(s.CookieHandle). + Doc("get prometheus_health"). + Writes("")) // 这里你可以替换为具体的返回类型 + + ws.Route(ws.GET("/jobs").To(s.getJobs).Filter(s.CookieHandle). + Doc("get jobs"). + Writes("")) // 这里你可以替换为具体的返回类型 + + ws.Route(ws.GET("/jobs/{job_id}").To(s.getJob).Filter(s.CookieHandle). + Doc("get single job"). + Param(ws.PathParameter("job_id", "job_id")). + Writes("")) // 这里你可以替换为具体的返回类型 + + ws.Route(ws.GET("/data/datasets/{job_id}").To(s.getDatasets).Filter(s.CookieHandle). + Doc("get datasets"). + Param(ws.PathParameter("job_id", "job_id")). + Writes("")) // 这里你可以替换为具体的返回类型 + + ws.Route(ws.GET("/serve/applications/").To(s.getServeApplications).Filter(s.CookieHandle). + Doc("get appliations"). + Writes("")) // 这里你可以替换为具体的返回类型 + + ws.Route(ws.GET("/v0/placement_groups/").To(s.getPlacementGroups).Filter(s.CookieHandle). + Doc("get placement_groups"). + Writes("")) // 这里你可以替换为具体的返回类型 + + ws.Route(ws.GET("/v0/logs").To(s.getNodeLogs).Filter(s.CookieHandle). + Doc("get appliations").Param(ws.QueryParameter("node_id", "node_id")). + Writes("")) // 这里你可以替换为具体的返回类型 + ws.Route(ws.GET("/v0/logs/file").To(s.getNodeLogFile).Filter(s.CookieHandle). + Doc("get logfile").Param(ws.QueryParameter("node_id", "node_id")). + Param(ws.QueryParameter("filename", "filename")). + Param(ws.QueryParameter("lines", "lines")). + Param(ws.QueryParameter("format", "format")). + Writes("")) // 这里你可以替换为具体的返回类型 + + ws.Route(ws.GET("/v0/tasks").To(s.getTaskDetail).Filter(s.CookieHandle). + Doc("get task detail ").Param(ws.QueryParameter("limit", "limit")). + Param(ws.QueryParameter("filter_keys", "filter_keys")). + Param(ws.QueryParameter("filter_predicates", "filter_predicates")). + Param(ws.QueryParameter("filter_values", "filter_values")). + Writes("")) // 这里你可以替换为具体的返回类型 + + ws.Route(ws.GET("/v0/tasks/summarize").To(s.getTaskSummarize).Filter(s.CookieHandle). + Doc("get summarize"). + Param(ws.QueryParameter("filter_keys", "filter_keys")). + Param(ws.QueryParameter("filter_predicates", "filter_predicates")). + Param(ws.QueryParameter("filter_values", "filter_values")). + Param(ws.QueryParameter("summary_by", "summary_by")). + Writes("")) // 这里你可以替换为具体的返回类型 +} + +func routerRoot(s *ServerHandler) { + ws := new(restful.WebService) + defer restful.Add(ws) + ws.Route(ws.GET("/").To(func(_ *restful.Request, w *restful.Response) { + data, err := os.ReadFile(path.Join(s.dashboardDir, "index.html")) // 确保 index.html 文件存在 + if err != nil { + http.Error(w, "could not read HTML file", http.StatusInternalServerError) + logrus.Errorf("could not read HTML file") + return + } + w.Header().Set("Content-Type", "text/html") + w.Write(data) + }).Writes("")) +} + +func routerHealthz(s *ServerHandler) { + + http.HandleFunc("/readz", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/plain") + w.Write([]byte("ok")) + logrus.Debugf("request /readz") + }) + http.HandleFunc("/livez", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/plain") + w.Write([]byte("ok")) + logrus.Debugf("request /livez") + }) + +} + +func routerStatic(s *ServerHandler) { + ws := new(restful.WebService) + defer restful.Add(ws) + ws.Path("/static").Consumes("*/*").Produces("*/*") + ws.Route(ws.GET("/{path:*}").To(s.staticFileHandler). + Doc("Get static file or directory"). + Param(ws.PathParameter("path", "path of the static file").DataType("string"))) + +} + +func routerLogical(s *ServerHandler) { + ws := new(restful.WebService) + defer restful.Add(ws) + ws.Path("/logical").Consumes(restful.MIME_JSON).Produces(restful.MIME_JSON) //.Filter(s.loginWrapper) + ws.Route(ws.GET("/actors").To(s.getLogicalActors).Filter(s.CookieHandle). + Doc("get logical actors"). + Writes("")) // 这里你可以替换为具体的返回类型 + ws.Route(ws.GET("/actors/{single_actor}").To(s.getLogicalActor).Filter(s.CookieHandle). + Doc("get logical single actor"). + Param(ws.PathParameter("single_actor", "single_actor")). + Writes("")) // 这里你可以替换为具体的返回类型 + +} + +func (s *ServerHandler) RegisterRouter() { + routerClusters(s) + routerNodes(s) + routerEvents(s) + routerAPI(s) + routerRoot(s) + routerHealthz(s) + routerStatic(s) + routerLogical(s) +} + +func (s *ServerHandler) getClusters(req *restful.Request, resp *restful.Response) { + clusters := s.listClusters(s.maxClusters) + resp.WriteAsJson(clusters) +} + +// getNodes 返回指定集群的节点 +func (s *ServerHandler) getNodes(req *restful.Request, resp *restful.Response) { + clusterNameID := req.Attribute(COOKIE_CLUSTER_NAME_KEY).(string) + view := req.QueryParameter("view") + logrus.Warnf("view is %s, but not do anything", view) + data := s.MetaKeyInfo(clusterNameID, utils.OssMetaFile_NodeSummaryKey) + + resp.Write(data) +} + +func (s *ServerHandler) getEvents(req *restful.Request, resp *restful.Response) { + clusterNameID := req.Attribute(COOKIE_CLUSTER_NAME_KEY).(string) + data := s.MetaKeyInfo(clusterNameID, utils.OssMetaFile_Events) + resp.Write(data) +} +func (s *ServerHandler) getPrometheusHealth(req *restful.Request, resp *restful.Response) { + data := `{"result": true, "msg": "prometheus running", "data": {}}` + resp.Write([]byte(data)) +} +func (s *ServerHandler) getJobs(req *restful.Request, resp *restful.Response) { + clusterNameID := req.Attribute(COOKIE_CLUSTER_NAME_KEY).(string) + data := s.MetaKeyInfo(clusterNameID, utils.OssMetaFile_Jobs) + resp.Write(data) +} +func (s *ServerHandler) getNode(req *restful.Request, resp *restful.Response) { + clusterNameID := req.Attribute(COOKIE_CLUSTER_NAME_KEY).(string) + node_id := req.PathParameter("node_id") + data := s.MetaKeyInfo(clusterNameID, fmt.Sprintf("%s%s", utils.OssMetaFile_Node_Prefix, node_id)) + resp.Write(data) +} + +func (s *ServerHandler) getJob(req *restful.Request, resp *restful.Response) { + clusterNameID := req.Attribute(COOKIE_CLUSTER_NAME_KEY).(string) + job_id := req.PathParameter("job_id") + logrus.Debugf("job_id is %s", job_id) + + data := s.MetaKeyInfo(clusterNameID, utils.OssMetaFile_Jobs) + allData := []map[string]interface{}{} + if err := json.Unmarshal(data, &allData); err != nil { + logrus.Errorf("Ummarshal alljobs error%v", err) + resp.WriteErrorString(http.StatusInternalServerError, err.Error()) + return + } + var job map[string]interface{} + var find bool + for _, singleData := range allData { + id, ok := singleData["job_id"].(string) + if ok && id == job_id { + job = singleData + find = true + break + } + } + if !find { + logrus.Warnf("Can not find jobid %s from alljobs", job_id) + } else { + logrus.Infof("Find jobid %s from alljobs", job_id) + } + jobData, err := json.MarshalIndent(job, "", " ") + if err != nil { + resp.WriteErrorString(http.StatusInternalServerError, err.Error()) + return + } + resp.Write(jobData) +} + +func (s *ServerHandler) getDatasets(req *restful.Request, resp *restful.Response) { + clusterNameID := req.Attribute(COOKIE_CLUSTER_NAME_KEY).(string) + job_id := req.PathParameter("job_id") + data := s.MetaKeyInfo(clusterNameID, fmt.Sprintf("%s%s", utils.OssMetaFile_JOBDATASETS_Prefix, job_id)) + resp.Write(data) +} + +func (s *ServerHandler) getServeApplications(req *restful.Request, resp *restful.Response) { + clusterNameID := req.Attribute(COOKIE_CLUSTER_NAME_KEY).(string) + data := s.MetaKeyInfo(clusterNameID, utils.OssMetaFile_Applications) + resp.Write(data) +} + +func (s *ServerHandler) getPlacementGroups(req *restful.Request, resp *restful.Response) { + clusterNameID := req.Attribute(COOKIE_CLUSTER_NAME_KEY).(string) + data := s.MetaKeyInfo(clusterNameID, utils.OssMetaFile_PlacementGroups) + resp.Write(data) +} + +func (s *ServerHandler) getClusterStatus(req *restful.Request, resp *restful.Response) { + clusterNameID := req.Attribute(COOKIE_CLUSTER_NAME_KEY).(string) + data := s.MetaKeyInfo(clusterNameID, utils.OssMetaFile_ClusterStatus) + + resp.Write(data) +} + +func (s *ServerHandler) getNodeLogs(req *restful.Request, resp *restful.Response) { + clusterNameID := req.Attribute(COOKIE_CLUSTER_NAME_KEY).(string) + nodeId := req.QueryParameter("node_id") + data := s.MetaKeyInfo(clusterNameID, fmt.Sprintf("%s%s", utils.OssMetaFile_NodeLogs_Prefix, nodeId)) + // 根据 clustername 返回节点信息,以下是示例 + //resp.WriteEntity(data) + resp.Write(data) +} + +func (s *ServerHandler) getLogicalActors(req *restful.Request, resp *restful.Response) { + clusterNameID := req.Attribute(COOKIE_CLUSTER_NAME_KEY).(string) + data := s.MetaKeyInfo(clusterNameID, utils.OssMetaFile_LOGICAL_ACTORS) + resp.Write(data) +} + +func (s *ServerHandler) getLogicalActor(req *restful.Request, resp *restful.Response) { + clusterNameID := req.Attribute(COOKIE_CLUSTER_NAME_KEY).(string) + nodeId := req.PathParameter("single_actor") + data := s.MetaKeyInfo(clusterNameID, utils.OssMetaFile_LOGICAL_ACTORS) + var allActors = map[string]interface{}{} + replyActorInfo := ReplyActorInfo{ + Result: true, + Msg: "All actors fetched.", + Data: ActorInfoData{}, + } + if err := json.Unmarshal(data, &allActors); err != nil { + logrus.Errorf("Ummarshal allTask error %v", err) + resp.WriteErrorString(http.StatusInternalServerError, err.Error()) + return + } + allActorsData := allActors["data"].(map[string]interface{}) + actors := allActorsData["actors"].(map[string]interface{}) + for k, actor := range actors { + a := actor.(map[string]interface{}) + if k == nodeId { + replyActorInfo.Data.Detail = a + break + } + } + actData, err := json.MarshalIndent(&replyActorInfo, "", " ") + if err != nil { + resp.WriteErrorString(http.StatusInternalServerError, err.Error()) + return + } + + resp.Write(actData) +} + +func (s *ServerHandler) getNodeLogFile(req *restful.Request, resp *restful.Response) { + resp.Header().Set("Content-Type", "text/plain") + clusterNameID := req.Attribute(COOKIE_CLUSTER_NAME_KEY).(string) + nodeId := req.QueryParameter("node_id") + filename := req.QueryParameter("filename") + lines := req.QueryParameter("lines") + logrus.Infof("get logfile lines %s", lines) + format := req.QueryParameter("format") + logrus.Infof("format is %s", format) + limit, err := strconv.ParseInt(lines, 10, 64) + if err != nil { + logrus.Errorf("ParseInt error ") + limit = 0 + } + data := make([]byte, 0, 1000) + if format == "leading_1" { + rawData := s.LogKeyInfo(clusterNameID, nodeId, filename, limit) + if len(rawData) > 0 { + data = append(data, byte('1')) + data = append(data, rawData...) + } + } else { + data = append(data, s.LogKeyInfo(clusterNameID, nodeId, filename, limit)...) + } + + resp.Write(data) +} + +func getTaskInfo(allTaskData []byte, findTaskID string) ([]byte, error) { + var allTasks = map[string]interface{}{} + var findTaskInfo = &ReplyTaskInfo{ + Msg: "", + Result: false, + } + + if err := json.Unmarshal(allTaskData, &allTasks); err != nil { + logrus.Errorf("Ummarshal allTask error %v", err) + return nil, err + } + data := allTasks["data"].(map[string]interface{}) + result := data["result"].(map[string]interface{}) + secondResults := result["result"].([]interface{}) + for _, single := range secondResults { + r := single.(map[string]interface{}) + taskid := r["task_id"].(string) + if taskid == findTaskID { + findTaskInfo.Result = true + findTaskInfo.Data.Result.Result = make([]interface{}, 0) + findTaskInfo.Data.Result.Result = append(findTaskInfo.Data.Result.Result, r) + findTaskInfo.Data.Result.NumFiltered = 1 + findTaskInfo.Data.Result.NumAfterTruncation = 1 + findTaskInfo.Data.Result.Total = 1 + break + } + } + return json.MarshalIndent(findTaskInfo, "", " ") +} + +func (s *ServerHandler) getTaskSummarize(req *restful.Request, resp *restful.Response) { + clusterNameID := req.Attribute(COOKIE_CLUSTER_NAME_KEY).(string) + // limit := req.QueryParameter("limit") + filter_keys := req.QueryParameter("filter_keys") + summary_by := req.QueryParameter("summary_by") + //filter_predicates := req.QueryParameter("filter_predicates") + filter_values := req.QueryParameter("filter_values") + + switch filter_keys { + case "job_id": + var data []byte + if summary_by == "" || summary_by == "func_name" { + data = s.MetaKeyInfo(clusterNameID, fmt.Sprintf("%s%s", utils.OssMetaFile_JOBTASK_SUMMARIZE_BY_FUNC_NAME_Prefix, filter_values)) + } else if summary_by == "lineage" { + data = s.MetaKeyInfo(clusterNameID, fmt.Sprintf("%s%s", utils.OssMetaFile_JOBTASK_SUMMARIZE_BY_LINEAGE_Prefix, filter_values)) + } + //OssMetaFile_JOBTASK_SUMMARIZE_BY_LINEAGE_Prefix + resp.Write(data) + default: + logrus.Errorf("Wrong filter keys %s", filter_keys) + resp.WriteErrorString(http.StatusInternalServerError, "Wrong filter keys") + } + +} + +func (s *ServerHandler) getTaskDetail(req *restful.Request, resp *restful.Response) { + clusterNameID := req.Attribute(COOKIE_CLUSTER_NAME_KEY).(string) + // limit := req.QueryParameter("limit") + filter_keys := req.QueryParameter("filter_keys") + //filter_predicates := req.QueryParameter("filter_predicates") + filter_values := req.QueryParameter("filter_values") + + switch filter_keys { + case "job_id": + data := s.MetaKeyInfo(clusterNameID, fmt.Sprintf("%s%s", utils.OssMetaFile_JOBTASK_DETAIL_Prefix, filter_values)) + resp.Write(data) + case "task_id": + data := s.MetaKeyInfo(clusterNameID, utils.OssMetaFile_ALLTASKS_DETAIL) + taskData, err := getTaskInfo(data, filter_values) + if err != nil { + logrus.Errorf("get task info error %v", err) + resp.WriteErrorString(http.StatusInternalServerError, "Wrong task info") + return + } + resp.Write(taskData) + + default: + logrus.Errorf("Wrong filter keys %s", filter_keys) + resp.WriteErrorString(http.StatusInternalServerError, "Wrong filter keys") + } + +} + +// CookieHandle 是一个示例的预处理函数 +func (s *ServerHandler) CookieHandle(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) { + // 从请求中获取 Cookie + clusterName, err := req.Request.Cookie(COOKIE_CLUSTER_NAME_KEY) + if err != nil { + resp.WriteHeaderAndEntity(http.StatusBadRequest, "Cluster Cookie not found") + return + } + sessionName, err := req.Request.Cookie(COOKIE_SESSION_NAME_KEY) + if err != nil { + resp.WriteHeaderAndEntity(http.StatusBadRequest, "RayCluster Session Name Cookie not found") + return + } + req.SetAttribute(COOKIE_CLUSTER_NAME_KEY, clusterName.Value) + req.SetAttribute(COOKIE_SESSION_NAME_KEY, sessionName.Value) + logrus.Infof("Request URL %s", req.Request.URL.String()) + chain.ProcessFilter(req, resp) +} diff --git a/historyserver/backend/historyserver/server.go b/historyserver/backend/historyserver/server.go new file mode 100644 index 00000000000..eff35ed86f5 --- /dev/null +++ b/historyserver/backend/historyserver/server.go @@ -0,0 +1,62 @@ +package historyserver + +import ( + "context" + "log" + "net/http" + "os" + "time" + + "github.com/ray-project/kuberay/historyserver/backend/collector/storage" + "github.com/ray-project/kuberay/historyserver/backend/types" + "github.com/sirupsen/logrus" +) + +type ServerHandler struct { + maxClusters int + rootDir string + dashboardDir string + + reader storage.StorageReader +} + +func NewServerHandler(c *types.RayHistoryServerConfig, reader storage.StorageReader) *ServerHandler { + return &ServerHandler{ + reader: reader, + + rootDir: c.RootDir, + dashboardDir: "/dashboard/ray/build", + } +} + +func (s *ServerHandler) Run(stop chan struct{}) error { + s.RegisterRouter() + port := ":8080" + server := &http.Server{ + Addr: port, // 监听地址 + ReadTimeout: 2 * time.Second, // 请求超时 + WriteTimeout: 5 * time.Second, // 写入响应超时 + IdleTimeout: 5 * time.Second, // 空闲超时 + } + go func() { + logrus.Infof("Starting server on %s", port) + err := server.ListenAndServe() + if err != nil { + logrus.Fatalf("Error starting server: %v", err) + os.Exit(1) + } + logrus.Errorf("Start server succssful, but end ...") + }() + + <-stop + logrus.Warnf("Receive stop single, so stop ray history server") + // 创建一个上下文,超时10秒 + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + // 关闭服务器 + if err := server.Shutdown(ctx); err != nil { + log.Fatalf("Ray HistoryServer forced to shutdown: %v", err) + } + return nil +} diff --git a/historyserver/backend/historyserver/types.go b/historyserver/backend/historyserver/types.go new file mode 100644 index 00000000000..0c9831adfbb --- /dev/null +++ b/historyserver/backend/historyserver/types.go @@ -0,0 +1,28 @@ +package historyserver + +type ReplyTaskInfo struct { + Data TaskInfoData `json:"data"` + Msg string `json:"msg"` + Result bool `json:"result"` +} +type TaskInfoData struct { + Result TaskInfoDataResult `json:"result"` +} +type TaskInfoDataResult struct { + NumAfterTruncation int `json:"num_after_truncation"` + NumFiltered int `json:"num_filtered"` + PartialFailureWarning string `json:"partial_failure_warning"` + Result []interface{} `json:"result"` + Total int `json:"total"` + Warnings interface{} `json:"warnings"` +} + +type ReplyActorInfo struct { + Result bool `json:"result"` + Msg string `json:"msg"` + Data ActorInfoData `json:"data"` +} + +type ActorInfoData struct { + Detail map[string]interface{} `json:"detail"` +} diff --git a/historyserver/backend/registry.go b/historyserver/backend/registry.go new file mode 100644 index 00000000000..37f8f202944 --- /dev/null +++ b/historyserver/backend/registry.go @@ -0,0 +1,27 @@ +package backend + +import ( + "github.com/ray-project/kuberay/historyserver/backend/collector/storage" + "github.com/ray-project/kuberay/historyserver/backend/collector/storage/aliyunoss/ray" + "github.com/ray-project/kuberay/historyserver/backend/types" +) + +type WriterRegistry map[string]func(globalData *types.RayCollectorConfig, data map[string]interface{}) (storage.StorageWritter, error) + +func GetWriterRegistry() WriterRegistry { + return writerRegistry +} + +var writerRegistry = WriterRegistry{ + "aliyunoss": ray.NewWritter, +} + +type ReaderRegistry map[string]func(globalData *types.RayHistoryServerConfig, data map[string]interface{}) (storage.StorageReader, error) + +func GetReaderRegistry() ReaderRegistry { + return readerRegistry +} + +var readerRegistry = ReaderRegistry{ + "aliyunoss": ray.NewReader, +} diff --git a/historyserver/backend/types/types.go b/historyserver/backend/types/types.go new file mode 100644 index 00000000000..c8457fec70e --- /dev/null +++ b/historyserver/backend/types/types.go @@ -0,0 +1,50 @@ +package types + +import ( + "time" + + "k8s.io/apimachinery/pkg/util/validation/field" +) + +type RayHistoryServerConfig struct { + RootDir string +} + +type RayCollectorConfig struct { + RootDir string + SessionDir string + RayNodeName string + + Role string + RayClusterName string + RayClusterID string + LogBatching int + PushInterval time.Duration +} + +// ValidateRayHanderConfig is +func ValidateRayHanderConfig(c *RayCollectorConfig, fldpath *field.Path) field.ErrorList { + var allErrs field.ErrorList + if len(c.SessionDir) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.SessionDir, "session-dir must be set")) + } + if len(c.RayClusterName) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.RayClusterName, "ray_cluster_name must be set")) + } + if len(c.RayNodeName) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.RayNodeName, "ray_node_name must be set")) + } + if len(c.RayClusterID) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.RayClusterID, "ray_cluster_id must be set")) + } + + if c.Role == "Head" { + if len(c.RayClusterName) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.RayClusterName, "ray_cluster_name must be set")) + } + if len(c.RayClusterID) == 0 { + allErrs = append(allErrs, field.Invalid(fldpath, c.RayClusterID, "ray_cluster_id must be set")) + } + } + return allErrs +} diff --git a/historyserver/cmd/collector/main.go b/historyserver/cmd/collector/main.go new file mode 100644 index 00000000000..d78eb466126 --- /dev/null +++ b/historyserver/cmd/collector/main.go @@ -0,0 +1,87 @@ +package main + +import ( + "encoding/json" + "flag" + "os" + "os/signal" + "syscall" + "time" + + "github.com/ray-project/kuberay/historyserver/backend" + "github.com/ray-project/kuberay/historyserver/backend/collector/runtime" + "github.com/ray-project/kuberay/historyserver/backend/types" + "github.com/ray-project/kuberay/historyserver/utils" +) + +const runtimeClassConfigPath = "/var/collector-config/data" + +func main() { + role := "" + runtimeClassName := "" + rayClusterName := "" + rayClusterId := "" + rayRootDir := "" + logBatching := 1000 + pushInterval := time.Minute + + flag.StringVar(&role, "role", "Worker", "") + flag.StringVar(&runtimeClassName, "runtime-class-name", "", "") + flag.StringVar(&rayClusterName, "ray-cluster-name", "", "") + flag.StringVar(&rayClusterId, "ray-cluster-id", "default", "") + flag.StringVar(&rayRootDir, "ray-root-dir", "", "") + flag.IntVar(&logBatching, "log-batching", 1000, "") + flag.DurationVar(&pushInterval, "push-interval", time.Minute, "") + + flag.Parse() + + sessionDir, err := utils.GetSessionDir() + if err != nil { + panic("Failed to get session dir: " + err.Error()) + } + + rayNodeId, err := utils.GetRayNodeID() + if err != nil { + panic("Failed to get ray node id: " + err.Error()) + } + + data, err := os.ReadFile(runtimeClassConfigPath) + if err != nil { + panic("Failed to read runtime class config " + err.Error()) + } + jsonData := make(map[string]interface{}) + err = json.Unmarshal(data, &jsonData) + if err != nil { + panic("Failed to parse runtime class config: " + err.Error()) + } + + registry := backend.GetWriterRegistry() + factory, ok := registry[runtimeClassName] + if !ok { + panic("Not supported runtime class name: " + runtimeClassName + " for role: " + role + ".") + } + + globalConfig := types.RayCollectorConfig{ + RootDir: rayRootDir, + SessionDir: sessionDir, + RayNodeName: rayNodeId, + Role: role, + RayClusterName: rayClusterName, + RayClusterID: rayClusterId, + PushInterval: pushInterval, + LogBatching: logBatching, + } + + writter, err := factory(&globalConfig, jsonData) + if err != nil { + panic("Failed to create writter for runtime class name: " + runtimeClassName + " for role: " + role + ".") + } + collector := runtime.NewCollector(&globalConfig, writter) + + sigChan := make(chan os.Signal, 1) + stop := make(chan struct{}, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGKILL) + collector.Start(stop) + <-sigChan + stop <- struct{}{} +} diff --git a/historyserver/cmd/historyserver/main.go b/historyserver/cmd/historyserver/main.go new file mode 100644 index 00000000000..26e539662dc --- /dev/null +++ b/historyserver/cmd/historyserver/main.go @@ -0,0 +1,58 @@ +package main + +import ( + "encoding/json" + "flag" + "os" + "os/signal" + "syscall" + + "github.com/ray-project/kuberay/historyserver/backend" + "github.com/ray-project/kuberay/historyserver/backend/historyserver" + "github.com/ray-project/kuberay/historyserver/backend/types" +) + +const runtimeClassConfigPath = "/var/collector-config/data" + +func main() { + runtimeClassName := "" + rayRootDir := "" + flag.StringVar(&runtimeClassName, "runtime-class-name", "", "") + flag.StringVar(&rayRootDir, "ray-root-dir", "", "") + + flag.Parse() + + data, err := os.ReadFile(runtimeClassConfigPath) + if err != nil { + panic("Failed to read runtime class config " + err.Error()) + } + jsonData := make(map[string]interface{}) + err = json.Unmarshal(data, &jsonData) + if err != nil { + panic("Failed to parse runtime class config: " + err.Error()) + } + + registry := backend.GetReaderRegistry() + factory, ok := registry[runtimeClassName] + if !ok { + panic("Not supported runtime class name: " + runtimeClassName + ".") + } + + globalConfig := types.RayHistoryServerConfig{ + RootDir: rayRootDir, + } + + reader, err := factory(&globalConfig, jsonData) + if err != nil { + panic("Failed to create reader for runtime class name: " + runtimeClassName + ".") + } + + handler := historyserver.NewServerHandler(&globalConfig, reader) + + sigChan := make(chan os.Signal, 1) + stop := make(chan struct{}, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGKILL) + go handler.Run(stop) + <-sigChan + stop <- struct{}{} +} diff --git a/historyserver/config/samples/aliyunoss/configmap.yaml b/historyserver/config/samples/aliyunoss/configmap.yaml new file mode 100644 index 00000000000..51d2424f48e --- /dev/null +++ b/historyserver/config/samples/aliyunoss/configmap.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +data: + data: '{"ossBucket":"","ossEndpoint":""}' +kind: ConfigMap +metadata: + name: aliyunoss-config + namespace: default \ No newline at end of file diff --git a/historyserver/config/samples/aliyunoss/historyserver.yaml b/historyserver/config/samples/aliyunoss/historyserver.yaml new file mode 100644 index 00000000000..54a41daa148 --- /dev/null +++ b/historyserver/config/samples/aliyunoss/historyserver.yaml @@ -0,0 +1,64 @@ +apiVersion: apps/v1 # for versions before 1.8.0 use apps/v1beta1 +kind: Deployment +metadata: + name: historyserver-demo + labels: + app: historyserver +spec: + replicas: 1 + selector: + matchLabels: + app: historyserver + template: + metadata: + labels: + app: historyserver + spec: + imagePullSecrets: + - name: acr-registry + containers: + - name: historyserver + env: + - name: ALIBABA_CLOUD_OIDC_TOKEN_FILE + value: + - name: ALIBABA_CLOUD_OIDC_PROVIDER_ARN + value: + - name: ALIBABA_CLOUD_ROLE_ARN + value: + - name: ALIBABA_CLOUD_STS_REGION + value: + - name: ALIBABA_CLOUD_VPC_ENDPOINT_ENABLED + value: "true" + image: registry.cn-hongkong.aliyuncs.com/image-yueming/ray-historyerver:v0.0.1 + imagePullPolicy: Always + command: + - historyserver + - --runtime-class-name=aliyunoss + - --ray-root-dir=log + ports: + - containerPort: 8080 + resources: + limits: + cpu: "500m" + volumeMounts: + - mountPath: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens + name: token-file + readOnly: true + - mountPath: /var/collector-config + name: config-volume + volumes: + - configMap: + defaultMode: 420 + items: + - key: data + path: data + name: aliyunoss-config + name: config-volume + - name: token-file + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + audience: sts.aliyuncs.com + expirationSeconds: 3600 + path: token \ No newline at end of file diff --git a/historyserver/config/samples/aliyunoss/raycluster.yaml b/historyserver/config/samples/aliyunoss/raycluster.yaml new file mode 100644 index 00000000000..f1ff9b6a98e --- /dev/null +++ b/historyserver/config/samples/aliyunoss/raycluster.yaml @@ -0,0 +1,208 @@ +--- +apiVersion: ray.io/v1 +kind: RayCluster +metadata: + labels: + ray.io/cluster: demo + name: demo + namespace: default +spec: + headGroupSpec: + rayStartParams: + dashboard-host: 0.0.0.0 + num-cpus: "0" + serviceType: ClusterIP + template: + metadata: + labels: + test: demo + spec: + imagePullSecrets: + shareProcessNamespace: true + affinity: + containers: + - env: + image: rayproject.io/ray:v2.44.1 + imagePullPolicy: Always + securityContext: + allowPrivilegeEscalation: true + privileged: true + name: ray-head + lifecycle: + postStart: + exec: + command: + - /bin/sh + - -lc + - -- + - | + GetNodeId(){ + while true; + do + nodeid=$(ps -ef | grep raylet | grep node_id | grep -v grep | grep -oP '(?<=--node_id=)[^ ]*') + if [ -n "$nodeid" ]; then + echo "$(date) raylet started: \"$(ps -ef | grep raylet | grep node_id | grep -v grep | grep -oP '(?<=--node_id=)[^ ]*')\" => ${nodeid}" >> /tmp/ray/init.log + echo $nodeid > /tmp/ray/raylet_node_id + break + else + echo "$(date) raylet not start >> /tmp/ray/init.log" + sleep 1 + fi + done + } + GetNodeId + resources: + limits: + cpu: "5" + memory: 10G + requests: + cpu: "50m" + memory: 1G + volumeMounts: + - name: historyserver + mountPath: /tmp/ray + - name: collector + image: registry.cn-hongkong.aliyuncs.com/image-yueming/ray-historyerver:v0.0.1 + imagePullPolicy: Always + env: + # https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/use-rrsa-to-authorize-pods-to-access-different-cloud-services + - name: ALIBABA_CLOUD_OIDC_TOKEN_FILE + value: + - name: ALIBABA_CLOUD_OIDC_PROVIDER_ARN + value: + - name: ALIBABA_CLOUD_ROLE_ARN + value: + - name: ALIBABA_CLOUD_STS_REGION + value: + - name: ALIBABA_CLOUD_VPC_ENDPOINT_ENABLED + value: "true" + command: + - collector + - --role=Head + - --runtime-class-name=aliyunoss + - --ray-cluster-name= + # no way to know cluster id when creating the RayCluster + # can be resolved if we inject the sidecar in KubeRay + # - --ray-cluster-id= + - --ray-root-dir=log + volumeMounts: + - name: historyserver + mountPath: /tmp/ray + - name: config-volume + mountPath: /var/collector-config + - mountPath: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens + name: token-file + readOnly: true + volumes: + - name: token-file + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + audience: sts.aliyuncs.com + expirationSeconds: 3600 + path: token + - name: config-volume + configMap: + name: aliyunoss-config + items: + - key: data + path: data + - name: historyserver + emptyDir: {} + workerGroupSpecs: + - groupName: cpu + maxReplicas: 1000 + minReplicas: 0 + numOfHosts: 1 + rayStartParams: {} + replicas: 0 + template: + metadata: + labels: + test: wukun + spec: + imagePullSecrets: + containers: + - env: + image: rayproject.io/ray:v2.44.1 + imagePullPolicy: Always + name: ray-worker + lifecycle: + postStart: + exec: + command: + - /bin/sh + - -lc + - -- + - | + GetNodeId(){ + while true; + do + nodeid=$(ps -ef | grep raylet | grep node_id | grep -v grep | grep -oP '(?<=--node_id=)[^ ]*') + if [ -n "$nodeid" ]; then + echo "$(date) raylet started: \"$(ps -ef | grep raylet | grep node_id | grep -v grep | grep -oP '(?<=--node_id=)[^ ]*')\" => ${nodeid}" >> /tmp/ray/init.log + echo $nodeid > /tmp/ray/raylet_node_id + break + else + echo "$(date) raylet not start >> /tmp/ray/init.log" + sleep 1 + fi + done + } + GetNodeId + resources: + limits: + cpu: "30" + memory: 30G + requests: + cpu: "50m" + memory: 1G + volumeMounts: + - name: historyserver + mountPath: /tmp/ray + - name: collector + image: registry.cn-hongkong.aliyuncs.com/image-yueming/ray-historyerver:v0.0.1 + imagePullPolicy: Always + env: + - name: ALIBABA_CLOUD_OIDC_TOKEN_FILE + value: + - name: ALIBABA_CLOUD_OIDC_PROVIDER_ARN + value: + - name: ALIBABA_CLOUD_ROLE_ARN + value: + - name: ALIBABA_CLOUD_STS_REGION + value: + - name: ALIBABA_CLOUD_VPC_ENDPOINT_ENABLED + value: "true" + command: + - collector + - --role=Worker + - --runtime-class-name=aliyunoss + - --ray-cluster-name=wukun + - --ray-root-dir=log + volumeMounts: + - name: historyserver + mountPath: /tmp/ray + - name: config-volume + mountPath: /var/collector-config + - mountPath: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens + name: token-file + readOnly: true + volumes: + - name: token-file + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + audience: sts.aliyuncs.com + expirationSeconds: 3600 + path: token + - name: config-volume + configMap: + name: aliyunoss-config + items: + - key: data + path: data + - name: historyserver + emptyDir: {} \ No newline at end of file diff --git a/historyserver/config/samples/aliyunoss/svc.yaml b/historyserver/config/samples/aliyunoss/svc.yaml new file mode 100644 index 00000000000..a33585e4b3a --- /dev/null +++ b/historyserver/config/samples/aliyunoss/svc.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: historyserver #TODO: to specify your service name + labels: + app: historyserver +spec: + selector: + app: historyserver + ports: + - protocol: TCP + name: http + port: 30080 + targetPort: 8080 + type: ClusterIP \ No newline at end of file diff --git a/historyserver/dashboard/ray/client/.env.production.local b/historyserver/dashboard/ray/client/.env.production.local new file mode 100644 index 00000000000..f85bcef1d79 --- /dev/null +++ b/historyserver/dashboard/ray/client/.env.production.local @@ -0,0 +1 @@ +PUBLIC_URL="." diff --git a/historyserver/dashboard/ray/client/.gitignore b/historyserver/dashboard/ray/client/.gitignore new file mode 100644 index 00000000000..f5c51c6ae77 --- /dev/null +++ b/historyserver/dashboard/ray/client/.gitignore @@ -0,0 +1,22 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/historyserver/dashboard/ray/client/README.rst b/historyserver/dashboard/ray/client/README.rst new file mode 100644 index 00000000000..d2291cbcf03 --- /dev/null +++ b/historyserver/dashboard/ray/client/README.rst @@ -0,0 +1,70 @@ +This project was bootstrapped with `Create React App +`__. + +Available Scripts +----------------- + +In the project directory, you can run: + +``npm ci`` +~~~~~~~~~~ + +Once you run this command, all the dependencies listed in your package.json are installed based on the versions in package-lock.json file. + +``npm start`` +~~~~~~~~~~~~~ + +Runs the app in the development mode. Open `http://localhost:3000 +`__ to view it in the browser. + +The page will reload if you make edits. You will also see any lint errors in the +console. + +``npm test`` +~~~~~~~~~~~~ + +Launches the test runner in the interactive watch mode. See the section about +`running tests +`__ for more +information. + +``npm run build`` +~~~~~~~~~~~~~~~~~ + +Builds the app for production to the ``build`` folder. It correctly bundles +React in production mode and optimizes the build for the best performance. + +The build is minified and the filenames include the hashes. Your app is ready to +be deployed! + +See the section about `deployment +`__ for more +information. + +``npm run eject`` +~~~~~~~~~~~~~~~~~ + +Note: this is a one-way operation. Once you ``eject``, you can’t go back! + +If you aren’t satisfied with the build tool and configuration choices, you can +``eject`` at any time. This command will remove the single build dependency from +your project. + +Instead, it will copy all the configuration files and the transitive +dependencies (Webpack, Babel, ESLint, etc) right into your project so you have +full control over them. All of the commands except ``eject`` will still work, +but they will point to the copied scripts so you can tweak them. At this point +you’re on your own. + +You don’t have to ever use ``eject``. The curated feature set is suitable for +small and middle deployments, and you shouldn’t feel obligated to use this +feature. However we understand that this tool wouldn’t be useful if you couldn’t +customize it when you are ready for it. + +Learn More +---------- + +You can learn more in the `Create React App documentation +`__. + +To learn React, check out the `React documentation `__. diff --git a/historyserver/dashboard/ray/client/package-lock.json b/historyserver/dashboard/ray/client/package-lock.json new file mode 100644 index 00000000000..bf0c53933fe --- /dev/null +++ b/historyserver/dashboard/ray/client/package-lock.json @@ -0,0 +1,18338 @@ +{ + "name": "ray-dashboard-client", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@adobe/css-tools": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", + "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==", + "dev": true + }, + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } + } + }, + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.19.4", + "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.19.4.tgz", + "integrity": "sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==" + }, + "@babel/core": { + "version": "7.19.6", + "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.19.6.tgz", + "integrity": "sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==", + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.6", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.6", + "@babel/helpers": "^7.19.4", + "@babel/parser": "^7.19.6", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.6", + "@babel/types": "^7.19.4", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@babel/eslint-parser": { + "version": "7.19.1", + "resolved": "https://registry.npmmirror.com/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz", + "integrity": "sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==", + "requires": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@babel/generator": { + "version": "7.19.6", + "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.19.6.tgz", + "integrity": "sha512-oHGRUQeoX1QrKeJIKVe0hwjGqNnVYsM5Nep5zo0uE0m42sLH+Fsd2pStJ5sRM1bNyTUUoz0pe2lTeMJrb/taTA==", + "requires": { + "@babel/types": "^7.19.4", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", + "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "dependencies": { + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.19.3", + "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", + "requires": { + "@babel/compat-data": "^7.19.3", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.19.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", + "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", + "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "dependencies": { + "@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.3.3", + "resolved": "https://registry.npmmirror.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "requires": { + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==" + }, + "@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "requires": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "requires": { + "@babel/types": "^7.24.7" + }, + "dependencies": { + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.18.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", + "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "requires": { + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-transforms": { + "version": "7.19.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.6.tgz", + "integrity": "sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.19.4", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.6", + "@babel/types": "^7.19.4" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.19.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", + "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==" + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", + "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-wrap-function": "^7.24.7" + }, + "dependencies": { + "@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-replace-supers": { + "version": "7.19.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", + "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/traverse": "^7.19.1", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.19.4", + "resolved": "https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", + "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", + "requires": { + "@babel/types": "^7.19.4" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.18.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", + "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", + "requires": { + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" + }, + "@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" + }, + "@babel/helper-wrap-function": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", + "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", + "requires": { + "@babel/helper-function-name": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "requires": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + } + }, + "@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "requires": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "requires": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + } + }, + "@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==" + }, + "@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "requires": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/helpers": { + "version": "7.19.4", + "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.19.4.tgz", + "integrity": "sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==", + "requires": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.4", + "@babel/types": "^7.19.4" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.19.6", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.19.6.tgz", + "integrity": "sha512-h1IUp81s2JYJ3mRkdxJgs4UvmSsRvDrx5ICSJbPvtWYv5i1nTBGcBpnog+89rAFMwvvru6E5NUHdBe01UeSzYA==" + }, + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz", + "integrity": "sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==", + "requires": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz", + "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", + "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz", + "integrity": "sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==", + "requires": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-proposal-decorators": { + "version": "7.19.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.6.tgz", + "integrity": "sha512-PKWforYpkVkogpOW0RaPuh7eQ7AoFgBJP+d87tQCRY2LVbvyGtfRM7RtrhCBsNgZb+2EY28SeWB6p2xe1Z5oAw==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-replace-supers": "^7.19.1", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/plugin-syntax-decorators": "^7.19.0" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.18.9", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", + "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==" + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-decorators": { + "version": "7.19.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz", + "integrity": "sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.19.0" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-flow": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", + "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-import-assertions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", + "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", + "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", + "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-async-generator-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", + "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", + "requires": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "dependencies": { + "@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", + "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", + "requires": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" + }, + "dependencies": { + "@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", + "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", + "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-class-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", + "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "requires": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", + "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "semver": "^6.3.1" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "requires": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", + "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-replace-supers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", + "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "requires": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "requires": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + } + }, + "@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==" + }, + "@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "requires": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/plugin-transform-class-static-block": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", + "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "requires": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", + "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "semver": "^6.3.1" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "requires": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", + "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-replace-supers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", + "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "requires": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "requires": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + } + }, + "@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==" + }, + "@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "requires": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/plugin-transform-classes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz", + "integrity": "sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "requires": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + } + }, + "@babel/compat-data": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==" + }, + "@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "requires": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "requires": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", + "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-replace-supers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", + "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "requires": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/helper-validator-option": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==" + }, + "@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "requires": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + } + }, + "@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==" + }, + "@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "requires": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "requires": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "electron-to-chromium": { + "version": "1.4.792", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.792.tgz", + "integrity": "sha512-rkg5/N3L+Y844JyfgPUyuKK0Hk0efo3JNxUDKvz3HgP6EmN4rNGhr2D8boLsfTV/hGo7ZGAL8djw+jlg99zQyA==" + }, + "escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "requires": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + } + } + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", + "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "requires": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "requires": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + } + }, + "@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==" + }, + "@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "requires": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz", + "integrity": "sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", + "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", + "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-dynamic-import": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", + "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", + "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-export-namespace-from": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", + "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-flow-strip-types": { + "version": "7.19.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", + "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", + "requires": { + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-flow": "^7.18.6" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", + "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", + "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", + "requires": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "requires": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + } + }, + "@babel/compat-data": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==" + }, + "@babel/helper-compilation-targets": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "requires": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + } + }, + "@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "requires": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/helper-validator-option": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==" + }, + "@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "requires": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + } + }, + "@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==" + }, + "@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "requires": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "requires": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "electron-to-chromium": { + "version": "1.4.792", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.792.tgz", + "integrity": "sha512-rkg5/N3L+Y844JyfgPUyuKK0Hk0efo3JNxUDKvz3HgP6EmN4rNGhr2D8boLsfTV/hGo7ZGAL8djw+jlg99zQyA==" + }, + "escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "requires": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + } + } + } + }, + "@babel/plugin-transform-json-strings": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", + "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", + "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", + "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", + "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", + "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "requires": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-module-transforms": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "requires": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", + "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", + "requires": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7" + }, + "dependencies": { + "@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-module-transforms": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "requires": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", + "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", + "requires": { + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + }, + "dependencies": { + "@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-module-transforms": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "requires": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", + "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "requires": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-module-transforms": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "requires": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", + "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", + "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", + "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-numeric-separator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", + "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-object-rest-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", + "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "requires": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.7" + }, + "dependencies": { + "@babel/compat-data": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==" + }, + "@babel/helper-compilation-targets": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "requires": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-validator-option": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==" + }, + "browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "requires": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + } + }, + "electron-to-chromium": { + "version": "1.4.792", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.792.tgz", + "integrity": "sha512-rkg5/N3L+Y844JyfgPUyuKK0Hk0efo3JNxUDKvz3HgP6EmN4rNGhr2D8boLsfTV/hGo7ZGAL8djw+jlg99zQyA==" + }, + "escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==" + }, + "node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "requires": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + } + } + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", + "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" + }, + "dependencies": { + "@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", + "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-replace-supers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", + "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "requires": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", + "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-optional-chaining": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", + "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", + "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-private-methods": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", + "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "requires": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", + "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "semver": "^6.3.1" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "requires": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", + "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-replace-supers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", + "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "requires": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "requires": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + } + }, + "@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==" + }, + "@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "requires": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/plugin-transform-private-property-in-object": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", + "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "requires": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", + "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "semver": "^6.3.1" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "requires": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", + "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-replace-supers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", + "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "requires": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "requires": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + } + }, + "@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==" + }, + "@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "requires": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", + "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-react-constant-elements": { + "version": "7.18.12", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.18.12.tgz", + "integrity": "sha512-Q99U9/ttiu+LMnRU8psd23HhvwXmKWDQIpocm0JKaICcZHnw+mdQbHm6xnSy7dOl8I5PELakYtNBubNQlBXbZw==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", + "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.19.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", + "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-jsx": "^7.18.6", + "@babel/types": "^7.19.0" + } + }, + "@babel/plugin-transform-react-jsx-development": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", + "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", + "requires": { + "@babel/plugin-transform-react-jsx": "^7.18.6" + } + }, + "@babel/plugin-transform-react-pure-annotations": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", + "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", + "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "regenerator-transform": "^0.15.2" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", + "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.19.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz", + "integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==", + "requires": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", + "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", + "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "requires": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", + "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", + "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz", + "integrity": "sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.19.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.3.tgz", + "integrity": "sha512-z6fnuK9ve9u/0X0rRvI9MY0xg+DOUaABDYOe+/SQTxtlptaBB/V9JIUxJn6xp3lMBeb9qe8xSFmHU35oZDXD+w==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-typescript": "^7.18.6" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", + "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", + "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", + "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/plugin-transform-unicode-sets-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", + "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + } + } + }, + "@babel/preset-env": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.7.tgz", + "integrity": "sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==", + "requires": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.24.7", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.24.7", + "@babel/plugin-transform-class-properties": "^7.24.7", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.24.7", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.7", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.24.7", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.24.7", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-modules-systemjs": "^7.24.7", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.7", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "dependencies": { + "@babel/compat-data": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==" + }, + "@babel/helper-compilation-targets": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "requires": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "requires": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" + }, + "@babel/helper-validator-option": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==" + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "requires": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "requires": { + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "requires": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + } + }, + "browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "requires": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + } + }, + "core-js-compat": { + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "requires": { + "browserslist": "^4.23.0" + } + }, + "electron-to-chromium": { + "version": "1.4.792", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.792.tgz", + "integrity": "sha512-rkg5/N3L+Y844JyfgPUyuKK0Hk0efo3JNxUDKvz3HgP6EmN4rNGhr2D8boLsfTV/hGo7ZGAL8djw+jlg99zQyA==" + }, + "escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==" + }, + "node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "requires": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + } + } + } + }, + "@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/preset-react": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/preset-react/-/preset-react-7.18.6.tgz", + "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-transform-react-display-name": "^7.18.6", + "@babel/plugin-transform-react-jsx": "^7.18.6", + "@babel/plugin-transform-react-jsx-development": "^7.18.6", + "@babel/plugin-transform-react-pure-annotations": "^7.18.6" + } + }, + "@babel/preset-typescript": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", + "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-transform-typescript": "^7.18.6" + } + }, + "@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, + "@babel/runtime": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz", + "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==", + "requires": { + "regenerator-runtime": "^0.14.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + } + } + }, + "@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + } + }, + "@babel/traverse": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "requires": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "requires": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + } + }, + "@babel/generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "requires": { + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "requires": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "requires": { + "@babel/types": "^7.24.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" + }, + "@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + }, + "@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "requires": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + } + }, + "@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==" + }, + "@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "requires": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + } + }, + "@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "requires": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "requires": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + }, + "@csstools/normalize.css": { + "version": "12.0.0", + "resolved": "https://registry.npmmirror.com/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", + "integrity": "sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg==" + }, + "@csstools/postcss-cascade-layers": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", + "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", + "requires": { + "@csstools/selector-specificity": "^2.0.2", + "postcss-selector-parser": "^6.0.10" + } + }, + "@csstools/postcss-color-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", + "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", + "requires": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-font-format-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", + "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-hwb-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", + "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-ic-unit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", + "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", + "requires": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-is-pseudo-class": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", + "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", + "requires": { + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" + } + }, + "@csstools/postcss-nested-calc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", + "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-normalize-display-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", + "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-oklab-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", + "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", + "requires": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-progressive-custom-properties": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", + "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-stepped-value-functions": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", + "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-text-decoration-shorthand": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", + "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-trigonometric-functions": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", + "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "@csstools/postcss-unset-value": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", + "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==" + }, + "@csstools/selector-specificity": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", + "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==" + }, + "@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "requires": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + }, + "dependencies": { + "@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + } + } + }, + "@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "requires": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "requires": { + "@emotion/memoize": "^0.8.1" + } + }, + "@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "@emotion/react": { + "version": "11.11.3", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.3.tgz", + "integrity": "sha512-Cnn0kuq4DoONOMcnoVsTOR8E+AdnKFf//6kUWc4LCdnxj31pZWn7rIULd6Y7/Js1PiPHzn7SKCM9vB/jBni8eA==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + } + }, + "@emotion/serialize": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", + "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", + "requires": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + }, + "dependencies": { + "@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + } + } + }, + "@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + } + }, + "@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==" + }, + "@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, + "@eslint/eslintrc": { + "version": "1.3.3", + "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "13.17.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "requires": { + "type-fest": "^0.20.2" + } + } + } + }, + "@floating-ui/core": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.3.tgz", + "integrity": "sha512-O0WKDOo0yhJuugCx6trZQj5jVJ9yR0ystG2JaNAemYUWce+pmM6WUEFIibnWyEJKdrDxhm75NoSRME35FNaM/Q==", + "requires": { + "@floating-ui/utils": "^0.2.0" + } + }, + "@floating-ui/dom": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.4.tgz", + "integrity": "sha512-jByEsHIY+eEdCjnTVu+E3ephzTOzkQ8hgUfGwos+bg7NlH33Zc5uO+QHz1mrQUOgIKKDD1RtS201P9NvAfq3XQ==", + "requires": { + "@floating-ui/core": "^1.5.3", + "@floating-ui/utils": "^0.2.0" + } + }, + "@floating-ui/react-dom": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.6.tgz", + "integrity": "sha512-IB8aCRFxr8nFkdYZgH+Otd9EVQPJoynxeFRGTB8voPoZMRWo8XjYuCRgpI1btvuKY69XMiLnW+ym7zoBHM90Rw==", + "requires": { + "@floating-ui/dom": "^1.5.4" + } + }, + "@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, + "@humanwhocodes/config-array": { + "version": "0.11.6", + "resolved": "https://registry.npmmirror.com/@humanwhocodes/config-array/-/config-array-0.11.6.tgz", + "integrity": "sha512-jJr+hPTJYKyDILJfhNSHsjiwXYf26Flsz8DvNndOsHs5pwSnpGUEy8yzF0JYhCEvTDdV2vuOK5tt8BVhwO5/hg==", + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==" + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" + }, + "@jest/console": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "requires": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "@jest/core": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "requires": { + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + }, + "jest-watcher": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "requires": { + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.5.1", + "string-length": "^4.0.1" + } + } + } + }, + "@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "requires": { + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "@jest/expect-utils": { + "version": "29.2.2", + "resolved": "https://registry.npmmirror.com/@jest/expect-utils/-/expect-utils-29.2.2.tgz", + "integrity": "sha512-vwnVmrVhTmGgQzyvcpze08br91OL61t9O0lJMDyb6Y/D8EKQ9V7rGUb/p7PDt0GPzK0zFYqXWFo4EO2legXmkg==", + "dev": true, + "requires": { + "jest-get-type": "^29.2.0" + }, + "dependencies": { + "jest-get-type": { + "version": "29.2.0", + "resolved": "https://registry.npmmirror.com/jest-get-type/-/jest-get-type-29.2.0.tgz", + "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", + "dev": true + } + } + }, + "@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "requires": { + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "requires": { + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" + } + }, + "@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "requires": { + "@sinclair/typebox": "^0.24.1" + } + }, + "@jest/source-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", + "requires": { + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "requires": { + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" + } + }, + "@jest/transform": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + } + } + }, + "@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "requires": { + "@types/yargs-parser": "*" + } + } + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + }, + "@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + }, + "@mui/base": { + "version": "5.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.32.tgz", + "integrity": "sha512-4VptvYeLUYMJhZapWBkD50GmKfOc0XT381KJcTK3ncZYIl8MdBhpR6l8jOyeP5cixUPBJhstjrnmQEAHjCLriw==", + "requires": { + "@babel/runtime": "^7.23.8", + "@floating-ui/react-dom": "^2.0.5", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.5", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "dependencies": { + "clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==" + } + } + }, + "@mui/core-downloads-tracker": { + "version": "5.15.5", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.5.tgz", + "integrity": "sha512-VhT8klyXy8GrWrARqLMoM6Nzz809Jc3Wn5wd7WOZfre2vFO1rBV1dBANAPBhBqpaQI0HCMRTWEYoSyOFgRnz4A==" + }, + "@mui/icons-material": { + "version": "5.15.5", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.5.tgz", + "integrity": "sha512-qiql0fd1JY7TZ1wm1RldvU7sL8QUatE9OC12i/qm5rnm/caTFyAfOyTIR7qqxorsJvoZGyrzwoMkal6Ij9kM0A==", + "requires": { + "@babel/runtime": "^7.23.8" + } + }, + "@mui/material": { + "version": "5.15.5", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.5.tgz", + "integrity": "sha512-2KfA39f/UWeQl0O22UJs3x1nG3chYlyu9wnux5vTnxUTLzkgYIzQIHaH+ZOGpv5JiZBMKktAPNfhqyhSaQ49qQ==", + "requires": { + "@babel/runtime": "^7.23.8", + "@mui/base": "5.0.0-beta.32", + "@mui/core-downloads-tracker": "^5.15.5", + "@mui/system": "^5.15.5", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.5", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "dependencies": { + "clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==" + }, + "csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@mui/private-theming": { + "version": "5.15.5", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.5.tgz", + "integrity": "sha512-HU1KCyGNcJFsUamTbOM539ZDZJNI/XU7sZFdsN29glktUf+T6hNvDuO2ISinBiLTZy7Ab3R6DSSoYXRrLc4uwQ==", + "requires": { + "@babel/runtime": "^7.23.8", + "@mui/utils": "^5.15.5", + "prop-types": "^15.8.1" + } + }, + "@mui/styled-engine": { + "version": "5.15.5", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.5.tgz", + "integrity": "sha512-xoMUd8h270thNL7ZsOzmlluIAMsQg/HT7SCdRjPBVle+XHgTKaiWiRy1ekDOsrrF0rhjME3T7xeeUq2G269UUw==", + "requires": { + "@babel/runtime": "^7.23.8", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + }, + "dependencies": { + "csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + } + } + }, + "@mui/system": { + "version": "5.15.5", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.5.tgz", + "integrity": "sha512-DMv2vGjUKaDt/m0RlzvLjpKiS5V0LoBhiMUHf5pWdj6uoNlN4FuKUe4pFeYmQMIO5DnVZKybmpPepfkdfEH+Og==", + "requires": { + "@babel/runtime": "^7.23.8", + "@mui/private-theming": "^5.15.5", + "@mui/styled-engine": "^5.15.5", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.5", + "clsx": "^2.1.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + }, + "dependencies": { + "clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==" + }, + "csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + } + } + }, + "@mui/types": { + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.13.tgz", + "integrity": "sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g==" + }, + "@mui/utils": { + "version": "5.15.5", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.5.tgz", + "integrity": "sha512-jEywgaMGZWPSlVFO7ZZAyXxNeLmq5XBp5At9Ne/sGohRJdesUcdxvyi8TP3odJxwQuL5L6PJV+JQ4DyIDM849A==", + "requires": { + "@babel/runtime": "^7.23.8", + "@types/prop-types": "^15.7.11", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "requires": { + "eslint-scope": "5.1.1" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.5.8", + "resolved": "https://registry.npmmirror.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.8.tgz", + "integrity": "sha512-wxXRwf+IQ6zvHSJZ+5T2RQNEsq+kx4jKRXfFvdt3nBIUzJUAvXEFsUeoaohDe/Kr84MTjGwcuIUPNcstNJORsA==", + "requires": { + "ansi-html-community": "^0.0.8", + "common-path-prefix": "^3.0.0", + "core-js-pure": "^3.23.3", + "error-stack-parser": "^2.0.6", + "find-up": "^5.0.0", + "html-entities": "^2.1.0", + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" + } + } + }, + "@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" + }, + "@reduxjs/toolkit": { + "version": "1.8.6", + "resolved": "https://registry.npmmirror.com/@reduxjs/toolkit/-/toolkit-1.8.6.tgz", + "integrity": "sha512-4Ia/Loc6WLmdSOzi7k5ff7dLK8CgG2b8aqpLsCAJhazAzGdp//YBUSaj0ceW6a3kDBDNRrq5CRwyCS0wBiL1ig==", + "requires": { + "immer": "^9.0.7", + "redux": "^4.1.2", + "redux-thunk": "^2.4.1", + "reselect": "^4.1.5" + } + }, + "@remix-run/router": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz", + "integrity": "sha512-ceuyTSs7PZ/tQqi19YZNBc5X7kj1f8p+4DIyrcIYFY9h+hd1OKm4RqtiWldR9eGEvIiJfsqwM4BsuCtRIuEw6Q==" + }, + "@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + } + }, + "@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "requires": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + } + }, + "@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "requires": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + } + }, + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "dependencies": { + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + } + } + }, + "@rushstack/eslint-patch": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz", + "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==" + }, + "@sinclair/typebox": { + "version": "0.24.50", + "resolved": "https://registry.npmmirror.com/@sinclair/typebox/-/typebox-0.24.50.tgz", + "integrity": "sha512-k8ETQOOQDg5FtK7y9KJWpsGLik+QlPmIi8zzl/dGUgshV2QitprkFlCR/AemjWOTyKn9UwSSGRTzLVotvgCjYQ==" + }, + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmmirror.com/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "requires": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "@svgr/babel-plugin-add-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==" + }, + "@svgr/babel-plugin-remove-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==" + }, + "@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", + "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==" + }, + "@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", + "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==" + }, + "@svgr/babel-plugin-svg-dynamic-title": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", + "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==" + }, + "@svgr/babel-plugin-svg-em-dimensions": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", + "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==" + }, + "@svgr/babel-plugin-transform-react-native-svg": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", + "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==" + }, + "@svgr/babel-plugin-transform-svg-component": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", + "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==" + }, + "@svgr/babel-preset": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", + "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", + "requires": { + "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", + "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", + "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", + "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", + "@svgr/babel-plugin-transform-svg-component": "^5.5.0" + } + }, + "@svgr/core": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", + "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "requires": { + "@svgr/plugin-jsx": "^5.5.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.0" + } + }, + "@svgr/hast-util-to-babel-ast": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", + "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", + "requires": { + "@babel/types": "^7.12.6" + } + }, + "@svgr/plugin-jsx": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", + "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", + "requires": { + "@babel/core": "^7.12.3", + "@svgr/babel-preset": "^5.5.0", + "@svgr/hast-util-to-babel-ast": "^5.5.0", + "svg-parser": "^2.0.2" + } + }, + "@svgr/plugin-svgo": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", + "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", + "requires": { + "cosmiconfig": "^7.0.0", + "deepmerge": "^4.2.2", + "svgo": "^1.2.2" + } + }, + "@svgr/webpack": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", + "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", + "requires": { + "@babel/core": "^7.12.3", + "@babel/plugin-transform-react-constant-elements": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@babel/preset-react": "^7.12.5", + "@svgr/core": "^5.5.0", + "@svgr/plugin-jsx": "^5.5.0", + "@svgr/plugin-svgo": "^5.5.0", + "loader-utils": "^2.0.0" + } + }, + "@testing-library/dom": { + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", + "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "dependencies": { + "aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "requires": { + "deep-equal": "^2.0.5" + } + } + } + }, + "@testing-library/jest-dom": { + "version": "5.16.5", + "resolved": "https://registry.npmmirror.com/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz", + "integrity": "sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA==", + "dev": true, + "requires": { + "@adobe/css-tools": "^4.0.1", + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.5.6", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@testing-library/react": { + "version": "14.3.0", + "resolved": "https://registry.npmmirror.com/@testing-library/react/-/react-14.3.0.tgz", + "integrity": "sha512-AYJGvNFMbCa5vt1UtDCa/dcaABrXq8gph6VN+cffIx0UeA0qiGqS+sT60+sb+Gjc8tGXdECWYQgaF0khf8b+Lg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^9.0.0", + "@types/react-dom": "^18.0.0" + }, + "dependencies": { + "@types/react-dom": { + "version": "18.3.0", + "resolved": "https://registry.npmmirror.com/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "dev": true, + "requires": { + "@types/react": "*" + } + } + } + }, + "@testing-library/user-event": { + "version": "14.4.3", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.4.3.tgz", + "integrity": "sha512-kCUc5MEwaEMakkO5x7aoD+DLi02ehmEM2QCGWvNqAS1dV/fAvORWEjnjsEIvml59M7Y5kCkWN6fCCyPOe8OL6Q==", + "dev": true + }, + "@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==" + }, + "@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true + }, + "@types/babel__core": { + "version": "7.1.19", + "resolved": "https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmmirror.com/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmmirror.com/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.18.2", + "resolved": "https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", + "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmmirror.com/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "@types/bonjour": { + "version": "3.5.10", + "resolved": "https://registry.npmmirror.com/@types/bonjour/-/bonjour-3.5.10.tgz", + "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", + "requires": { + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmmirror.com/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "requires": { + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "@types/connect-history-api-fallback": { + "version": "1.3.5", + "resolved": "https://registry.npmmirror.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", + "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", + "requires": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "@types/eslint": { + "version": "8.4.8", + "resolved": "https://registry.npmmirror.com/@types/eslint/-/eslint-8.4.8.tgz", + "integrity": "sha512-zUCKQI1bUCTi+0kQs5ZQzQ/XILWRLIlh15FXWNykJ+NG3TMKMVvwwC6GP3DR1Ylga15fB7iAExSzc4PNlR5i3w==", + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmmirror.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" + }, + "@types/express": { + "version": "4.17.14", + "resolved": "https://registry.npmmirror.com/@types/express/-/express-4.17.14.tgz", + "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.31", + "resolved": "https://registry.npmmirror.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", + "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmmirror.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "requires": { + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "requires": { + "@types/unist": "^2" + } + }, + "@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + }, + "@types/http-proxy": { + "version": "1.17.9", + "resolved": "https://registry.npmmirror.com/@types/http-proxy/-/http-proxy-1.17.9.tgz", + "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", + "requires": { + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==" + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "27.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", + "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", + "requires": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "@types/js-cookie": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz", + "integrity": "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==", + "dev": true + }, + "@types/js-yaml": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz", + "integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + }, + "@types/lodash": { + "version": "4.14.186", + "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.186.tgz", + "integrity": "sha512-eHcVlLXP0c2FlMPm56ITode2AgLMSa6aJ05JTTbYbI+7EMkCEE5qk2E41d5g2lCVTqRe0GnnRFurmlCsDODrPw==" + }, + "@types/mime": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" + }, + "@types/node": { + "version": "13.9.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.5.tgz", + "integrity": "sha512-hkzMMD3xu6BrJpGVLeQ3htQQNAcOrJjX7WFmtK8zWQpz2UJf13LCFF2ALA7c9OVdvc2vQJeDdjfR35M0sBCxvw==" + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, + "@types/prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmmirror.com/@types/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==" + }, + "@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + }, + "@types/q": { + "version": "1.5.5", + "resolved": "https://registry.npmmirror.com/@types/q/-/q-1.5.5.tgz", + "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==" + }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmmirror.com/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, + "@types/react": { + "version": "18.3.0", + "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.3.0.tgz", + "integrity": "sha512-DiUcKjzE6soLyln8NNZmyhcQjVv+WsUIFSqetMN0p8927OztKT4VTfFTqsbAi5oAGIcgOmOajlfBqyptDDjZRw==", + "requires": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-dom": { + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/react-redux": { + "version": "7.1.24", + "resolved": "https://registry.npmmirror.com/@types/react-redux/-/react-redux-7.1.24.tgz", + "integrity": "sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==", + "requires": { + "@types/hoist-non-react-statics": "^3.3.0", + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0", + "redux": "^4.0.0" + } + }, + "@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "requires": { + "@types/react": "*" + } + }, + "@types/react-window": { + "version": "1.8.5", + "resolved": "https://registry.npmmirror.com/@types/react-window/-/react-window-1.8.5.tgz", + "integrity": "sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==", + "requires": { + "@types/react": "*" + } + }, + "@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "requires": { + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + }, + "@types/semver": { + "version": "7.3.12", + "resolved": "https://registry.npmmirror.com/@types/semver/-/semver-7.3.12.tgz", + "integrity": "sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==" + }, + "@types/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmmirror.com/@types/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", + "requires": { + "@types/express": "*" + } + }, + "@types/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmmirror.com/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", + "requires": { + "@types/mime": "*", + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "@types/sockjs": { + "version": "0.3.33", + "resolved": "https://registry.npmmirror.com/@types/sockjs/-/sockjs-0.3.33.tgz", + "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", + "requires": { + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" + }, + "@types/testing-library__jest-dom": { + "version": "5.14.5", + "resolved": "https://registry.npmmirror.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.5.tgz", + "integrity": "sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==", + "dev": true, + "requires": { + "@types/jest": "*" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.0.0", + "resolved": "https://registry.npmmirror.com/@jest/schemas/-/schemas-29.0.0.tgz", + "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.24.1" + } + }, + "@jest/types": { + "version": "29.2.1", + "resolved": "https://registry.npmmirror.com/@jest/types/-/types-29.2.1.tgz", + "integrity": "sha512-O/QNDQODLnINEPAI0cl9U6zUIDXEWXt6IC1o2N2QENuos7hlGUIthlKyV4p6ki3TvXFX071blj8HUhgLGquPjw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.0.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@types/jest": { + "version": "29.2.0", + "resolved": "https://registry.npmmirror.com/@types/jest/-/jest-29.2.0.tgz", + "integrity": "sha512-KO7bPV21d65PKwv3LLsD8Jn3E05pjNjRZvkm+YTacWhVmykAb07wW6IkZUmQAltwQafNcDUEUrMO2h3jeBSisg==", + "dev": true, + "requires": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==", + "dev": true + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "diff-sequences": { + "version": "29.2.0", + "resolved": "https://registry.npmmirror.com/diff-sequences/-/diff-sequences-29.2.0.tgz", + "integrity": "sha512-413SY5JpYeSBZxmenGEmCVQ8mCgtFJF0w9PROdaS6z987XC2Pd2GOKqOITLtMftmyFZqgtCOb/QA7/Z3ZXfzIw==", + "dev": true + }, + "expect": { + "version": "29.2.2", + "resolved": "https://registry.npmmirror.com/expect/-/expect-29.2.2.tgz", + "integrity": "sha512-hE09QerxZ5wXiOhqkXy5d2G9ar+EqOyifnCXCpMNu+vZ6DG9TJ6CO2c2kPDSLqERTTWrO7OZj8EkYHQqSd78Yw==", + "dev": true, + "requires": { + "@jest/expect-utils": "^29.2.2", + "jest-get-type": "^29.2.0", + "jest-matcher-utils": "^29.2.2", + "jest-message-util": "^29.2.1", + "jest-util": "^29.2.1" + } + }, + "jest-diff": { + "version": "29.2.1", + "resolved": "https://registry.npmmirror.com/jest-diff/-/jest-diff-29.2.1.tgz", + "integrity": "sha512-gfh/SMNlQmP3MOUgdzxPOd4XETDJifADpT937fN1iUGz+9DgOu2eUPHH25JDkLVcLwwqxv3GzVyK4VBUr9fjfA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^29.2.0", + "jest-get-type": "^29.2.0", + "pretty-format": "^29.2.1" + } + }, + "jest-get-type": { + "version": "29.2.0", + "resolved": "https://registry.npmmirror.com/jest-get-type/-/jest-get-type-29.2.0.tgz", + "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", + "dev": true + }, + "jest-matcher-utils": { + "version": "29.2.2", + "resolved": "https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-29.2.2.tgz", + "integrity": "sha512-4DkJ1sDPT+UX2MR7Y3od6KtvRi9Im1ZGLGgdLFLm4lPexbTaCgJW5NN3IOXlQHF7NSHY/VHhflQ+WoKtD/vyCw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^29.2.1", + "jest-get-type": "^29.2.0", + "pretty-format": "^29.2.1" + } + }, + "jest-message-util": { + "version": "29.2.1", + "resolved": "https://registry.npmmirror.com/jest-message-util/-/jest-message-util-29.2.1.tgz", + "integrity": "sha512-Dx5nEjw9V8C1/Yj10S/8ivA8F439VS8vTq1L7hEgwHFn9ovSKNpYW/kwNh7UglaEgXO42XxzKJB+2x0nSglFVw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.2.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.2.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-util": { + "version": "29.2.1", + "resolved": "https://registry.npmmirror.com/jest-util/-/jest-util-29.2.1.tgz", + "integrity": "sha512-P5VWDj25r7kj7kl4pN2rG/RN2c1TLfYYYZYULnS/35nFDjBai+hBeo3MDrYZS7p6IoY3YHZnt2vq4L6mKnLk0g==", + "dev": true, + "requires": { + "@jest/types": "^29.2.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "pretty-format": { + "version": "29.2.1", + "resolved": "https://registry.npmmirror.com/pretty-format/-/pretty-format-29.2.1.tgz", + "integrity": "sha512-Y41Sa4aLCtKAXvwuIpTvcFBkyeYp2gdFWzXGA+ZNES3VwURIB165XO/z7CjETwzCCS53MjW/rLMyyqEnTtaOfA==", + "dev": true, + "requires": { + "@jest/schemas": "^29.0.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmmirror.com/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + } + } + }, + "@types/trusted-types": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/@types/trusted-types/-/trusted-types-2.0.2.tgz", + "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" + }, + "@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + }, + "@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmmirror.com/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "requires": { + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "@types/yargs": { + "version": "17.0.13", + "resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-17.0.13.tgz", + "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmmirror.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.41.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.41.0.tgz", + "integrity": "sha512-DXUS22Y57/LAFSg3x7Vi6RNAuLpTXwxB9S2nIA7msBb/Zt8p7XqMwdpdc1IU7CkOQUPgAqR5fWvxuKCbneKGmA==", + "requires": { + "@typescript-eslint/scope-manager": "5.41.0", + "@typescript-eslint/type-utils": "5.41.0", + "@typescript-eslint/utils": "5.41.0", + "debug": "^4.3.4", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "5.41.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.41.0.tgz", + "integrity": "sha512-/qxT2Kd2q/A22JVIllvws4rvc00/3AT4rAo/0YgEN28y+HPhbJbk6X4+MAHEoZzpNyAOugIT7D/OLnKBW8FfhA==", + "requires": { + "@typescript-eslint/utils": "5.41.0" + } + }, + "@typescript-eslint/parser": { + "version": "5.41.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-5.41.0.tgz", + "integrity": "sha512-HQVfix4+RL5YRWZboMD1pUfFN8MpRH4laziWkkAzyO1fvNOY/uinZcvo3QiFJVS/siNHupV8E5+xSwQZrl6PZA==", + "requires": { + "@typescript-eslint/scope-manager": "5.41.0", + "@typescript-eslint/types": "5.41.0", + "@typescript-eslint/typescript-estree": "5.41.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.41.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-5.41.0.tgz", + "integrity": "sha512-xOxPJCnuktUkY2xoEZBKXO5DBCugFzjrVndKdUnyQr3+9aDWZReKq9MhaoVnbL+maVwWJu/N0SEtrtEUNb62QQ==", + "requires": { + "@typescript-eslint/types": "5.41.0", + "@typescript-eslint/visitor-keys": "5.41.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.41.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-5.41.0.tgz", + "integrity": "sha512-L30HNvIG6A1Q0R58e4hu4h+fZqaO909UcnnPbwKiN6Rc3BUEx6ez2wgN7aC0cBfcAjZfwkzE+E2PQQ9nEuoqfA==", + "requires": { + "@typescript-eslint/typescript-estree": "5.41.0", + "@typescript-eslint/utils": "5.41.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.41.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/types/-/types-5.41.0.tgz", + "integrity": "sha512-5BejraMXMC+2UjefDvrH0Fo/eLwZRV6859SXRg+FgbhA0R0l6lDqDGAQYhKbXhPN2ofk2kY5sgGyLNL907UXpA==" + }, + "@typescript-eslint/typescript-estree": { + "version": "5.41.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.41.0.tgz", + "integrity": "sha512-SlzFYRwFSvswzDSQ/zPkIWcHv8O5y42YUskko9c4ki+fV6HATsTODUPbRbcGDFYP86gaJL5xohUEytvyNNcXWg==", + "requires": { + "@typescript-eslint/types": "5.41.0", + "@typescript-eslint/visitor-keys": "5.41.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.41.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-5.41.0.tgz", + "integrity": "sha512-QlvfwaN9jaMga9EBazQ+5DDx/4sAdqDkcs05AsQHMaopluVCUyu1bTRUVKzXbgjDlrRAQrYVoi/sXJ9fmG+KLQ==", + "requires": { + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.41.0", + "@typescript-eslint/types": "5.41.0", + "@typescript-eslint/typescript-estree": "5.41.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.41.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.41.0.tgz", + "integrity": "sha512-vilqeHj267v8uzzakbm13HkPMl7cbYpKVjgFWZPIOHIJHZtinvypUhJ5xBXfWYg4eFKqztbMMpOgFpT9Gfx4fw==", + "requires": { + "@typescript-eslint/types": "5.41.0", + "eslint-visitor-keys": "^3.3.0" + } + }, + "@webassemblyjs/ast": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "requires": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==" + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==" + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==" + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==" + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==" + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==" + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + } + } + }, + "acorn-import-assertions": { + "version": "1.8.0", + "resolved": "https://registry.npmmirror.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==" + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==" + }, + "acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmmirror.com/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "requires": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + } + } + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" + }, + "address": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/address/-/address-1.2.1.tgz", + "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==" + }, + "adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "requires": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + } + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + } + } + }, + "ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmmirror.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==" + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "aria-query": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/aria-query/-/aria-query-5.1.1.tgz", + "integrity": "sha512-4cPQjOYM2mqq7mZG8CSxkUvL2Yv/x29VhGq5LKehTsxRnoVQps1YGt9NyjcNQsznEsD4rr8a6zGxqeNTqJWjpA==", + "dev": true, + "requires": { + "deep-equal": "^2.0.5" + } + }, + "array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "requires": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "dependencies": { + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + } + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "array-includes": { + "version": "3.1.5", + "resolved": "https://registry.npmmirror.com/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + }, + "array.prototype.flat": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.flatmap": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz", + "integrity": "sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.reduce": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", + "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + } + }, + "arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "requires": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "dependencies": { + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "requires": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "requires": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "dependencies": { + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "requires": { + "es-define-property": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "requires": { + "call-bind": "^1.0.7" + } + } + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + } + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "requires": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + } + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "requires": { + "has-symbols": "^1.0.3" + } + }, + "internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "requires": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + } + }, + "is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==" + }, + "is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "requires": { + "which-typed-array": "^1.1.14" + } + }, + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" + }, + "object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "requires": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "requires": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + } + }, + "safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + } + }, + "string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + } + } + } + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==" + }, + "async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" + }, + "autoprefixer": { + "version": "10.4.12", + "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.12.tgz", + "integrity": "sha512-WrCGV9/b97Pa+jtwf5UGaRjgQIg7OK3D06GnoYoZNcG1Xb8Gt3EfuKjlhh9i/VtT16g6PYjZ69jdJ2g8FxSC4Q==", + "requires": { + "browserslist": "^4.21.4", + "caniuse-lite": "^1.0.30001407", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + } + }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true + }, + "axe-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==" + }, + "axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "requires": { + "follow-redirects": "^1.14.0" + } + }, + "axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "requires": { + "dequal": "^2.0.3" + } + }, + "babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "requires": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + } + }, + "babel-loader": { + "version": "8.2.5", + "resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.2.5.tgz", + "integrity": "sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==", + "requires": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "dependencies": { + "schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "requires": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "requires": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + } + }, + "babel-plugin-named-asset-import": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==" + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.3.3", + "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "requires": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.3", + "semver": "^6.1.1" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.6.0", + "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "requires": { + "@babel/helper-define-polyfill-provider": "^0.3.3", + "core-js-compat": "^3.25.1" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", + "requires": { + "@babel/helper-define-polyfill-provider": "^0.3.3" + } + }, + "babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" + }, + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "requires": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "babel-preset-react-app": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz", + "integrity": "sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==", + "requires": { + "@babel/core": "^7.16.0", + "@babel/plugin-proposal-class-properties": "^7.16.0", + "@babel/plugin-proposal-decorators": "^7.16.4", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", + "@babel/plugin-proposal-numeric-separator": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.0", + "@babel/plugin-proposal-private-methods": "^7.16.0", + "@babel/plugin-transform-flow-strip-types": "^7.16.0", + "@babel/plugin-transform-react-display-name": "^7.16.0", + "@babel/plugin-transform-runtime": "^7.16.4", + "@babel/preset-env": "^7.16.4", + "@babel/preset-react": "^7.16.0", + "@babel/preset-typescript": "^7.16.0", + "@babel/runtime": "^7.16.3", + "babel-plugin-macros": "^3.1.0", + "babel-plugin-transform-react-remove-prop-types": "^0.4.24" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + }, + "bfj": { + "version": "7.0.2", + "resolved": "https://registry.npmmirror.com/bfj/-/bfj-7.0.2.tgz", + "integrity": "sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw==", + "requires": { + "bluebird": "^3.5.5", + "check-types": "^11.1.1", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" + } + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "bonjour-service": { + "version": "1.0.14", + "resolved": "https://registry.npmmirror.com/bonjour-service/-/bonjour-service-1.0.14.tgz", + "integrity": "sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ==", + "requires": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + }, + "dependencies": { + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + } + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + }, + "browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "requires": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==" + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" + }, + "camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" + }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001620", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001620.tgz", + "integrity": "sha512-WJvYsOjd1/BYUY6SNGUosK9DUidBPDTnOARHp3fSmFO1ekdxaY6nKRttEVrfMmYi80ctS0kz1wiWmm14fVc3ew==" + }, + "case-sensitive-paths-webpack-plugin": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==" + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==" + }, + "check-types": { + "version": "11.1.2", + "resolved": "https://registry.npmmirror.com/check-types/-/check-types-11.1.2.tgz", + "integrity": "sha512-tzWzvgePgLORb9/3a0YenggReLKAIb2owL03H2Xdoe5pKcUyWRSEQ8xfCar8t2SIAuEDwtmx2da1YB52YuHQMQ==" + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" + }, + "ci-info": { + "version": "3.5.0", + "resolved": "https://registry.npmmirror.com/ci-info/-/ci-info-3.5.0.tgz", + "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==" + }, + "cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" + }, + "clean-css": { + "version": "5.3.1", + "resolved": "https://registry.npmmirror.com/clean-css/-/clean-css-5.3.1.tgz", + "integrity": "sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg==", + "requires": { + "source-map": "~0.6.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==" + }, + "coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "requires": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==" + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + }, + "colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmmirror.com/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + }, + "common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" + }, + "connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==" + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" + }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "copy-to-clipboard": { + "version": "3.3.2", + "resolved": "https://registry.npmmirror.com/copy-to-clipboard/-/copy-to-clipboard-3.3.2.tgz", + "integrity": "sha512-Vme1Z6RUDzrb6xAI7EZlVZ5uvOk2F//GaxKUxajDqm9LhOVM1inxNAD2vy+UZDYsd0uyA9s7b3/FVZPSxqrCfg==", + "requires": { + "toggle-selection": "^1.0.6" + } + }, + "core-js": { + "version": "3.26.0", + "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.26.0.tgz", + "integrity": "sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==" + }, + "core-js-compat": { + "version": "3.26.0", + "resolved": "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.26.0.tgz", + "integrity": "sha512-piOX9Go+Z4f9ZiBFLnZ5VrOpBl0h7IGCkiFUN11QTe6LjAvOT3ifL/5TdoizMh99hcGy5SoLyWbapIY/PIb/3A==", + "requires": { + "browserslist": "^4.21.4" + } + }, + "core-js-pure": { + "version": "3.26.0", + "resolved": "https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.26.0.tgz", + "integrity": "sha512-LiN6fylpVBVwT8twhhluD9TzXmZQQsr2I2eIKtWNbZI1XMfBT7CV18itaN6RA7EtQd/SDdRx/wzvAShX2HvhQA==" + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" + }, + "css-blank-pseudo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", + "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", + "requires": { + "postcss-selector-parser": "^6.0.9" + } + }, + "css-declaration-sorter": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", + "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==" + }, + "css-has-pseudo": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", + "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", + "requires": { + "postcss-selector-parser": "^6.0.9" + } + }, + "css-loader": { + "version": "6.7.1", + "resolved": "https://registry.npmmirror.com/css-loader/-/css-loader-6.7.1.tgz", + "integrity": "sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==", + "requires": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.7", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.5" + } + }, + "css-minimizer-webpack-plugin": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", + "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", + "requires": { + "cssnano": "^5.0.6", + "jest-worker": "^27.0.2", + "postcss": "^8.3.5", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1" + } + }, + "css-prefers-color-scheme": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==" + }, + "css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + } + }, + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" + }, + "css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "requires": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + } + }, + "css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" + }, + "css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true + }, + "cssdb": { + "version": "7.0.2", + "resolved": "https://registry.npmmirror.com/cssdb/-/cssdb-7.0.2.tgz", + "integrity": "sha512-Vm4b6P/PifADu0a76H0DKRNVWq3Rq9xa/Nx6oEMUBJlwTUuZoZ3dkZxo8Gob3UEL53Cq+Ma1GBgISed6XEBs3w==" + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + }, + "cssnano": { + "version": "5.1.13", + "resolved": "https://registry.npmmirror.com/cssnano/-/cssnano-5.1.13.tgz", + "integrity": "sha512-S2SL2ekdEz6w6a2epXn4CmMKU4K3KpcyXLKfAYc9UQQqJRkD/2eLUG0vJ3Db/9OvO5GuAdgXw3pFbR6abqghDQ==", + "requires": { + "cssnano-preset-default": "^5.2.12", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + } + }, + "cssnano-preset-default": { + "version": "5.2.12", + "resolved": "https://registry.npmmirror.com/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz", + "integrity": "sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew==", + "requires": { + "css-declaration-sorter": "^6.3.0", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.0", + "postcss-convert-values": "^5.1.2", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.6", + "postcss-merge-rules": "^5.1.2", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.3", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.0", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.0", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + } + }, + "cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==" + }, + "csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "requires": { + "css-tree": "^1.1.2" + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + } + } + }, + "csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "dependencies": { + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + } + } + }, + "data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "dependencies": { + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + } + } + }, + "data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "dependencies": { + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + } + } + }, + "dayjs": { + "version": "1.11.6", + "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.6.tgz", + "integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "decimal.js": { + "version": "10.4.2", + "resolved": "https://registry.npmmirror.com/decimal.js/-/decimal.js-10.4.2.tgz", + "integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==" + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" + }, + "deep-equal": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/deep-equal/-/deep-equal-2.0.5.tgz", + "integrity": "sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "es-get-iterator": "^1.1.1", + "get-intrinsic": "^1.0.1", + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.2", + "is-regex": "^1.1.1", + "isarray": "^2.0.5", + "object-is": "^1.1.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.3.0", + "side-channel": "^1.0.3", + "which-boxed-primitive": "^1.0.1", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.2" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + }, + "default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "requires": { + "execa": "^5.0.0" + } + }, + "define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==" + }, + "define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "defined": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==" + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" + }, + "detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "requires": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "detective": { + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/detective/-/detective-5.2.1.tgz", + "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "requires": { + "acorn-node": "^1.8.2", + "defined": "^1.0.0", + "minimist": "^1.2.6" + } + }, + "didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==" + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "requires": { + "path-type": "^4.0.0" + } + }, + "dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" + }, + "dns-packet": { + "version": "5.4.0", + "resolved": "https://registry.npmmirror.com/dns-packet/-/dns-packet-5.4.0.tgz", + "integrity": "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==", + "requires": { + "@leichtgewicht/ip-codec": "^2.0.1" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-accessibility-api": { + "version": "0.5.14", + "resolved": "https://registry.npmmirror.com/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz", + "integrity": "sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg==", + "dev": true + }, + "dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "requires": { + "utila": "~0.4" + } + }, + "dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + }, + "dependencies": { + "csstype": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + } + } + }, + "dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" + } + } + }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmmirror.com/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + }, + "dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" + }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "requires": { + "jake": "^10.8.5" + } + }, + "electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" + }, + "emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + }, + "enhanced-resolve": { + "version": "5.10.0", + "resolved": "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", + "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "requires": { + "stackframe": "^1.3.4" + } + }, + "es-abstract": { + "version": "1.20.4", + "resolved": "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.20.4.tgz", + "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.2", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + } + }, + "es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" + }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "requires": { + "get-intrinsic": "^1.2.4" + }, + "dependencies": { + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + } + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, + "es-get-iterator": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/es-get-iterator/-/es-get-iterator-1.1.2.tgz", + "integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.0", + "has-symbols": "^1.0.1", + "is-arguments": "^1.1.0", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.5", + "isarray": "^2.0.5" + } + }, + "es-iterator-helpers": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.2" + }, + "dependencies": { + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "requires": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "requires": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + } + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "requires": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + } + }, + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "requires": { + "es-define-property": "^1.0.0" + } + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "requires": { + "has-symbols": "^1.0.3" + } + }, + "internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "requires": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + } + }, + "is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==" + }, + "is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "requires": { + "call-bind": "^1.0.7" + } + }, + "is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "requires": { + "which-typed-array": "^1.1.14" + } + }, + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" + }, + "object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "requires": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "requires": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + } + }, + "safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + } + }, + "string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + } + } + } + }, + "es-module-lexer": { + "version": "0.9.3", + "resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==" + }, + "es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "requires": { + "es-errors": "^1.3.0" + } + }, + "es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "requires": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "dependencies": { + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "requires": { + "has-symbols": "^1.0.3" + } + } + } + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "requires": { + "has": "^1.0.3" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmmirror.com/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmmirror.com/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + } + } + }, + "eslint": { + "version": "8.26.0", + "resolved": "https://registry.npmmirror.com/eslint/-/eslint-8.26.0.tgz", + "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==", + "requires": { + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.11.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.15.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "dependencies": { + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.17.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "requires": { + "type-fest": "^0.20.2" + } + } + } + }, + "eslint-config-react-app": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", + "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", + "requires": { + "@babel/core": "^7.16.0", + "@babel/eslint-parser": "^7.16.3", + "@rushstack/eslint-patch": "^1.1.0", + "@typescript-eslint/eslint-plugin": "^5.5.0", + "@typescript-eslint/parser": "^5.5.0", + "babel-preset-react-app": "^10.0.1", + "confusing-browser-globals": "^1.0.11", + "eslint-plugin-flowtype": "^8.0.3", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jest": "^25.3.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.27.1", + "eslint-plugin-react-hooks": "^4.3.0", + "eslint-plugin-testing-library": "^5.0.1" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmmirror.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.7.4", + "resolved": "https://registry.npmmirror.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "requires": { + "debug": "^3.2.7" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-flowtype": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", + "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", + "requires": { + "lodash": "^4.17.21", + "string-natural-compare": "^3.0.1" + } + }, + "eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmmirror.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "requires": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "eslint-plugin-jest": { + "version": "25.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", + "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", + "requires": { + "@typescript-eslint/experimental-utils": "^5.0.0" + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", + "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "requires": { + "@babel/runtime": "^7.23.2", + "aria-query": "^5.3.0", + "array-includes": "^3.1.7", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "=4.7.0", + "axobject-query": "^3.2.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.15", + "hasown": "^2.0.0", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7" + }, + "dependencies": { + "aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "requires": { + "dequal": "^2.0.3" + } + }, + "array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + } + }, + "array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "requires": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "requires": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "dependencies": { + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "requires": { + "es-define-property": "^1.0.0" + } + } + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + } + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "requires": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + } + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "requires": { + "has-symbols": "^1.0.3" + } + }, + "internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "requires": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + } + }, + "is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==" + }, + "is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "requires": { + "call-bind": "^1.0.7" + } + }, + "is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "requires": { + "which-typed-array": "^1.1.14" + } + }, + "jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "requires": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + } + }, + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" + }, + "object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "requires": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + } + }, + "object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "requires": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + } + }, + "safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + } + }, + "string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + } + } + } + }, + "eslint-plugin-prefer-arrow": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prefer-arrow/-/eslint-plugin-prefer-arrow-1.2.3.tgz", + "integrity": "sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ==", + "dev": true + }, + "eslint-plugin-react": { + "version": "7.31.10", + "resolved": "https://registry.npmmirror.com/eslint-plugin-react/-/eslint-plugin-react-7.31.10.tgz", + "integrity": "sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA==", + "requires": { + "array-includes": "^3.1.5", + "array.prototype.flatmap": "^1.3.0", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.5", + "object.fromentries": "^2.0.5", + "object.hasown": "^1.1.1", + "object.values": "^1.1.5", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.3", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.7" + }, + "dependencies": { + "resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmmirror.com/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmmirror.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==" + }, + "eslint-plugin-testing-library": { + "version": "5.9.1", + "resolved": "https://registry.npmmirror.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.9.1.tgz", + "integrity": "sha512-6BQp3tmb79jLLasPHJmy8DnxREe+2Pgf7L+7o09TSWPfdqqtQfRZmZNetr5mOs3yqZk/MRNxpN3RUpJe0wB4LQ==", + "requires": { + "@typescript-eslint/utils": "^5.13.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + } + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==" + }, + "eslint-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", + "requires": { + "@types/eslint": "^7.29.0 || ^8.4.1", + "jest-worker": "^28.0.2", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + }, + "jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "espree": { + "version": "9.4.0", + "resolved": "https://registry.npmmirror.com/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + }, + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==" + }, + "expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "requires": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + } + }, + "express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "requires": { + "reusify": "^1.0.4" + } + }, + "fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "requires": { + "format": "^0.2.0" + } + }, + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "requires": { + "bser": "2.1.1" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "requires": { + "minimatch": "^5.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "filesize": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmmirror.com/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" + }, + "follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "requires": { + "is-callable": "^1.1.3" + } + }, + "fork-ts-checker-webpack-plugin": { + "version": "6.5.2", + "resolved": "https://registry.npmmirror.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz", + "integrity": "sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" + } + } + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==" + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs-monkey": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/fs-monkey/-/fs-monkey-1.0.3.tgz", + "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmmirror.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "requires": { + "global-prefix": "^3.0.0" + } + }, + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "dependencies": { + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "requires": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "dependencies": { + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "requires": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + } + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" + }, + "gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "requires": { + "duplexer": "^0.1.2" + } + }, + "handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + }, + "harmony-reflect": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "requires": { + "function-bind": "^1.1.2" + }, + "dependencies": { + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + } + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "highlight.js": { + "version": "11.8.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.8.0.tgz", + "integrity": "sha512-MedQhoqVdr0U6SSnWPzfiadUcDHfN/Wzq25AkXiQv9oiOO/sG0S7XkvpFIqWBl9Yq1UYyYOOVORs5UW2XlPyzg==" + }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, + "hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==" + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "html-entities": { + "version": "2.3.3", + "resolved": "https://registry.npmmirror.com/html-entities/-/html-entities-2.3.3.tgz", + "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "requires": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "dependencies": { + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" + } + } + }, + "html-webpack-plugin": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", + "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "requires": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + } + }, + "htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "requires": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==" + }, + "idb": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/idb/-/idb-7.1.0.tgz", + "integrity": "sha512-Wsk07aAxDsntgYJY4h0knZJuTxM73eQ4reRAO+Z1liOh8eMCJ/MoDS8fCui1vGT9mnjtl1sOu3I2i/W1swPYZg==" + }, + "identity-obj-proxy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", + "requires": { + "harmony-reflect": "^1.4.6" + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" + }, + "immer": { + "version": "9.0.16", + "resolved": "https://registry.npmmirror.com/immer/-/immer-9.0.16.tgz", + "integrity": "sha512-qenGE7CstVm1NrHQbMh8YaSzTZTFNP3zPqr3YU0S0UY441j4bJTg4A2Hh5KAhwgaiU6ZZ1Ar6y/2f4TblnMReQ==" + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + } + } + }, + "import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "ipaddr.js": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz", + "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==" + }, + "is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "dependencies": { + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "requires": { + "has": "^1.0.3" + } + }, + "is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "requires": { + "is-typed-array": "^1.1.13" + }, + "dependencies": { + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "requires": { + "has-symbols": "^1.0.3" + } + }, + "is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "requires": { + "which-typed-array": "^1.1.14" + } + }, + "which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + } + } + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==" + }, + "is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==" + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==" + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" + }, + "is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==" + }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==" + }, + "is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==" + }, + "is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==" + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmmirror.com/is-typed-array/-/is-typed-array-1.1.9.tgz", + "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==" + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==" + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "requires": { + "semver": "^7.5.3" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "requires": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + }, + "dependencies": { + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "requires": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + } + } + }, + "jake": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", + "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", + "requires": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + } + }, + "jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "requires": { + "@jest/core": "^27.5.1", + "import-local": "^3.0.2", + "jest-cli": "^27.5.1" + } + }, + "jest-changed-files": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "requires": { + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" + } + }, + "jest-circus": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "requires": { + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "jest-cli": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", + "requires": { + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + } + }, + "jest-config": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "requires": { + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + } + }, + "jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + } + }, + "jest-docblock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "requires": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" + } + }, + "jest-environment-jsdom": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", + "requires": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "jest-environment-node": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "requires": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==" + }, + "jest-haste-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "requires": { + "@jest/types": "^27.5.1", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "jest-jasmine2": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "requires": { + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "jest-leak-detector": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "requires": { + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + } + }, + "jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + } + }, + "jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "requires": { + "@jest/types": "^27.5.1", + "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==" + }, + "jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==" + }, + "jest-resolve": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", + "requires": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "requires": { + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" + } + }, + "jest-runner": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "requires": { + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "jest-runtime": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "requires": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + } + } + }, + "jest-serializer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.9" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "requires": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.5.1", + "semver": "^7.3.2" + } + }, + "jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "requires": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + } + } + }, + "jest-validate": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", + "requires": { + "@jest/types": "^27.5.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "leven": "^3.1.0", + "pretty-format": "^27.5.1" + } + }, + "jest-watch-typeahead": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", + "integrity": "sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==", + "requires": { + "ansi-escapes": "^4.3.1", + "chalk": "^4.0.0", + "jest-regex-util": "^28.0.0", + "jest-watcher": "^28.0.0", + "slash": "^4.0.0", + "string-length": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + }, + "char-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/char-regex/-/char-regex-2.0.1.tgz", + "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==" + }, + "jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==" + }, + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==" + }, + "string-length": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", + "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", + "requires": { + "char-regex": "^2.0.0", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "jest-watcher": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", + "requires": { + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.3", + "string-length": "^4.0.1" + }, + "dependencies": { + "@jest/console": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", + "requires": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0" + } + }, + "@jest/test-result": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", + "requires": { + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "requires": { + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" + }, + "emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmmirror.com/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==" + }, + "jest-message-util": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-util": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "requires": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "requires": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmmirror.com/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==" + }, + "js-sdsl": { + "version": "4.1.5", + "resolved": "https://registry.npmmirror.com/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "requires": { + "argparse": "^2.0.1" + } + }, + "jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "requires": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "ws": { + "version": "7.5.9", + "resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==" + } + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==" + }, + "jsx-ast-utils": { + "version": "3.3.3", + "resolved": "https://registry.npmmirror.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", + "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", + "requires": { + "array-includes": "^3.1.5", + "object.assign": "^4.1.3" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "klona": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/klona/-/klona-2.0.5.tgz", + "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==" + }, + "language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==" + }, + "language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "requires": { + "language-subtag-registry": "^0.3.20" + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "dependencies": { + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "requires": { + "prelude-ls": "^1.2.1" + } + } + } + }, + "lilconfig": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.0.6.tgz", + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==" + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==" + }, + "loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "requires": { + "tslib": "^2.0.3" + } + }, + "lowlight": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-2.9.0.tgz", + "integrity": "sha512-OpcaUTCLmHuVuBcyNckKfH5B0oA4JUavb/M/8n9iAvanJYNQkrVm4pvyX0SUaqkBG4dnWHKt7p50B3ngAG2Rfw==", + "requires": { + "@types/hast": "^2.0.0", + "fault": "^2.0.0", + "highlight.js": "~11.8.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true + }, + "magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "requires": { + "sourcemap-codec": "^1.4.8" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "requires": { + "tmpl": "1.0.5" + } + }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + }, + "memfs": { + "version": "3.4.7", + "resolved": "https://registry.npmmirror.com/memfs/-/memfs-3.4.7.tgz", + "integrity": "sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw==", + "requires": { + "fs-monkey": "^1.0.3" + } + }, + "memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "mini-css-extract-plugin": { + "version": "2.6.1", + "resolved": "https://registry.npmmirror.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz", + "integrity": "sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg==", + "requires": { + "schema-utils": "^4.0.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" + }, + "mockdate": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz", + "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==", + "dev": true + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "requires": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + } + }, + "nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" + }, + "node-releases": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" + }, + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" + }, + "npm": { + "version": "8.19.2", + "resolved": "https://registry.npmmirror.com/npm/-/npm-8.19.2.tgz", + "integrity": "sha512-MWkISVv5f7iZbfNkry5/5YBqSYJEDAKSJdL+uzSQuyLg+hgLQUyZynu3SH6bOZlvR9ZvJYk2EiJO6B1r+ynwHg==", + "dev": true, + "requires": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^5.6.2", + "@npmcli/ci-detect": "^2.0.0", + "@npmcli/config": "^4.2.1", + "@npmcli/fs": "^2.1.0", + "@npmcli/map-workspaces": "^2.0.3", + "@npmcli/package-json": "^2.0.0", + "@npmcli/promise-spawn": "*", + "@npmcli/run-script": "^4.2.1", + "abbrev": "~1.1.1", + "archy": "~1.0.0", + "cacache": "^16.1.3", + "chalk": "^4.1.2", + "chownr": "^2.0.0", + "cli-columns": "^4.0.0", + "cli-table3": "^0.6.2", + "columnify": "^1.6.0", + "fastest-levenshtein": "^1.0.12", + "fs-minipass": "*", + "glob": "^8.0.1", + "graceful-fs": "^4.2.10", + "hosted-git-info": "^5.1.0", + "ini": "^3.0.1", + "init-package-json": "^3.0.2", + "is-cidr": "^4.0.2", + "json-parse-even-better-errors": "^2.3.1", + "libnpmaccess": "^6.0.4", + "libnpmdiff": "^4.0.5", + "libnpmexec": "^4.0.13", + "libnpmfund": "^3.0.4", + "libnpmhook": "^8.0.4", + "libnpmorg": "^4.0.4", + "libnpmpack": "^4.1.3", + "libnpmpublish": "^6.0.5", + "libnpmsearch": "^5.0.4", + "libnpmteam": "^4.0.4", + "libnpmversion": "^3.0.7", + "make-fetch-happen": "^10.2.0", + "minimatch": "*", + "minipass": "^3.1.6", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "mkdirp-infer-owner": "^2.0.0", + "ms": "^2.1.2", + "node-gyp": "^9.1.0", + "nopt": "^6.0.0", + "npm-audit-report": "^3.0.0", + "npm-install-checks": "^5.0.0", + "npm-package-arg": "^9.1.0", + "npm-pick-manifest": "^7.0.2", + "npm-profile": "^6.2.0", + "npm-registry-fetch": "^13.3.1", + "npm-user-validate": "^1.0.1", + "npmlog": "^6.0.2", + "opener": "^1.5.2", + "p-map": "^4.0.0", + "pacote": "^13.6.2", + "parse-conflict-json": "^2.0.2", + "proc-log": "^2.0.1", + "qrcode-terminal": "^0.12.0", + "read": "~1.0.7", + "read-package-json": "^5.0.2", + "read-package-json-fast": "^2.0.3", + "readdir-scoped-modules": "^1.1.0", + "rimraf": "^3.0.2", + "semver": "^7.3.7", + "ssri": "^9.0.1", + "tar": "^6.1.11", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "treeverse": "^2.0.0", + "validate-npm-package-name": "^4.0.0", + "which": "^2.0.2", + "write-file-atomic": "^4.0.1" + }, + "dependencies": { + "@colors/colors": { + "version": "1.5.0", + "bundled": true, + "dev": true, + "optional": true + }, + "@gar/promisify": { + "version": "1.1.3", + "bundled": true, + "dev": true + }, + "@isaacs/string-locale-compare": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "@npmcli/arborist": { + "version": "5.6.2", + "bundled": true, + "dev": true, + "requires": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/installed-package-contents": "^1.0.7", + "@npmcli/map-workspaces": "^2.0.3", + "@npmcli/metavuln-calculator": "^3.0.1", + "@npmcli/move-file": "^2.0.0", + "@npmcli/name-from-folder": "^1.0.1", + "@npmcli/node-gyp": "^2.0.0", + "@npmcli/package-json": "^2.0.0", + "@npmcli/query": "^1.2.0", + "@npmcli/run-script": "^4.1.3", + "bin-links": "^3.0.3", + "cacache": "^16.1.3", + "common-ancestor-path": "^1.0.1", + "json-parse-even-better-errors": "^2.3.1", + "json-stringify-nice": "^1.1.4", + "minimatch": "^5.1.0", + "mkdirp": "^1.0.4", + "mkdirp-infer-owner": "^2.0.0", + "nopt": "^6.0.0", + "npm-install-checks": "^5.0.0", + "npm-package-arg": "^9.0.0", + "npm-pick-manifest": "^7.0.2", + "npm-registry-fetch": "^13.0.0", + "npmlog": "^6.0.2", + "pacote": "^13.6.1", + "parse-conflict-json": "^2.0.1", + "proc-log": "^2.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^1.0.1", + "read-package-json-fast": "^2.0.2", + "readdir-scoped-modules": "^1.1.0", + "rimraf": "^3.0.2", + "semver": "^7.3.7", + "ssri": "^9.0.0", + "treeverse": "^2.0.0", + "walk-up-path": "^1.0.0" + } + }, + "@npmcli/ci-detect": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "@npmcli/config": { + "version": "4.2.2", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/map-workspaces": "^2.0.2", + "ini": "^3.0.0", + "mkdirp-infer-owner": "^2.0.0", + "nopt": "^6.0.0", + "proc-log": "^2.0.0", + "read-package-json-fast": "^2.0.3", + "semver": "^7.3.5", + "walk-up-path": "^1.0.0" + } + }, + "@npmcli/disparity-colors": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "^4.3.0" + } + }, + "@npmcli/fs": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "requires": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + } + }, + "@npmcli/git": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/promise-spawn": "^3.0.0", + "lru-cache": "^7.4.4", + "mkdirp": "^1.0.4", + "npm-pick-manifest": "^7.0.0", + "proc-log": "^2.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^2.0.2" + } + }, + "@npmcli/installed-package-contents": { + "version": "1.0.7", + "bundled": true, + "dev": true, + "requires": { + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + }, + "dependencies": { + "npm-bundled": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + } + } + }, + "@npmcli/map-workspaces": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/name-from-folder": "^1.0.1", + "glob": "^8.0.1", + "minimatch": "^5.0.1", + "read-package-json-fast": "^2.0.3" + } + }, + "@npmcli/metavuln-calculator": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "requires": { + "cacache": "^16.0.0", + "json-parse-even-better-errors": "^2.3.1", + "pacote": "^13.0.3", + "semver": "^7.3.5" + } + }, + "@npmcli/move-file": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + } + }, + "@npmcli/name-from-folder": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "@npmcli/node-gyp": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "@npmcli/package-json": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "json-parse-even-better-errors": "^2.3.1" + } + }, + "@npmcli/promise-spawn": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "infer-owner": "^1.0.4" + } + }, + "@npmcli/query": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "npm-package-arg": "^9.1.0", + "postcss-selector-parser": "^6.0.10", + "semver": "^7.3.7" + } + }, + "@npmcli/run-script": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/node-gyp": "^2.0.0", + "@npmcli/promise-spawn": "^3.0.0", + "node-gyp": "^9.0.0", + "read-package-json-fast": "^2.0.3", + "which": "^2.0.2" + } + }, + "@tootallnate/once": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "bundled": true, + "dev": true, + "requires": { + "debug": "4" + } + }, + "agentkeepalive": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "requires": { + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" + } + }, + "aggregate-error": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ansi-regex": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "bundled": true, + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "aproba": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "are-we-there-yet": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + } + }, + "asap": { + "version": "2.0.6", + "bundled": true, + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "bin-links": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "requires": { + "cmd-shim": "^5.0.0", + "mkdirp-infer-owner": "^2.0.0", + "npm-normalize-package-bin": "^2.0.0", + "read-cmd-shim": "^3.0.0", + "rimraf": "^3.0.0", + "write-file-atomic": "^4.0.0" + }, + "dependencies": { + "npm-normalize-package-bin": { + "version": "2.0.0", + "bundled": true, + "dev": true + } + } + }, + "binary-extensions": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "builtins": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "requires": { + "semver": "^7.0.0" + } + }, + "cacache": { + "version": "16.1.3", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + } + }, + "chalk": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chownr": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "cidr-regex": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "requires": { + "ip-regex": "^4.1.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "cli-columns": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + } + }, + "cli-table3": { + "version": "0.6.2", + "bundled": true, + "dev": true, + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" + } + }, + "clone": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "cmd-shim": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "mkdirp-infer-owner": "^2.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "bundled": true, + "dev": true + }, + "color-support": { + "version": "1.1.3", + "bundled": true, + "dev": true + }, + "columnify": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "requires": { + "strip-ansi": "^6.0.1", + "wcwidth": "^1.0.0" + } + }, + "common-ancestor-path": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "cssesc": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "debug": { + "version": "4.3.4", + "bundled": true, + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true + } + } + }, + "debuglog": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "defaults": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "depd": { + "version": "1.1.2", + "bundled": true, + "dev": true + }, + "dezalgo": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "diff": { + "version": "5.1.0", + "bundled": true, + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "bundled": true, + "dev": true + }, + "encoding": { + "version": "0.1.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "iconv-lite": "^0.6.2" + } + }, + "env-paths": { + "version": "2.2.1", + "bundled": true, + "dev": true + }, + "err-code": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.12", + "bundled": true, + "dev": true + }, + "fs-minipass": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "gauge": { + "version": "4.0.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + } + }, + "glob": { + "version": "8.0.3", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + }, + "graceful-fs": { + "version": "4.2.10", + "bundled": true, + "dev": true + }, + "has": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "hosted-git-info": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^7.5.1" + } + }, + "http-cache-semantics": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "http-proxy-agent": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "humanize-ms": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "requires": { + "ms": "^2.0.0" + } + }, + "iconv-lite": { + "version": "0.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "ignore-walk": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "requires": { + "minimatch": "^5.0.1" + } + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true + }, + "ini": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "init-package-json": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "npm-package-arg": "^9.0.1", + "promzard": "^0.3.0", + "read": "^1.0.7", + "read-package-json": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^4.0.0" + } + }, + "ip": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "ip-regex": { + "version": "4.3.0", + "bundled": true, + "dev": true + }, + "is-cidr": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "cidr-regex": "^3.1.1" + } + }, + "is-core-module": { + "version": "2.10.0", + "bundled": true, + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "is-lambda": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "bundled": true, + "dev": true + }, + "json-stringify-nice": { + "version": "1.1.4", + "bundled": true, + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "bundled": true, + "dev": true + }, + "just-diff": { + "version": "5.1.1", + "bundled": true, + "dev": true + }, + "just-diff-apply": { + "version": "5.4.1", + "bundled": true, + "dev": true + }, + "libnpmaccess": { + "version": "6.0.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "minipass": "^3.1.1", + "npm-package-arg": "^9.0.1", + "npm-registry-fetch": "^13.0.0" + } + }, + "libnpmdiff": { + "version": "4.0.5", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/disparity-colors": "^2.0.0", + "@npmcli/installed-package-contents": "^1.0.7", + "binary-extensions": "^2.2.0", + "diff": "^5.1.0", + "minimatch": "^5.0.1", + "npm-package-arg": "^9.0.1", + "pacote": "^13.6.1", + "tar": "^6.1.0" + } + }, + "libnpmexec": { + "version": "4.0.13", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/arborist": "^5.6.2", + "@npmcli/ci-detect": "^2.0.0", + "@npmcli/fs": "^2.1.1", + "@npmcli/run-script": "^4.2.0", + "chalk": "^4.1.0", + "mkdirp-infer-owner": "^2.0.0", + "npm-package-arg": "^9.0.1", + "npmlog": "^6.0.2", + "pacote": "^13.6.1", + "proc-log": "^2.0.0", + "read": "^1.0.7", + "read-package-json-fast": "^2.0.2", + "semver": "^7.3.7", + "walk-up-path": "^1.0.0" + } + }, + "libnpmfund": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/arborist": "^5.6.2" + } + }, + "libnpmhook": { + "version": "8.0.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^13.0.0" + } + }, + "libnpmorg": { + "version": "4.0.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^13.0.0" + } + }, + "libnpmpack": { + "version": "4.1.3", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/run-script": "^4.1.3", + "npm-package-arg": "^9.0.1", + "pacote": "^13.6.1" + } + }, + "libnpmpublish": { + "version": "6.0.5", + "bundled": true, + "dev": true, + "requires": { + "normalize-package-data": "^4.0.0", + "npm-package-arg": "^9.0.1", + "npm-registry-fetch": "^13.0.0", + "semver": "^7.3.7", + "ssri": "^9.0.0" + } + }, + "libnpmsearch": { + "version": "5.0.4", + "bundled": true, + "dev": true, + "requires": { + "npm-registry-fetch": "^13.0.0" + } + }, + "libnpmteam": { + "version": "4.0.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^13.0.0" + } + }, + "libnpmversion": { + "version": "3.0.7", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/git": "^3.0.0", + "@npmcli/run-script": "^4.1.3", + "json-parse-even-better-errors": "^2.3.1", + "proc-log": "^2.0.0", + "semver": "^7.3.7" + } + }, + "lru-cache": { + "version": "7.13.2", + "bundled": true, + "dev": true + }, + "make-fetch-happen": { + "version": "10.2.1", + "bundled": true, + "dev": true, + "requires": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + } + }, + "minimatch": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "minipass": { + "version": "3.3.4", + "bundled": true, + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minipass-collect": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-fetch": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "encoding": "^0.1.13", + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + } + }, + "minipass-flush": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-json-stream": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "minipass-pipeline": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-sized": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "mkdirp-infer-owner": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "chownr": "^2.0.0", + "infer-owner": "^1.0.4", + "mkdirp": "^1.0.3" + } + }, + "ms": { + "version": "2.1.3", + "bundled": true, + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "negotiator": { + "version": "0.6.3", + "bundled": true, + "dev": true + }, + "node-gyp": { + "version": "9.1.0", + "bundled": true, + "dev": true, + "requires": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.0.3", + "nopt": "^5.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.3", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "nopt": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "abbrev": "1" + } + } + } + }, + "nopt": { + "version": "6.0.0", + "bundled": true, + "dev": true, + "requires": { + "abbrev": "^1.0.0" + } + }, + "normalize-package-data": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "requires": { + "hosted-git-info": "^5.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + } + }, + "npm-audit-report": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, + "npm-bundled": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "npm-normalize-package-bin": "^2.0.0" + }, + "dependencies": { + "npm-normalize-package-bin": { + "version": "2.0.0", + "bundled": true, + "dev": true + } + } + }, + "npm-install-checks": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "semver": "^7.1.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "npm-package-arg": { + "version": "9.1.0", + "bundled": true, + "dev": true, + "requires": { + "hosted-git-info": "^5.0.0", + "proc-log": "^2.0.1", + "semver": "^7.3.5", + "validate-npm-package-name": "^4.0.0" + } + }, + "npm-packlist": { + "version": "5.1.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^8.0.1", + "ignore-walk": "^5.0.1", + "npm-bundled": "^2.0.0", + "npm-normalize-package-bin": "^2.0.0" + }, + "dependencies": { + "npm-normalize-package-bin": { + "version": "2.0.0", + "bundled": true, + "dev": true + } + } + }, + "npm-pick-manifest": { + "version": "7.0.2", + "bundled": true, + "dev": true, + "requires": { + "npm-install-checks": "^5.0.0", + "npm-normalize-package-bin": "^2.0.0", + "npm-package-arg": "^9.0.0", + "semver": "^7.3.5" + }, + "dependencies": { + "npm-normalize-package-bin": { + "version": "2.0.0", + "bundled": true, + "dev": true + } + } + }, + "npm-profile": { + "version": "6.2.1", + "bundled": true, + "dev": true, + "requires": { + "npm-registry-fetch": "^13.0.1", + "proc-log": "^2.0.0" + } + }, + "npm-registry-fetch": { + "version": "13.3.1", + "bundled": true, + "dev": true, + "requires": { + "make-fetch-happen": "^10.0.6", + "minipass": "^3.1.6", + "minipass-fetch": "^2.0.3", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^9.0.1", + "proc-log": "^2.0.0" + } + }, + "npm-user-validate": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "npmlog": { + "version": "6.0.2", + "bundled": true, + "dev": true, + "requires": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + } + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opener": { + "version": "1.5.2", + "bundled": true, + "dev": true + }, + "p-map": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "pacote": { + "version": "13.6.2", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/git": "^3.0.0", + "@npmcli/installed-package-contents": "^1.0.7", + "@npmcli/promise-spawn": "^3.0.0", + "@npmcli/run-script": "^4.1.0", + "cacache": "^16.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "infer-owner": "^1.0.4", + "minipass": "^3.1.6", + "mkdirp": "^1.0.4", + "npm-package-arg": "^9.0.0", + "npm-packlist": "^5.1.0", + "npm-pick-manifest": "^7.0.0", + "npm-registry-fetch": "^13.0.1", + "proc-log": "^2.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^5.0.0", + "read-package-json-fast": "^2.0.3", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11" + } + }, + "parse-conflict-json": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "json-parse-even-better-errors": "^2.3.1", + "just-diff": "^5.0.1", + "just-diff-apply": "^5.2.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "postcss-selector-parser": { + "version": "6.0.10", + "bundled": true, + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "proc-log": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "promise-all-reject-late": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "promise-call-limit": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "promise-retry": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + } + }, + "promzard": { + "version": "0.3.0", + "bundled": true, + "dev": true, + "requires": { + "read": "1" + } + }, + "qrcode-terminal": { + "version": "0.12.0", + "bundled": true, + "dev": true + }, + "read": { + "version": "1.0.7", + "bundled": true, + "dev": true, + "requires": { + "mute-stream": "~0.0.4" + } + }, + "read-cmd-shim": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "read-package-json": { + "version": "5.0.2", + "bundled": true, + "dev": true, + "requires": { + "glob": "^8.0.1", + "json-parse-even-better-errors": "^2.3.1", + "normalize-package-data": "^4.0.0", + "npm-normalize-package-bin": "^2.0.0" + }, + "dependencies": { + "npm-normalize-package-bin": { + "version": "2.0.0", + "bundled": true, + "dev": true + } + } + }, + "read-package-json-fast": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "json-parse-even-better-errors": "^2.3.0", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdir-scoped-modules": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "retry": { + "version": "0.12.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.3", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "safe-buffer": { + "version": "5.2.1", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "7.3.7", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "bundled": true, + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.7", + "bundled": true, + "dev": true + }, + "smart-buffer": { + "version": "4.2.0", + "bundled": true, + "dev": true + }, + "socks": { + "version": "2.7.0", + "bundled": true, + "dev": true, + "requires": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + } + }, + "socks-proxy-agent": { + "version": "7.0.0", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + } + }, + "spdx-correct": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.11", + "bundled": true, + "dev": true + }, + "ssri": { + "version": "9.0.1", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^3.1.1" + } + }, + "string-width": { + "version": "4.2.3", + "bundled": true, + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strip-ansi": { + "version": "6.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tar": { + "version": "6.1.11", + "bundled": true, + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, + "text-table": { + "version": "0.2.0", + "bundled": true, + "dev": true + }, + "tiny-relative-date": { + "version": "1.3.0", + "bundled": true, + "dev": true + }, + "treeverse": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "unique-filename": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "unique-slug": "^3.0.0" + } + }, + "unique-slug": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validate-npm-package-name": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtins": "^5.0.0" + } + }, + "walk-up-path": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "wcwidth": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "which": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wide-align": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + }, + "yallist": { + "version": "4.0.0", + "bundled": true, + "dev": true + } + } + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "requires": { + "path-key": "^3.0.0" + } + }, + "nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "requires": { + "boolbase": "^1.0.0" + } + }, + "nwsapi": { + "version": "2.2.2", + "resolved": "https://registry.npmmirror.com/nwsapi/-/nwsapi-2.2.2.tgz", + "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==" + }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + }, + "object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmmirror.com/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmmirror.com/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "object.entries": { + "version": "1.1.5", + "resolved": "https://registry.npmmirror.com/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "object.fromentries": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/object.fromentries/-/object.fromentries-2.0.5.tgz", + "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.4", + "resolved": "https://registry.npmmirror.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", + "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", + "requires": { + "array.prototype.reduce": "^1.0.4", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.1" + } + }, + "object.hasown": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/object.hasown/-/object.hasown-1.1.1.tgz", + "integrity": "sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==", + "requires": { + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmmirror.com/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "8.4.0", + "resolved": "https://registry.npmmirror.com/open/-/open-8.4.0.tgz", + "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmmirror.com/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "dependencies": { + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "requires": { + "prelude-ls": "^1.2.1" + } + } + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "requires": { + "p-limit": "^3.0.2" + }, + "dependencies": { + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + } + } + }, + "p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "requires": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "dependencies": { + "retry": { + "version": "0.13.1", + "resolved": "https://registry.npmmirror.com/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" + } + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" + }, + "pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmmirror.com/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==" + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + } + } + }, + "pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" + } + } + }, + "possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==" + }, + "postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "requires": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "dependencies": { + "source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==" + } + } + }, + "postcss-attribute-case-insensitive": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", + "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", + "requires": { + "postcss-selector-parser": "^6.0.10" + } + }, + "postcss-browser-comments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==" + }, + "postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "requires": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-color-functional-notation": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", + "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-color-hex-alpha": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", + "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-color-rebeccapurple": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", + "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-colormin": { + "version": "5.3.0", + "resolved": "https://registry.npmmirror.com/postcss-colormin/-/postcss-colormin-5.3.0.tgz", + "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", + "requires": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-convert-values": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz", + "integrity": "sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g==", + "requires": { + "browserslist": "^4.20.3", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-custom-media": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", + "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-custom-properties": { + "version": "12.1.10", + "resolved": "https://registry.npmmirror.com/postcss-custom-properties/-/postcss-custom-properties-12.1.10.tgz", + "integrity": "sha512-U3BHdgrYhCrwTVcByFHs9EOBoqcKq4Lf3kXwbTi4hhq0qWhl/pDWq2THbv/ICX/Fl9KqeHBb8OVrTf2OaYF07A==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-custom-selectors": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", + "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-dir-pseudo-class": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", + "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", + "requires": { + "postcss-selector-parser": "^6.0.10" + } + }, + "postcss-discard-comments": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==" + }, + "postcss-discard-duplicates": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==" + }, + "postcss-discard-empty": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==" + }, + "postcss-discard-overridden": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==" + }, + "postcss-double-position-gradients": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", + "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", + "requires": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-env-function": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", + "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-flexbugs-fixes": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==" + }, + "postcss-focus-visible": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", + "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", + "requires": { + "postcss-selector-parser": "^6.0.9" + } + }, + "postcss-focus-within": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", + "requires": { + "postcss-selector-parser": "^6.0.9" + } + }, + "postcss-font-variant": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==" + }, + "postcss-gap-properties": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", + "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==" + }, + "postcss-image-set-function": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", + "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-import": { + "version": "14.1.0", + "resolved": "https://registry.npmmirror.com/postcss-import/-/postcss-import-14.1.0.tgz", + "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "requires": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + } + }, + "postcss-initial": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==" + }, + "postcss-js": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/postcss-js/-/postcss-js-4.0.0.tgz", + "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==", + "requires": { + "camelcase-css": "^2.0.1" + } + }, + "postcss-lab-function": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", + "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", + "requires": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "requires": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + } + }, + "postcss-loader": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", + "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", + "requires": { + "cosmiconfig": "^7.0.0", + "klona": "^2.0.5", + "semver": "^7.3.5" + } + }, + "postcss-logical": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==" + }, + "postcss-media-minmax": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==" + }, + "postcss-merge-longhand": { + "version": "5.1.6", + "resolved": "https://registry.npmmirror.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz", + "integrity": "sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw==", + "requires": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.0" + } + }, + "postcss-merge-rules": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz", + "integrity": "sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ==", + "requires": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-minify-font-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-gradients": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "requires": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-params": { + "version": "5.1.3", + "resolved": "https://registry.npmmirror.com/postcss-minify-params/-/postcss-minify-params-5.1.3.tgz", + "integrity": "sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg==", + "requires": { + "browserslist": "^4.16.6", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-selectors": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", + "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "requires": { + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==" + }, + "postcss-modules-local-by-default": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "requires": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "requires": { + "icss-utils": "^5.0.0" + } + }, + "postcss-nested": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/postcss-nested/-/postcss-nested-6.0.0.tgz", + "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", + "requires": { + "postcss-selector-parser": "^6.0.10" + } + }, + "postcss-nesting": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", + "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", + "requires": { + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" + } + }, + "postcss-normalize": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", + "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", + "requires": { + "@csstools/normalize.css": "*", + "postcss-browser-comments": "^4", + "sanitize.css": "*" + } + }, + "postcss-normalize-charset": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==" + }, + "postcss-normalize-display-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-positions": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", + "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", + "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-string": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-unicode": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz", + "integrity": "sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ==", + "requires": { + "browserslist": "^4.16.6", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "requires": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-whitespace": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-opacity-percentage": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz", + "integrity": "sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w==" + }, + "postcss-ordered-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", + "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "requires": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-overflow-shorthand": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", + "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-page-break": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==" + }, + "postcss-place": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", + "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-preset-env": { + "version": "7.8.2", + "resolved": "https://registry.npmmirror.com/postcss-preset-env/-/postcss-preset-env-7.8.2.tgz", + "integrity": "sha512-rSMUEaOCnovKnwc5LvBDHUDzpGP+nrUeWZGWt9M72fBvckCi45JmnJigUr4QG4zZeOHmOCNCZnd2LKDvP++ZuQ==", + "requires": { + "@csstools/postcss-cascade-layers": "^1.1.0", + "@csstools/postcss-color-function": "^1.1.1", + "@csstools/postcss-font-format-keywords": "^1.0.1", + "@csstools/postcss-hwb-function": "^1.0.2", + "@csstools/postcss-ic-unit": "^1.0.1", + "@csstools/postcss-is-pseudo-class": "^2.0.7", + "@csstools/postcss-nested-calc": "^1.0.0", + "@csstools/postcss-normalize-display-values": "^1.0.1", + "@csstools/postcss-oklab-function": "^1.1.1", + "@csstools/postcss-progressive-custom-properties": "^1.3.0", + "@csstools/postcss-stepped-value-functions": "^1.0.1", + "@csstools/postcss-text-decoration-shorthand": "^1.0.0", + "@csstools/postcss-trigonometric-functions": "^1.0.2", + "@csstools/postcss-unset-value": "^1.0.2", + "autoprefixer": "^10.4.11", + "browserslist": "^4.21.3", + "css-blank-pseudo": "^3.0.3", + "css-has-pseudo": "^3.0.4", + "css-prefers-color-scheme": "^6.0.3", + "cssdb": "^7.0.1", + "postcss-attribute-case-insensitive": "^5.0.2", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^4.2.4", + "postcss-color-hex-alpha": "^8.0.4", + "postcss-color-rebeccapurple": "^7.1.1", + "postcss-custom-media": "^8.0.2", + "postcss-custom-properties": "^12.1.9", + "postcss-custom-selectors": "^6.0.3", + "postcss-dir-pseudo-class": "^6.0.5", + "postcss-double-position-gradients": "^3.1.2", + "postcss-env-function": "^4.0.6", + "postcss-focus-visible": "^6.0.4", + "postcss-focus-within": "^5.0.4", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^3.0.5", + "postcss-image-set-function": "^4.0.7", + "postcss-initial": "^4.0.1", + "postcss-lab-function": "^4.2.1", + "postcss-logical": "^5.0.4", + "postcss-media-minmax": "^5.0.0", + "postcss-nesting": "^10.2.0", + "postcss-opacity-percentage": "^1.1.2", + "postcss-overflow-shorthand": "^3.0.4", + "postcss-page-break": "^3.0.4", + "postcss-place": "^7.0.5", + "postcss-pseudo-class-any-link": "^7.1.6", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^6.0.1", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-pseudo-class-any-link": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", + "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", + "requires": { + "postcss-selector-parser": "^6.0.10" + } + }, + "postcss-reduce-initial": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz", + "integrity": "sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw==", + "requires": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-replace-overflow-wrap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==" + }, + "postcss-selector-not": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", + "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", + "requires": { + "postcss-selector-parser": "^6.0.10" + } + }, + "postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-svgo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "requires": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + }, + "svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "requires": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + } + } + } + }, + "postcss-unique-selectors": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "requires": { + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==" + }, + "prettier": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", + "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==", + "dev": true + }, + "pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==" + }, + "pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "requires": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "requires": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" + } + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "requires": { + "asap": "~2.0.6" + } + }, + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "dependencies": { + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + } + } + }, + "psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" + }, + "raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "requires": { + "performance-now": "^2.1.0" + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "react": { + "version": "18.3.0", + "resolved": "https://registry.npmmirror.com/react/-/react-18.3.0.tgz", + "integrity": "sha512-RPutkJftSAldDibyrjuku7q11d3oy6wKOyPe5K1HA/HwwrXcEqBdHsLypkC2FFYjP7bPUa6gbzSBhw4sY2JcDg==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "react-app-polyfill": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", + "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", + "requires": { + "core-js": "^3.19.2", + "object-assign": "^4.1.1", + "promise": "^8.1.0", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.9", + "whatwg-fetch": "^3.6.2" + } + }, + "react-dev-utils": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "requires": { + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "dependencies": { + "loader-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==" + } + } + }, + "react-dom": { + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-zaKdLBftQJnvb7FtDIpZtsAIb2MZU087RM8bRDZU8LVCCFYjPTsDZJNFUWPcVz3HFSN1n/caxi0ca4B/aaVQGQ==", + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.1" + } + }, + "react-error-overlay": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" + }, + "react-icons": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.7.1.tgz", + "integrity": "sha512-yHd3oKGMgm7zxo3EA7H2n7vxSoiGmHk5t6Ou4bXsfcgWyhfDKMpyKfhHR6Bjnn63c+YXBLBPUql9H4wPJM6sXw==" + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmmirror.com/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "react-refresh": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", + "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==" + }, + "react-router": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.4.3.tgz", + "integrity": "sha512-BT6DoGn6aV1FVP5yfODMOiieakp3z46P1Fk0RNzJMACzE7C339sFuHebfvWtnB4pzBvXXkHP2vscJzWRuUjTtA==", + "requires": { + "@remix-run/router": "1.0.3" + } + }, + "react-router-dom": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.4.3.tgz", + "integrity": "sha512-MiaYQU8CwVCaOfJdYvt84KQNjT78VF0TJrA17SIQgNHRvLnXDJO6qsFqq8F/zzB1BWZjCFIrQpu4QxcshitziQ==", + "requires": { + "@remix-run/router": "1.0.3", + "react-router": "6.4.3" + } + }, + "react-scripts": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", + "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", + "requires": { + "@babel/core": "^7.16.0", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", + "@svgr/webpack": "^5.5.0", + "babel-jest": "^27.4.2", + "babel-loader": "^8.2.3", + "babel-plugin-named-asset-import": "^0.3.8", + "babel-preset-react-app": "^10.0.1", + "bfj": "^7.0.2", + "browserslist": "^4.18.1", + "camelcase": "^6.2.1", + "case-sensitive-paths-webpack-plugin": "^2.4.0", + "css-loader": "^6.5.1", + "css-minimizer-webpack-plugin": "^3.2.0", + "dotenv": "^10.0.0", + "dotenv-expand": "^5.1.0", + "eslint": "^8.3.0", + "eslint-config-react-app": "^7.0.1", + "eslint-webpack-plugin": "^3.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^10.0.0", + "fsevents": "^2.3.2", + "html-webpack-plugin": "^5.5.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^27.4.3", + "jest-resolve": "^27.4.2", + "jest-watch-typeahead": "^1.0.0", + "mini-css-extract-plugin": "^2.4.5", + "postcss": "^8.4.4", + "postcss-flexbugs-fixes": "^5.0.2", + "postcss-loader": "^6.2.1", + "postcss-normalize": "^10.0.1", + "postcss-preset-env": "^7.0.1", + "prompts": "^2.4.2", + "react-app-polyfill": "^3.0.0", + "react-dev-utils": "^12.0.1", + "react-refresh": "^0.11.0", + "resolve": "^1.20.0", + "resolve-url-loader": "^4.0.0", + "sass-loader": "^12.3.0", + "semver": "^7.3.5", + "source-map-loader": "^3.0.0", + "style-loader": "^3.3.1", + "tailwindcss": "^3.0.2", + "terser-webpack-plugin": "^5.2.5", + "webpack": "^5.64.4", + "webpack-dev-server": "^4.6.0", + "webpack-manifest-plugin": "^4.0.2", + "workbox-webpack-plugin": "^6.4.1" + }, + "dependencies": { + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + } + } + }, + "react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, + "react-window": { + "version": "1.8.7", + "resolved": "https://registry.npmmirror.com/react-window/-/react-window-1.8.7.tgz", + "integrity": "sha512-JHEZbPXBpKMmoNO1bNhoXOOLg/ujhL/BU4IqVU9r8eQPcy5KQnGHIHDRkJ0ns9IM5+Aq5LNwt3j8t3tIrePQzA==", + "requires": { + "@babel/runtime": "^7.0.0", + "memoize-one": ">=3.1.1 <6" + } + }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "requires": { + "pify": "^2.3.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "requires": { + "minimatch": "^3.0.5" + } + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "redux": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/redux/-/redux-4.2.0.tgz", + "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==", + "requires": { + "@babel/runtime": "^7.9.2" + } + }, + "redux-thunk": { + "version": "2.4.1", + "resolved": "https://registry.npmmirror.com/redux-thunk/-/redux-thunk-2.4.1.tgz", + "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==" + }, + "reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "dependencies": { + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "requires": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "requires": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "dependencies": { + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "requires": { + "es-define-property": "^1.0.0" + } + } + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + } + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "requires": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + } + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "requires": { + "has-symbols": "^1.0.3" + } + }, + "internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "requires": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + } + }, + "is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==" + }, + "is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "requires": { + "call-bind": "^1.0.7" + } + }, + "is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "requires": { + "which-typed-array": "^1.1.14" + } + }, + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" + }, + "object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "requires": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "requires": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + } + }, + "safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + } + }, + "string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + } + } + } + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "requires": { + "regenerate": "^1.4.2" + } + }, + "regenerator-runtime": { + "version": "0.13.10", + "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", + "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==" + }, + "regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "requires": { + "@babel/runtime": "^7.8.4" + } + }, + "regex-parser": { + "version": "2.2.11", + "resolved": "https://registry.npmmirror.com/regex-parser/-/regex-parser-2.2.11.tgz", + "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==" + }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmmirror.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" + }, + "regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "requires": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + } + }, + "regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==" + } + } + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==" + }, + "renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "requires": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "reselect": { + "version": "4.1.6", + "resolved": "https://registry.npmmirror.com/reselect/-/reselect-4.1.6.tgz", + "integrity": "sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ==" + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + }, + "resolve-url-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", + "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==", + "requires": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^7.0.35", + "source-map": "0.6.1" + }, + "dependencies": { + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" + }, + "postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "requires": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + } + } + } + }, + "resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==" + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "requires": { + "fsevents": "~2.3.2" + } + }, + "rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "requires": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "dependencies": { + "@types/node": { + "version": "18.11.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.11.5.tgz", + "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==" + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "requires": { + "randombytes": "^2.1.0" + } + } + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "requires": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "dependencies": { + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + } + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sanitize.css": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", + "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" + }, + "sass-loader": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", + "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", + "requires": { + "klona": "^2.0.4", + "neo-async": "^2.6.2" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "requires": { + "xmlchars": "^2.2.0" + } + }, + "scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "schema-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "requires": { + "ajv": "^8.0.0" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + } + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + }, + "selfsigned": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/selfsigned/-/selfsigned-2.1.1.tgz", + "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", + "requires": { + "node-forge": "^1" + } + }, + "semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==" + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + } + } + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" + } + } + }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "dependencies": { + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "requires": { + "es-define-property": "^1.0.0" + } + } + } + }, + "set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "dependencies": { + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "requires": { + "es-define-property": "^1.0.0" + } + } + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "shell-quote": { + "version": "1.7.4", + "resolved": "https://registry.npmmirror.com/shell-quote/-/shell-quote-1.7.4.tgz", + "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==" + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "requires": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" + }, + "source-map-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.2.tgz", + "integrity": "sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg==", + "requires": { + "abab": "^2.0.5", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.1" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" + }, + "spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" + }, + "stack-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" + } + } + }, + "stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + }, + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-natural-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", + "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string.prototype.matchall": { + "version": "4.0.7", + "resolved": "https://registry.npmmirror.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", + "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.1", + "side-channel": "^1.0.4" + } + }, + "string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "dependencies": { + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "requires": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "requires": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "dependencies": { + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "requires": { + "es-define-property": "^1.0.0" + } + } + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + } + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "requires": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + } + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "requires": { + "has-symbols": "^1.0.3" + } + }, + "internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "requires": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + } + }, + "is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==" + }, + "is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "requires": { + "call-bind": "^1.0.7" + } + }, + "is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "requires": { + "which-typed-array": "^1.1.14" + } + }, + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" + }, + "object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "requires": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "requires": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + } + }, + "safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + } + }, + "string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + } + } + } + }, + "string.prototype.trimend": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" + }, + "strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==" + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + }, + "style-loader": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/style-loader/-/style-loader-3.3.1.tgz", + "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==" + }, + "stylehacks": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/stylehacks/-/stylehacks-5.1.0.tgz", + "integrity": "sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q==", + "requires": { + "browserslist": "^4.16.6", + "postcss-selector-parser": "^6.0.4" + } + }, + "stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + }, + "svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "requires": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "requires": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + } + }, + "css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmmirror.com/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==" + }, + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" + } + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmmirror.com/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "requires": { + "minimist": "^1.2.6" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "requires": { + "boolbase": "~1.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "swr": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.1.0.tgz", + "integrity": "sha512-4hYl5p3/KalQ1MORealM79g/DtLohmud6yyfXw5l4wjtFksYUnocRFudvyaoUtgj3FrVNK9lS25Av9dsZYvz0g==", + "requires": { + "use-sync-external-store": "^1.2.0" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "tailwindcss": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.2.1.tgz", + "integrity": "sha512-Uw+GVSxp5CM48krnjHObqoOwlCt5Qo6nw1jlCRwfGy68dSYb/LwS9ZFidYGRiM+w6rMawkZiu1mEMAsHYAfoLg==", + "requires": { + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "color-name": "^1.1.4", + "detective": "^5.2.1", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "lilconfig": "^2.0.6", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.17", + "postcss-import": "^14.1.0", + "postcss-js": "^4.0.0", + "postcss-load-config": "^3.1.4", + "postcss-nested": "6.0.0", + "postcss-selector-parser": "^6.0.10", + "postcss-value-parser": "^4.2.0", + "quick-lru": "^5.1.1", + "resolve": "^1.22.1" + }, + "dependencies": { + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "requires": { + "is-glob": "^4.0.3" + } + } + } + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" + }, + "temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==" + }, + "tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "requires": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "dependencies": { + "type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==" + } + } + }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "terser": { + "version": "5.15.1", + "resolved": "https://registry.npmmirror.com/terser/-/terser-5.15.1.tgz", + "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", + "requires": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + } + }, + "terser-webpack-plugin": { + "version": "5.3.6", + "resolved": "https://registry.npmmirror.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", + "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", + "requires": { + "@jridgewell/trace-mapping": "^0.3.14", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "terser": "^5.14.1" + }, + "dependencies": { + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, + "throat": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==" + }, + "thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + }, + "tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, + "tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "dependencies": { + "universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" + } + } + }, + "tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "requires": { + "punycode": "^2.1.1" + } + }, + "tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" + }, + "tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmmirror.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "dependencies": { + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "requires": { + "has-symbols": "^1.0.3" + } + }, + "is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "requires": { + "which-typed-array": "^1.1.14" + } + }, + "which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + } + } + } + }, + "typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "requires": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "dependencies": { + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "requires": { + "has-symbols": "^1.0.3" + } + }, + "is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "requires": { + "which-typed-array": "^1.1.14" + } + }, + "which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + } + } + } + }, + "typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "dependencies": { + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "requires": { + "has-symbols": "^1.0.3" + } + }, + "is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "requires": { + "which-typed-array": "^1.1.14" + } + }, + "which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + } + } + } + }, + "typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "requires": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "dependencies": { + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "requires": { + "has-symbols": "^1.0.3" + } + }, + "is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "requires": { + "which-typed-array": "^1.1.14" + } + }, + "which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + } + } + } + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typeface-roboto": { + "version": "0.0.75", + "resolved": "https://registry.npmjs.org/typeface-roboto/-/typeface-roboto-0.0.75.tgz", + "integrity": "sha512-VrR/IiH00Z1tFP4vDGfwZ1esNqTiDMchBEXYY9kilT6wRGgFoCAlgkEUMHb1E3mB0FsfZhv756IF0+R+SFPfdg==" + }, + "typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==" + }, + "unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "requires": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==" + }, + "unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==" + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" + }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==" + }, + "usehooks-ts": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/usehooks-ts/-/usehooks-ts-2.9.4.tgz", + "integrity": "sha512-VOSEbA+BGGORLttsICowNb5CG0D2/IEoVvMEl9OuuOoQi99W6XuNipo3SPFhWo3Bhdwi0Swj1D+IMQDQB9KrwQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + } + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, + "v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" + } + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "requires": { + "makeerror": "1.0.12" + } + }, + "watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmmirror.com/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" + }, + "webpack": { + "version": "5.76.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.2.tgz", + "integrity": "sha512-Th05ggRm23rVzEOlX8y67NkYCHa9nTNcwHPBhdg+lKG+mtiW7XgggjAeeLnADAe7mLjJ6LUNfgHAuRRh+Z6J7w==", + "requires": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.10.0", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "dependencies": { + "@types/estree": { + "version": "0.0.51", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" + }, + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==" + } + } + }, + "webpack-dev-middleware": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", + "requires": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + } + }, + "webpack-dev-server": { + "version": "4.11.1", + "resolved": "https://registry.npmmirror.com/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz", + "integrity": "sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==", + "requires": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.1", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.4.2" + } + }, + "webpack-manifest-plugin": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", + "integrity": "sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==", + "requires": { + "tapable": "^2.0.0", + "webpack-sources": "^2.2.0" + }, + "dependencies": { + "webpack-sources": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", + "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", + "requires": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + } + } + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmmirror.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "requires": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "requires": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "dependencies": { + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "dependencies": { + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "requires": { + "has-symbols": "^1.0.3" + } + } + } + } + } + }, + "which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "requires": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + } + }, + "which-typed-array": { + "version": "1.1.8", + "resolved": "https://registry.npmmirror.com/which-typed-array/-/which-typed-array-1.1.8.tgz", + "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.9" + } + }, + "word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==" + }, + "workbox-background-sync": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz", + "integrity": "sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g==", + "requires": { + "idb": "^7.0.1", + "workbox-core": "6.5.4" + } + }, + "workbox-broadcast-update": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-broadcast-update/-/workbox-broadcast-update-6.5.4.tgz", + "integrity": "sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw==", + "requires": { + "workbox-core": "6.5.4" + } + }, + "workbox-build": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-build/-/workbox-build-6.5.4.tgz", + "integrity": "sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA==", + "requires": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.11.1", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^2.4.1", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "rollup-plugin-terser": "^7.0.0", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "6.5.4", + "workbox-broadcast-update": "6.5.4", + "workbox-cacheable-response": "6.5.4", + "workbox-core": "6.5.4", + "workbox-expiration": "6.5.4", + "workbox-google-analytics": "6.5.4", + "workbox-navigation-preload": "6.5.4", + "workbox-precaching": "6.5.4", + "workbox-range-requests": "6.5.4", + "workbox-recipes": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4", + "workbox-streams": "6.5.4", + "workbox-sw": "6.5.4", + "workbox-window": "6.5.4" + }, + "dependencies": { + "@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmmirror.com/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "requires": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + } + }, + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "requires": { + "whatwg-url": "^7.0.0" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "requires": { + "punycode": "^2.1.0" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + } + } + }, + "workbox-cacheable-response": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-cacheable-response/-/workbox-cacheable-response-6.5.4.tgz", + "integrity": "sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug==", + "requires": { + "workbox-core": "6.5.4" + } + }, + "workbox-core": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-core/-/workbox-core-6.5.4.tgz", + "integrity": "sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q==" + }, + "workbox-expiration": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-expiration/-/workbox-expiration-6.5.4.tgz", + "integrity": "sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ==", + "requires": { + "idb": "^7.0.1", + "workbox-core": "6.5.4" + } + }, + "workbox-google-analytics": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-google-analytics/-/workbox-google-analytics-6.5.4.tgz", + "integrity": "sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg==", + "requires": { + "workbox-background-sync": "6.5.4", + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" + } + }, + "workbox-navigation-preload": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-navigation-preload/-/workbox-navigation-preload-6.5.4.tgz", + "integrity": "sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng==", + "requires": { + "workbox-core": "6.5.4" + } + }, + "workbox-precaching": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-precaching/-/workbox-precaching-6.5.4.tgz", + "integrity": "sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg==", + "requires": { + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" + } + }, + "workbox-range-requests": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-range-requests/-/workbox-range-requests-6.5.4.tgz", + "integrity": "sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg==", + "requires": { + "workbox-core": "6.5.4" + } + }, + "workbox-recipes": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-recipes/-/workbox-recipes-6.5.4.tgz", + "integrity": "sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA==", + "requires": { + "workbox-cacheable-response": "6.5.4", + "workbox-core": "6.5.4", + "workbox-expiration": "6.5.4", + "workbox-precaching": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" + } + }, + "workbox-routing": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-routing/-/workbox-routing-6.5.4.tgz", + "integrity": "sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==", + "requires": { + "workbox-core": "6.5.4" + } + }, + "workbox-strategies": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-strategies/-/workbox-strategies-6.5.4.tgz", + "integrity": "sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==", + "requires": { + "workbox-core": "6.5.4" + } + }, + "workbox-streams": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-streams/-/workbox-streams-6.5.4.tgz", + "integrity": "sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg==", + "requires": { + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4" + } + }, + "workbox-sw": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-sw/-/workbox-sw-6.5.4.tgz", + "integrity": "sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA==" + }, + "workbox-webpack-plugin": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-webpack-plugin/-/workbox-webpack-plugin-6.5.4.tgz", + "integrity": "sha512-LmWm/zoaahe0EGmMTrSLUi+BjyR3cdGEfU3fS6PN1zKFYbqAKuQ+Oy/27e4VSXsyIwAw8+QDfk1XHNGtZu9nQg==", + "requires": { + "fast-json-stable-stringify": "^2.1.0", + "pretty-bytes": "^5.4.1", + "upath": "^1.2.0", + "webpack-sources": "^1.4.3", + "workbox-build": "6.5.4" + } + }, + "workbox-window": { + "version": "6.5.4", + "resolved": "https://registry.npmmirror.com/workbox-window/-/workbox-window-6.5.4.tgz", + "integrity": "sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==", + "requires": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "6.5.4" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "ws": { + "version": "8.10.0", + "resolved": "https://registry.npmmirror.com/ws/-/ws-8.10.0.tgz", + "integrity": "sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==" + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + } + } +} diff --git a/historyserver/dashboard/ray/client/package.json b/historyserver/dashboard/ray/client/package.json new file mode 100644 index 00000000000..7af11a9f435 --- /dev/null +++ b/historyserver/dashboard/ray/client/package.json @@ -0,0 +1,159 @@ +{ + "name": "ray-dashboard-client", + "version": "1.0.0", + "private": true, + "dependencies": { + "@emotion/react": "^11.11.3", + "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.15.5", + "@mui/material": "^5.15.5", + "@reduxjs/toolkit": "^1.3.1", + "@types/jest": "^27.5.2", + "@types/lodash": "^4.14.161", + "@types/node": "13.9.5", + "@types/react-redux": "^7.1.7", + "@types/react-window": "^1.8.2", + "axios": "^0.21.1", + "copy-to-clipboard": "^3.3.2", + "dayjs": "^1.9.4", + "js-cookie": "^3.0.5", + "js-yaml": "^4.1.0", + "lodash": "^4.17.20", + "lowlight": "^2.9.0", + "react": "^18.3.0", + "react-dom": "^18.3.0", + "react-icons": "^4.7.1", + "react-router-dom": "^6.4.3", + "react-scripts": "^5.0.1", + "react-window": "^1.8.5", + "swr": "^2.1.0", + "typeface-roboto": "0.0.75", + "typescript": "^4.8.4", + "usehooks-ts": "^2.9.4" + }, + "devDependencies": { + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^14.3.0", + "@testing-library/user-event": "^14.4.3", + "@types/js-cookie": "^3.0.6", + "@types/js-yaml": "^4.0.5", + "@types/react": "^18.3.0", + "@types/react-dom": "^18.3.0", + "@typescript-eslint/eslint-plugin": "^5.41.0", + "@typescript-eslint/parser": "^5.41.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-prefer-arrow": "^1.2.3", + "mockdate": "^3.0.5", + "npm": "^8.19.2", + "prettier": "2.3.0" + }, + "resolutions": { + "@types/react": "16.9.26" + }, + "jest": { + "transformIgnorePatterns": [ + "/node_modules/(?!lowlight)/" + ] + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject", + "lint": "npm run eslint && npm run prettier", + "lint-fix": "npm run prettier -- --write && npm run eslint -- --fix", + "prettier": "./node_modules/.bin/prettier -c src/", + "eslint": "./node_modules/.bin/eslint \"src/**\"" + }, + "eslintConfig": { + "ignorePatterns": [ + "*.svg", + "*.css" + ], + "parser": "@typescript-eslint/parser", + "extends": [ + "plugin:import/warnings", + "plugin:@typescript-eslint/recommended", + "react-app" + ], + "plugins": [ + "prefer-arrow", + "@typescript-eslint" + ], + "rules": { + "@typescript-eslint/consistent-type-definitions": [ + "error", + "type" + ], + "@typescript-eslint/no-explicit-any": 0, + "@typescript-eslint/ban-types": [ + "error", + { + "types": { + "{}": false + }, + "extendDefaults": true + } + ], + "@typescript-eslint/explicit-module-boundary-types": 0, + "comma-dangle": [ + "warn", + "always-multiline" + ], + "curly": [ + "warn", + "all" + ], + "eqeqeq": [ + "error", + "always" + ], + "import/order": [ + "warn", + { + "alphabetize": { + "order": "asc", + "caseInsensitive": true + } + } + ], + "no-var": "error", + "prefer-arrow/prefer-arrow-functions": [ + "warn", + { + "disallowPrototype": true, + "singleReturnOnly": false, + "classPropertiesAllowed": false + } + ], + "prefer-const": "error", + "react/jsx-fragments": [ + "warn", + "element" + ], + "sort-imports": [ + "warn", + { + "ignoreCase": true, + "ignoreDeclarationSort": true + } + ] + } + }, + "prettier": { + "trailingComma": "all" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "proxy": "http://localhost:8080" +} diff --git a/historyserver/dashboard/ray/client/public/favicon.ico b/historyserver/dashboard/ray/client/public/favicon.ico new file mode 100644 index 00000000000..9417b6ada1d Binary files /dev/null and b/historyserver/dashboard/ray/client/public/favicon.ico differ diff --git a/historyserver/dashboard/ray/client/public/index.html b/historyserver/dashboard/ray/client/public/index.html new file mode 100644 index 00000000000..86d104c0fec --- /dev/null +++ b/historyserver/dashboard/ray/client/public/index.html @@ -0,0 +1,32 @@ + + + + + + + + Ray HistoryServer Dashboard + + + +
+ + + diff --git a/historyserver/dashboard/ray/client/public/speedscope-1.5.3/LICENSE b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/LICENSE new file mode 100644 index 00000000000..baf3e9d982f --- /dev/null +++ b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Jamie Wong + +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. diff --git a/historyserver/dashboard/ray/client/public/speedscope-1.5.3/README b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/README new file mode 100644 index 00000000000..4d897271d38 --- /dev/null +++ b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/README @@ -0,0 +1,2 @@ +This is a self-contained release of https://github.com/jlfwong/speedscope. +To use it, open index.html in Chrome or Firefox. diff --git a/historyserver/dashboard/ray/client/public/speedscope-1.5.3/demangle-cpp.8a387750.js b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/demangle-cpp.8a387750.js new file mode 100644 index 00000000000..73686d88c66 --- /dev/null +++ b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/demangle-cpp.8a387750.js @@ -0,0 +1,4 @@ +parcelRequire=function(e,r,n,t){var i="function"==typeof parcelRequire&&parcelRequire,o="function"==typeof require&&require;function u(n,t){if(!r[n]){if(!e[n]){var f="function"==typeof parcelRequire&&parcelRequire;if(!t&&f)return f(n,!0);if(i)return i(n,!0);if(o&&"string"==typeof n)return o(n);var c=new Error("Cannot find module '"+n+"'");throw c.code="MODULE_NOT_FOUND",c}p.resolve=function(r){return e[n][1][r]||r};var l=r[n]=new u.Module(n);e[n][0].call(l.exports,p,l,l.exports,this)}return r[n].exports;function p(e){return u(p.resolve(e))}}u.isParcelRequire=!0,u.Module=function(e){this.id=e,this.bundle=u,this.exports={}},u.modules=e,u.cache=r,u.parent=i,u.register=function(r,n){e[r]=[function(e,r){r.exports=n},{}]};for(var f=0;f0&&$e.streams[2].object.output("\\n".charCodeAt(0)),$e.streams[3]&&$e.streams[3].object.output.buffer.length>0&&$e.streams[3].object.output("\\n".charCodeAt(0)))}},Je=Ja;Ve.unshift({func:function(){$e.ignorePermissions=!1,$e.init.initialized||$e.init()}}),Be.push({func:function(){$e.quit()}}),Ya(0),ae.buf=_(12,"void*",we),Module.callMain=function(r){function a(){for(var r=0;r<3;r++)i.push(0)}var e=r.length+1,i=[_(p("/bin/this.program"),"i8",we)];a();for(var v=0;v>2]=0|He.__str,Se[ri+4>>2]=0|He.__str1,Se[ri+16>>2]=0|He.__str2,Se[ri+20>>2]=0|He.__str3,Se[ri+32>>2]=0|He.__str4,Se[ri+36>>2]=0|He.__str5,Se[ri+48>>2]=0|He.__str6,Se[ri+52>>2]=0|He.__str7,Se[ri+64>>2]=0|He.__str8,Se[ri+68>>2]=0|He.__str7,Se[ri+80>>2]=0|He.__str9,Se[ri+84>>2]=0|He.__str10,Se[ri+96>>2]=0|He.__str11,Se[ri+100>>2]=0|He.__str12,Se[ri+112>>2]=0|He.__str13,Se[ri+116>>2]=0|He.__str14,Se[ri+128>>2]=0|He.__str15,Se[ri+132>>2]=0|He.__str16,Se[ri+144>>2]=0|He.__str17,Se[ri+148>>2]=0|He.__str18,Se[ri+160>>2]=0|He.__str19,Se[ri+164>>2]=0|He.__str20,Se[ri+176>>2]=0|He.__str21,Se[ri+180>>2]=0|He.__str22,Se[ri+192>>2]=0|He.__str23,Se[ri+196>>2]=0|He.__str24,Se[ri+208>>2]=0|He.__str25,Se[ri+212>>2]=0|He.__str26,Se[ri+224>>2]=0|He.__str27,Se[ri+228>>2]=0|He.__str28,Se[ri+240>>2]=0|He.__str29,Se[ri+244>>2]=0|He.__str30,Se[ri+256>>2]=0|He.__str31,Se[ri+260>>2]=0|He.__str32,Se[ri+272>>2]=0|He.__str33,Se[ri+276>>2]=0|He.__str34,Se[ri+288>>2]=0|He.__str35,Se[ri+292>>2]=0|He.__str36,Se[ri+304>>2]=0|He.__str37,Se[ri+308>>2]=0|He.__str38,Se[ri+320>>2]=0|He.__str39,Se[ri+324>>2]=0|He.__str40,Se[ri+336>>2]=0|He.__str41,Se[ri+340>>2]=0|He.__str42,Se[ri+352>>2]=0|He.__str43,Se[ri+356>>2]=0|He.__str44,Se[ri+368>>2]=0|He.__str45,Se[ri+372>>2]=0|He.__str46,Se[ri+384>>2]=0|He.__str47,Se[ri+388>>2]=0|He.__str48,Se[ri+400>>2]=0|He.__str49,Se[ri+404>>2]=0|He.__str119289,Se[ri+416>>2]=0|He.__str51,Se[ri+420>>2]=0|He.__str20,Se[ri+432>>2]=0|He.__str52,Se[ri+436>>2]=0|He.__str53,Se[ri+448>>2]=0|He.__str54,Se[ri+452>>2]=0|He.__str55,Se[ri+464>>2]=0|He.__str56,Se[ri+468>>2]=0|He.__str57,Se[ri+480>>2]=0|He.__str58,Se[ri+484>>2]=0|He.__str119289,Se[ri+496>>2]=0|He.__str59,Se[ri+500>>2]=0|He.__str60,Se[ri+512>>2]=0|He.__str61,Se[ri+516>>2]=0|He.__str62,Se[ri+528>>2]=0|He.__str63,Se[ri+532>>2]=0|He.__str64,Se[ri+544>>2]=0|He.__str65,Se[ri+548>>2]=0|He.__str66,Se[ri+560>>2]=0|He.__str67,Se[ri+564>>2]=0|He.__str68,Se[ri+576>>2]=0|He.__str69,Se[ri+580>>2]=0|He.__str70,Se[ri+592>>2]=0|He.__str71,Se[ri+596>>2]=0|He.__str72,Se[ri+608>>2]=0|He.__str73,Se[ri+612>>2]=0|He.__str74,Se[ri+624>>2]=0|He.__str75,Se[ri+628>>2]=0|He.__str76,Se[ri+640>>2]=0|He.__str77,Se[ri+644>>2]=0|He.__str72,Se[ri+656>>2]=0|He.__str78,Se[ri+660>>2]=0|He.__str79,Se[ri+672>>2]=0|He.__str80,Se[ri+676>>2]=0|He.__str81,Se[ri+688>>2]=0|He.__str82,Se[ri+692>>2]=0|He.__str83,Se[ri+704>>2]=0|He.__str84,Se[ri+708>>2]=0|He.__str85,Se[ri+720>>2]=0|He.__str86,Se[ri+724>>2]=0|He.__str87,Se[ri+736>>2]=0|He.__str88,Se[ri+740>>2]=0|He.__str89,Se[ri+752>>2]=0|He.__str90,Se[ri+756>>2]=0|He.__str91,Se[ri+768>>2]=0|He.__str92,Se[ri+772>>2]=0|He.__str91,Se[ai>>2]=0|He.__str145315,Se[ai+8>>2]=0|He.__str145315,Se[ai+20>>2]=0|He.__str167337,Se[ai+28>>2]=0|He.__str95,Se[ai+40>>2]=0|He.__str146316,Se[ai+48>>2]=0|He.__str97,Se[ai+60>>2]=0|He.__str155325,Se[ai+68>>2]=0|He.__str155325,Se[ai+80>>2]=0|He.__str156326,Se[ai+88>>2]=0|He.__str156326,Se[ai+100>>2]=0|He.__str154324,Se[ai+108>>2]=0|He.__str154324,Se[ai+120>>2]=0|He.__str101,Se[ai+128>>2]=0|He.__str101,Se[ai+140>>2]=0|He.__str147317,Se[ai+148>>2]=0|He.__str147317,Se[ai+160>>2]=0|He.__str150320,Se[ai+168>>2]=0|He.__str150320,Se[ai+180>>2]=0|He.__str151321,Se[ai+188>>2]=0|He.__str105,Se[ai+220>>2]=0|He.__str152322,Se[ai+228>>2]=0|He.__str152322,Se[ai+240>>2]=0|He.__str153323,Se[ai+248>>2]=0|He.__str153323,Se[ai+260>>2]=0|He.__str165335,Se[ai+268>>2]=0|He.__str165335,Se[ai+280>>2]=0|He.__str166336,Se[ai+288>>2]=0|He.__str166336,Se[ai+360>>2]=0|He.__str148318,Se[ai+368>>2]=0|He.__str148318,Se[ai+380>>2]=0|He.__str149319,Se[ai+388>>2]=0|He.__str149319,Se[ai+420>>2]=0|He.__str84254,Se[ai+428>>2]=0|He.__str84254,Se[ai+440>>2]=0|He.__str168338,Se[ai+448>>2]=0|He.__str146316,Se[ai+460>>2]=0|He.__str114,Se[ai+468>>2]=0|He.__str152322,Se[ai+480>>2]=0|He.__str115,Se[ai+488>>2]=0|He.__str115,Se[ai+500>>2]=0|He.__str110280,Se[ai+508>>2]=0|He.__str110280,Se[ei+4>>2]=0|He.__str152,Se[ei+12>>2]=0|He.__str152,Se[ei+32>>2]=0|He.__str153,Se[ei+40>>2]=0|He.__str153,Se[ei+48>>2]=0|He.__str154,Se[ei+60>>2]=0|He.__str155,Se[ei+68>>2]=0|He.__str155,Se[ei+76>>2]=0|He.__str156,Se[ei+88>>2]=0|He.__str157,Se[ei+96>>2]=0|He.__str158,Se[ei+104>>2]=0|He.__str156,Se[ei+116>>2]=0|He.__str159,Se[ei+124>>2]=0|He.__str160,Se[ei+132>>2]=0|He.__str161,Se[ei+144>>2]=0|He.__str162,Se[ei+152>>2]=0|He.__str163,Se[ei+160>>2]=0|He.__str164,Se[ei+172>>2]=0|He.__str165,Se[ei+180>>2]=0|He.__str166,Se[ei+188>>2]=0|He.__str167,Se[si+4>>2]=bi,Se[ni+4>>2]=ki,oi=_([2,0,0,0,0],["i8*",0,0,0,0],we),Se[bi>>2]=oi+8|0,Se[bi+4>>2]=0|He.__ZTSSt9bad_alloc,Se[bi+8>>2]=li,Se[ki>>2]=oi+8|0,Se[ki+4>>2]=0|He.__ZTSSt20bad_array_new_length,Se[ki+8>>2]=bi,ui=16,ci=6,hi=18,di=6,wi=6,pe=[0,0,Jr,0,va,0,ya,0,ga,0,wa,0,Sa,0,pa,0,Ea,0,ma,0],Module.FUNCTION_TABLE=pe,Module.run=ee,Module.preRun&&Module.preRun(),0==Ke){ee()}Module.postRun&&Module.postRun(),Module.___cxa_demangle=G;var pi=v("__cxa_demangle","string",["string","string","number","number"]);return function(r){return pi(r,"",1,0)}}();\n'; +},{}]},{},[180], null) +//# sourceMappingURL=demangle-cpp.8a387750.map \ No newline at end of file diff --git a/historyserver/dashboard/ray/client/public/speedscope-1.5.3/favicon-16x16.361d2b26.png b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/favicon-16x16.361d2b26.png new file mode 100644 index 00000000000..2db188b0932 Binary files /dev/null and b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/favicon-16x16.361d2b26.png differ diff --git a/historyserver/dashboard/ray/client/public/speedscope-1.5.3/favicon-32x32.1165a94e.png b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/favicon-32x32.1165a94e.png new file mode 100644 index 00000000000..d49690de338 Binary files /dev/null and b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/favicon-32x32.1165a94e.png differ diff --git a/historyserver/dashboard/ray/client/public/speedscope-1.5.3/file-format-schema.json b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/file-format-schema.json new file mode 100644 index 00000000000..63842505efb --- /dev/null +++ b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/file-format-schema.json @@ -0,0 +1,324 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "FileFormat.Profile": { + "anyOf": [ + { + "$ref": "#/definitions/FileFormat.EventedProfile" + }, + { + "$ref": "#/definitions/FileFormat.SampledProfile" + } + ] + }, + "FileFormat.File": { + "title": "FileFormat.File", + "type": "object", + "properties": { + "$schema": { + "type": "string", + "enum": [ + "https://www.speedscope.app/file-format-schema.json" + ], + "title": "$schema" + }, + "shared": { + "type": "object", + "properties": { + "frames": { + "type": "array", + "items": { + "$ref": "#/definitions/FileFormat.Frame" + }, + "title": "frames" + } + }, + "required": [ + "frames" + ], + "title": "shared" + }, + "profiles": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/FileFormat.EventedProfile" + }, + { + "$ref": "#/definitions/FileFormat.SampledProfile" + } + ] + }, + "title": "profiles" + }, + "name": { + "type": "string", + "title": "name" + }, + "activeProfileIndex": { + "type": "number", + "title": "activeProfileIndex" + }, + "exporter": { + "type": "string", + "title": "exporter" + } + }, + "required": [ + "$schema", + "profiles", + "shared" + ] + }, + "FileFormat.Frame": { + "title": "FileFormat.Frame", + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "name" + }, + "file": { + "type": "string", + "title": "file" + }, + "line": { + "type": "number", + "title": "line" + }, + "col": { + "type": "number", + "title": "col" + } + }, + "required": [ + "name" + ] + }, + "FileFormat.ProfileType": { + "title": "FileFormat.ProfileType", + "enum": [ + "evented", + "sampled" + ], + "type": "string" + }, + "FileFormat.IProfile": { + "title": "FileFormat.IProfile", + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/FileFormat.ProfileType", + "title": "type" + } + }, + "required": [ + "type" + ] + }, + "FileFormat.EventedProfile": { + "title": "FileFormat.EventedProfile", + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "evented" + ], + "title": "type" + }, + "name": { + "type": "string", + "title": "name" + }, + "unit": { + "$ref": "#/definitions/FileFormat.ValueUnit", + "title": "unit" + }, + "startValue": { + "type": "number", + "title": "startValue" + }, + "endValue": { + "type": "number", + "title": "endValue" + }, + "events": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/OpenFrameEvent" + }, + { + "$ref": "#/definitions/CloseFrameEvent" + } + ] + }, + "title": "events" + } + }, + "required": [ + "endValue", + "events", + "name", + "startValue", + "type", + "unit" + ] + }, + "SampledStack": { + "type": "array", + "items": { + "type": "number" + } + }, + "FileFormat.SampledProfile": { + "title": "FileFormat.SampledProfile", + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "sampled" + ], + "title": "type" + }, + "name": { + "type": "string", + "title": "name" + }, + "unit": { + "$ref": "#/definitions/FileFormat.ValueUnit", + "title": "unit" + }, + "startValue": { + "type": "number", + "title": "startValue" + }, + "endValue": { + "type": "number", + "title": "endValue" + }, + "samples": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "number" + } + }, + "title": "samples" + }, + "weights": { + "type": "array", + "items": { + "type": "number" + }, + "title": "weights" + } + }, + "required": [ + "endValue", + "name", + "samples", + "startValue", + "type", + "unit", + "weights" + ] + }, + "FileFormat.ValueUnit": { + "title": "FileFormat.ValueUnit", + "enum": [ + "bytes", + "microseconds", + "milliseconds", + "nanoseconds", + "none", + "seconds" + ], + "type": "string" + }, + "FileFormat.EventType": { + "title": "FileFormat.EventType", + "enum": [ + "C", + "O" + ], + "type": "string" + }, + "IEvent": { + "title": "IEvent", + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/FileFormat.EventType", + "title": "type" + }, + "at": { + "type": "number", + "title": "at" + } + }, + "required": [ + "at", + "type" + ] + }, + "OpenFrameEvent": { + "title": "OpenFrameEvent", + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "O" + ], + "title": "type" + }, + "frame": { + "type": "number", + "title": "frame" + }, + "at": { + "type": "number", + "title": "at" + } + }, + "required": [ + "at", + "frame", + "type" + ] + }, + "CloseFrameEvent": { + "title": "CloseFrameEvent", + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "C" + ], + "title": "type" + }, + "frame": { + "type": "number", + "title": "frame" + }, + "at": { + "type": "number", + "title": "at" + } + }, + "required": [ + "at", + "frame", + "type" + ] + } + }, + "$ref": "#/definitions/FileFormat.File" +} diff --git a/historyserver/dashboard/ray/client/public/speedscope-1.5.3/import.a03c2bef.js b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/import.a03c2bef.js new file mode 100644 index 00000000000..483e825f3d3 --- /dev/null +++ b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/import.a03c2bef.js @@ -0,0 +1,113 @@ +parcelRequire=function(e,r,n,t){var i="function"==typeof parcelRequire&&parcelRequire,o="function"==typeof require&&require;function u(n,t){if(!r[n]){if(!e[n]){var f="function"==typeof parcelRequire&&parcelRequire;if(!t&&f)return f(n,!0);if(i)return i(n,!0);if(o&&"string"==typeof n)return o(n);var c=new Error("Cannot find module '"+n+"'");throw c.code="MODULE_NOT_FOUND",c}p.resolve=function(r){return e[n][1][r]||r};var l=r[n]=new u.Module(n);e[n][0].call(l.exports,p,l,l.exports,this)}return r[n].exports;function p(e){return u(p.resolve(e))}}u.isParcelRequire=!0,u.Module=function(e){this.id=e,this.bundle=u,this.exports={}},u.modules=e,u.cache=r,u.parent=i,u.register=function(r,n){e[r]=[function(e,r){r.exports=n},{}]};for(var f=0;fe.id)}),r.children.forEach(e)}(e),t}function t(e,t){return e.map((r,n)=>{return r-(0===n?1e6*t:e[n-1])})}function r(r){return{samples:r.samples,startTime:1e6*r.startTime,endTime:1e6*r.endTime,nodes:e(r.head),timeDeltas:t(r.timestamps,r.startTime)}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.chromeTreeToNodes=r; +},{}],146:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.isChromeTimeline=i,exports.importFromChromeTimeline=o,exports.importFromChromeCPUProfile=f,exports.importFromOldV8CPUProfile=u;var e=require("../lib/profile"),t=require("../lib/utils"),r=require("../lib/value-formatters"),n=require("./v8cpuFormatter");function i(e){if(!Array.isArray(e))return!1;if(e.length<1)return!1;const t=e[0];return"pid"in t&&"tid"in t&&"ph"in t&&"cat"in t&&!!e.find(e=>"CpuProfile"===e.name||"Profile"===e.name||"ProfileChunk"===e.name)}function o(e,r){const n=new Map,i=new Map,o=new Map;(0,t.sortBy)(e,e=>e.ts);for(let t of e){if("CpuProfile"===t.name){const e=`${t.pid}:${t.tid}`,r=t.id||e;n.set(r,t.args.data.cpuProfile),i.set(r,e)}if("Profile"===t.name){const e=`${t.pid}:${t.tid}`;n.set(t.id||e,Object.assign({startTime:0,endTime:0,nodes:[],samples:[],timeDeltas:[]},t.args.data)),t.id&&i.set(t.id,`${t.pid}:${t.tid}`)}if("thread_name"===t.name&&o.set(`${t.pid}:${t.tid}`,t.args.name),"ProfileChunk"===t.name){const e=`${t.pid}:${t.tid}`,r=n.get(t.id||e);if(r){const e=t.args.data;e.cpuProfile&&(e.cpuProfile.nodes&&(r.nodes=r.nodes.concat(e.cpuProfile.nodes)),e.cpuProfile.samples&&(r.samples=r.samples.concat(e.cpuProfile.samples))),e.timeDeltas&&(r.timeDeltas=r.timeDeltas.concat(e.timeDeltas)),null!=e.startTime&&(r.startTime=e.startTime),null!=e.endTime&&(r.endTime=e.endTime)}else console.warn(`Ignoring ProfileChunk for undeclared Profile with id ${t.id||e}`)}}if(n.size>0){const e=[];let l=0;return(0,t.itForEach)(n.keys(),t=>{let a=null,s=i.get(t);s&&(a=o.get(s)||null);const m=f(n.get(t));a&&n.size>1?(m.setName(`${r} - ${a}`),"CrRendererMain"===a&&(l=e.length)):m.setName(`${r}`),e.push(m)}),{name:r,indexToView:l,profiles:e}}throw new Error("Could not find CPU profile in Timeline")}const l=new Map;function a(e){return(0,t.getOrInsert)(l,e,e=>{const t=e.functionName||"(anonymous)",r=e.url,n=e.lineNumber,i=e.columnNumber;return{key:`${t}:${r}:${n}:${i}`,name:t,file:r,line:n,col:i}})}function s(e){const{functionName:t,url:r}=e;return"native dummy.js"===r||("(root)"===t||"(idle)"===t)}function m(e){return"(garbage collector)"===e||"(program)"===e}function f(n){const i=new e.CallTreeProfileBuilder(n.endTime-n.startTime),o=new Map;for(let e of n.nodes)o.set(e.id,e);for(let e of n.nodes)if("number"==typeof e.parent&&(e.parent=o.get(e.parent)),e.children)for(let t of e.children){const r=o.get(t);r&&(r.parent=e)}const l=[],f=[];let u=n.timeDeltas[0],c=NaN;for(let e=0;e0&&(0,t.lastOf)(p)!=c;){const e=a(p.pop().callFrame);i.leaveFrame(e,r)}const d=[];for(let e=u;e&&e!=c&&!s(e.callFrame);e=m(e.callFrame.functionName)?(0,t.lastOf)(p):e.parent||null)d.push(e);d.reverse();for(let e of d)i.enterFrame(a(e.callFrame),r);p=p.concat(d)}for(let e=p.length-1;e>=0;e--)i.leaveFrame(a(p[e].callFrame),(0,t.lastOf)(f));return i.setValueFormatter(new r.TimeFormatter("microseconds")),i.build()}function u(e){return f((0,n.chromeTreeToNodes)(e))} +},{"../lib/profile":139,"../lib/utils":70,"../lib/value-formatters":140,"./v8cpuFormatter":172}],147:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.importFromStackprof=r;var e=require("../lib/profile"),t=require("../lib/value-formatters");function r(r){const o=r.raw_timestamp_deltas.reduce((e,t)=>e+t,0),a=new e.StackListProfileBuilder(o),{frames:l,raw:s,raw_timestamp_deltas:i}=r;let n=0,c=[];for(let e=0;e=0;)e[t]=0}var i=0,l=1,d=2,f=3,o=258,b=29,s=256,u=s+1+b,c=30,p=19,h=2*u+1,v=15,y=16,x=7,g=256,m=16,w=17,A=18,k=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],q=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],z=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],S=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],j=512,B=new Array(2*(u+2));a(B);var C=new Array(2*c);a(C);var D=new Array(j);a(D);var E=new Array(o-f+1);a(E);var F=new Array(b);a(F);var G,H,I,J=new Array(c);function K(e,t,n,_,r){this.static_tree=e,this.extra_bits=t,this.extra_base=n,this.elems=_,this.max_length=r,this.has_stree=e&&e.length}function L(e,t){this.dyn_tree=e,this.max_code=0,this.stat_desc=t}function M(e){return e<256?D[e]:D[256+(e>>>7)]}function N(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255}function O(e,t,n){e.bi_valid>y-n?(e.bi_buf|=t<>y-e.bi_valid,e.bi_valid+=n-y):(e.bi_buf|=t<>>=1,n<<=1}while(--t>0);return n>>>1}function R(e){16===e.bi_valid?(N(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):e.bi_valid>=8&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8)}function T(e,t){var n,_,r,a,i,l,d=t.dyn_tree,f=t.max_code,o=t.stat_desc.static_tree,b=t.stat_desc.has_stree,s=t.stat_desc.extra_bits,u=t.stat_desc.extra_base,c=t.stat_desc.max_length,p=0;for(a=0;a<=v;a++)e.bl_count[a]=0;for(d[2*e.heap[e.heap_max]+1]=0,n=e.heap_max+1;nc&&(a=c,p++),d[2*_+1]=a,_>f||(e.bl_count[a]++,i=0,_>=u&&(i=s[_-u]),l=d[2*_],e.opt_len+=l*(a+i),b&&(e.static_len+=l*(o[2*_+1]+i)));if(0!==p){do{for(a=c-1;0===e.bl_count[a];)a--;e.bl_count[a]--,e.bl_count[a+1]+=2,e.bl_count[c]--,p-=2}while(p>0);for(a=c;0!==a;a--)for(_=e.bl_count[a];0!==_;)(r=e.heap[--n])>f||(d[2*r+1]!==a&&(e.opt_len+=(a-d[2*r+1])*d[2*r],d[2*r+1]=a),_--)}}function U(e,t,n){var _,r,a=new Array(v+1),i=0;for(_=1;_<=v;_++)a[_]=i=i+n[_-1]<<1;for(r=0;r<=t;r++){var l=e[2*r+1];0!==l&&(e[2*r]=Q(a[l]++,l))}}function V(){var e,t,n,_,r,a=new Array(v+1);for(n=0,_=0;_>=7;_8?N(e,e.bi_buf):e.bi_valid>0&&(e.pending_buf[e.pending++]=e.bi_buf),e.bi_buf=0,e.bi_valid=0}function Y(t,n,_,r){X(t),r&&(N(t,_),N(t,~_)),e.arraySet(t.pending_buf,t.window,n,_,t.pending),t.pending+=_}function Z(e,t,n,_){var r=2*t,a=2*n;return e[r]>1;n>=1;n--)$(e,a,n);r=d;do{n=e.heap[1],e.heap[1]=e.heap[e.heap_len--],$(e,a,1),_=e.heap[1],e.heap[--e.heap_max]=n,e.heap[--e.heap_max]=_,a[2*r]=a[2*n]+a[2*_],e.depth[r]=(e.depth[n]>=e.depth[_]?e.depth[n]:e.depth[_])+1,a[2*n+1]=a[2*_+1]=r,e.heap[1]=r++,$(e,a,1)}while(e.heap_len>=2);e.heap[--e.heap_max]=e.heap[1],T(e,t),U(a,f,e.bl_count)}function ne(e,t,n){var _,r,a=-1,i=t[1],l=0,d=7,f=4;for(0===i&&(d=138,f=3),t[2*(n+1)+1]=65535,_=0;_<=n;_++)r=i,i=t[2*(_+1)+1],++l=3&&0===e.bl_tree[2*S[t]+1];t--);return e.opt_len+=3*(t+1)+5+5+4,t}function ae(e,t,n,_){var r;for(O(e,t-257,5),O(e,n-1,5),O(e,_-4,4),r=0;r<_;r++)O(e,e.bl_tree[2*S[r]+1],3);_e(e,e.dyn_ltree,t-1),_e(e,e.dyn_dtree,n-1)}function ie(e){var t,r=4093624447;for(t=0;t<=31;t++,r>>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return n;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return _;for(t=32;t0?(e.strm.data_type===r&&(e.strm.data_type=ie(e)),te(e,e.l_desc),te(e,e.d_desc),o=re(e),i=e.opt_len+3+7>>>3,(f=e.static_len+3+7>>>3)<=i&&(i=f)):i=f=_+5,_+4<=i&&-1!==n?fe(e,n,_,a):e.strategy===t||f===i?(O(e,(l<<1)+(a?1:0),3),ee(e,B,C)):(O(e,(d<<1)+(a?1:0),3),ae(e,e.l_desc.max_code+1,e.d_desc.max_code+1,o+1),ee(e,e.dyn_ltree,e.dyn_dtree)),W(e),a&&X(e)}function se(e,t,n){return e.pending_buf[e.d_buf+2*e.last_lit]=t>>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&n,e.last_lit++,0===t?e.dyn_ltree[2*n]++:(e.matches++,t--,e.dyn_ltree[2*(E[n]+s+1)]++,e.dyn_dtree[2*M(t)]++),e.last_lit===e.lit_bufsize-1}exports._tr_init=de,exports._tr_stored_block=fe,exports._tr_flush_block=be,exports._tr_tally=se,exports._tr_align=oe; +},{"../utils/common":178}],191:[function(require,module,exports) { +"use strict";function e(e,r,o,t){for(var u=65535&e|0,i=e>>>16&65535|0,n=0;0!==o;){o-=n=o>2e3?2e3:o;do{i=i+(u=u+r[t++]|0)|0}while(--n);u%=65521,i%=65521}return u|i<<16|0}module.exports=e; +},{}],192:[function(require,module,exports) { +"use strict";function r(){for(var r,o=[],t=0;t<256;t++){r=t;for(var n=0;n<8;n++)r=1&r?3988292384^r>>>1:r>>>1;o[t]=r}return o}var o=r();function t(r,t,n,u){var a=o,e=u+n;r^=-1;for(var f=u;f>>8^a[255&(r^t[f])];return-1^r}module.exports=t; +},{}],185:[function(require,module,exports) { +"use strict";module.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}; +},{}],182:[function(require,module,exports) { +"use strict";var t,a=require("../utils/common"),e=require("./trees"),s=require("./adler32"),i=require("./crc32"),r=require("./messages"),n=0,h=1,l=3,_=4,d=5,o=0,u=1,g=-2,f=-3,c=-5,p=-1,m=1,w=2,v=3,k=4,z=0,b=2,x=8,y=9,B=15,S=8,q=29,I=256,A=I+1+q,C=30,R=19,j=2*A+1,D=15,E=3,H=258,K=H+E+1,N=32,F=42,G=69,J=73,L=91,M=103,O=113,P=666,Q=1,T=2,U=3,V=4,W=3;function X(t,a){return t.msg=r[a],a}function Y(t){return(t<<1)-(t>4?9:0)}function Z(t){for(var a=t.length;--a>=0;)t[a]=0}function $(t){var e=t.state,s=e.pending;s>t.avail_out&&(s=t.avail_out),0!==s&&(a.arraySet(t.output,e.pending_buf,e.pending_out,s,t.next_out),t.next_out+=s,e.pending_out+=s,t.total_out+=s,t.avail_out-=s,e.pending-=s,0===e.pending&&(e.pending_out=0))}function tt(t,a){e._tr_flush_block(t,t.block_start>=0?t.block_start:-1,t.strstart-t.block_start,a),t.block_start=t.strstart,$(t.strm)}function at(t,a){t.pending_buf[t.pending++]=a}function et(t,a){t.pending_buf[t.pending++]=a>>>8&255,t.pending_buf[t.pending++]=255&a}function st(t,e,r,n){var h=t.avail_in;return h>n&&(h=n),0===h?0:(t.avail_in-=h,a.arraySet(e,t.input,t.next_in,h,r),1===t.state.wrap?t.adler=s(t.adler,e,h,r):2===t.state.wrap&&(t.adler=i(t.adler,e,h,r)),t.next_in+=h,t.total_in+=h,h)}function it(t,a){var e,s,i=t.max_chain_length,r=t.strstart,n=t.prev_length,h=t.nice_match,l=t.strstart>t.w_size-K?t.strstart-(t.w_size-K):0,_=t.window,d=t.w_mask,o=t.prev,u=t.strstart+H,g=_[r+n-1],f=_[r+n];t.prev_length>=t.good_match&&(i>>=2),h>t.lookahead&&(h=t.lookahead);do{if(_[(e=a)+n]===f&&_[e+n-1]===g&&_[e]===_[r]&&_[++e]===_[r+1]){r+=2,e++;do{}while(_[++r]===_[++e]&&_[++r]===_[++e]&&_[++r]===_[++e]&&_[++r]===_[++e]&&_[++r]===_[++e]&&_[++r]===_[++e]&&_[++r]===_[++e]&&_[++r]===_[++e]&&rn){if(t.match_start=a,n=s,s>=h)break;g=_[r+n-1],f=_[r+n]}}}while((a=o[a&d])>l&&0!=--i);return n<=t.lookahead?n:t.lookahead}function rt(t){var e,s,i,r,n,h=t.w_size;do{if(r=t.window_size-t.lookahead-t.strstart,t.strstart>=h+(h-K)){a.arraySet(t.window,t.window,h,h,0),t.match_start-=h,t.strstart-=h,t.block_start-=h,e=s=t.hash_size;do{i=t.head[--e],t.head[e]=i>=h?i-h:0}while(--s);e=s=h;do{i=t.prev[--e],t.prev[e]=i>=h?i-h:0}while(--s);r+=h}if(0===t.strm.avail_in)break;if(s=st(t.strm,t.window,t.strstart+t.lookahead,r),t.lookahead+=s,t.lookahead+t.insert>=E)for(n=t.strstart-t.insert,t.ins_h=t.window[n],t.ins_h=(t.ins_h<t.pending_buf_size-5&&(e=t.pending_buf_size-5);;){if(t.lookahead<=1){if(rt(t),0===t.lookahead&&a===n)return Q;if(0===t.lookahead)break}t.strstart+=t.lookahead,t.lookahead=0;var s=t.block_start+e;if((0===t.strstart||t.strstart>=s)&&(t.lookahead=t.strstart-s,t.strstart=s,tt(t,!1),0===t.strm.avail_out))return Q;if(t.strstart-t.block_start>=t.w_size-K&&(tt(t,!1),0===t.strm.avail_out))return Q}return t.insert=0,a===_?(tt(t,!0),0===t.strm.avail_out?U:V):(t.strstart>t.block_start&&(tt(t,!1),t.strm.avail_out),Q)}function ht(t,a){for(var s,i;;){if(t.lookahead=E&&(t.ins_h=(t.ins_h<=E)if(i=e._tr_tally(t,t.strstart-t.match_start,t.match_length-E),t.lookahead-=t.match_length,t.match_length<=t.max_lazy_match&&t.lookahead>=E){t.match_length--;do{t.strstart++,t.ins_h=(t.ins_h<=E&&(t.ins_h=(t.ins_h<4096)&&(t.match_length=E-1)),t.prev_length>=E&&t.match_length<=t.prev_length){r=t.strstart+t.lookahead-E,i=e._tr_tally(t,t.strstart-1-t.prev_match,t.prev_length-E),t.lookahead-=t.prev_length-1,t.prev_length-=2;do{++t.strstart<=r&&(t.ins_h=(t.ins_h<=E&&t.strstart>0&&(i=l[r=t.strstart-1])===l[++r]&&i===l[++r]&&i===l[++r]){h=t.strstart+H;do{}while(i===l[++r]&&i===l[++r]&&i===l[++r]&&i===l[++r]&&i===l[++r]&&i===l[++r]&&i===l[++r]&&i===l[++r]&&rt.lookahead&&(t.match_length=t.lookahead)}if(t.match_length>=E?(s=e._tr_tally(t,1,t.match_length-E),t.lookahead-=t.match_length,t.strstart+=t.match_length,t.match_length=0):(s=e._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++),s&&(tt(t,!1),0===t.strm.avail_out))return Q}return t.insert=0,a===_?(tt(t,!0),0===t.strm.avail_out?U:V):t.last_lit&&(tt(t,!1),0===t.strm.avail_out)?Q:T}function dt(t,a){for(var s;;){if(0===t.lookahead&&(rt(t),0===t.lookahead)){if(a===n)return Q;break}if(t.match_length=0,s=e._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++,s&&(tt(t,!1),0===t.strm.avail_out))return Q}return t.insert=0,a===_?(tt(t,!0),0===t.strm.avail_out?U:V):t.last_lit&&(tt(t,!1),0===t.strm.avail_out)?Q:T}function ot(t,a,e,s,i){this.good_length=t,this.max_lazy=a,this.nice_length=e,this.max_chain=s,this.func=i}function ut(a){a.window_size=2*a.w_size,Z(a.head),a.max_lazy_match=t[a.level].max_lazy,a.good_match=t[a.level].good_length,a.nice_match=t[a.level].nice_length,a.max_chain_length=t[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=E-1,a.match_available=0,a.ins_h=0}function gt(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=x,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new a.Buf16(2*j),this.dyn_dtree=new a.Buf16(2*(2*C+1)),this.bl_tree=new a.Buf16(2*(2*R+1)),Z(this.dyn_ltree),Z(this.dyn_dtree),Z(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new a.Buf16(D+1),this.heap=new a.Buf16(2*A+1),Z(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new a.Buf16(2*A+1),Z(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function ft(t){var a;return t&&t.state?(t.total_in=t.total_out=0,t.data_type=b,(a=t.state).pending=0,a.pending_out=0,a.wrap<0&&(a.wrap=-a.wrap),a.status=a.wrap?F:O,t.adler=2===a.wrap?0:1,a.last_flush=n,e._tr_init(a),o):X(t,g)}function ct(t){var a=ft(t);return a===o&&ut(t.state),a}function pt(t,a){return t&&t.state?2!==t.state.wrap?g:(t.state.gzhead=a,o):g}function mt(t,e,s,i,r,n){if(!t)return g;var h=1;if(e===p&&(e=6),i<0?(h=0,i=-i):i>15&&(h=2,i-=16),r<1||r>y||s!==x||i<8||i>15||e<0||e>9||n<0||n>k)return X(t,g);8===i&&(i=9);var l=new gt;return t.state=l,l.strm=t,l.wrap=h,l.gzhead=null,l.w_bits=i,l.w_size=1<d||s<0)return a?X(a,g):g;if(f=a.state,!a.output||!a.input&&0!==a.avail_in||f.status===P&&s!==_)return X(a,0===a.avail_out?c:g);if(f.strm=a,r=f.last_flush,f.last_flush=s,f.status===F)if(2===f.wrap)a.adler=0,at(f,31),at(f,139),at(f,8),f.gzhead?(at(f,(f.gzhead.text?1:0)+(f.gzhead.hcrc?2:0)+(f.gzhead.extra?4:0)+(f.gzhead.name?8:0)+(f.gzhead.comment?16:0)),at(f,255&f.gzhead.time),at(f,f.gzhead.time>>8&255),at(f,f.gzhead.time>>16&255),at(f,f.gzhead.time>>24&255),at(f,9===f.level?2:f.strategy>=w||f.level<2?4:0),at(f,255&f.gzhead.os),f.gzhead.extra&&f.gzhead.extra.length&&(at(f,255&f.gzhead.extra.length),at(f,f.gzhead.extra.length>>8&255)),f.gzhead.hcrc&&(a.adler=i(a.adler,f.pending_buf,f.pending,0)),f.gzindex=0,f.status=G):(at(f,0),at(f,0),at(f,0),at(f,0),at(f,0),at(f,9===f.level?2:f.strategy>=w||f.level<2?4:0),at(f,W),f.status=O);else{var k=x+(f.w_bits-8<<4)<<8;k|=(f.strategy>=w||f.level<2?0:f.level<6?1:6===f.level?2:3)<<6,0!==f.strstart&&(k|=N),k+=31-k%31,f.status=O,et(f,k),0!==f.strstart&&(et(f,a.adler>>>16),et(f,65535&a.adler)),a.adler=1}if(f.status===G)if(f.gzhead.extra){for(p=f.pending;f.gzindex<(65535&f.gzhead.extra.length)&&(f.pending!==f.pending_buf_size||(f.gzhead.hcrc&&f.pending>p&&(a.adler=i(a.adler,f.pending_buf,f.pending-p,p)),$(a),p=f.pending,f.pending!==f.pending_buf_size));)at(f,255&f.gzhead.extra[f.gzindex]),f.gzindex++;f.gzhead.hcrc&&f.pending>p&&(a.adler=i(a.adler,f.pending_buf,f.pending-p,p)),f.gzindex===f.gzhead.extra.length&&(f.gzindex=0,f.status=J)}else f.status=J;if(f.status===J)if(f.gzhead.name){p=f.pending;do{if(f.pending===f.pending_buf_size&&(f.gzhead.hcrc&&f.pending>p&&(a.adler=i(a.adler,f.pending_buf,f.pending-p,p)),$(a),p=f.pending,f.pending===f.pending_buf_size)){m=1;break}m=f.gzindexp&&(a.adler=i(a.adler,f.pending_buf,f.pending-p,p)),0===m&&(f.gzindex=0,f.status=L)}else f.status=L;if(f.status===L)if(f.gzhead.comment){p=f.pending;do{if(f.pending===f.pending_buf_size&&(f.gzhead.hcrc&&f.pending>p&&(a.adler=i(a.adler,f.pending_buf,f.pending-p,p)),$(a),p=f.pending,f.pending===f.pending_buf_size)){m=1;break}m=f.gzindexp&&(a.adler=i(a.adler,f.pending_buf,f.pending-p,p)),0===m&&(f.status=M)}else f.status=M;if(f.status===M&&(f.gzhead.hcrc?(f.pending+2>f.pending_buf_size&&$(a),f.pending+2<=f.pending_buf_size&&(at(f,255&a.adler),at(f,a.adler>>8&255),a.adler=0,f.status=O)):f.status=O),0!==f.pending){if($(a),0===a.avail_out)return f.last_flush=-1,o}else if(0===a.avail_in&&Y(s)<=Y(r)&&s!==_)return X(a,c);if(f.status===P&&0!==a.avail_in)return X(a,c);if(0!==a.avail_in||0!==f.lookahead||s!==n&&f.status!==P){var z=f.strategy===w?dt(f,s):f.strategy===v?_t(f,s):t[f.level].func(f,s);if(z!==U&&z!==V||(f.status=P),z===Q||z===U)return 0===a.avail_out&&(f.last_flush=-1),o;if(z===T&&(s===h?e._tr_align(f):s!==d&&(e._tr_stored_block(f,0,0,!1),s===l&&(Z(f.head),0===f.lookahead&&(f.strstart=0,f.block_start=0,f.insert=0))),$(a),0===a.avail_out))return f.last_flush=-1,o}return s!==_?o:f.wrap<=0?u:(2===f.wrap?(at(f,255&a.adler),at(f,a.adler>>8&255),at(f,a.adler>>16&255),at(f,a.adler>>24&255),at(f,255&a.total_in),at(f,a.total_in>>8&255),at(f,a.total_in>>16&255),at(f,a.total_in>>24&255)):(et(f,a.adler>>>16),et(f,65535&a.adler)),$(a),f.wrap>0&&(f.wrap=-f.wrap),0!==f.pending?o:u)}function kt(t){var a;return t&&t.state?(a=t.state.status)!==F&&a!==G&&a!==J&&a!==L&&a!==M&&a!==O&&a!==P?X(t,g):(t.state=null,a===O?X(t,f):o):g}function zt(t,e){var i,r,n,h,l,_,d,u,f=e.length;if(!t||!t.state)return g;if(2===(h=(i=t.state).wrap)||1===h&&i.status!==F||i.lookahead)return g;for(1===h&&(t.adler=s(t.adler,e,f,0)),i.wrap=0,f>=i.w_size&&(0===h&&(Z(i.head),i.strstart=0,i.block_start=0,i.insert=0),u=new a.Buf8(i.w_size),a.arraySet(u,e,f-i.w_size,i.w_size,0),e=u,f=i.w_size),l=t.avail_in,_=t.next_in,d=t.input,t.avail_in=f,t.next_in=0,t.input=e,rt(i);i.lookahead>=E;){r=i.strstart,n=i.lookahead-(E-1);do{i.ins_h=(i.ins_h<=252?6:o>=248?5:o>=240?4:o>=224?3:o>=192?2:1;function f(e,o){if(o<65537&&(e.subarray&&t||!e.subarray&&n))return String.fromCharCode.apply(null,r.shrinkBuf(e,o));for(var f="",u=0;u>>6,t[u++]=128|63&e):e<65536?(t[u++]=224|e>>>12,t[u++]=128|e>>>6&63,t[u++]=128|63&e):(t[u++]=240|e>>>18,t[u++]=128|e>>>12&63,t[u++]=128|e>>>6&63,t[u++]=128|63&e);return t},exports.buf2binstring=function(r){return f(r,r.length)},exports.binstring2buf=function(n){for(var t=new r.Buf8(n.length),e=0,o=t.length;e4)h[o++]=65533,t+=a-1;else{for(u&=2===a?31:3===a?15:7;a>1&&t1?h[o++]=65533:u<65536?h[o++]=u:(u-=65536,h[o++]=55296|u>>10&1023,h[o++]=56320|1023&u)}return f(h,o)},exports.utf8border=function(r,n){var t;for((n=n||r.length)>r.length&&(n=r.length),t=n-1;t>=0&&128==(192&r[t]);)t--;return t<0?n:0===t?n:t+e[r[t]]>n?t:n}; +},{"./common":178}],184:[function(require,module,exports) { +"use strict";function t(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}module.exports=t; +},{}],176:[function(require,module,exports) { +"use strict";var t=require("./zlib/deflate"),i=require("./utils/common"),e=require("./utils/strings"),n=require("./zlib/messages"),r=require("./zlib/zstream"),s=Object.prototype.toString,o=0,a=4,u=0,h=1,d=2,l=-1,f=0,p=8;function w(o){if(!(this instanceof w))return new w(o);this.options=i.assign({level:l,method:p,chunkSize:16384,windowBits:15,memLevel:8,strategy:f,to:""},o||{});var a=this.options;a.raw&&a.windowBits>0?a.windowBits=-a.windowBits:a.gzip&&a.windowBits>0&&a.windowBits<16&&(a.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new r,this.strm.avail_out=0;var h=t.deflateInit2(this.strm,a.level,a.method,a.windowBits,a.memLevel,a.strategy);if(h!==u)throw new Error(n[h]);if(a.header&&t.deflateSetHeader(this.strm,a.header),a.dictionary){var d;if(d="string"==typeof a.dictionary?e.string2buf(a.dictionary):"[object ArrayBuffer]"===s.call(a.dictionary)?new Uint8Array(a.dictionary):a.dictionary,(h=t.deflateSetDictionary(this.strm,d))!==u)throw new Error(n[h]);this._dict_set=!0}}function c(t,i){var e=new w(i);if(e.push(t,!0),e.err)throw e.msg||n[e.err];return e.result}function m(t,i){return(i=i||{}).raw=!0,c(t,i)}function g(t,i){return(i=i||{}).gzip=!0,c(t,i)}w.prototype.push=function(n,r){var l,f,p=this.strm,w=this.options.chunkSize;if(this.ended)return!1;f=r===~~r?r:!0===r?a:o,"string"==typeof n?p.input=e.string2buf(n):"[object ArrayBuffer]"===s.call(n)?p.input=new Uint8Array(n):p.input=n,p.next_in=0,p.avail_in=p.input.length;do{if(0===p.avail_out&&(p.output=new i.Buf8(w),p.next_out=0,p.avail_out=w),(l=t.deflate(p,f))!==h&&l!==u)return this.onEnd(l),this.ended=!0,!1;0!==p.avail_out&&(0!==p.avail_in||f!==a&&f!==d)||("string"===this.options.to?this.onData(e.buf2binstring(i.shrinkBuf(p.output,p.next_out))):this.onData(i.shrinkBuf(p.output,p.next_out)))}while((p.avail_in>0||0===p.avail_out)&&l!==h);return f===a?(l=t.deflateEnd(this.strm),this.onEnd(l),this.ended=!0,l===u):f!==d||(this.onEnd(u),p.avail_out=0,!0)},w.prototype.onData=function(t){this.chunks.push(t)},w.prototype.onEnd=function(t){t===u&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=i.flattenChunks(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg},exports.Deflate=w,exports.deflate=c,exports.deflateRaw=m,exports.gzip=g; +},{"./zlib/deflate":182,"./utils/common":178,"./utils/strings":183,"./zlib/messages":185,"./zlib/zstream":184}],199:[function(require,module,exports) { +"use strict";var i=30,e=12;module.exports=function(o,a){var t,d,n,l,s,f,r,b,c,u,v,m,w,h,k,_,x,g,p,z,j,q,y,A,B;t=o.state,d=o.next_in,A=o.input,n=d+(o.avail_in-5),l=o.next_out,B=o.output,s=l-(a-o.avail_out),f=l+(o.avail_out-257),r=t.dmax,b=t.wsize,c=t.whave,u=t.wnext,v=t.window,m=t.hold,w=t.bits,h=t.lencode,k=t.distcode,_=(1<>>=p=g>>>24,w-=p,0===(p=g>>>16&255))B[l++]=65535&g;else{if(!(16&p)){if(0==(64&p)){g=h[(65535&g)+(m&(1<>>=p,w-=p),w<15&&(m+=A[d++]<>>=p=g>>>24,w-=p,!(16&(p=g>>>16&255))){if(0==(64&p)){g=k[(65535&g)+(m&(1<r){o.msg="invalid distance too far back",t.mode=i;break i}if(m>>>=p,w-=p,j>(p=l-s)){if((p=j-p)>c&&t.sane){o.msg="invalid distance too far back",t.mode=i;break i}if(q=0,y=v,0===u){if(q+=b-p,p2;)B[l++]=y[q++],B[l++]=y[q++],B[l++]=y[q++],z-=3;z&&(B[l++]=y[q++],z>1&&(B[l++]=y[q++]))}else{q=l-j;do{B[l++]=B[q++],B[l++]=B[q++],B[l++]=B[q++],z-=3}while(z>2);z&&(B[l++]=B[q++],z>1&&(B[l++]=B[q++]))}break}}break}}while(d>3,m&=(1<<(w-=z<<3))-1,o.next_in=d,o.next_out=l,o.avail_in=d=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return d[v++]=20971520,d[v++]=20971520,h.bits=1,0;for(F=1;F0&&(a===e||1!==G))return-1;for(Q[1]=0,D=1;Di||a===t&&L>o)return 1;for(;;){y=D-J,B[E]j?(z=R[S+B[E]],A=N[O+B[E]]):(z=96,A=0),k=1<>J)+(p-=k)]=y<<24|z<<16|A|0}while(0!==p);for(k=1<>=1;if(0!==k?(M&=k-1,M+=k):M=0,E++,0==--P[D]){if(D===G)break;D=c[m+B[E]]}if(D>H&&(M&x)!==q){for(0===J&&(J=H),g+=F,K=1<<(I=D-J);I+Ji||a===t&&L>o)return 1;d[q=M&x]=H<<24|I<<16|g-v|0}}return 0!==M&&(d[g+M]=D-J<<24|64<<16|0),h.bits=H,0}; +},{"../utils/common":178}],187:[function(require,module,exports) { +"use strict";var e=require("../utils/common"),a=require("./adler32"),t=require("./crc32"),i=require("./inffast"),s=require("./inftrees"),n=0,r=1,o=2,d=4,l=5,f=6,c=0,h=1,k=2,b=-2,m=-3,w=-4,u=-5,g=8,v=1,x=2,p=3,_=4,y=5,z=6,B=7,S=8,q=9,C=10,I=11,R=12,j=13,A=14,D=15,E=16,G=17,H=18,K=19,N=20,F=21,J=22,L=23,M=24,O=25,P=26,Q=27,T=28,U=29,V=30,W=31,X=32,Y=852,Z=592,$=15,ee=$;function ae(e){return(e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function te(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new e.Buf16(320),this.work=new e.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function ie(a){var t;return a&&a.state?(t=a.state,a.total_in=a.total_out=t.total=0,a.msg="",t.wrap&&(a.adler=1&t.wrap),t.mode=v,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new e.Buf32(Y),t.distcode=t.distdyn=new e.Buf32(Z),t.sane=1,t.back=-1,c):b}function se(e){var a;return e&&e.state?((a=e.state).wsize=0,a.whave=0,a.wnext=0,ie(e)):b}function ne(e,a){var t,i;return e&&e.state?(i=e.state,a<0?(t=0,a=-a):(t=1+(a>>4),a<48&&(a&=15)),a&&(a<8||a>15)?b:(null!==i.window&&i.wbits!==a&&(i.window=null),i.wrap=t,i.wbits=a,se(e))):b}function re(e,a){var t,i;return e?(i=new te,e.state=i,i.window=null,(t=ne(e,a))!==c&&(e.state=null),t):b}function oe(e){return re(e,ee)}var de,le,fe=!0;function ce(a){if(fe){var t;for(de=new e.Buf32(512),le=new e.Buf32(32),t=0;t<144;)a.lens[t++]=8;for(;t<256;)a.lens[t++]=9;for(;t<280;)a.lens[t++]=7;for(;t<288;)a.lens[t++]=8;for(s(r,a.lens,0,288,de,0,a.work,{bits:9}),t=0;t<32;)a.lens[t++]=5;s(o,a.lens,0,32,le,0,a.work,{bits:5}),fe=!1}a.lencode=de,a.lenbits=9,a.distcode=le,a.distbits=5}function he(a,t,i,s){var n,r=a.state;return null===r.window&&(r.wsize=1<=r.wsize?(e.arraySet(r.window,t,i-r.wsize,r.wsize,0),r.wnext=0,r.whave=r.wsize):((n=r.wsize-r.wnext)>s&&(n=s),e.arraySet(r.window,t,i-s,n,r.wnext),(s-=n)?(e.arraySet(r.window,t,i-s,s,0),r.wnext=s,r.whave=r.wsize):(r.wnext+=n,r.wnext===r.wsize&&(r.wnext=0),r.whave>>8&255,$.check=t($.check,qe,2,0),oe=0,de=0,$.mode=x;break}if($.flags=0,$.head&&($.head.done=!1),!(1&$.wrap)||(((255&oe)<<8)+(oe>>8))%31){Y.msg="incorrect header check",$.mode=V;break}if((15&oe)!==g){Y.msg="unknown compression method",$.mode=V;break}if(de-=4,_e=8+(15&(oe>>>=4)),0===$.wbits)$.wbits=_e;else if(_e>$.wbits){Y.msg="invalid window size",$.mode=V;break}$.dmax=1<<_e,Y.adler=$.check=1,$.mode=512&oe?C:R,oe=0,de=0;break;case x:for(;de<16;){if(0===ne)break e;ne--,oe+=ee[ie++]<>8&1),512&$.flags&&(qe[0]=255&oe,qe[1]=oe>>>8&255,$.check=t($.check,qe,2,0)),oe=0,de=0,$.mode=p;case p:for(;de<32;){if(0===ne)break e;ne--,oe+=ee[ie++]<>>8&255,qe[2]=oe>>>16&255,qe[3]=oe>>>24&255,$.check=t($.check,qe,4,0)),oe=0,de=0,$.mode=_;case _:for(;de<16;){if(0===ne)break e;ne--,oe+=ee[ie++]<>8),512&$.flags&&(qe[0]=255&oe,qe[1]=oe>>>8&255,$.check=t($.check,qe,2,0)),oe=0,de=0,$.mode=y;case y:if(1024&$.flags){for(;de<16;){if(0===ne)break e;ne--,oe+=ee[ie++]<>>8&255,$.check=t($.check,qe,2,0)),oe=0,de=0}else $.head&&($.head.extra=null);$.mode=z;case z:if(1024&$.flags&&((ke=$.length)>ne&&(ke=ne),ke&&($.head&&(_e=$.head.extra_len-$.length,$.head.extra||($.head.extra=new Array($.head.extra_len)),e.arraySet($.head.extra,ee,ie,ke,_e)),512&$.flags&&($.check=t($.check,ee,ke,ie)),ne-=ke,ie+=ke,$.length-=ke),$.length))break e;$.length=0,$.mode=B;case B:if(2048&$.flags){if(0===ne)break e;ke=0;do{_e=ee[ie+ke++],$.head&&_e&&$.length<65536&&($.head.name+=String.fromCharCode(_e))}while(_e&&ke>9&1,$.head.done=!0),Y.adler=$.check=0,$.mode=R;break;case C:for(;de<32;){if(0===ne)break e;ne--,oe+=ee[ie++]<>>=7&de,de-=7&de,$.mode=Q;break}for(;de<3;){if(0===ne)break e;ne--,oe+=ee[ie++]<>>=1)){case 0:$.mode=A;break;case 1:if(ce($),$.mode=N,Z===f){oe>>>=2,de-=2;break e}break;case 2:$.mode=G;break;case 3:Y.msg="invalid block type",$.mode=V}oe>>>=2,de-=2;break;case A:for(oe>>>=7&de,de-=7&de;de<32;){if(0===ne)break e;ne--,oe+=ee[ie++]<>>16^65535)){Y.msg="invalid stored block lengths",$.mode=V;break}if($.length=65535&oe,oe=0,de=0,$.mode=D,Z===f)break e;case D:$.mode=E;case E:if(ke=$.length){if(ke>ne&&(ke=ne),ke>re&&(ke=re),0===ke)break e;e.arraySet(te,ee,ie,ke,se),ne-=ke,ie+=ke,re-=ke,se+=ke,$.length-=ke;break}$.mode=R;break;case G:for(;de<14;){if(0===ne)break e;ne--,oe+=ee[ie++]<>>=5,de-=5,$.ndist=1+(31&oe),oe>>>=5,de-=5,$.ncode=4+(15&oe),oe>>>=4,de-=4,$.nlen>286||$.ndist>30){Y.msg="too many length or distance symbols",$.mode=V;break}$.have=0,$.mode=H;case H:for(;$.have<$.ncode;){for(;de<3;){if(0===ne)break e;ne--,oe+=ee[ie++]<>>=3,de-=3}for(;$.have<19;)$.lens[Ce[$.have++]]=0;if($.lencode=$.lendyn,$.lenbits=7,ze={bits:$.lenbits},ye=s(n,$.lens,0,19,$.lencode,0,$.work,ze),$.lenbits=ze.bits,ye){Y.msg="invalid code lengths set",$.mode=V;break}$.have=0,$.mode=K;case K:for(;$.have<$.nlen+$.ndist;){for(;ue=(Se=$.lencode[oe&(1<<$.lenbits)-1])>>>16&255,ge=65535&Se,!((we=Se>>>24)<=de);){if(0===ne)break e;ne--,oe+=ee[ie++]<>>=we,de-=we,$.lens[$.have++]=ge;else{if(16===ge){for(Be=we+2;de>>=we,de-=we,0===$.have){Y.msg="invalid bit length repeat",$.mode=V;break}_e=$.lens[$.have-1],ke=3+(3&oe),oe>>>=2,de-=2}else if(17===ge){for(Be=we+3;de>>=we)),oe>>>=3,de-=3}else{for(Be=we+7;de>>=we)),oe>>>=7,de-=7}if($.have+ke>$.nlen+$.ndist){Y.msg="invalid bit length repeat",$.mode=V;break}for(;ke--;)$.lens[$.have++]=_e}}if($.mode===V)break;if(0===$.lens[256]){Y.msg="invalid code -- missing end-of-block",$.mode=V;break}if($.lenbits=9,ze={bits:$.lenbits},ye=s(r,$.lens,0,$.nlen,$.lencode,0,$.work,ze),$.lenbits=ze.bits,ye){Y.msg="invalid literal/lengths set",$.mode=V;break}if($.distbits=6,$.distcode=$.distdyn,ze={bits:$.distbits},ye=s(o,$.lens,$.nlen,$.ndist,$.distcode,0,$.work,ze),$.distbits=ze.bits,ye){Y.msg="invalid distances set",$.mode=V;break}if($.mode=N,Z===f)break e;case N:$.mode=F;case F:if(ne>=6&&re>=258){Y.next_out=se,Y.avail_out=re,Y.next_in=ie,Y.avail_in=ne,$.hold=oe,$.bits=de,i(Y,fe),se=Y.next_out,te=Y.output,re=Y.avail_out,ie=Y.next_in,ee=Y.input,ne=Y.avail_in,oe=$.hold,de=$.bits,$.mode===R&&($.back=-1);break}for($.back=0;ue=(Se=$.lencode[oe&(1<<$.lenbits)-1])>>>16&255,ge=65535&Se,!((we=Se>>>24)<=de);){if(0===ne)break e;ne--,oe+=ee[ie++]<>ve)])>>>16&255,ge=65535&Se,!(ve+(we=Se>>>24)<=de);){if(0===ne)break e;ne--,oe+=ee[ie++]<>>=ve,de-=ve,$.back+=ve}if(oe>>>=we,de-=we,$.back+=we,$.length=ge,0===ue){$.mode=P;break}if(32&ue){$.back=-1,$.mode=R;break}if(64&ue){Y.msg="invalid literal/length code",$.mode=V;break}$.extra=15&ue,$.mode=J;case J:if($.extra){for(Be=$.extra;de>>=$.extra,de-=$.extra,$.back+=$.extra}$.was=$.length,$.mode=L;case L:for(;ue=(Se=$.distcode[oe&(1<<$.distbits)-1])>>>16&255,ge=65535&Se,!((we=Se>>>24)<=de);){if(0===ne)break e;ne--,oe+=ee[ie++]<>ve)])>>>16&255,ge=65535&Se,!(ve+(we=Se>>>24)<=de);){if(0===ne)break e;ne--,oe+=ee[ie++]<>>=ve,de-=ve,$.back+=ve}if(oe>>>=we,de-=we,$.back+=we,64&ue){Y.msg="invalid distance code",$.mode=V;break}$.offset=ge,$.extra=15&ue,$.mode=M;case M:if($.extra){for(Be=$.extra;de>>=$.extra,de-=$.extra,$.back+=$.extra}if($.offset>$.dmax){Y.msg="invalid distance too far back",$.mode=V;break}$.mode=O;case O:if(0===re)break e;if(ke=fe-re,$.offset>ke){if((ke=$.offset-ke)>$.whave&&$.sane){Y.msg="invalid distance too far back",$.mode=V;break}ke>$.wnext?(ke-=$.wnext,be=$.wsize-ke):be=$.wnext-ke,ke>$.length&&(ke=$.length),me=$.window}else me=te,be=se-$.offset,ke=$.length;ke>re&&(ke=re),re-=ke,$.length-=ke;do{te[se++]=me[be++]}while(--ke);0===$.length&&($.mode=F);break;case P:if(0===re)break e;te[se++]=$.length,re--,$.mode=F;break;case Q:if($.wrap){for(;de<32;){if(0===ne)break e;ne--,oe|=ee[ie++]<=0&&u.windowBits<16&&(u.windowBits=-u.windowBits,0===u.windowBits&&(u.windowBits=-15)),!(u.windowBits>=0&&u.windowBits<16)||n&&n.windowBits||(u.windowBits+=32),u.windowBits>15&&u.windowBits<48&&0==(15&u.windowBits)&&(u.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new e,this.strm.avail_out=0;var h=t.inflateInit2(this.strm,u.windowBits);if(h!==s.Z_OK)throw new Error(r[h]);this.header=new o,t.inflateGetHeader(this.strm,this.header)}function h(t,i){var n=new a(i);if(n.push(t,!0),n.err)throw n.msg||r[n.err];return n.result}function _(t,i){return(i=i||{}).raw=!0,h(t,i)}a.prototype.push=function(r,e){var o,a,h,_,w,l,d=this.strm,f=this.options.chunkSize,p=this.options.dictionary,c=!1;if(this.ended)return!1;a=e===~~e?e:!0===e?s.Z_FINISH:s.Z_NO_FLUSH,"string"==typeof r?d.input=n.binstring2buf(r):"[object ArrayBuffer]"===u.call(r)?d.input=new Uint8Array(r):d.input=r,d.next_in=0,d.avail_in=d.input.length;do{if(0===d.avail_out&&(d.output=new i.Buf8(f),d.next_out=0,d.avail_out=f),(o=t.inflate(d,s.Z_NO_FLUSH))===s.Z_NEED_DICT&&p&&(l="string"==typeof p?n.string2buf(p):"[object ArrayBuffer]"===u.call(p)?new Uint8Array(p):p,o=t.inflateSetDictionary(this.strm,l)),o===s.Z_BUF_ERROR&&!0===c&&(o=s.Z_OK,c=!1),o!==s.Z_STREAM_END&&o!==s.Z_OK)return this.onEnd(o),this.ended=!0,!1;d.next_out&&(0!==d.avail_out&&o!==s.Z_STREAM_END&&(0!==d.avail_in||a!==s.Z_FINISH&&a!==s.Z_SYNC_FLUSH)||("string"===this.options.to?(h=n.utf8border(d.output,d.next_out),_=d.next_out-h,w=n.buf2string(d.output,h),d.next_out=_,d.avail_out=f-_,_&&i.arraySet(d.output,d.output,h,_,0),this.onData(w)):this.onData(i.shrinkBuf(d.output,d.next_out)))),0===d.avail_in&&0===d.avail_out&&(c=!0)}while((d.avail_in>0||0===d.avail_out)&&o!==s.Z_STREAM_END);return o===s.Z_STREAM_END&&(a=s.Z_FINISH),a===s.Z_FINISH?(o=t.inflateEnd(this.strm),this.onEnd(o),this.ended=!0,o===s.Z_OK):a!==s.Z_SYNC_FLUSH||(this.onEnd(s.Z_OK),d.avail_out=0,!0)},a.prototype.onData=function(t){this.chunks.push(t)},a.prototype.onEnd=function(t){t===s.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=i.flattenChunks(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg},exports.Inflate=a,exports.inflate=h,exports.inflateRaw=_,exports.ungzip=h; +},{"./zlib/inflate":187,"./utils/common":178,"./utils/strings":183,"./zlib/constants":179,"./zlib/messages":185,"./zlib/zstream":184,"./zlib/gzheader":188}],175:[function(require,module,exports) { +"use strict";var e=require("./lib/utils/common").assign,i=require("./lib/deflate"),r=require("./lib/inflate"),l=require("./lib/zlib/constants"),s={};e(s,i,r,l),module.exports=s; +},{"./lib/utils/common":178,"./lib/deflate":176,"./lib/inflate":177,"./lib/zlib/constants":179}],154:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.MaybeCompressedDataReader=exports.TextProfileDataSource=void 0;var e=require("pako"),r=t(e);function t(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var t in e)Object.prototype.hasOwnProperty.call(e,t)&&(r[t]=e[t]);return r.default=e,r}var n=function(e,r,t,n){return new(t||(t=Promise))(function(o,i){function s(e){try{u(n.next(e))}catch(e){i(e)}}function a(e){try{u(n.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new t(function(r){r(e.value)}).then(s,a)}u((n=n.apply(e,r||[])).next())})};class o{constructor(e,r){this.fileName=e,this.contents=r}name(){return n(this,void 0,void 0,function*(){return this.fileName})}readAsArrayBuffer(){return n(this,void 0,void 0,function*(){return new ArrayBuffer(0)})}readAsText(){return n(this,void 0,void 0,function*(){return this.contents})}}exports.TextProfileDataSource=o;class i{constructor(e,t){this.namePromise=e,this.uncompressedData=t.then(e=>n(this,void 0,void 0,function*(){try{return r.inflate(new Uint8Array(e)).buffer}catch(r){return e}}))}name(){return n(this,void 0,void 0,function*(){return yield this.namePromise})}readAsArrayBuffer(){return n(this,void 0,void 0,function*(){return yield this.uncompressedData})}readAsText(){return n(this,void 0,void 0,function*(){const e=yield this.readAsArrayBuffer();let r="";if("undefined"!=typeof TextDecoder){return(new TextDecoder).decode(e)}{const t=new Uint8Array(e);for(let e=0;e{const t=new FileReader;t.addEventListener("loadend",()=>{if(!(t.result instanceof ArrayBuffer))throw new Error("Expected reader.result to be an instance of ArrayBuffer");r(t.result)}),t.readAsArrayBuffer(e)});return new i(Promise.resolve(e.name),r)}static fromArrayBuffer(e,r){return new i(Promise.resolve(e),Promise.resolve(r))}}exports.MaybeCompressedDataReader=i; +},{"pako":175}],148:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.UID=void 0,exports.importFromInstrumentsDeepCopy=a,exports.importFromInstrumentsTrace=w,exports.importRunFromInstrumentsTrace=g,exports.importThreadFromInstrumentsTrace=b,exports.readInstrumentsKeyedArchive=y,exports.decodeUTF8=v;var e=require("../lib/profile"),t=require("../lib/utils"),r=require("../lib/value-formatters"),n=require("./utils"),s=function(e,t,r,n){return new(r||(r=Promise))(function(s,i){function o(e){try{l(n.next(e))}catch(e){i(e)}}function a(e){try{l(n.throw(e))}catch(e){i(e)}}function l(e){e.done?s(e.value):new r(function(t){t(e.value)}).then(o,a)}l((n=n.apply(e,t||[])).next())})};function i(e){const t=e.split("\n").map(e=>e.split("\t")),r=t.shift();if(!r)return[];const n=new Map;for(let e=0;e0;){const e=a.pop();l=Math.max(l,e.endValue),n.leaveFrame(e,l)}return"Bytes Used"in s[0]?n.setValueFormatter(new r.ByteFormatter):("Weight"in s[0]||"Running Time"in s[0])&&n.setValueFormatter(new r.TimeFormatter("milliseconds")),n.build()}function l(e){return s(this,void 0,void 0,function*(){const t={name:e.name,files:new Map,subdirectories:new Map},r=yield new Promise((t,r)=>{e.createReader().readEntries(e=>{t(e)},r)});for(let e of r)if(e.isDirectory){const r=yield l(e);t.subdirectories.set(r.name,r)}else{const r=yield new Promise((t,r)=>{e.file(t,r)});t.files.set(r.name,r)}return t})}function c(e){return n.MaybeCompressedDataReader.fromFile(e).readAsArrayBuffer()}function u(e){return n.MaybeCompressedDataReader.fromFile(e).readAsText()}function f(e,r){const n=(0,t.getOrThrow)(e.subdirectories,"corespace"),s=(0,t.getOrThrow)(n.subdirectories,`run${r}`);return(0,t.getOrThrow)(s.subdirectories,"core")}class h{constructor(e){this.bytePos=0,this.view=new DataView(e)}seek(e){this.bytePos=e}skip(e){this.bytePos+=e}hasMore(){return this.bytePosthis.view.byteLength?0:this.view.getUint8(this.bytePos-1)}readUint32(){return this.bytePos+=4,this.bytePos>this.view.byteLength?0:this.view.getUint32(this.bytePos-4,!0)}readUint48(){return this.bytePos+=6,this.bytePos>this.view.byteLength?0:this.view.getUint32(this.bytePos-6,!0)+this.view.getUint16(this.bytePos-2,!0)*Math.pow(2,32)}readUint64(){return this.bytePos+=8,this.bytePos>this.view.byteLength?0:this.view.getUint32(this.bytePos-8,!0)+this.view.getUint32(this.bytePos-4,!0)*Math.pow(2,32)}}function p(e){return s(this,void 0,void 0,function*(){const r=(0,t.getOrThrow)(e.subdirectories,"stores");for(let e of r.subdirectories.values()){const r=e.files.get("schema.xml");if(!r)continue;const n=yield u(r);if(!/name="time-profile"/.exec(n))continue;const s=new h(yield c((0,t.getOrThrow)(e.files,"bulkstore")));s.readUint32(),s.readUint32(),s.readUint32();const i=s.readUint32(),o=s.readUint32();s.seek(i);const a=[];for(;;){const e=s.readUint48();if(0===e)break;const t=s.readUint32();s.skip(o-6-4-4);const r=s.readUint32();a.push({timestamp:e,threadID:t,backtraceID:r})}return a}throw new Error("Could not find sample list")})}function d(e,r){return s(this,void 0,void 0,function*(){const e=(0,t.getOrThrow)(r.subdirectories,"uniquing"),n=(0,t.getOrThrow)(e.subdirectories,"arrayUniquer"),s=(0,t.getOrThrow)(n.files,"integeruniquer.index"),i=(0,t.getOrThrow)(n.files,"integeruniquer.data"),o=new h(yield c(s)),a=new h(yield c(i));o.seek(32);let l=[];for(;o.hasMore();){const e=o.readUint32()+1048576*o.readUint32();if(0===e)continue;a.seek(e);let t=a.readUint32(),r=[];for(;t--;)r.push(a.readUint64());l.push(r)}return l})}function m(e){return s(this,void 0,void 0,function*(){const r=y(yield c((0,t.getOrThrow)(e.files,"form.template"))),n=r["com.apple.xray.owner.template.version"];let s=1;"com.apple.xray.owner.template"in r&&(s=r["com.apple.xray.owner.template"].get("_selectedRunNumber"));let i=r.$1;"stubInfoByUUID"in r&&(i=Array.from(r.stubInfoByUUID.keys())[0]);const o=r["com.apple.xray.run.data"],a=[];for(let e of o.runNumbers){const r=(0,t.getOrThrow)(o.runData,e),n=(0,t.getOrThrow)(r,"symbolsByPid"),s=new Map;for(let r of n.values()){for(let e of r.symbols){if(!e)continue;const{sourcePath:r,symbolName:n,addressToLine:i}=e;for(let e of i.keys())(0,t.getOrInsert)(s,e,()=>{const s=n||`0x${(0,t.zeroPad)(e.toString(16),16)}`,i={key:`${r}:${s}`,name:s};return r&&(i.file=r),i})}a.push({number:e,addressToFrameMap:s})}}return{version:n,instrument:i,selectedRunNumber:s,runs:a}})}function w(e){return s(this,void 0,void 0,function*(){const t=yield l(e),{version:r,runs:n,instrument:s,selectedRunNumber:i}=yield m(t);if("com.apple.xray.instrument-type.coresampler2"!==s)throw new Error(`The only supported instrument from .trace import is "com.apple.xray.instrument-type.coresampler2". Got ${s}`);console.log("version: ",r),console.log("Importing time profile");const o=[];let a=0;for(let r of n){const{addressToFrameMap:n,number:s}=r,l=yield g({fileName:e.name,tree:t,addressToFrameMap:n,runNumber:s});r.number===i&&(a=o.length+l.indexToView),o.push(...l.profiles)}return{name:e.name,indexToView:a,profiles:o}})}function g(e){return s(this,void 0,void 0,function*(){const{fileName:r,tree:n,addressToFrameMap:s,runNumber:i}=e,o=f(n,i);let a=yield p(o);const l=yield d(a,o),c=new Map;for(let e of a)c.set(e.threadID,(0,t.getOrElse)(c,e.threadID,()=>0)+1);const u=Array.from(c.entries());(0,t.sortBy)(u,e=>-e[1]);const h=u.map(e=>e[0]);return{name:r,indexToView:0,profiles:h.map(e=>b({threadID:e,fileName:r,arrays:l,addressToFrameMap:s,samples:a}))}})}function b(n){let{fileName:s,addressToFrameMap:i,arrays:o,threadID:a,samples:l}=n;const c=new Map;l=l.filter(e=>e.threadID===a);const u=new e.StackListProfileBuilder((0,t.lastOf)(l).timestamp);function f(e,r){const n=i.get(e);if(n)r.push(n);else if(e in o)for(let t of o[e])f(t,r);else{const n={key:e,name:`0x${(0,t.zeroPad)(e.toString(16),16)}`};i.set(e,n),r.push(n)}}u.setName(`${s} - thread ${a}`);let h=null;for(let e of l){const r=(0,t.getOrInsert)(c,e.backtraceID,e=>{const t=[];return f(e,t),t.reverse(),t});if(null===h&&(u.appendSampleWithWeight([],e.timestamp),h=e.timestamp),e.timestamp{switch(e){case"NSTextStorage":case"NSParagraphStyle":case"NSFont":return null;case"PFTSymbolData":{const e=Object.create(null);e.symbolName=t.$0,e.sourcePath=t.$1,e.addressToLine=new Map;for(let r=3;;r+=2){const n=t["$"+r],s=t["$"+(r+1)];if(null==n||null==s)break;e.addressToLine.set(n,s)}return e}case"PFTOwnerData":{const e=Object.create(null);return e.ownerName=t.$0,e.ownerPath=t.$1,e}case"PFTPersistentSymbols":{const e=Object.create(null),r=t.$4;e.threadNames=t.$3,e.symbols=[];for(let n=1;ne)){if(1e5!==e.$version||"NSKeyedArchiver"!==e.$archiver||!S(e.$top)||!U(e.$objects))throw new Error("Invalid keyed archive");"$null"===e.$objects[0]&&(e.$objects[0]=null);for(let r=0;r{if(t instanceof x)return e.$objects[t.index];if(U(t))for(let e=0;ee)){if(S(t)&&t.$class){let n=N(e,t.$class).$classname;switch(n){case"NSDecimalNumberPlaceholder":{let e=t["NS.length"],r=t["NS.exponent"],n=t["NS.mantissa.bo"],s=t["NS.negative"],i=new Uint16Array(new Uint8Array(t["NS.mantissa"]).buffer),o=0;for(let t=0;t>8|(255&e)<<8),o+=e*Math.pow(65536,t)}return o*=Math.pow(10,r),s?-o:o}case"NSData":case"NSMutableData":return t["NS.bytes"]||t["NS.data"];case"NSString":case"NSMutableString":return t["NS.string"]?t["NS.string"]:t["NS.bytes"]?v(t["NS.bytes"]):(console.warn(`Unexpected ${n} format: `,t),null);case"NSArray":case"NSMutableArray":if("NS.objects"in t)return t["NS.objects"];let e=[];for(;;){let r="NS.object."+e.length;if(!(r in t))break;e.push(t[r])}return e;case"_NSKeyedCoderOldStyleArray":{const e=t["NS.count"];let r=[];for(let n=0;n>4){case 0:return this.parseSingleton(e,r);case 1:return this.parseInteger(e,1<(r.push({stack:t.split(";").map(e=>({key:e,name:e})),duration:parseInt(i,10)}),e)),r}function t(t){const i=r(t),n=i.reduce((e,r)=>e+r.duration,0),o=new e.StackListProfileBuilder(n);if(0===i.length)return null;for(let e of i)o.appendSampleWithWeight(e.stack,e.duration);return o.build()} +},{"../lib/profile":139}],150:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.importFromFirefox=l;var e=require("../lib/profile"),t=require("../lib/utils"),r=require("../lib/value-formatters");function l(l){const n=l.profile,s=1===n.threads.length?n.threads[0]:n.threads.filter(e=>"GeckoMain"===e.name)[0],a=new Map;function o(e){let r=e[0];const l=[];for(;null!=r;){const e=s.stackTable.data[r],[t,n]=e;l.push(n),r=t}return l.reverse(),l.map(e=>{const r=s.frameTable.data[e],l=s.stringTable[r[0]],n=/(.*)\s+\((.*?):?(\d+)?\)$/.exec(l);return n?n[2].startsWith("resource:")||"self-hosted"===n[2]||n[2].startsWith("self-hosted:")?null:(0,t.getOrInsert)(a,l,()=>({key:l,name:n[1],file:n[2],line:n[3]?parseInt(n[3]):void 0})):null}).filter(e=>null!=e)}const i=new e.CallTreeProfileBuilder(l.duration);let u=[];for(let e of s.samples.data){const t=o(e),r=e[1];let l=-1;for(let e=0;el;e--)i.leaveFrame(u[e],r);for(let e=l+1;e0?e[1]:"(anonymous)",file:e[2].length>0?e[2]:"(unknown file)",line:parseInt(e[3],10),col:parseInt(e[4],10)};break}case"CODE":switch(e.kind){case"LoadIC":case"StoreIC":case"KeyedStoreIC":case"KeyedLoadIC":case"LoadGlobalIC":case"Handler":r="(IC) "+r;break;case"BytecodeHandler":r="(bytecode) ~"+r;break;case"Stub":r="(stub) "+r;break;case"Builtin":r="(builtin) "+r;break;case"RegExp":r="(regexp) "+r}break;default:r=`(${e.type}) ${r}`}return{key:r,name:r}}function n(n){const s=new e.StackListProfileBuilder,o=new Map;let c=0;(0,t.sortBy)(n.ticks,e=>e.tm);for(let e of n.ticks){const r=[];for(let s=e.s.length-2;s>=0;s-=2){const c=e.s[s];-1!==c&&(c>n.code.length?r.push({key:c,name:`0x${c.toString(16)}`}):r.push((i=c,(0,t.getOrInsert)(o,i,e=>a(n.code[e],n)))))}s.appendSampleWithWeight(r,e.tm-c),c=e.tm}var i;return s.setValueFormatter(new r.TimeFormatter("microseconds")),s.build()} +},{"../lib/profile":139,"../lib/utils":70,"../lib/value-formatters":140}],152:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.importFromLinuxPerf=r;var e=require("../lib/profile"),t=require("../lib/utils"),n=require("../lib/value-formatters");function s(e){const t=e.split("\n").filter(e=>!/^\s*#/.exec(e)),n={command:null,processID:null,threadID:null,time:null,eventType:"",stack:[]},s=t.shift();if(!s)return null;const r=/^(\S.+?)\s+(\d+)(?:\/?(\d+))?\s+/.exec(s);if(!r)return null;n.command=r[1],r[3]?(n.processID=parseInt(r[2],10),n.threadID=parseInt(r[3],10)):n.threadID=parseInt(r[2],10);const l=/\s+(\d+\.\d+):\s+/.exec(s);l&&(n.time=parseFloat(l[1]));const i=/(\S+):\s*$/.exec(s);i&&(n.eventType=i[1]);for(let e of t){const t=/^\s*(\w+)\s*(.+) \((\S*)\)/.exec(e);if(!t)continue;let[,s,r,l]=t;r=r.replace(/\+0x[\da-f]+$/,""),n.stack.push({address:`0x${s}`,symbolName:r,file:l})}return n.stack.reverse(),n}function r(r){const l=new Map;let i=null;const o=r.split("\n\n").map(s);for(let s of o){if(null==s)continue;if(null!=i&&i!=s.eventType)continue;if(null==s.time)continue;i=s.eventType;let r=[];s.command&&r.push(s.command),s.processID&&r.push(`pid: ${s.processID}`),s.threadID&&r.push(`tid: ${s.threadID}`);const o=r.join(" ");(0,t.getOrInsert)(l,o,()=>{const t=new e.StackListProfileBuilder;return t.setName(o),t.setValueFormatter(new n.TimeFormatter("seconds")),t}).appendSampleWithTimestamp(s.stack.map(({symbolName:e,file:t})=>({key:`${e} (${t})`,name:"[unknown]"===e?`??? (${t})`:e,file:t})),s.time)}return 0===l.size?null:{name:1===l.size?Array.from(l.keys())[0]:"",indexToView:0,profiles:Array.from((0,t.itMap)(l.values(),e=>e.build()))}} +},{"../lib/profile":139,"../lib/utils":70,"../lib/value-formatters":140}],153:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.importFromHaskell=l;var e=require("../lib/profile"),r=require("../lib/value-formatters");function t(e,r,l,o,i){if(0===e.ticks&&0===e.entries&&0===e.alloc&&0===e.children.length)return r;let a=r,s=o.get(e.id);l.enterFrame(s,a);for(let r of e.children)a=t(r,a,l,o,i);return a+=i(e),l.leaveFrame(s,a),a}function l(l){const o=new Map;for(let e of l.cost_centres){const r={key:e.id,name:`${e.module}.${e.label}`};e.src_loc.startsWith("<")||(r.file=e.src_loc),o.set(e.id,r)}const i=new e.CallTreeProfileBuilder(l.total_ticks);t(l.profile,0,i,o,e=>e.ticks),i.setValueFormatter(new r.TimeFormatter("milliseconds")),i.setName(`${l.program} time`);const a=new e.CallTreeProfileBuilder(l.total_ticks);return t(l.profile,0,a,o,e=>e.alloc),a.setValueFormatter(new r.ByteFormatter),a.setName(`${l.program} allocation`),{name:l.program,indexToView:0,profiles:[i.build(),a.build()]}} +},{"../lib/profile":139,"../lib/value-formatters":140}],206:[function(require,module,exports) { +"use strict";function n(n,e){for(var r=new Array(arguments.length-1),t=0,l=2,o=!0;l1&&"="===r.charAt(e);)++a;return Math.ceil(3*r.length)/4-a};for(var e=new Array(64),a=new Array(123),t=0;t<64;)a[e[t]=t<26?t+65:t<52?t+71:t<62?t-4:t-59|43]=t++;r.encode=function(r,a,t){for(var n,i=null,o=[],c=0,s=0;a>2],n=(3&h)<<4,s=1;break;case 1:o[c++]=e[n|h>>4],n=(15&h)<<2,s=2;break;case 2:o[c++]=e[n|h>>6],o[c++]=e[63&h],s=0}c>8191&&((i||(i=[])).push(String.fromCharCode.apply(String,o)),c=0)}return s&&(o[c++]=e[n],o[c++]=61,1===s&&(o[c++]=61)),i?(c&&i.push(String.fromCharCode.apply(String,o.slice(0,c))),i.join("")):String.fromCharCode.apply(String,o.slice(0,c))};var n="invalid encoding";r.decode=function(r,e,t){for(var i,o=t,c=0,s=0;s1)break;if(void 0===(h=a[h]))throw Error(n);switch(c){case 0:i=h,c=1;break;case 1:e[t++]=i<<2|(48&h)>>4,i=h,c=2;break;case 2:e[t++]=(15&i)<<4|(60&h)>>2,i=h,c=3;break;case 3:e[t++]=(3&i)<<6|h,c=0}}if(1===c)throw Error(n);return t-o},r.test=function(r){return/^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/.test(r)}; +},{}],207:[function(require,module,exports) { +"use strict";function t(){this._listeners={}}module.exports=t,t.prototype.on=function(t,s,e){return(this._listeners[t]||(this._listeners[t]=[])).push({fn:s,ctx:e||this}),this},t.prototype.off=function(t,s){if(void 0===t)this._listeners={};else if(void 0===s)this._listeners[t]=[];else for(var e=this._listeners[t],i=0;i0?0:2147483648,t,r);else if(isNaN(e))n(2143289344,t,r);else if(e>3.4028234663852886e38)n((o<<31|2139095040)>>>0,t,r);else if(e<1.1754943508222875e-38)n((o<<31|Math.round(e/1.401298464324817e-45))>>>0,t,r);else{var u=Math.floor(Math.log(e)/Math.LN2);n((o<<31|u+127<<23|8388607&Math.round(e*Math.pow(2,-u)*8388608))>>>0,t,r)}}function i(n,e,t){var r=n(e,t),o=2*(r>>31)+1,u=r>>>23&255,i=8388607&r;return 255===u?i?NaN:o*(1/0):0===u?1.401298464324817e-45*o*i:o*Math.pow(2,u-150)*(i+8388608)}n.writeFloatLE=u.bind(null,e),n.writeFloatBE=u.bind(null,t),n.readFloatLE=i.bind(null,r),n.readFloatBE=i.bind(null,o)}(),"undefined"!=typeof Float64Array?function(){var e=new Float64Array([-0]),t=new Uint8Array(e.buffer),r=128===t[7];function o(n,r,o){e[0]=n,r[o]=t[0],r[o+1]=t[1],r[o+2]=t[2],r[o+3]=t[3],r[o+4]=t[4],r[o+5]=t[5],r[o+6]=t[6],r[o+7]=t[7]}function u(n,r,o){e[0]=n,r[o]=t[7],r[o+1]=t[6],r[o+2]=t[5],r[o+3]=t[4],r[o+4]=t[3],r[o+5]=t[2],r[o+6]=t[1],r[o+7]=t[0]}function i(n,r){return t[0]=n[r],t[1]=n[r+1],t[2]=n[r+2],t[3]=n[r+3],t[4]=n[r+4],t[5]=n[r+5],t[6]=n[r+6],t[7]=n[r+7],e[0]}function a(n,r){return t[7]=n[r],t[6]=n[r+1],t[5]=n[r+2],t[4]=n[r+3],t[3]=n[r+4],t[2]=n[r+5],t[1]=n[r+6],t[0]=n[r+7],e[0]}n.writeDoubleLE=r?o:u,n.writeDoubleBE=r?u:o,n.readDoubleLE=r?i:a,n.readDoubleBE=r?a:i}():function(){function u(n,e,t,r,o,u){var i=r<0?1:0;if(i&&(r=-r),0===r)n(0,o,u+e),n(1/r>0?0:2147483648,o,u+t);else if(isNaN(r))n(0,o,u+e),n(2146959360,o,u+t);else if(r>1.7976931348623157e308)n(0,o,u+e),n((i<<31|2146435072)>>>0,o,u+t);else{var a;if(r<2.2250738585072014e-308)n((a=r/5e-324)>>>0,o,u+e),n((i<<31|a/4294967296)>>>0,o,u+t);else{var l=Math.floor(Math.log(r)/Math.LN2);1024===l&&(l=1023),n(4503599627370496*(a=r*Math.pow(2,-l))>>>0,o,u+e),n((i<<31|l+1023<<20|1048576*a&1048575)>>>0,o,u+t)}}}function i(n,e,t,r,o){var u=n(r,o+e),i=n(r,o+t),a=2*(i>>31)+1,l=i>>>20&2047,f=4294967296*(1048575&i)+u;return 2047===l?f?NaN:a*(1/0):0===l?5e-324*a*f:a*Math.pow(2,l-1075)*(f+4503599627370496)}n.writeDoubleLE=u.bind(null,e,0,4),n.writeDoubleBE=u.bind(null,t,4,0),n.readDoubleLE=i.bind(null,r,0,4),n.readDoubleBE=i.bind(null,o,4,0)}(),n}function e(n,e,t){e[t]=255&n,e[t+1]=n>>>8&255,e[t+2]=n>>>16&255,e[t+3]=n>>>24}function t(n,e,t){e[t]=n>>>24,e[t+1]=n>>>16&255,e[t+2]=n>>>8&255,e[t+3]=255&n}function r(n,e){return(n[e]|n[e+1]<<8|n[e+2]<<16|n[e+3]<<24)>>>0}function o(n,e){return(n[e]<<24|n[e+1]<<16|n[e+2]<<8|n[e+3])>>>0}module.exports=n(n); +},{}],209:[function(require,module,exports) { +"use strict";function inquire(moduleName){try{var mod=eval("quire".replace(/^/,"re"))(moduleName);if(mod&&(mod.length||Object.keys(mod).length))return mod}catch(e){}return null}module.exports=inquire; +},{}],210:[function(require,module,exports) { +"use strict";var r=exports;r.length=function(r){for(var t=0,n=0,e=0;e191&&e<224?a[i++]=(31&e)<<6|63&r[t++]:e>239&&e<365?(e=((7&e)<<18|(63&r[t++])<<12|(63&r[t++])<<6|63&r[t++])-65536,a[i++]=55296+(e>>10),a[i++]=56320+(1023&e)):a[i++]=(15&e)<<12|(63&r[t++])<<6|63&r[t++],i>8191&&((o||(o=[])).push(String.fromCharCode.apply(String,a)),i=0);return o?(i&&o.push(String.fromCharCode.apply(String,a.slice(0,i))),o.join("")):String.fromCharCode.apply(String,a.slice(0,i))},r.write=function(r,t,n){for(var e,o,a=n,i=0;i>6|192,t[n++]=63&e|128):55296==(64512&e)&&56320==(64512&(o=r.charCodeAt(i+1)))?(e=65536+((1023&e)<<10)+(1023&o),++i,t[n++]=e>>18|240,t[n++]=e>>12&63|128,t[n++]=e>>6&63|128,t[n++]=63&e|128):(t[n++]=e>>12|224,t[n++]=e>>6&63|128,t[n++]=63&e|128);return n-a}; +},{}],211:[function(require,module,exports) { +"use strict";function r(r,n,t){var u=t||8192,e=u>>>1,l=null,c=u;return function(t){if(t<1||t>e)return r(t);c+t>u&&(l=r(u),c=0);var i=n.call(l,c,c+=t);return 7&c&&(c=1+(7|c)),i}}module.exports=r; +},{}],203:[function(require,module,exports) { +"use strict";module.exports=i;var t=require("../util/minimal");function i(t,i){this.lo=t>>>0,this.hi=i>>>0}var o=i.zero=new i(0,0);o.toNumber=function(){return 0},o.zzEncode=o.zzDecode=function(){return this},o.length=function(){return 1};var r=i.zeroHash="\0\0\0\0\0\0\0\0";i.fromNumber=function(t){if(0===t)return o;var r=t<0;r&&(t=-t);var h=t>>>0,n=(t-h)/4294967296>>>0;return r&&(n=~n>>>0,h=~h>>>0,++h>4294967295&&(h=0,++n>4294967295&&(n=0))),new i(h,n)},i.from=function(r){if("number"==typeof r)return i.fromNumber(r);if(t.isString(r)){if(!t.Long)return i.fromNumber(parseInt(r,10));r=t.Long.fromString(r)}return r.low||r.high?new i(r.low>>>0,r.high>>>0):o},i.prototype.toNumber=function(t){if(!t&&this.hi>>>31){var i=1+~this.lo>>>0,o=~this.hi>>>0;return i||(o=o+1>>>0),-(i+4294967296*o)}return this.lo+4294967296*this.hi},i.prototype.toLong=function(i){return t.Long?new t.Long(0|this.lo,0|this.hi,Boolean(i)):{low:0|this.lo,high:0|this.hi,unsigned:Boolean(i)}};var h=String.prototype.charCodeAt;i.fromHash=function(t){return t===r?o:new i((h.call(t,0)|h.call(t,1)<<8|h.call(t,2)<<16|h.call(t,3)<<24)>>>0,(h.call(t,4)|h.call(t,5)<<8|h.call(t,6)<<16|h.call(t,7)<<24)>>>0)},i.prototype.toHash=function(){return String.fromCharCode(255&this.lo,this.lo>>>8&255,this.lo>>>16&255,this.lo>>>24,255&this.hi,this.hi>>>8&255,this.hi>>>16&255,this.hi>>>24)},i.prototype.zzEncode=function(){var t=this.hi>>31;return this.hi=((this.hi<<1|this.lo>>>31)^t)>>>0,this.lo=(this.lo<<1^t)>>>0,this},i.prototype.zzDecode=function(){var t=-(1&this.lo);return this.lo=((this.lo>>>1|this.hi<<31)^t)>>>0,this.hi=(this.hi>>>1^t)>>>0,this},i.prototype.length=function(){var t=this.lo,i=(this.lo>>>28|this.hi<<4)>>>0,o=this.hi>>>24;return 0===o?0===i?t<16384?t<128?1:2:t<2097152?3:4:i<16384?i<128?5:6:i<2097152?7:8:o<128?9:10}; +},{"../util/minimal":201}],212:[function(require,module,exports) { +"use strict";exports.byteLength=u,exports.toByteArray=i,exports.fromByteArray=d;for(var r=[],t=[],e="undefined"!=typeof Uint8Array?Uint8Array:Array,n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",o=0,a=n.length;o0)throw new Error("Invalid string. Length must be a multiple of 4");var e=r.indexOf("=");return-1===e&&(e=t),[e,e===t?0:4-e%4]}function u(r){var t=h(r),e=t[0],n=t[1];return 3*(e+n)/4-n}function c(r,t,e){return 3*(t+e)/4-e}function i(r){for(var n,o=h(r),a=o[0],u=o[1],i=new e(c(r,a,u)),f=0,A=u>0?a-4:a,d=0;d>16&255,i[f++]=n>>8&255,i[f++]=255&n;return 2===u&&(n=t[r.charCodeAt(d)]<<2|t[r.charCodeAt(d+1)]>>4,i[f++]=255&n),1===u&&(n=t[r.charCodeAt(d)]<<10|t[r.charCodeAt(d+1)]<<4|t[r.charCodeAt(d+2)]>>2,i[f++]=n>>8&255,i[f++]=255&n),i}function f(t){return r[t>>18&63]+r[t>>12&63]+r[t>>6&63]+r[63&t]}function A(r,t,e){for(var n,o=[],a=t;au?u:h+16383));return 1===o?(e=t[n-1],a.push(r[e>>2]+r[e<<4&63]+"==")):2===o&&(e=(t[n-2]<<8)+t[n-1],a.push(r[e>>10]+r[e>>4&63]+r[e<<2&63]+"=")),a.join("")}t["-".charCodeAt(0)]=62,t["_".charCodeAt(0)]=63; +},{}],213:[function(require,module,exports) { +exports.read=function(a,o,t,r,h){var M,p,w=8*h-r-1,f=(1<>1,i=-7,N=t?h-1:0,n=t?-1:1,s=a[o+N];for(N+=n,M=s&(1<<-i)-1,s>>=-i,i+=w;i>0;M=256*M+a[o+N],N+=n,i-=8);for(p=M&(1<<-i)-1,M>>=-i,i+=r;i>0;p=256*p+a[o+N],N+=n,i-=8);if(0===M)M=1-e;else{if(M===f)return p?NaN:1/0*(s?-1:1);p+=Math.pow(2,r),M-=e}return(s?-1:1)*p*Math.pow(2,M-r)},exports.write=function(a,o,t,r,h,M){var p,w,f,e=8*M-h-1,i=(1<>1,n=23===h?Math.pow(2,-24)-Math.pow(2,-77):0,s=r?0:M-1,u=r?1:-1,l=o<0||0===o&&1/o<0?1:0;for(o=Math.abs(o),isNaN(o)||o===1/0?(w=isNaN(o)?1:0,p=i):(p=Math.floor(Math.log(o)/Math.LN2),o*(f=Math.pow(2,-p))<1&&(p--,f*=2),(o+=p+N>=1?n/f:n*Math.pow(2,1-N))*f>=2&&(p++,f/=2),p+N>=i?(w=0,p=i):p+N>=1?(w=(o*f-1)*Math.pow(2,h),p+=N):(w=o*Math.pow(2,N-1)*Math.pow(2,h),p=0));h>=8;a[t+s]=255&w,s+=u,w/=256,h-=8);for(p=p<0;a[t+s]=255&p,s+=u,p/=256,e-=8);a[t+s-u]|=128*l}; +},{}],214:[function(require,module,exports) { +var r={}.toString;module.exports=Array.isArray||function(t){return"[object Array]"==r.call(t)}; +},{}],204:[function(require,module,exports) { + +var global = arguments[3]; +var t=arguments[3],r=require("base64-js"),e=require("ieee754"),n=require("isarray");function i(){try{var t=new Uint8Array(1);return t.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}},42===t.foo()&&"function"==typeof t.subarray&&0===t.subarray(1,1).byteLength}catch(t){return!1}}function o(){return f.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function u(t,r){if(o()=o())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+o().toString(16)+" bytes");return 0|t}function d(t){return+t!=t&&(t=0),f.alloc(+t)}function v(t,r){if(f.isBuffer(t))return t.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!=typeof t&&(t=""+t);var e=t.length;if(0===e)return 0;for(var n=!1;;)switch(r){case"ascii":case"latin1":case"binary":return e;case"utf8":case"utf-8":case void 0:return $(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*e;case"hex":return e>>>1;case"base64":return K(t).length;default:if(n)return $(t).length;r=(""+r).toLowerCase(),n=!0}}function E(t,r,e){var n=!1;if((void 0===r||r<0)&&(r=0),r>this.length)return"";if((void 0===e||e>this.length)&&(e=this.length),e<=0)return"";if((e>>>=0)<=(r>>>=0))return"";for(t||(t="utf8");;)switch(t){case"hex":return x(this,r,e);case"utf8":case"utf-8":return Y(this,r,e);case"ascii":return L(this,r,e);case"latin1":case"binary":return D(this,r,e);case"base64":return S(this,r,e);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return C(this,r,e);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}function b(t,r,e){var n=t[r];t[r]=t[e],t[e]=n}function R(t,r,e,n,i){if(0===t.length)return-1;if("string"==typeof e?(n=e,e=0):e>2147483647?e=2147483647:e<-2147483648&&(e=-2147483648),e=+e,isNaN(e)&&(e=i?0:t.length-1),e<0&&(e=t.length+e),e>=t.length){if(i)return-1;e=t.length-1}else if(e<0){if(!i)return-1;e=0}if("string"==typeof r&&(r=f.from(r,n)),f.isBuffer(r))return 0===r.length?-1:_(t,r,e,n,i);if("number"==typeof r)return r&=255,f.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(t,r,e):Uint8Array.prototype.lastIndexOf.call(t,r,e):_(t,[r],e,n,i);throw new TypeError("val must be string, number or Buffer")}function _(t,r,e,n,i){var o,u=1,f=t.length,s=r.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(t.length<2||r.length<2)return-1;u=2,f/=2,s/=2,e/=2}function h(t,r){return 1===u?t[r]:t.readUInt16BE(r*u)}if(i){var a=-1;for(o=e;of&&(e=f-s),o=e;o>=0;o--){for(var c=!0,l=0;li&&(n=i):n=i;var o=r.length;if(o%2!=0)throw new TypeError("Invalid hex string");n>o/2&&(n=o/2);for(var u=0;u239?4:h>223?3:h>191?2:1;if(i+c<=e)switch(c){case 1:h<128&&(a=h);break;case 2:128==(192&(o=t[i+1]))&&(s=(31&h)<<6|63&o)>127&&(a=s);break;case 3:o=t[i+1],u=t[i+2],128==(192&o)&&128==(192&u)&&(s=(15&h)<<12|(63&o)<<6|63&u)>2047&&(s<55296||s>57343)&&(a=s);break;case 4:o=t[i+1],u=t[i+2],f=t[i+3],128==(192&o)&&128==(192&u)&&128==(192&f)&&(s=(15&h)<<18|(63&o)<<12|(63&u)<<6|63&f)>65535&&s<1114112&&(a=s)}null===a?(a=65533,c=1):a>65535&&(a-=65536,n.push(a>>>10&1023|55296),a=56320|1023&a),n.push(a),i+=c}return O(n)}exports.Buffer=f,exports.SlowBuffer=d,exports.INSPECT_MAX_BYTES=50,f.TYPED_ARRAY_SUPPORT=void 0!==t.TYPED_ARRAY_SUPPORT?t.TYPED_ARRAY_SUPPORT:i(),exports.kMaxLength=o(),f.poolSize=8192,f._augment=function(t){return t.__proto__=f.prototype,t},f.from=function(t,r,e){return s(null,t,r,e)},f.TYPED_ARRAY_SUPPORT&&(f.prototype.__proto__=Uint8Array.prototype,f.__proto__=Uint8Array,"undefined"!=typeof Symbol&&Symbol.species&&f[Symbol.species]===f&&Object.defineProperty(f,Symbol.species,{value:null,configurable:!0})),f.alloc=function(t,r,e){return a(null,t,r,e)},f.allocUnsafe=function(t){return c(null,t)},f.allocUnsafeSlow=function(t){return c(null,t)},f.isBuffer=function(t){return!(null==t||!t._isBuffer)},f.compare=function(t,r){if(!f.isBuffer(t)||!f.isBuffer(r))throw new TypeError("Arguments must be Buffers");if(t===r)return 0;for(var e=t.length,n=r.length,i=0,o=Math.min(e,n);i0&&(t=this.toString("hex",0,r).match(/.{2}/g).join(" "),this.length>r&&(t+=" ... ")),""},f.prototype.compare=function(t,r,e,n,i){if(!f.isBuffer(t))throw new TypeError("Argument must be a Buffer");if(void 0===r&&(r=0),void 0===e&&(e=t?t.length:0),void 0===n&&(n=0),void 0===i&&(i=this.length),r<0||e>t.length||n<0||i>this.length)throw new RangeError("out of range index");if(n>=i&&r>=e)return 0;if(n>=i)return-1;if(r>=e)return 1;if(this===t)return 0;for(var o=(i>>>=0)-(n>>>=0),u=(e>>>=0)-(r>>>=0),s=Math.min(o,u),h=this.slice(n,i),a=t.slice(r,e),c=0;ci)&&(e=i),t.length>0&&(e<0||r<0)||r>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var o=!1;;)switch(n){case"hex":return A(this,t,r,e);case"utf8":case"utf-8":return m(this,t,r,e);case"ascii":return P(this,t,r,e);case"latin1":case"binary":return T(this,t,r,e);case"base64":return B(this,t,r,e);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return U(this,t,r,e);default:if(o)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),o=!0}},f.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var I=4096;function O(t){var r=t.length;if(r<=I)return String.fromCharCode.apply(String,t);for(var e="",n=0;nn)&&(e=n);for(var i="",o=r;oe)throw new RangeError("Trying to access beyond buffer length")}function k(t,r,e,n,i,o){if(!f.isBuffer(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(r>i||rt.length)throw new RangeError("Index out of range")}function N(t,r,e,n){r<0&&(r=65535+r+1);for(var i=0,o=Math.min(t.length-e,2);i>>8*(n?i:1-i)}function z(t,r,e,n){r<0&&(r=4294967295+r+1);for(var i=0,o=Math.min(t.length-e,4);i>>8*(n?i:3-i)&255}function F(t,r,e,n,i,o){if(e+n>t.length)throw new RangeError("Index out of range");if(e<0)throw new RangeError("Index out of range")}function j(t,r,n,i,o){return o||F(t,r,n,4,3.4028234663852886e38,-3.4028234663852886e38),e.write(t,r,n,i,23,4),n+4}function q(t,r,n,i,o){return o||F(t,r,n,8,1.7976931348623157e308,-1.7976931348623157e308),e.write(t,r,n,i,52,8),n+8}f.prototype.slice=function(t,r){var e,n=this.length;if((t=~~t)<0?(t+=n)<0&&(t=0):t>n&&(t=n),(r=void 0===r?n:~~r)<0?(r+=n)<0&&(r=0):r>n&&(r=n),r0&&(i*=256);)n+=this[t+--r]*i;return n},f.prototype.readUInt8=function(t,r){return r||M(t,1,this.length),this[t]},f.prototype.readUInt16LE=function(t,r){return r||M(t,2,this.length),this[t]|this[t+1]<<8},f.prototype.readUInt16BE=function(t,r){return r||M(t,2,this.length),this[t]<<8|this[t+1]},f.prototype.readUInt32LE=function(t,r){return r||M(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},f.prototype.readUInt32BE=function(t,r){return r||M(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},f.prototype.readIntLE=function(t,r,e){t|=0,r|=0,e||M(t,r,this.length);for(var n=this[t],i=1,o=0;++o=(i*=128)&&(n-=Math.pow(2,8*r)),n},f.prototype.readIntBE=function(t,r,e){t|=0,r|=0,e||M(t,r,this.length);for(var n=r,i=1,o=this[t+--n];n>0&&(i*=256);)o+=this[t+--n]*i;return o>=(i*=128)&&(o-=Math.pow(2,8*r)),o},f.prototype.readInt8=function(t,r){return r||M(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},f.prototype.readInt16LE=function(t,r){r||M(t,2,this.length);var e=this[t]|this[t+1]<<8;return 32768&e?4294901760|e:e},f.prototype.readInt16BE=function(t,r){r||M(t,2,this.length);var e=this[t+1]|this[t]<<8;return 32768&e?4294901760|e:e},f.prototype.readInt32LE=function(t,r){return r||M(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},f.prototype.readInt32BE=function(t,r){return r||M(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},f.prototype.readFloatLE=function(t,r){return r||M(t,4,this.length),e.read(this,t,!0,23,4)},f.prototype.readFloatBE=function(t,r){return r||M(t,4,this.length),e.read(this,t,!1,23,4)},f.prototype.readDoubleLE=function(t,r){return r||M(t,8,this.length),e.read(this,t,!0,52,8)},f.prototype.readDoubleBE=function(t,r){return r||M(t,8,this.length),e.read(this,t,!1,52,8)},f.prototype.writeUIntLE=function(t,r,e,n){(t=+t,r|=0,e|=0,n)||k(this,t,r,e,Math.pow(2,8*e)-1,0);var i=1,o=0;for(this[r]=255&t;++o=0&&(o*=256);)this[r+i]=t/o&255;return r+e},f.prototype.writeUInt8=function(t,r,e){return t=+t,r|=0,e||k(this,t,r,1,255,0),f.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),this[r]=255&t,r+1},f.prototype.writeUInt16LE=function(t,r,e){return t=+t,r|=0,e||k(this,t,r,2,65535,0),f.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8):N(this,t,r,!0),r+2},f.prototype.writeUInt16BE=function(t,r,e){return t=+t,r|=0,e||k(this,t,r,2,65535,0),f.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):N(this,t,r,!1),r+2},f.prototype.writeUInt32LE=function(t,r,e){return t=+t,r|=0,e||k(this,t,r,4,4294967295,0),f.TYPED_ARRAY_SUPPORT?(this[r+3]=t>>>24,this[r+2]=t>>>16,this[r+1]=t>>>8,this[r]=255&t):z(this,t,r,!0),r+4},f.prototype.writeUInt32BE=function(t,r,e){return t=+t,r|=0,e||k(this,t,r,4,4294967295,0),f.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):z(this,t,r,!1),r+4},f.prototype.writeIntLE=function(t,r,e,n){if(t=+t,r|=0,!n){var i=Math.pow(2,8*e-1);k(this,t,r,e,i-1,-i)}var o=0,u=1,f=0;for(this[r]=255&t;++o>0)-f&255;return r+e},f.prototype.writeIntBE=function(t,r,e,n){if(t=+t,r|=0,!n){var i=Math.pow(2,8*e-1);k(this,t,r,e,i-1,-i)}var o=e-1,u=1,f=0;for(this[r+o]=255&t;--o>=0&&(u*=256);)t<0&&0===f&&0!==this[r+o+1]&&(f=1),this[r+o]=(t/u>>0)-f&255;return r+e},f.prototype.writeInt8=function(t,r,e){return t=+t,r|=0,e||k(this,t,r,1,127,-128),f.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[r]=255&t,r+1},f.prototype.writeInt16LE=function(t,r,e){return t=+t,r|=0,e||k(this,t,r,2,32767,-32768),f.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8):N(this,t,r,!0),r+2},f.prototype.writeInt16BE=function(t,r,e){return t=+t,r|=0,e||k(this,t,r,2,32767,-32768),f.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):N(this,t,r,!1),r+2},f.prototype.writeInt32LE=function(t,r,e){return t=+t,r|=0,e||k(this,t,r,4,2147483647,-2147483648),f.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8,this[r+2]=t>>>16,this[r+3]=t>>>24):z(this,t,r,!0),r+4},f.prototype.writeInt32BE=function(t,r,e){return t=+t,r|=0,e||k(this,t,r,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),f.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):z(this,t,r,!1),r+4},f.prototype.writeFloatLE=function(t,r,e){return j(this,t,r,!0,e)},f.prototype.writeFloatBE=function(t,r,e){return j(this,t,r,!1,e)},f.prototype.writeDoubleLE=function(t,r,e){return q(this,t,r,!0,e)},f.prototype.writeDoubleBE=function(t,r,e){return q(this,t,r,!1,e)},f.prototype.copy=function(t,r,e,n){if(e||(e=0),n||0===n||(n=this.length),r>=t.length&&(r=t.length),r||(r=0),n>0&&n=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),t.length-r=0;--i)t[i+r]=this[i+e];else if(o<1e3||!f.TYPED_ARRAY_SUPPORT)for(i=0;i>>=0,e=void 0===e?this.length:e>>>0,t||(t=0),"number"==typeof t)for(o=r;o55295&&e<57344){if(!i){if(e>56319){(r-=3)>-1&&o.push(239,191,189);continue}if(u+1===n){(r-=3)>-1&&o.push(239,191,189);continue}i=e;continue}if(e<56320){(r-=3)>-1&&o.push(239,191,189),i=e;continue}e=65536+(i-55296<<10|e-56320)}else i&&(r-=3)>-1&&o.push(239,191,189);if(i=null,e<128){if((r-=1)<0)break;o.push(e)}else if(e<2048){if((r-=2)<0)break;o.push(e>>6|192,63&e|128)}else if(e<65536){if((r-=3)<0)break;o.push(e>>12|224,e>>6&63|128,63&e|128)}else{if(!(e<1114112))throw new Error("Invalid code point");if((r-=4)<0)break;o.push(e>>18|240,e>>12&63|128,e>>6&63|128,63&e|128)}}return o}function G(t){for(var r=[],e=0;e>8,i=e%256,o.push(i),o.push(n);return o}function K(t){return r.toByteArray(X(t))}function Q(t,r,e,n){for(var i=0;i=r.length||i>=t.length);++i)r[i+e]=t[i];return i}function W(t){return t!=t} +},{"base64-js":212,"ieee754":213,"isarray":214,"buffer":204}],201:[function(require,module,exports) { +var global = arguments[3]; +var Buffer = require("buffer").Buffer; +var e=arguments[3],r=require("buffer").Buffer,t=exports;function n(e,r,t){for(var n=Object.keys(r),o=0;o0)},t.Buffer=function(){try{var e=t.inquire("buffer").Buffer;return e.prototype.utf8Write?e:null}catch(e){return null}}(),t._Buffer_from=null,t._Buffer_allocUnsafe=null,t.newBuffer=function(e){return"number"==typeof e?t.Buffer?t._Buffer_allocUnsafe(e):new t.Array(e):t.Buffer?t._Buffer_from(e):"undefined"==typeof Uint8Array?e:new Uint8Array(e)},t.Array="undefined"!=typeof Uint8Array?Uint8Array:Array,t.Long=t.global.dcodeIO&&t.global.dcodeIO.Long||t.global.Long||t.inquire("long"),t.key2Re=/^true|false|0|1$/,t.key32Re=/^-?(?:0|[1-9][0-9]*)$/,t.key64Re=/^(?:[\\x00-\\xff]{8}|-?(?:0|[1-9][0-9]*))$/,t.longToHash=function(e){return e?t.LongBits.from(e).toHash():t.LongBits.zeroHash},t.longFromHash=function(e,r){var n=t.LongBits.fromHash(e);return t.Long?t.Long.fromBits(n.lo,n.hi,r):n.toNumber(Boolean(r))},t.merge=n,t.lcFirst=function(e){return e.charAt(0).toLowerCase()+e.substring(1)},t.newError=o,t.ProtocolError=o("ProtocolError"),t.oneOfGetter=function(e){for(var r={},t=0;t-1;--t)if(1===r[e[t]]&&void 0!==this[e[t]]&&null!==this[e[t]])return e[t]}},t.oneOfSetter=function(e){return function(r){for(var t=0;t127;)i[n++]=127&t|128,t>>>=7;i[n]=t}function a(t,i){this.len=t,this.next=void 0,this.val=i}function f(t,i,n){for(;t.hi;)i[n++]=127&t.lo|128,t.lo=(t.lo>>>7|t.hi<<25)>>>0,t.hi>>>=7;for(;t.lo>127;)i[n++]=127&t.lo|128,t.lo=t.lo>>>7;i[n++]=t.lo}function c(t,i,n){i[n]=255&t,i[n+1]=t>>>8&255,i[n+2]=t>>>16&255,i[n+3]=t>>>24}u.create=i.Buffer?function(){return(u.create=function(){return new t})()}:function(){return new u},u.alloc=function(t){return new i.Array(t)},i.Array!==Array&&(u.alloc=i.pool(u.alloc,i.Array.prototype.subarray)),u.prototype._push=function(t,i,n){return this.tail=this.tail.next=new r(t,i,n),this.len+=i,this},a.prototype=Object.create(r.prototype),a.prototype.fn=p,u.prototype.uint32=function(t){return this.len+=(this.tail=this.tail.next=new a((t>>>=0)<128?1:t<16384?2:t<2097152?3:t<268435456?4:5,t)).len,this},u.prototype.int32=function(t){return t<0?this._push(f,10,n.fromNumber(t)):this.uint32(t)},u.prototype.sint32=function(t){return this.uint32((t<<1^t>>31)>>>0)},u.prototype.uint64=function(t){var i=n.from(t);return this._push(f,i.length(),i)},u.prototype.int64=u.prototype.uint64,u.prototype.sint64=function(t){var i=n.from(t).zzEncode();return this._push(f,i.length(),i)},u.prototype.bool=function(t){return this._push(l,1,t?1:0)},u.prototype.fixed32=function(t){return this._push(c,4,t>>>0)},u.prototype.sfixed32=u.prototype.fixed32,u.prototype.fixed64=function(t){var i=n.from(t);return this._push(c,4,i.lo)._push(c,4,i.hi)},u.prototype.sfixed64=u.prototype.fixed64,u.prototype.float=function(t){return this._push(i.float.writeFloatLE,4,t)},u.prototype.double=function(t){return this._push(i.float.writeDoubleLE,8,t)};var y=i.Array.prototype.set?function(t,i,n){i.set(t,n)}:function(t,i,n){for(var e=0;e>>0;if(!n)return this._push(l,1,0);if(i.isString(t)){var o=u.alloc(n=e.length(t));e.decode(t,o,0),t=o}return this.uint32(n)._push(y,n,t)},u.prototype.string=function(t){var i=o.length(t);return i?this.uint32(i)._push(o.write,i,t):this._push(l,1,0)},u.prototype.fork=function(){return this.states=new h(this),this.head=this.tail=new r(s,0,0),this.len=0,this},u.prototype.reset=function(){return this.states?(this.head=this.states.head,this.tail=this.states.tail,this.len=this.states.len,this.states=this.states.next):(this.head=this.tail=new r(s,0,0),this.len=0),this},u.prototype.ldelim=function(){var t=this.head,i=this.tail,n=this.len;return this.reset().uint32(n),n&&(this.tail.next=t.next,this.tail=i,this.len+=n),this},u.prototype.finish=function(){for(var t=this.head.next,i=this.constructor.alloc(this.len),n=0;t;)t.fn(t.val,i,n),n+=t.len,t=t.next;return i},u._configure=function(i){t=i}; +},{"./util/minimal":201}],194:[function(require,module,exports) { + +"use strict";module.exports=n;var t=require("./writer");(n.prototype=Object.create(t.prototype)).constructor=n;var e=require("./util/minimal"),r=e.Buffer;function n(){t.call(this)}n.alloc=function(t){return(n.alloc=e._Buffer_allocUnsafe)(t)};var i=r&&r.prototype instanceof Uint8Array&&"set"===r.prototype.set.name?function(t,e,r){e.set(t,r)}:function(t,e,r){if(t.copy)t.copy(e,r,0,t.length);else for(var n=0;n>>0;return this.uint32(r),r&&this._push(i,r,t),this},n.prototype.string=function(t){var e=r.byteLength(t);return this.uint32(e),e&&this._push(o,e,t),this}; +},{"./writer":193,"./util/minimal":201}],195:[function(require,module,exports) { +"use strict";module.exports=h;var t,i=require("./util/minimal"),s=i.LongBits,r=i.utf8;function o(t,i){return RangeError("index out of range: "+t.pos+" + "+(i||1)+" > "+t.len)}function h(t){this.buf=t,this.pos=0,this.len=t.length}var n="undefined"!=typeof Uint8Array?function(t){if(t instanceof Uint8Array||Array.isArray(t))return new h(t);throw Error("illegal buffer")}:function(t){if(Array.isArray(t))return new h(t);throw Error("illegal buffer")};function e(){var t=new s(0,0),i=0;if(!(this.len-this.pos>4)){for(;i<3;++i){if(this.pos>=this.len)throw o(this);if(t.lo=(t.lo|(127&this.buf[this.pos])<<7*i)>>>0,this.buf[this.pos++]<128)return t}return t.lo=(t.lo|(127&this.buf[this.pos++])<<7*i)>>>0,t}for(;i<4;++i)if(t.lo=(t.lo|(127&this.buf[this.pos])<<7*i)>>>0,this.buf[this.pos++]<128)return t;if(t.lo=(t.lo|(127&this.buf[this.pos])<<28)>>>0,t.hi=(t.hi|(127&this.buf[this.pos])>>4)>>>0,this.buf[this.pos++]<128)return t;if(i=0,this.len-this.pos>4){for(;i<5;++i)if(t.hi=(t.hi|(127&this.buf[this.pos])<<7*i+3)>>>0,this.buf[this.pos++]<128)return t}else for(;i<5;++i){if(this.pos>=this.len)throw o(this);if(t.hi=(t.hi|(127&this.buf[this.pos])<<7*i+3)>>>0,this.buf[this.pos++]<128)return t}throw Error("invalid varint encoding")}function u(t,i){return(t[i-4]|t[i-3]<<8|t[i-2]<<16|t[i-1]<<24)>>>0}function f(){if(this.pos+8>this.len)throw o(this,8);return new s(u(this.buf,this.pos+=4),u(this.buf,this.pos+=4))}h.create=i.Buffer?function(s){return(h.create=function(s){return i.Buffer.isBuffer(s)?new t(s):n(s)})(s)}:n,h.prototype._slice=i.Array.prototype.subarray||i.Array.prototype.slice,h.prototype.uint32=function(){var t=4294967295;return function(){if(t=(127&this.buf[this.pos])>>>0,this.buf[this.pos++]<128)return t;if(t=(t|(127&this.buf[this.pos])<<7)>>>0,this.buf[this.pos++]<128)return t;if(t=(t|(127&this.buf[this.pos])<<14)>>>0,this.buf[this.pos++]<128)return t;if(t=(t|(127&this.buf[this.pos])<<21)>>>0,this.buf[this.pos++]<128)return t;if(t=(t|(15&this.buf[this.pos])<<28)>>>0,this.buf[this.pos++]<128)return t;if((this.pos+=5)>this.len)throw this.pos=this.len,o(this,10);return t}}(),h.prototype.int32=function(){return 0|this.uint32()},h.prototype.sint32=function(){var t=this.uint32();return t>>>1^-(1&t)|0},h.prototype.bool=function(){return 0!==this.uint32()},h.prototype.fixed32=function(){if(this.pos+4>this.len)throw o(this,4);return u(this.buf,this.pos+=4)},h.prototype.sfixed32=function(){if(this.pos+4>this.len)throw o(this,4);return 0|u(this.buf,this.pos+=4)},h.prototype.float=function(){if(this.pos+4>this.len)throw o(this,4);var t=i.float.readFloatLE(this.buf,this.pos);return this.pos+=4,t},h.prototype.double=function(){if(this.pos+8>this.len)throw o(this,4);var t=i.float.readDoubleLE(this.buf,this.pos);return this.pos+=8,t},h.prototype.bytes=function(){var t=this.uint32(),i=this.pos,s=this.pos+t;if(s>this.len)throw o(this,t);return this.pos+=t,Array.isArray(this.buf)?this.buf.slice(i,s):i===s?new this.buf.constructor(0):this._slice.call(this.buf,i,s)},h.prototype.string=function(){var t=this.bytes();return r.read(t,0,t.length)},h.prototype.skip=function(t){if("number"==typeof t){if(this.pos+t>this.len)throw o(this,t);this.pos+=t}else do{if(this.pos>=this.len)throw o(this)}while(128&this.buf[this.pos++]);return this},h.prototype.skipType=function(t){switch(t){case 0:this.skip();break;case 1:this.skip(8);break;case 2:this.skip(this.uint32());break;case 3:for(;4!=(t=7&this.uint32());)this.skipType(t);break;case 5:this.skip(4);break;default:throw Error("invalid wire type "+t+" at offset "+this.pos)}return this},h._configure=function(s){t=s;var r=i.Long?"toLong":"toNumber";i.merge(h.prototype,{int64:function(){return e.call(this)[r](!1)},uint64:function(){return e.call(this)[r](!0)},sint64:function(){return e.call(this).zzDecode()[r](!1)},fixed64:function(){return f.call(this)[r](!0)},sfixed64:function(){return f.call(this)[r](!1)}})}; +},{"./util/minimal":201}],196:[function(require,module,exports) { +"use strict";module.exports=r;var t=require("./reader");(r.prototype=Object.create(t.prototype)).constructor=r;var e=require("./util/minimal");function r(e){t.call(this,e)}e.Buffer&&(r.prototype._slice=e.Buffer.prototype.slice),r.prototype.string=function(){var t=this.uint32();return this.buf.utf8Slice(this.pos,this.pos=Math.min(this.pos+t,this.len))}; +},{"./reader":195,"./util/minimal":201}],202:[function(require,module,exports) { +"use strict";module.exports=t;var e=require("../util/minimal");function t(t,r,i){if("function"!=typeof t)throw TypeError("rpcImpl must be a function");e.EventEmitter.call(this),this.rpcImpl=t,this.requestDelimited=Boolean(r),this.responseDelimited=Boolean(i)}(t.prototype=Object.create(e.EventEmitter.prototype)).constructor=t,t.prototype.rpcCall=function t(r,i,n,o,l){if(!o)throw TypeError("request must be specified");var u=this;if(!l)return e.asPromise(t,u,r,i,n,o);if(u.rpcImpl)try{return u.rpcImpl(r,i[u.requestDelimited?"encodeDelimited":"encode"](o).finish(),function(e,t){if(e)return u.emit("error",e,r),l(e);if(null!==t){if(!(t instanceof n))try{t=n[u.responseDelimited?"decodeDelimited":"decode"](t)}catch(e){return u.emit("error",e,r),l(e)}return u.emit("data",t,r),l(null,t)}u.end(!0)})}catch(e){return u.emit("error",e,r),void setTimeout(function(){l(e)},0)}else setTimeout(function(){l(Error("already ended"))},0)},t.prototype.end=function(e){return this.rpcImpl&&(e||this.rpcImpl(null,null,null),this.rpcImpl=null,this.emit("end").off()),this}; +},{"../util/minimal":201}],197:[function(require,module,exports) { +"use strict";var e=exports;e.Service=require("./rpc/service"); +},{"./rpc/service":202}],198:[function(require,module,exports) { +"use strict";module.exports={}; +},{}],189:[function(require,module,exports) { +"use strict";var r=exports;function e(){r.Reader._configure(r.BufferReader),r.util._configure()}r.build="minimal",r.Writer=require("./writer"),r.BufferWriter=require("./writer_buffer"),r.Reader=require("./reader"),r.BufferReader=require("./reader_buffer"),r.util=require("./util/minimal"),r.rpc=require("./rpc"),r.roots=require("./roots"),r.configure=e,r.Writer._configure(r.BufferWriter),e(); +},{"./writer":193,"./writer_buffer":194,"./reader":195,"./reader_buffer":196,"./util/minimal":201,"./rpc":197,"./roots":198}],186:[function(require,module,exports) { +"use strict";module.exports=require("./src/index-minimal"); +},{"./src/index-minimal":189}],174:[function(require,module,exports) { +"use strict";var e=require("protobufjs/minimal"),n=e.Reader,t=e.Writer,o=e.util,r=e.roots.default||(e.roots.default={});r.perftools=function(){var i,l={};return l.profiles=((i={}).Profile=function(){function i(e){if(this.sampleType=[],this.sample=[],this.mapping=[],this.location=[],this.function=[],this.stringTable=[],this.comment=[],e)for(var n=Object.keys(e),t=0;t>>3){case 1:i.sampleType&&i.sampleType.length||(i.sampleType=[]),i.sampleType.push(r.perftools.profiles.ValueType.decode(e,e.uint32()));break;case 2:i.sample&&i.sample.length||(i.sample=[]),i.sample.push(r.perftools.profiles.Sample.decode(e,e.uint32()));break;case 3:i.mapping&&i.mapping.length||(i.mapping=[]),i.mapping.push(r.perftools.profiles.Mapping.decode(e,e.uint32()));break;case 4:i.location&&i.location.length||(i.location=[]),i.location.push(r.perftools.profiles.Location.decode(e,e.uint32()));break;case 5:i.function&&i.function.length||(i.function=[]),i.function.push(r.perftools.profiles.Function.decode(e,e.uint32()));break;case 6:i.stringTable&&i.stringTable.length||(i.stringTable=[]),i.stringTable.push(e.string());break;case 7:i.dropFrames=e.int64();break;case 8:i.keepFrames=e.int64();break;case 9:i.timeNanos=e.int64();break;case 10:i.durationNanos=e.int64();break;case 11:i.periodType=r.perftools.profiles.ValueType.decode(e,e.uint32());break;case 12:i.period=e.int64();break;case 13:if(i.comment&&i.comment.length||(i.comment=[]),2==(7&l))for(var s=e.uint32()+e.pos;e.pos>>0,e.dropFrames.high>>>0).toNumber())),null!=e.keepFrames&&(o.Long?(n.keepFrames=o.Long.fromValue(e.keepFrames)).unsigned=!1:"string"==typeof e.keepFrames?n.keepFrames=parseInt(e.keepFrames,10):"number"==typeof e.keepFrames?n.keepFrames=e.keepFrames:"object"==typeof e.keepFrames&&(n.keepFrames=new o.LongBits(e.keepFrames.low>>>0,e.keepFrames.high>>>0).toNumber())),null!=e.timeNanos&&(o.Long?(n.timeNanos=o.Long.fromValue(e.timeNanos)).unsigned=!1:"string"==typeof e.timeNanos?n.timeNanos=parseInt(e.timeNanos,10):"number"==typeof e.timeNanos?n.timeNanos=e.timeNanos:"object"==typeof e.timeNanos&&(n.timeNanos=new o.LongBits(e.timeNanos.low>>>0,e.timeNanos.high>>>0).toNumber())),null!=e.durationNanos&&(o.Long?(n.durationNanos=o.Long.fromValue(e.durationNanos)).unsigned=!1:"string"==typeof e.durationNanos?n.durationNanos=parseInt(e.durationNanos,10):"number"==typeof e.durationNanos?n.durationNanos=e.durationNanos:"object"==typeof e.durationNanos&&(n.durationNanos=new o.LongBits(e.durationNanos.low>>>0,e.durationNanos.high>>>0).toNumber())),null!=e.periodType){if("object"!=typeof e.periodType)throw TypeError(".perftools.profiles.Profile.periodType: object expected");n.periodType=r.perftools.profiles.ValueType.fromObject(e.periodType)}if(null!=e.period&&(o.Long?(n.period=o.Long.fromValue(e.period)).unsigned=!1:"string"==typeof e.period?n.period=parseInt(e.period,10):"number"==typeof e.period?n.period=e.period:"object"==typeof e.period&&(n.period=new o.LongBits(e.period.low>>>0,e.period.high>>>0).toNumber())),e.comment){if(!Array.isArray(e.comment))throw TypeError(".perftools.profiles.Profile.comment: array expected");for(n.comment=[],t=0;t>>0,e.comment[t].high>>>0).toNumber())}return null!=e.defaultSampleType&&(o.Long?(n.defaultSampleType=o.Long.fromValue(e.defaultSampleType)).unsigned=!1:"string"==typeof e.defaultSampleType?n.defaultSampleType=parseInt(e.defaultSampleType,10):"number"==typeof e.defaultSampleType?n.defaultSampleType=e.defaultSampleType:"object"==typeof e.defaultSampleType&&(n.defaultSampleType=new o.LongBits(e.defaultSampleType.low>>>0,e.defaultSampleType.high>>>0).toNumber())),n},i.toObject=function(e,n){n||(n={});var t={};if((n.arrays||n.defaults)&&(t.sampleType=[],t.sample=[],t.mapping=[],t.location=[],t.function=[],t.stringTable=[],t.comment=[]),n.defaults){if(o.Long){var i=new o.Long(0,0,!1);t.dropFrames=n.longs===String?i.toString():n.longs===Number?i.toNumber():i}else t.dropFrames=n.longs===String?"0":0;o.Long?(i=new o.Long(0,0,!1),t.keepFrames=n.longs===String?i.toString():n.longs===Number?i.toNumber():i):t.keepFrames=n.longs===String?"0":0,o.Long?(i=new o.Long(0,0,!1),t.timeNanos=n.longs===String?i.toString():n.longs===Number?i.toNumber():i):t.timeNanos=n.longs===String?"0":0,o.Long?(i=new o.Long(0,0,!1),t.durationNanos=n.longs===String?i.toString():n.longs===Number?i.toNumber():i):t.durationNanos=n.longs===String?"0":0,t.periodType=null,o.Long?(i=new o.Long(0,0,!1),t.period=n.longs===String?i.toString():n.longs===Number?i.toNumber():i):t.period=n.longs===String?"0":0,o.Long?(i=new o.Long(0,0,!1),t.defaultSampleType=n.longs===String?i.toString():n.longs===Number?i.toNumber():i):t.defaultSampleType=n.longs===String?"0":0}if(e.sampleType&&e.sampleType.length){t.sampleType=[];for(var l=0;l>>0,e.dropFrames.high>>>0).toNumber():e.dropFrames),null!=e.keepFrames&&e.hasOwnProperty("keepFrames")&&("number"==typeof e.keepFrames?t.keepFrames=n.longs===String?String(e.keepFrames):e.keepFrames:t.keepFrames=n.longs===String?o.Long.prototype.toString.call(e.keepFrames):n.longs===Number?new o.LongBits(e.keepFrames.low>>>0,e.keepFrames.high>>>0).toNumber():e.keepFrames),null!=e.timeNanos&&e.hasOwnProperty("timeNanos")&&("number"==typeof e.timeNanos?t.timeNanos=n.longs===String?String(e.timeNanos):e.timeNanos:t.timeNanos=n.longs===String?o.Long.prototype.toString.call(e.timeNanos):n.longs===Number?new o.LongBits(e.timeNanos.low>>>0,e.timeNanos.high>>>0).toNumber():e.timeNanos),null!=e.durationNanos&&e.hasOwnProperty("durationNanos")&&("number"==typeof e.durationNanos?t.durationNanos=n.longs===String?String(e.durationNanos):e.durationNanos:t.durationNanos=n.longs===String?o.Long.prototype.toString.call(e.durationNanos):n.longs===Number?new o.LongBits(e.durationNanos.low>>>0,e.durationNanos.high>>>0).toNumber():e.durationNanos),null!=e.periodType&&e.hasOwnProperty("periodType")&&(t.periodType=r.perftools.profiles.ValueType.toObject(e.periodType,n)),null!=e.period&&e.hasOwnProperty("period")&&("number"==typeof e.period?t.period=n.longs===String?String(e.period):e.period:t.period=n.longs===String?o.Long.prototype.toString.call(e.period):n.longs===Number?new o.LongBits(e.period.low>>>0,e.period.high>>>0).toNumber():e.period),e.comment&&e.comment.length)for(t.comment=[],l=0;l>>0,e.comment[l].high>>>0).toNumber():e.comment[l];return null!=e.defaultSampleType&&e.hasOwnProperty("defaultSampleType")&&("number"==typeof e.defaultSampleType?t.defaultSampleType=n.longs===String?String(e.defaultSampleType):e.defaultSampleType:t.defaultSampleType=n.longs===String?o.Long.prototype.toString.call(e.defaultSampleType):n.longs===Number?new o.LongBits(e.defaultSampleType.low>>>0,e.defaultSampleType.high>>>0).toNumber():e.defaultSampleType),t},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),i.ValueType=function(){function i(e){if(e)for(var n=Object.keys(e),t=0;t>>3){case 1:i.type=e.int64();break;case 2:i.unit=e.int64();break;default:e.skipType(7&l)}}return i},i.decodeDelimited=function(e){return e instanceof n||(e=new n(e)),this.decode(e,e.uint32())},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":null!=e.type&&e.hasOwnProperty("type")&&!(o.isInteger(e.type)||e.type&&o.isInteger(e.type.low)&&o.isInteger(e.type.high))?"type: integer|Long expected":null!=e.unit&&e.hasOwnProperty("unit")&&!(o.isInteger(e.unit)||e.unit&&o.isInteger(e.unit.low)&&o.isInteger(e.unit.high))?"unit: integer|Long expected":null},i.fromObject=function(e){if(e instanceof r.perftools.profiles.ValueType)return e;var n=new r.perftools.profiles.ValueType;return null!=e.type&&(o.Long?(n.type=o.Long.fromValue(e.type)).unsigned=!1:"string"==typeof e.type?n.type=parseInt(e.type,10):"number"==typeof e.type?n.type=e.type:"object"==typeof e.type&&(n.type=new o.LongBits(e.type.low>>>0,e.type.high>>>0).toNumber())),null!=e.unit&&(o.Long?(n.unit=o.Long.fromValue(e.unit)).unsigned=!1:"string"==typeof e.unit?n.unit=parseInt(e.unit,10):"number"==typeof e.unit?n.unit=e.unit:"object"==typeof e.unit&&(n.unit=new o.LongBits(e.unit.low>>>0,e.unit.high>>>0).toNumber())),n},i.toObject=function(e,n){n||(n={});var t={};if(n.defaults){if(o.Long){var r=new o.Long(0,0,!1);t.type=n.longs===String?r.toString():n.longs===Number?r.toNumber():r}else t.type=n.longs===String?"0":0;o.Long?(r=new o.Long(0,0,!1),t.unit=n.longs===String?r.toString():n.longs===Number?r.toNumber():r):t.unit=n.longs===String?"0":0}return null!=e.type&&e.hasOwnProperty("type")&&("number"==typeof e.type?t.type=n.longs===String?String(e.type):e.type:t.type=n.longs===String?o.Long.prototype.toString.call(e.type):n.longs===Number?new o.LongBits(e.type.low>>>0,e.type.high>>>0).toNumber():e.type),null!=e.unit&&e.hasOwnProperty("unit")&&("number"==typeof e.unit?t.unit=n.longs===String?String(e.unit):e.unit:t.unit=n.longs===String?o.Long.prototype.toString.call(e.unit):n.longs===Number?new o.LongBits(e.unit.low>>>0,e.unit.high>>>0).toNumber():e.unit),t},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),i.Sample=function(){function i(e){if(this.locationId=[],this.value=[],this.label=[],e)for(var n=Object.keys(e),t=0;t>>3){case 1:if(i.locationId&&i.locationId.length||(i.locationId=[]),2==(7&l))for(var s=e.uint32()+e.pos;e.pos>>0,e.locationId[t].high>>>0).toNumber(!0))}if(e.value){if(!Array.isArray(e.value))throw TypeError(".perftools.profiles.Sample.value: array expected");for(n.value=[],t=0;t>>0,e.value[t].high>>>0).toNumber())}if(e.label){if(!Array.isArray(e.label))throw TypeError(".perftools.profiles.Sample.label: array expected");for(n.label=[],t=0;t>>0,e.locationId[i].high>>>0).toNumber(!0):e.locationId[i]}if(e.value&&e.value.length)for(t.value=[],i=0;i>>0,e.value[i].high>>>0).toNumber():e.value[i];if(e.label&&e.label.length)for(t.label=[],i=0;i>>3){case 1:i.key=e.int64();break;case 2:i.str=e.int64();break;case 3:i.num=e.int64();break;case 4:i.numUnit=e.int64();break;default:e.skipType(7&l)}}return i},i.decodeDelimited=function(e){return e instanceof n||(e=new n(e)),this.decode(e,e.uint32())},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":null!=e.key&&e.hasOwnProperty("key")&&!(o.isInteger(e.key)||e.key&&o.isInteger(e.key.low)&&o.isInteger(e.key.high))?"key: integer|Long expected":null!=e.str&&e.hasOwnProperty("str")&&!(o.isInteger(e.str)||e.str&&o.isInteger(e.str.low)&&o.isInteger(e.str.high))?"str: integer|Long expected":null!=e.num&&e.hasOwnProperty("num")&&!(o.isInteger(e.num)||e.num&&o.isInteger(e.num.low)&&o.isInteger(e.num.high))?"num: integer|Long expected":null!=e.numUnit&&e.hasOwnProperty("numUnit")&&!(o.isInteger(e.numUnit)||e.numUnit&&o.isInteger(e.numUnit.low)&&o.isInteger(e.numUnit.high))?"numUnit: integer|Long expected":null},i.fromObject=function(e){if(e instanceof r.perftools.profiles.Label)return e;var n=new r.perftools.profiles.Label;return null!=e.key&&(o.Long?(n.key=o.Long.fromValue(e.key)).unsigned=!1:"string"==typeof e.key?n.key=parseInt(e.key,10):"number"==typeof e.key?n.key=e.key:"object"==typeof e.key&&(n.key=new o.LongBits(e.key.low>>>0,e.key.high>>>0).toNumber())),null!=e.str&&(o.Long?(n.str=o.Long.fromValue(e.str)).unsigned=!1:"string"==typeof e.str?n.str=parseInt(e.str,10):"number"==typeof e.str?n.str=e.str:"object"==typeof e.str&&(n.str=new o.LongBits(e.str.low>>>0,e.str.high>>>0).toNumber())),null!=e.num&&(o.Long?(n.num=o.Long.fromValue(e.num)).unsigned=!1:"string"==typeof e.num?n.num=parseInt(e.num,10):"number"==typeof e.num?n.num=e.num:"object"==typeof e.num&&(n.num=new o.LongBits(e.num.low>>>0,e.num.high>>>0).toNumber())),null!=e.numUnit&&(o.Long?(n.numUnit=o.Long.fromValue(e.numUnit)).unsigned=!1:"string"==typeof e.numUnit?n.numUnit=parseInt(e.numUnit,10):"number"==typeof e.numUnit?n.numUnit=e.numUnit:"object"==typeof e.numUnit&&(n.numUnit=new o.LongBits(e.numUnit.low>>>0,e.numUnit.high>>>0).toNumber())),n},i.toObject=function(e,n){n||(n={});var t={};if(n.defaults){if(o.Long){var r=new o.Long(0,0,!1);t.key=n.longs===String?r.toString():n.longs===Number?r.toNumber():r}else t.key=n.longs===String?"0":0;o.Long?(r=new o.Long(0,0,!1),t.str=n.longs===String?r.toString():n.longs===Number?r.toNumber():r):t.str=n.longs===String?"0":0,o.Long?(r=new o.Long(0,0,!1),t.num=n.longs===String?r.toString():n.longs===Number?r.toNumber():r):t.num=n.longs===String?"0":0,o.Long?(r=new o.Long(0,0,!1),t.numUnit=n.longs===String?r.toString():n.longs===Number?r.toNumber():r):t.numUnit=n.longs===String?"0":0}return null!=e.key&&e.hasOwnProperty("key")&&("number"==typeof e.key?t.key=n.longs===String?String(e.key):e.key:t.key=n.longs===String?o.Long.prototype.toString.call(e.key):n.longs===Number?new o.LongBits(e.key.low>>>0,e.key.high>>>0).toNumber():e.key),null!=e.str&&e.hasOwnProperty("str")&&("number"==typeof e.str?t.str=n.longs===String?String(e.str):e.str:t.str=n.longs===String?o.Long.prototype.toString.call(e.str):n.longs===Number?new o.LongBits(e.str.low>>>0,e.str.high>>>0).toNumber():e.str),null!=e.num&&e.hasOwnProperty("num")&&("number"==typeof e.num?t.num=n.longs===String?String(e.num):e.num:t.num=n.longs===String?o.Long.prototype.toString.call(e.num):n.longs===Number?new o.LongBits(e.num.low>>>0,e.num.high>>>0).toNumber():e.num),null!=e.numUnit&&e.hasOwnProperty("numUnit")&&("number"==typeof e.numUnit?t.numUnit=n.longs===String?String(e.numUnit):e.numUnit:t.numUnit=n.longs===String?o.Long.prototype.toString.call(e.numUnit):n.longs===Number?new o.LongBits(e.numUnit.low>>>0,e.numUnit.high>>>0).toNumber():e.numUnit),t},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),i.Mapping=function(){function i(e){if(e)for(var n=Object.keys(e),t=0;t>>3){case 1:i.id=e.uint64();break;case 2:i.memoryStart=e.uint64();break;case 3:i.memoryLimit=e.uint64();break;case 4:i.fileOffset=e.uint64();break;case 5:i.filename=e.int64();break;case 6:i.buildId=e.int64();break;case 7:i.hasFunctions=e.bool();break;case 8:i.hasFilenames=e.bool();break;case 9:i.hasLineNumbers=e.bool();break;case 10:i.hasInlineFrames=e.bool();break;default:e.skipType(7&l)}}return i},i.decodeDelimited=function(e){return e instanceof n||(e=new n(e)),this.decode(e,e.uint32())},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":null!=e.id&&e.hasOwnProperty("id")&&!(o.isInteger(e.id)||e.id&&o.isInteger(e.id.low)&&o.isInteger(e.id.high))?"id: integer|Long expected":null!=e.memoryStart&&e.hasOwnProperty("memoryStart")&&!(o.isInteger(e.memoryStart)||e.memoryStart&&o.isInteger(e.memoryStart.low)&&o.isInteger(e.memoryStart.high))?"memoryStart: integer|Long expected":null!=e.memoryLimit&&e.hasOwnProperty("memoryLimit")&&!(o.isInteger(e.memoryLimit)||e.memoryLimit&&o.isInteger(e.memoryLimit.low)&&o.isInteger(e.memoryLimit.high))?"memoryLimit: integer|Long expected":null!=e.fileOffset&&e.hasOwnProperty("fileOffset")&&!(o.isInteger(e.fileOffset)||e.fileOffset&&o.isInteger(e.fileOffset.low)&&o.isInteger(e.fileOffset.high))?"fileOffset: integer|Long expected":null!=e.filename&&e.hasOwnProperty("filename")&&!(o.isInteger(e.filename)||e.filename&&o.isInteger(e.filename.low)&&o.isInteger(e.filename.high))?"filename: integer|Long expected":null!=e.buildId&&e.hasOwnProperty("buildId")&&!(o.isInteger(e.buildId)||e.buildId&&o.isInteger(e.buildId.low)&&o.isInteger(e.buildId.high))?"buildId: integer|Long expected":null!=e.hasFunctions&&e.hasOwnProperty("hasFunctions")&&"boolean"!=typeof e.hasFunctions?"hasFunctions: boolean expected":null!=e.hasFilenames&&e.hasOwnProperty("hasFilenames")&&"boolean"!=typeof e.hasFilenames?"hasFilenames: boolean expected":null!=e.hasLineNumbers&&e.hasOwnProperty("hasLineNumbers")&&"boolean"!=typeof e.hasLineNumbers?"hasLineNumbers: boolean expected":null!=e.hasInlineFrames&&e.hasOwnProperty("hasInlineFrames")&&"boolean"!=typeof e.hasInlineFrames?"hasInlineFrames: boolean expected":null},i.fromObject=function(e){if(e instanceof r.perftools.profiles.Mapping)return e;var n=new r.perftools.profiles.Mapping;return null!=e.id&&(o.Long?(n.id=o.Long.fromValue(e.id)).unsigned=!0:"string"==typeof e.id?n.id=parseInt(e.id,10):"number"==typeof e.id?n.id=e.id:"object"==typeof e.id&&(n.id=new o.LongBits(e.id.low>>>0,e.id.high>>>0).toNumber(!0))),null!=e.memoryStart&&(o.Long?(n.memoryStart=o.Long.fromValue(e.memoryStart)).unsigned=!0:"string"==typeof e.memoryStart?n.memoryStart=parseInt(e.memoryStart,10):"number"==typeof e.memoryStart?n.memoryStart=e.memoryStart:"object"==typeof e.memoryStart&&(n.memoryStart=new o.LongBits(e.memoryStart.low>>>0,e.memoryStart.high>>>0).toNumber(!0))),null!=e.memoryLimit&&(o.Long?(n.memoryLimit=o.Long.fromValue(e.memoryLimit)).unsigned=!0:"string"==typeof e.memoryLimit?n.memoryLimit=parseInt(e.memoryLimit,10):"number"==typeof e.memoryLimit?n.memoryLimit=e.memoryLimit:"object"==typeof e.memoryLimit&&(n.memoryLimit=new o.LongBits(e.memoryLimit.low>>>0,e.memoryLimit.high>>>0).toNumber(!0))),null!=e.fileOffset&&(o.Long?(n.fileOffset=o.Long.fromValue(e.fileOffset)).unsigned=!0:"string"==typeof e.fileOffset?n.fileOffset=parseInt(e.fileOffset,10):"number"==typeof e.fileOffset?n.fileOffset=e.fileOffset:"object"==typeof e.fileOffset&&(n.fileOffset=new o.LongBits(e.fileOffset.low>>>0,e.fileOffset.high>>>0).toNumber(!0))),null!=e.filename&&(o.Long?(n.filename=o.Long.fromValue(e.filename)).unsigned=!1:"string"==typeof e.filename?n.filename=parseInt(e.filename,10):"number"==typeof e.filename?n.filename=e.filename:"object"==typeof e.filename&&(n.filename=new o.LongBits(e.filename.low>>>0,e.filename.high>>>0).toNumber())),null!=e.buildId&&(o.Long?(n.buildId=o.Long.fromValue(e.buildId)).unsigned=!1:"string"==typeof e.buildId?n.buildId=parseInt(e.buildId,10):"number"==typeof e.buildId?n.buildId=e.buildId:"object"==typeof e.buildId&&(n.buildId=new o.LongBits(e.buildId.low>>>0,e.buildId.high>>>0).toNumber())),null!=e.hasFunctions&&(n.hasFunctions=Boolean(e.hasFunctions)),null!=e.hasFilenames&&(n.hasFilenames=Boolean(e.hasFilenames)),null!=e.hasLineNumbers&&(n.hasLineNumbers=Boolean(e.hasLineNumbers)),null!=e.hasInlineFrames&&(n.hasInlineFrames=Boolean(e.hasInlineFrames)),n},i.toObject=function(e,n){n||(n={});var t={};if(n.defaults){if(o.Long){var r=new o.Long(0,0,!0);t.id=n.longs===String?r.toString():n.longs===Number?r.toNumber():r}else t.id=n.longs===String?"0":0;o.Long?(r=new o.Long(0,0,!0),t.memoryStart=n.longs===String?r.toString():n.longs===Number?r.toNumber():r):t.memoryStart=n.longs===String?"0":0,o.Long?(r=new o.Long(0,0,!0),t.memoryLimit=n.longs===String?r.toString():n.longs===Number?r.toNumber():r):t.memoryLimit=n.longs===String?"0":0,o.Long?(r=new o.Long(0,0,!0),t.fileOffset=n.longs===String?r.toString():n.longs===Number?r.toNumber():r):t.fileOffset=n.longs===String?"0":0,o.Long?(r=new o.Long(0,0,!1),t.filename=n.longs===String?r.toString():n.longs===Number?r.toNumber():r):t.filename=n.longs===String?"0":0,o.Long?(r=new o.Long(0,0,!1),t.buildId=n.longs===String?r.toString():n.longs===Number?r.toNumber():r):t.buildId=n.longs===String?"0":0,t.hasFunctions=!1,t.hasFilenames=!1,t.hasLineNumbers=!1,t.hasInlineFrames=!1}return null!=e.id&&e.hasOwnProperty("id")&&("number"==typeof e.id?t.id=n.longs===String?String(e.id):e.id:t.id=n.longs===String?o.Long.prototype.toString.call(e.id):n.longs===Number?new o.LongBits(e.id.low>>>0,e.id.high>>>0).toNumber(!0):e.id),null!=e.memoryStart&&e.hasOwnProperty("memoryStart")&&("number"==typeof e.memoryStart?t.memoryStart=n.longs===String?String(e.memoryStart):e.memoryStart:t.memoryStart=n.longs===String?o.Long.prototype.toString.call(e.memoryStart):n.longs===Number?new o.LongBits(e.memoryStart.low>>>0,e.memoryStart.high>>>0).toNumber(!0):e.memoryStart),null!=e.memoryLimit&&e.hasOwnProperty("memoryLimit")&&("number"==typeof e.memoryLimit?t.memoryLimit=n.longs===String?String(e.memoryLimit):e.memoryLimit:t.memoryLimit=n.longs===String?o.Long.prototype.toString.call(e.memoryLimit):n.longs===Number?new o.LongBits(e.memoryLimit.low>>>0,e.memoryLimit.high>>>0).toNumber(!0):e.memoryLimit),null!=e.fileOffset&&e.hasOwnProperty("fileOffset")&&("number"==typeof e.fileOffset?t.fileOffset=n.longs===String?String(e.fileOffset):e.fileOffset:t.fileOffset=n.longs===String?o.Long.prototype.toString.call(e.fileOffset):n.longs===Number?new o.LongBits(e.fileOffset.low>>>0,e.fileOffset.high>>>0).toNumber(!0):e.fileOffset),null!=e.filename&&e.hasOwnProperty("filename")&&("number"==typeof e.filename?t.filename=n.longs===String?String(e.filename):e.filename:t.filename=n.longs===String?o.Long.prototype.toString.call(e.filename):n.longs===Number?new o.LongBits(e.filename.low>>>0,e.filename.high>>>0).toNumber():e.filename),null!=e.buildId&&e.hasOwnProperty("buildId")&&("number"==typeof e.buildId?t.buildId=n.longs===String?String(e.buildId):e.buildId:t.buildId=n.longs===String?o.Long.prototype.toString.call(e.buildId):n.longs===Number?new o.LongBits(e.buildId.low>>>0,e.buildId.high>>>0).toNumber():e.buildId),null!=e.hasFunctions&&e.hasOwnProperty("hasFunctions")&&(t.hasFunctions=e.hasFunctions),null!=e.hasFilenames&&e.hasOwnProperty("hasFilenames")&&(t.hasFilenames=e.hasFilenames),null!=e.hasLineNumbers&&e.hasOwnProperty("hasLineNumbers")&&(t.hasLineNumbers=e.hasLineNumbers),null!=e.hasInlineFrames&&e.hasOwnProperty("hasInlineFrames")&&(t.hasInlineFrames=e.hasInlineFrames),t},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),i.Location=function(){function i(e){if(this.line=[],e)for(var n=Object.keys(e),t=0;t>>3){case 1:i.id=e.uint64();break;case 2:i.mappingId=e.uint64();break;case 3:i.address=e.uint64();break;case 4:i.line&&i.line.length||(i.line=[]),i.line.push(r.perftools.profiles.Line.decode(e,e.uint32()));break;case 5:i.isFolded=e.bool();break;default:e.skipType(7&l)}}return i},i.decodeDelimited=function(e){return e instanceof n||(e=new n(e)),this.decode(e,e.uint32())},i.verify=function(e){if("object"!=typeof e||null===e)return"object expected";if(null!=e.id&&e.hasOwnProperty("id")&&!(o.isInteger(e.id)||e.id&&o.isInteger(e.id.low)&&o.isInteger(e.id.high)))return"id: integer|Long expected";if(null!=e.mappingId&&e.hasOwnProperty("mappingId")&&!(o.isInteger(e.mappingId)||e.mappingId&&o.isInteger(e.mappingId.low)&&o.isInteger(e.mappingId.high)))return"mappingId: integer|Long expected";if(null!=e.address&&e.hasOwnProperty("address")&&!(o.isInteger(e.address)||e.address&&o.isInteger(e.address.low)&&o.isInteger(e.address.high)))return"address: integer|Long expected";if(null!=e.line&&e.hasOwnProperty("line")){if(!Array.isArray(e.line))return"line: array expected";for(var n=0;n>>0,e.id.high>>>0).toNumber(!0))),null!=e.mappingId&&(o.Long?(n.mappingId=o.Long.fromValue(e.mappingId)).unsigned=!0:"string"==typeof e.mappingId?n.mappingId=parseInt(e.mappingId,10):"number"==typeof e.mappingId?n.mappingId=e.mappingId:"object"==typeof e.mappingId&&(n.mappingId=new o.LongBits(e.mappingId.low>>>0,e.mappingId.high>>>0).toNumber(!0))),null!=e.address&&(o.Long?(n.address=o.Long.fromValue(e.address)).unsigned=!0:"string"==typeof e.address?n.address=parseInt(e.address,10):"number"==typeof e.address?n.address=e.address:"object"==typeof e.address&&(n.address=new o.LongBits(e.address.low>>>0,e.address.high>>>0).toNumber(!0))),e.line){if(!Array.isArray(e.line))throw TypeError(".perftools.profiles.Location.line: array expected");n.line=[];for(var t=0;t>>0,e.id.high>>>0).toNumber(!0):e.id),null!=e.mappingId&&e.hasOwnProperty("mappingId")&&("number"==typeof e.mappingId?t.mappingId=n.longs===String?String(e.mappingId):e.mappingId:t.mappingId=n.longs===String?o.Long.prototype.toString.call(e.mappingId):n.longs===Number?new o.LongBits(e.mappingId.low>>>0,e.mappingId.high>>>0).toNumber(!0):e.mappingId),null!=e.address&&e.hasOwnProperty("address")&&("number"==typeof e.address?t.address=n.longs===String?String(e.address):e.address:t.address=n.longs===String?o.Long.prototype.toString.call(e.address):n.longs===Number?new o.LongBits(e.address.low>>>0,e.address.high>>>0).toNumber(!0):e.address),e.line&&e.line.length){t.line=[];for(var l=0;l>>3){case 1:i.functionId=e.uint64();break;case 2:i.line=e.int64();break;default:e.skipType(7&l)}}return i},i.decodeDelimited=function(e){return e instanceof n||(e=new n(e)),this.decode(e,e.uint32())},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":null!=e.functionId&&e.hasOwnProperty("functionId")&&!(o.isInteger(e.functionId)||e.functionId&&o.isInteger(e.functionId.low)&&o.isInteger(e.functionId.high))?"functionId: integer|Long expected":null!=e.line&&e.hasOwnProperty("line")&&!(o.isInteger(e.line)||e.line&&o.isInteger(e.line.low)&&o.isInteger(e.line.high))?"line: integer|Long expected":null},i.fromObject=function(e){if(e instanceof r.perftools.profiles.Line)return e;var n=new r.perftools.profiles.Line;return null!=e.functionId&&(o.Long?(n.functionId=o.Long.fromValue(e.functionId)).unsigned=!0:"string"==typeof e.functionId?n.functionId=parseInt(e.functionId,10):"number"==typeof e.functionId?n.functionId=e.functionId:"object"==typeof e.functionId&&(n.functionId=new o.LongBits(e.functionId.low>>>0,e.functionId.high>>>0).toNumber(!0))),null!=e.line&&(o.Long?(n.line=o.Long.fromValue(e.line)).unsigned=!1:"string"==typeof e.line?n.line=parseInt(e.line,10):"number"==typeof e.line?n.line=e.line:"object"==typeof e.line&&(n.line=new o.LongBits(e.line.low>>>0,e.line.high>>>0).toNumber())),n},i.toObject=function(e,n){n||(n={});var t={};if(n.defaults){if(o.Long){var r=new o.Long(0,0,!0);t.functionId=n.longs===String?r.toString():n.longs===Number?r.toNumber():r}else t.functionId=n.longs===String?"0":0;o.Long?(r=new o.Long(0,0,!1),t.line=n.longs===String?r.toString():n.longs===Number?r.toNumber():r):t.line=n.longs===String?"0":0}return null!=e.functionId&&e.hasOwnProperty("functionId")&&("number"==typeof e.functionId?t.functionId=n.longs===String?String(e.functionId):e.functionId:t.functionId=n.longs===String?o.Long.prototype.toString.call(e.functionId):n.longs===Number?new o.LongBits(e.functionId.low>>>0,e.functionId.high>>>0).toNumber(!0):e.functionId),null!=e.line&&e.hasOwnProperty("line")&&("number"==typeof e.line?t.line=n.longs===String?String(e.line):e.line:t.line=n.longs===String?o.Long.prototype.toString.call(e.line):n.longs===Number?new o.LongBits(e.line.low>>>0,e.line.high>>>0).toNumber():e.line),t},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),i.Function=function(){function i(e){if(e)for(var n=Object.keys(e),t=0;t>>3){case 1:i.id=e.uint64();break;case 2:i.name=e.int64();break;case 3:i.systemName=e.int64();break;case 4:i.filename=e.int64();break;case 5:i.startLine=e.int64();break;default:e.skipType(7&l)}}return i},i.decodeDelimited=function(e){return e instanceof n||(e=new n(e)),this.decode(e,e.uint32())},i.verify=function(e){return"object"!=typeof e||null===e?"object expected":null!=e.id&&e.hasOwnProperty("id")&&!(o.isInteger(e.id)||e.id&&o.isInteger(e.id.low)&&o.isInteger(e.id.high))?"id: integer|Long expected":null!=e.name&&e.hasOwnProperty("name")&&!(o.isInteger(e.name)||e.name&&o.isInteger(e.name.low)&&o.isInteger(e.name.high))?"name: integer|Long expected":null!=e.systemName&&e.hasOwnProperty("systemName")&&!(o.isInteger(e.systemName)||e.systemName&&o.isInteger(e.systemName.low)&&o.isInteger(e.systemName.high))?"systemName: integer|Long expected":null!=e.filename&&e.hasOwnProperty("filename")&&!(o.isInteger(e.filename)||e.filename&&o.isInteger(e.filename.low)&&o.isInteger(e.filename.high))?"filename: integer|Long expected":null!=e.startLine&&e.hasOwnProperty("startLine")&&!(o.isInteger(e.startLine)||e.startLine&&o.isInteger(e.startLine.low)&&o.isInteger(e.startLine.high))?"startLine: integer|Long expected":null},i.fromObject=function(e){if(e instanceof r.perftools.profiles.Function)return e;var n=new r.perftools.profiles.Function;return null!=e.id&&(o.Long?(n.id=o.Long.fromValue(e.id)).unsigned=!0:"string"==typeof e.id?n.id=parseInt(e.id,10):"number"==typeof e.id?n.id=e.id:"object"==typeof e.id&&(n.id=new o.LongBits(e.id.low>>>0,e.id.high>>>0).toNumber(!0))),null!=e.name&&(o.Long?(n.name=o.Long.fromValue(e.name)).unsigned=!1:"string"==typeof e.name?n.name=parseInt(e.name,10):"number"==typeof e.name?n.name=e.name:"object"==typeof e.name&&(n.name=new o.LongBits(e.name.low>>>0,e.name.high>>>0).toNumber())),null!=e.systemName&&(o.Long?(n.systemName=o.Long.fromValue(e.systemName)).unsigned=!1:"string"==typeof e.systemName?n.systemName=parseInt(e.systemName,10):"number"==typeof e.systemName?n.systemName=e.systemName:"object"==typeof e.systemName&&(n.systemName=new o.LongBits(e.systemName.low>>>0,e.systemName.high>>>0).toNumber())),null!=e.filename&&(o.Long?(n.filename=o.Long.fromValue(e.filename)).unsigned=!1:"string"==typeof e.filename?n.filename=parseInt(e.filename,10):"number"==typeof e.filename?n.filename=e.filename:"object"==typeof e.filename&&(n.filename=new o.LongBits(e.filename.low>>>0,e.filename.high>>>0).toNumber())),null!=e.startLine&&(o.Long?(n.startLine=o.Long.fromValue(e.startLine)).unsigned=!1:"string"==typeof e.startLine?n.startLine=parseInt(e.startLine,10):"number"==typeof e.startLine?n.startLine=e.startLine:"object"==typeof e.startLine&&(n.startLine=new o.LongBits(e.startLine.low>>>0,e.startLine.high>>>0).toNumber())),n},i.toObject=function(e,n){n||(n={});var t={};if(n.defaults){if(o.Long){var r=new o.Long(0,0,!0);t.id=n.longs===String?r.toString():n.longs===Number?r.toNumber():r}else t.id=n.longs===String?"0":0;o.Long?(r=new o.Long(0,0,!1),t.name=n.longs===String?r.toString():n.longs===Number?r.toNumber():r):t.name=n.longs===String?"0":0,o.Long?(r=new o.Long(0,0,!1),t.systemName=n.longs===String?r.toString():n.longs===Number?r.toNumber():r):t.systemName=n.longs===String?"0":0,o.Long?(r=new o.Long(0,0,!1),t.filename=n.longs===String?r.toString():n.longs===Number?r.toNumber():r):t.filename=n.longs===String?"0":0,o.Long?(r=new o.Long(0,0,!1),t.startLine=n.longs===String?r.toString():n.longs===Number?r.toNumber():r):t.startLine=n.longs===String?"0":0}return null!=e.id&&e.hasOwnProperty("id")&&("number"==typeof e.id?t.id=n.longs===String?String(e.id):e.id:t.id=n.longs===String?o.Long.prototype.toString.call(e.id):n.longs===Number?new o.LongBits(e.id.low>>>0,e.id.high>>>0).toNumber(!0):e.id),null!=e.name&&e.hasOwnProperty("name")&&("number"==typeof e.name?t.name=n.longs===String?String(e.name):e.name:t.name=n.longs===String?o.Long.prototype.toString.call(e.name):n.longs===Number?new o.LongBits(e.name.low>>>0,e.name.high>>>0).toNumber():e.name),null!=e.systemName&&e.hasOwnProperty("systemName")&&("number"==typeof e.systemName?t.systemName=n.longs===String?String(e.systemName):e.systemName:t.systemName=n.longs===String?o.Long.prototype.toString.call(e.systemName):n.longs===Number?new o.LongBits(e.systemName.low>>>0,e.systemName.high>>>0).toNumber():e.systemName),null!=e.filename&&e.hasOwnProperty("filename")&&("number"==typeof e.filename?t.filename=n.longs===String?String(e.filename):e.filename:t.filename=n.longs===String?o.Long.prototype.toString.call(e.filename):n.longs===Number?new o.LongBits(e.filename.low>>>0,e.filename.high>>>0).toNumber():e.filename),null!=e.startLine&&e.hasOwnProperty("startLine")&&("number"==typeof e.startLine?t.startLine=n.longs===String?String(e.startLine):e.startLine:t.startLine=n.longs===String?o.Long.prototype.toString.call(e.startLine):n.longs===Number?new o.LongBits(e.startLine.low>>>0,e.startLine.high>>>0).toNumber():e.startLine),t},i.prototype.toJSON=function(){return this.constructor.toObject(this,e.util.toJSONOptions)},i}(),i),l}(),module.exports=r; +},{"protobufjs/minimal":186}],155:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.importAsPprofProfile=r;var e=require("./profile.proto.js"),n=require("../lib/profile"),t=require("../lib/utils"),l=require("../lib/value-formatters");function r(r){if(0===r.byteLength)return null;let o;try{o=e.perftools.profiles.Profile.decode(new Uint8Array(r))}catch(e){return null}function i(e){return"number"==typeof e?e:e.low}function u(e){return o.stringTable[i(e)]||null}const s=new Map;function a(e){const{name:n,filename:t,startLine:l}=e,r=null!=n&&u(n)||"(unknown)",o=null!=t?u(t):null,i=null!=l?+l:null,s={key:`${r}:${o}:${i}`,name:r};return null!=o&&(s.file=o),null!=i&&(s.line=i),s}for(let e of o.function)if(e.id){const n=a(e);null!=n&&s.set(i(e.id),n)}function c(e){const{line:n}=e;if(null==n)return null;const l=(0,t.lastOf)(n);return null==l?null:l.functionId&&s.get(i(l.functionId))||null}const f=new Map;for(let e of o.location)if(null!=e.id){const n=c(e);n&&f.set(i(e.id),n)}const p=o.sampleType.map(e=>({type:e.type&&u(e.type)||"samples",unit:e.unit&&u(e.unit)||"count"})),d=o.defaultSampleType?+o.defaultSampleType:p.length-1,m=p[d],y=new n.StackListProfileBuilder;switch(m.unit){case"nanoseconds":case"microseconds":case"milliseconds":case"seconds":y.setValueFormatter(new l.TimeFormatter(m.unit));break;case"bytes":y.setValueFormatter(new l.ByteFormatter)}for(let e of o.sample){const n=e.locationId?e.locationId.map(e=>f.get(i(e))):[];n.reverse();const t=e.value[d];y.appendSampleWithWeight(n.filter(e=>null!=e),+t)}return y.build()} +},{"./profile.proto.js":174,"../lib/profile":139,"../lib/utils":70,"../lib/value-formatters":140}],156:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.importFromChromeHeapProfile=o;var e=require("../lib/profile"),r=require("../lib/utils"),t=require("../lib/value-formatters");const n=new Map;function i(e){return(0,r.getOrInsert)(n,e,e=>{const r=e.functionName||"(anonymous)",t=e.url,n=e.lineNumber,i=e.columnNumber;return{key:`${r}:${t}:${n}:${i}`,name:r,file:t,line:n,col:i}})}function o(r){const n=new Map;let o=0;const l=(e,r)=>{e.id=o++,n.set(e.id,e),r&&(e.parent=r.id),e.children.forEach(r=>l(r,e))};l(r.head);const u=e=>{if(0===e.children.length)return e.selfSize||0;const r=e.children.reduce((e,r)=>e+=u(r),e.selfSize);return e.totalSize=r,r},a=u(r.head),s=[];for(let e of n.values()){let r=[];for(r.push(e);void 0!==e.parent;){const t=n.get(e.parent);if(void 0===t)break;r.unshift(t),e=t}s.push(r)}const c=new e.StackListProfileBuilder(a);for(let e of s){const r=e[e.length-1];c.appendSampleWithWeight(e.map(e=>i(e.callFrame)),r.selfSize)}return c.setValueFormatter(new t.ByteFormatter),c.build()} +},{"../lib/profile":139,"../lib/utils":70,"../lib/value-formatters":140}],157:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.isTraceEventFormatted=l,exports.importTraceEvents=p;var e=require("../lib/utils"),t=require("../lib/profile"),r=require("../lib/value-formatters");function n(e){const t=[];for(let r of e)switch(r.ph){case"B":case"E":case"X":t.push(r)}return t}function i(e){const t=[];for(let r of e)switch(r.ph){case"B":case"E":t.push(r);break;case"X":let e=null;if(null!=r.dur?e=r.dur:null!=r.tdur&&(e=r.tdur),null==e){console.warn("Found a complete event (X) with no duration. Skipping: ",r);continue}t.push(Object.assign({},r,{ph:"B"})),t.push(Object.assign({},r,{ph:"E",ts:r.ts+e}));break;default:return r}return t}function s(e){const t=new Map;for(let r of e)"M"===r.ph&&"process_name"===r.name&&r.args&&r.args.name&&t.set(r.pid,r.args.name);return t}function a(e){const t=new Map;for(let r of e)if("M"===r.ph&&"thread_name"===r.name&&r.args&&r.args.name){const e=`${r.pid}:${r.tid}`;t.set(e,r.args.name)}return t}function u(e){let t=`${e.name||"(unnamed)"}`;return e.args&&(t+=` ${JSON.stringify(e.args)}`),t}function o(o){const c=new Map,f=i(n(o)),l=s(o),p=a(o);if(f.sort((e,t)=>{if(e.tst.ts)return 1;if(e.pidt.pid)return 1;if(e.tidt.tid)return 1;if(u(e)===u(t)){if("B"===e.ph&&"E"===t.ph)return-1;if("E"===e.ph&&"B"===t.ph)return 1}else{if("B"===e.ph&&"E"===t.ph)return 1;if("E"===e.ph&&"B"===t.ph)return-1}return 0}),f.length>0){const e=f[0].ts;for(let t of f)t.ts-=e}function d(n,i){const s=`${(0,e.zeroPad)(""+n,10)}:${(0,e.zeroPad)(""+i,10)}`;let a=c.get(s);if(null!=a)return a;let u=new t.CallTreeProfileBuilder;a={profile:u,eventStack:[]},u.setValueFormatter(new r.TimeFormatter("microseconds")),c.set(s,a);const o=l.get(n),f=p.get(`${n}:${i}`);return null!=o&&null!=f?u.setName(`${o} (pid ${n}), ${f} (tid ${i})`):null!=o?u.setName(`${o} (pid ${n}, tid ${i})`):null!=f?u.setName(`${f} (pid ${n}, tid ${i})`):u.setName(`pid ${n}, tid ${i}`),a}for(let t of f){const{profile:r,eventStack:n}=d(t.pid,t.tid),i=u(t),s={key:i,name:i};switch(t.ph){case"B":n.push(t),r.enterFrame(s,t.ts);break;case"E":const i=(0,e.lastOf)(n);null!=i&&i.name===t.name?(r.leaveFrame(s,t.ts),n.pop()):console.warn("Event discarded because it did not match top-of-stack. Discarded event:",t,"Top of stack:",i);break;default:return t}}const h=Array.from(c.entries());return(0,e.sortBy)(h,e=>e[0]),{name:"",indexToView:0,profiles:h.map(e=>e[1].profile)}}function c(e){if(!Array.isArray(e))return!1;if(0===e.length)return!1;for(let t of e){if(!("ph"in t))return!1;switch(t.ph){case"B":case"E":case"X":if(!("ts"in t))return!1}}return!0}function f(e){return"traceEvents"in e&&c(e.traceEvents)}function l(e){return f(e)||c(e)}function p(e){if(f(e))return o(e.traceEvents);if(c(e))return o(e);return e} +},{"../lib/utils":70,"../lib/profile":139,"../lib/value-formatters":140}],104:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.importProfileGroupFromText=g,exports.importProfileGroupFromBase64=h,exports.importProfilesFromFile=F,exports.importProfilesFromArrayBuffer=y,exports.importFromFileSystemDirectoryEntry=C;var e=require("./chrome"),r=require("./stackprof"),o=require("./instruments"),t=require("./bg-flamegraph"),i=require("./firefox"),n=require("../lib/file-format"),s=require("./v8proflog"),p=require("./linux-tools-perf"),l=require("./haskell"),m=require("./utils"),a=require("./pprof"),f=require("../lib/utils"),u=require("./v8heapalloc"),c=require("./trace-event"),d=function(e,r,o,t){return new(o||(o=Promise))(function(i,n){function s(e){try{l(t.next(e))}catch(e){n(e)}}function p(e){try{l(t.throw(e))}catch(e){n(e)}}function l(e){e.done?i(e.value):new o(function(r){r(e.value)}).then(s,p)}l((t=t.apply(e,r||[])).next())})};function g(e,r){return d(this,void 0,void 0,function*(){return yield P(new m.TextProfileDataSource(e,r))})}function h(e,r){return d(this,void 0,void 0,function*(){return yield P(m.MaybeCompressedDataReader.fromArrayBuffer(e,(0,f.decodeBase64)(r).buffer))})}function F(e){return d(this,void 0,void 0,function*(){return P(m.MaybeCompressedDataReader.fromFile(e))})}function y(e,r){return d(this,void 0,void 0,function*(){return P(m.MaybeCompressedDataReader.fromArrayBuffer(e,r))})}function P(e){return d(this,void 0,void 0,function*(){const r=yield e.name(),o=yield I(e);if(o){o.name||(o.name=r);for(let e of o.profiles)e&&!e.getName()&&e.setName(r);return o}return null})}function v(e){return e?{name:e.getName(),indexToView:0,profiles:[e]}:null}function x(e){return"["===(e=e.trim())[0]&&"]"!==(e=e.replace(/,\s*$/,""))[e.length-1]&&(e+="]"),e}function I(m){return d(this,void 0,void 0,function*(){const f=yield m.name(),d=yield m.readAsArrayBuffer();{const e=(0,a.importAsPprofProfile)(d);if(e)return console.log("Importing as protobuf encoded pprof file"),v(e)}const g=yield m.readAsText();if(f.endsWith(".speedscope.json"))return console.log("Importing as speedscope json file"),(0,n.importSpeedscopeProfiles)(JSON.parse(g));if(f.endsWith(".chrome.json")||/Profile-\d{8}T\d{6}/.exec(f))return console.log("Importing as Chrome Timeline"),(0,e.importFromChromeTimeline)(JSON.parse(g),f);if(f.endsWith(".stackprof.json"))return console.log("Importing as stackprof profile"),v((0,r.importFromStackprof)(JSON.parse(g)));if(f.endsWith(".instruments.txt"))return console.log("Importing as Instruments.app deep copy"),v((0,o.importFromInstrumentsDeepCopy)(g));if(f.endsWith(".linux-perf.txt"))return console.log("Importing as output of linux perf script"),(0,p.importFromLinuxPerf)(g);if(f.endsWith(".collapsedstack.txt"))return console.log("Importing as collapsed stack format"),v((0,t.importFromBGFlameGraph)(g));if(f.endsWith(".v8log.json"))return console.log("Importing as --prof-process v8 log"),v((0,s.importFromV8ProfLog)(JSON.parse(g)));if(f.endsWith(".heapprofile"))return console.log("Importing as Chrome Heap Profile"),v((0,u.importFromChromeHeapProfile)(JSON.parse(g)));let h;try{h=JSON.parse(x(g))}catch(e){}if(h){if("https://www.speedscope.app/file-format-schema.json"===h.$schema)return console.log("Importing as speedscope json file"),(0,n.importSpeedscopeProfiles)(JSON.parse(g));if(h.systemHost&&"Firefox"==h.systemHost.name)return console.log("Importing as Firefox profile"),v((0,i.importFromFirefox)(h));if((0,e.isChromeTimeline)(h))return console.log("Importing as Chrome Timeline"),(0,e.importFromChromeTimeline)(h,f);if("nodes"in h&&"samples"in h&&"timeDeltas"in h)return console.log("Importing as Chrome CPU Profile"),v((0,e.importFromChromeCPUProfile)(h));if((0,c.isTraceEventFormatted)(h))return console.log("Importing as Trace Event Format profile"),(0,c.importTraceEvents)(h);if("head"in h&&"samples"in h&&"timestamps"in h)return console.log("Importing as Chrome CPU Profile (old format)"),v((0,e.importFromOldV8CPUProfile)(h));if("mode"in h&&"frames"in h&&"raw_timestamp_deltas"in h)return console.log("Importing as stackprof profile"),v((0,r.importFromStackprof)(h));if("code"in h&&"functions"in h&&"ticks"in h)return console.log("Importing as --prof-process v8 log"),v((0,s.importFromV8ProfLog)(h));if("head"in h&&"selfSize"in h.head)return console.log("Importing as Chrome Heap Profile"),v((0,u.importFromChromeHeapProfile)(JSON.parse(g)));if("rts_arguments"in h&&"initial_capabilities"in h)return console.log("Importing as Haskell GHC JSON Profile"),(0,l.importFromHaskell)(h)}else{if(/^[\w \t\(\)]*\tSymbol Name/.exec(g))return console.log("Importing as Instruments.app deep copy"),v((0,o.importFromInstrumentsDeepCopy)(g));const e=g.split(/\n/).length;if(e>=1&&e===g.split(/ \d+\r?\n/).length)return console.log("Importing as collapsed stack format"),v((0,t.importFromBGFlameGraph)(g));const r=(0,p.importFromLinuxPerf)(g);if(r)return console.log("Importing from linux perf script output"),r}return null})}function C(e){return d(this,void 0,void 0,function*(){return(0,o.importFromInstrumentsTrace)(e)})} +},{"./chrome":146,"./stackprof":147,"./instruments":148,"./bg-flamegraph":149,"./firefox":150,"../lib/file-format":83,"./v8proflog":151,"./linux-tools-perf":152,"./haskell":153,"./utils":154,"./pprof":155,"../lib/utils":70,"./v8heapalloc":156,"./trace-event":157}]},{},[104], null) +//# sourceMappingURL=import.a03c2bef.map \ No newline at end of file diff --git a/historyserver/dashboard/ray/client/public/speedscope-1.5.3/index.html b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/index.html new file mode 100644 index 00000000000..3db6f9064ca --- /dev/null +++ b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/index.html @@ -0,0 +1 @@ + speedscope \ No newline at end of file diff --git a/historyserver/dashboard/ray/client/public/speedscope-1.5.3/perf-vertx-stacks-01-collapsed-all.3e0a632c.txt b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/perf-vertx-stacks-01-collapsed-all.3e0a632c.txt new file mode 100644 index 00000000000..4b5f79febee --- /dev/null +++ b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/perf-vertx-stacks-01-collapsed-all.3e0a632c.txt @@ -0,0 +1,199 @@ +java;read;check_events_[k];hypercall_page_[k] 1 +java;start_thread;java_start;GCTaskThread::run;ScavengeRootsTask::do_it;ClassLoaderDataGraph::oops_do;ClassLoaderData::oops_do;PSScavengeKlassClosure::do_klass 1 +java;start_thread;java_start;GCTaskThread::run;StealTask::do_it;PSPromotionManager::drain_stacks_depth;oopDesc* PSPromotionManager::copy_to_survivor_space;InstanceKlass::oop_push_contents 1 +java;start_thread;java_start;GCTaskThread::run;StealTask::do_it;ParallelTaskTerminator::offer_termination 5 +java;start_thread;java_start;GCTaskThread::run;StealTask::do_it;SpinPause 7 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/buffer/AbstractByteBufAllocator:.directBuffer_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/AbstractReferenceCountedByteBuf:.release_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];io/netty/buffer/PooledByteBuf:.internalNioBuffer_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/NativeThread:.current_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j]; 3 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];Java_sun_nio_ch_FileDispatcherImpl_write0 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;sys_write_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];fget_light_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];__srcu_read_lock_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];__tcp_push_pending_frames_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];ktime_get_real_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];skb_clone_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_set_skb_tso_segs_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_hard_start_xmit_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_pick_tx_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];dev_hard_start_xmit_[k];dev_queue_xmit_nit_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];dev_hard_start_xmit_[k];loopback_xmit_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];dev_hard_start_xmit_[k];loopback_xmit_[k];netif_rx_[k];netif_rx.part.82_[k];xen_restore_fl_direct_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];dev_hard_start_xmit_[k];loopback_xmit_[k];netif_rx_[k];netif_rx.part.82_[k];xen_restore_fl_direct_end_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];__do_softirq_[k];net_rx_action_[k];dma_issue_pending_all_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];__do_softirq_[k];net_rx_action_[k];process_backlog_[k];__netif_receive_skb_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];__do_softirq_[k];net_rx_action_[k];process_backlog_[k];__netif_receive_skb_[k];ip_rcv_[k];ip_rcv_finish_[k];ip_local_deliver_[k];ip_local_deliver_finish_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];__do_softirq_[k];net_rx_action_[k];process_backlog_[k];__netif_receive_skb_[k];ip_rcv_[k];ip_rcv_finish_[k];ip_local_deliver_[k];ip_local_deliver_finish_[k];tcp_v4_rcv_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];__do_softirq_[k];net_rx_action_[k];process_backlog_[k];__netif_receive_skb_[k];ip_rcv_[k];ip_rcv_finish_[k];ip_local_deliver_[k];ip_local_deliver_finish_[k];tcp_v4_rcv_[k];__inet_lookup_established_[k] 3 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];__do_softirq_[k];net_rx_action_[k];process_backlog_[k];__netif_receive_skb_[k];ip_rcv_[k];ip_rcv_finish_[k];ip_local_deliver_[k];ip_local_deliver_finish_[k];tcp_v4_rcv_[k];tcp_v4_do_rcv_[k];tcp_event_data_recv_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];__do_softirq_[k];net_rx_action_[k];process_backlog_[k];__netif_receive_skb_[k];ip_rcv_[k];ip_rcv_finish_[k];ip_local_deliver_[k];ip_local_deliver_finish_[k];tcp_v4_rcv_[k];tcp_v4_do_rcv_[k];tcp_rcv_established_[k];sock_def_readable_[k];__wake_up_sync_key_[k];check_events_[k];hypercall_page_[k] 19 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];__do_softirq_[k];net_rx_action_[k];process_backlog_[k];__netif_receive_skb_[k];ip_rcv_[k];ip_rcv_finish_[k];ip_local_deliver_[k];ip_local_deliver_finish_[k];tcp_v4_rcv_[k];tcp_v4_do_rcv_[k];tcp_rcv_established_[k];tcp_ack_[k] 3 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];__do_softirq_[k];net_rx_action_[k];process_backlog_[k];__netif_receive_skb_[k];ip_rcv_[k];ip_rcv_finish_[k];ip_local_deliver_[k];ip_local_deliver_finish_[k];tcp_v4_rcv_[k];tcp_v4_do_rcv_[k];tcp_rcv_established_[k];tcp_ack_[k];tcp_clean_rtx_queue_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];__do_softirq_[k];net_rx_action_[k];process_backlog_[k];__netif_receive_skb_[k];ip_rcv_[k];ip_rcv_finish_[k];ip_local_deliver_[k];ip_local_deliver_finish_[k];tcp_v4_rcv_[k];tcp_v4_do_rcv_[k];tcp_rcv_established_[k];tcp_ack_[k];tcp_clean_rtx_queue_[k];bictcp_acked_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];__do_softirq_[k];net_rx_action_[k];process_backlog_[k];__netif_receive_skb_[k];ip_rcv_[k];ip_rcv_finish_[k];ip_local_deliver_[k];ip_local_deliver_finish_[k];tcp_v4_rcv_[k];tcp_v4_do_rcv_[k];tcp_rcv_established_[k];tcp_ack_[k];tcp_clean_rtx_queue_[k];ktime_get_real_[k];getnstimeofday_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];__do_softirq_[k];net_rx_action_[k];process_backlog_[k];__netif_receive_skb_[k];ip_rcv_[k];ip_rcv_finish_[k];ip_local_deliver_[k];ip_local_deliver_finish_[k];tcp_v4_rcv_[k];tcp_v4_do_rcv_[k];tcp_rcv_established_[k];tcp_ack_[k];tcp_clean_rtx_queue_[k];ktime_get_real_[k];getnstimeofday_[k];xen_clocksource_get_cycles_[k];xen_clocksource_read_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];__do_softirq_[k];net_rx_action_[k];process_backlog_[k];__netif_receive_skb_[k];ip_rcv_[k];ip_rcv_finish_[k];ip_local_deliver_[k];ip_local_deliver_finish_[k];tcp_v4_rcv_[k];tcp_v4_do_rcv_[k];tcp_rcv_established_[k];tcp_ack_[k];tcp_clean_rtx_queue_[k];tcp_rtt_estimator_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];__do_softirq_[k];net_rx_action_[k];process_backlog_[k];__netif_receive_skb_[k];ip_rcv_[k];ip_rcv_finish_[k];ip_local_deliver_[k];ip_local_deliver_finish_[k];tcp_v4_rcv_[k];tcp_v4_do_rcv_[k];tcp_rcv_established_[k];tcp_ack_[k];tcp_clean_rtx_queue_[k];tcp_valid_rtt_meas_[k];tcp_rtt_estimator_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];__do_softirq_[k];net_rx_action_[k];process_backlog_[k];__netif_receive_skb_[k];ip_rcv_[k];ip_rcv_finish_[k];ip_local_deliver_finish_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];local_bh_enable_[k];do_softirq_[k];call_softirq_[k];rcu_bh_qs_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_local_out_[k];ip_output_[k];ip_finish_output_[k];dev_queue_xmit_[k];netif_skb_features_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ip_queue_xmit_[k];ip_output_[k] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ktime_get_real_[k];getnstimeofday_[k];xen_clocksource_get_cycles_[k];pvclock_clocksource_read_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ktime_get_real_[k];getnstimeofday_[k];xen_clocksource_get_cycles_[k];xen_clocksource_read_[k];pvclock_clocksource_read_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];ktime_get_real_[k];xen_clocksource_get_cycles_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];__tcp_push_pending_frames_[k];tcp_write_xmit_[k];tcp_transmit_skb_[k];skb_dst_set_noref_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];lock_sock_nested_[k];_raw_spin_lock_bh_[k];local_bh_disable_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];sk_stream_alloc_skb_[k];__alloc_skb_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];sk_stream_alloc_skb_[k];__alloc_skb_[k];__kmalloc_node_track_caller_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];sk_stream_alloc_skb_[k];__alloc_skb_[k];__kmalloc_node_track_caller_[k];arch_local_irq_save_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];sk_stream_alloc_skb_[k];__alloc_skb_[k];__phys_addr_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];sk_stream_alloc_skb_[k];__alloc_skb_[k];get_slab_[k] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];sk_stream_alloc_skb_[k];__alloc_skb_[k];kmem_cache_alloc_node_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];sk_stream_alloc_skb_[k];ksize_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];tcp_send_mss_[k];tcp_current_mss_[k];ipv4_mtu_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];tcp_send_mss_[k];tcp_current_mss_[k];tcp_established_options_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];tcp_send_mss_[k];tcp_xmit_size_goal_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];do_sync_write_[k];sock_aio_write_[k];do_sock_write.isra.10_[k];inet_sendmsg_[k];tcp_sendmsg_[k];tcp_xmit_size_goal_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];fsnotify_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];fsnotify_[k];__srcu_read_lock_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k];apparmor_file_permission_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k];security_file_permission_[k];apparmor_file_permission_[k];common_file_perm_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/FileDispatcherImpl:.write0_[j];write;system_call_fastpath_[k];sys_write_[k];vfs_write_[k];sock_aio_write_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.write_[j];sun/nio/ch/SocketChannelImpl:.writerCleanup_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/buffer/PooledUnsafeDirectByteBuf:.readBytes_[j];sun/nio/ch/SocketChannelImpl:.writerCleanup_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/ChannelOutboundHandlerAdapter:.flush_[j];io/netty/channel/AbstractChannelHandlerContext:.flush_[j];io/netty/channel/DefaultChannelPipeline$HeadContext:.flush_[j];io/netty/channel/AbstractChannel$AbstractUnsafe:.flush0_[j];io/netty/channel/nio/AbstractNioByteChannel:.doWrite_[j];io/netty/util/Recycler:.recycle_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j];io/netty/channel/ChannelDuplexHandler:.flush_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelReadComplete_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j];org/vertx/java/core/net/impl/VertxHandler:.channelReadComplete_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/buffer/AbstractReferenceCountedByteBuf:.release_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];java/util/concurrent/ConcurrentHashMap:.get_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/mozilla/javascript/Context:.getWrapFactory_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j] 3 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/ScriptableObject:.getParentScope_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/WrapFactory:.wrapAsJavaObject_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/WrapFactory:.wrapAsJavaObject_[j];java/util/HashMap:.get_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/WrapFactory:.wrap_[j];java/util/HashMap:.get_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.getObjectProp_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.getObjectProp_[j];org/mozilla/javascript/ScriptableObject$RelinkedSlot:.getValue_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.getObjectProp_[j];vtable chunks_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.nameOrFunction_[j];org/mozilla/javascript/ScriptableObject$Slot:.getValue_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.name_[j];org/mozilla/javascript/IdScriptableObject:.get_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.getPropFunctionAndThis_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/IdScriptableObject:.findInstanceIdInfo_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/IdScriptableObject:.has_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/IdScriptableObject:.has_[j];org/mozilla/javascript/ScriptableObject:.getSlot_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/IdScriptableObject:.put_[j];org/mozilla/javascript/ScriptableObject:.getSlot_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/IdScriptableObject:.setAttributes_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/MemberBox:.invoke_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/WrapFactory:.wrap_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.findFunction_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaObject:.get_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.createFunctionActivation_[j];org/mozilla/javascript/IdScriptableObject:.get_[j];org/mozilla/javascript/ScriptableObject:.getSlot_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.createFunctionActivation_[j];org/mozilla/javascript/IdScriptableObject:.put_[j];org/mozilla/javascript/ScriptableObject:.getSlot_[j];org/mozilla/javascript/ScriptableObject:.createSlot_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.createFunctionActivation_[j];org/mozilla/javascript/IdScriptableObject:.setAttributes_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.createFunctionActivation_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.getObjectProp_[j];org/mozilla/javascript/ScriptableObject$Slot:.getValue_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.getPropFunctionAndThis_[j];org/mozilla/javascript/NativeJavaObject:.get_[j];java/util/HashMap:.get_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];jint_disjoint_arraycopy_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/IdScriptableObject:.get_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/IdScriptableObject:.has_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.createFunctionActivation_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.createFunctionActivation_[j];org/mozilla/javascript/IdScriptableObject:.put_[j];org/mozilla/javascript/ScriptableObject:.getSlot_[j];org/mozilla/javascript/ScriptableObject:.createSlot_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.createFunctionActivation_[j];org/mozilla/javascript/IdScriptableObject:.setAttributes_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.getObjectProp_[j];org/mozilla/javascript/IdScriptableObject:.get_[j];org/mozilla/javascript/ScriptableObject:.getSlot_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.nameOrFunction_[j];org/mozilla/javascript/IdScriptableObject:.get_[j];org/mozilla/javascript/ScriptableObject$RelinkedSlot:.getValue_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.setObjectProp_[j];org/mozilla/javascript/IdScriptableObject:.findInstanceIdInfo_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.setObjectProp_[j];org/mozilla/javascript/IdScriptableObject:.put_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.setObjectProp_[j];org/mozilla/javascript/IdScriptableObject:.put_[j];org/mozilla/javascript/ScriptableObject:.getSlot_[j];org/mozilla/javascript/ScriptableObject:.createSlot_[j] 3 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.setObjectProp_[j];org/mozilla/javascript/ScriptableObject:.getSlot_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.setObjectProp_[j];vtable chunks_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/optimizer/OptRuntime:.call2_[j];org/mozilla/javascript/NativeFunction:.initScriptFunction_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/optimizer/OptRuntime:.call2_[j];org/mozilla/javascript/ScriptRuntime:.createFunctionActivation_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/optimizer/OptRuntime:.call2_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.createFunctionActivation_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/optimizer/OptRuntime:.call2_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.createFunctionActivation_[j];org/mozilla/javascript/IdScriptableObject:.get_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/optimizer/OptRuntime:.call2_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.setObjectProp_[j];org/mozilla/javascript/IdScriptableObject:.has_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/optimizer/OptRuntime:.call2_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.setObjectProp_[j];org/mozilla/javascript/IdScriptableObject:.put_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/optimizer/OptRuntime:.call2_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.setObjectProp_[j];org/mozilla/javascript/IdScriptableObject:.put_[j];org/mozilla/javascript/ScriptableObject:.getSlot_[j];org/mozilla/javascript/ScriptableObject:.createSlot_[j] 6 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.newObject_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/optimizer/OptRuntime:.call2_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptableObject:.getParentScope_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.setObjectProp_[j];org/mozilla/javascript/IdScriptableObject:.has_[j] 4 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.setObjectProp_[j];org/mozilla/javascript/IdScriptableObject:.has_[j];org/mozilla/javascript/ScriptableObject:.getSlot_[j] 5 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.setObjectProp_[j];org/mozilla/javascript/IdScriptableObject:.put_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.setObjectProp_[j];org/mozilla/javascript/IdScriptableObject:.put_[j];org/mozilla/javascript/ScriptableObject:.getSlot_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.setObjectProp_[j];org/mozilla/javascript/IdScriptableObject:.put_[j];org/mozilla/javascript/ScriptableObject:.getSlot_[j];org/mozilla/javascript/ScriptableObject:.createSlot_[j] 6 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptableObject:.getPrototype_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptableObject:.getParentScope_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/TopLevel:.getBuiltinPrototype_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/optimizer/OptRuntime:.call2_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/optimizer/OptRuntime:.call2_[j];org/mozilla/javascript/ScriptRuntime:.name_[j];org/mozilla/javascript/ScriptRuntime:.nameOrFunction_[j];vtable chunks_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/optimizer/OptRuntime:.call2_[j];org/mozilla/javascript/ScriptRuntime:.setObjectProp_[j];org/mozilla/javascript/IdScriptableObject:.has_[j];org/mozilla/javascript/ScriptableObject:.getSlot_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/optimizer/OptRuntime:.call2_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.createFunctionActivation_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/optimizer/OptRuntime:.call2_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.createFunctionActivation_[j];org/mozilla/javascript/IdScriptableObject:.setAttributes_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/optimizer/OptRuntime:.call2_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.createFunctionActivation_[j];org/mozilla/javascript/TopLevel:.getBuiltinPrototype_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/optimizer/OptRuntime:.call2_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.setObjectProp_[j];org/mozilla/javascript/IdScriptableObject:.put_[j];org/mozilla/javascript/ScriptableObject:.getSlot_[j];org/mozilla/javascript/ScriptableObject:.createSlot_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/ScriptRuntime:.indexFromString_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/ScriptRuntime:.setObjectElem_[j];org/mozilla/javascript/ScriptRuntime:.indexFromString_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];io/netty/handler/codec/http/DefaultHttpHeaders:.set_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j] 3 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];org/vertx/java/core/http/impl/VertxHttpHandler:.write_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];org/vertx/java/core/http/impl/VertxHttpHandler:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/handler/codec/MessageToMessageEncoder:.write_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];org/vertx/java/core/http/impl/VertxHttpHandler:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/handler/codec/MessageToMessageEncoder:.write_[j];io/netty/buffer/AbstractByteBuf:.writeBytes_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];org/vertx/java/core/http/impl/VertxHttpHandler:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/handler/codec/MessageToMessageEncoder:.write_[j];io/netty/handler/codec/http/HttpObjectEncoder:.encode_[j];io/netty/buffer/AbstractByteBuf:.writeBytes_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];org/vertx/java/core/http/impl/VertxHttpHandler:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/handler/codec/MessageToMessageEncoder:.write_[j];io/netty/handler/codec/http/HttpObjectEncoder:.encode_[j];io/netty/buffer/AbstractByteBufAllocator:.directBuffer_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];org/vertx/java/core/http/impl/VertxHttpHandler:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/handler/codec/MessageToMessageEncoder:.write_[j];io/netty/handler/codec/http/HttpObjectEncoder:.encode_[j];io/netty/buffer/AbstractByteBufAllocator:.directBuffer_[j];io/netty/util/concurrent/FastThreadLocal:.get_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];org/vertx/java/core/http/impl/VertxHttpHandler:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/handler/codec/MessageToMessageEncoder:.write_[j];io/netty/handler/codec/http/HttpObjectEncoder:.encode_[j];java/util/ArrayList:.add_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];org/vertx/java/core/http/impl/VertxHttpHandler:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/handler/codec/MessageToMessageEncoder:.write_[j];io/netty/util/internal/RecyclableArrayList:.newInstance_[j];io/netty/util/concurrent/FastThreadLocal:.get_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];org/vertx/java/core/http/impl/VertxHttpHandler:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/handler/codec/MessageToMessageEncoder:.write_[j];java/util/ArrayList:.ensureExplicitCapacity_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];org/vertx/java/core/http/impl/VertxHttpHandler:.write_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];io/netty/handler/codec/MessageToMessageEncoder:.write_[j];vtable chunks_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j];io/netty/channel/AbstractChannelHandlerContext:.write_[j];org/vertx/java/core/http/impl/VertxHttpHandler:.write_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j];io/netty/handler/codec/http/DefaultHttpHeaders:.add0_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j];io/netty/handler/codec/http/DefaultHttpHeaders:.set_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/NativeJavaMethod:.call_[j];org/mozilla/javascript/MemberBox:.invoke_[j];sun/reflect/DelegatingMethodAccessorImpl:.invoke_[j];sun/nio/cs/UTF_8$Encoder:._[j];jbyte_disjoint_arraycopy_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];org/vertx/java/core/net/impl/VertxHandler:.channelRead_[j];org/vertx/java/core/http/impl/DefaultHttpServer$ServerHandler:.doMessageReceived_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vhello_js_1:.call_[j];org/mozilla/javascript/gen/file__home_bgregg_testtest_vert_x_2_1_4_sys_mods_io_vertx_lang_js_1_1_0_[j];org/mozilla/javascript/ScriptRuntime:.name_[j];org/mozilla/javascript/ScriptRuntime:.nameOrFunction_[j];org/mozilla/javascript/IdScriptableObject:.get_[j];org/mozilla/javascript/ScriptableObject$RelinkedSlot:.getValue_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/handler/codec/http/HttpObjectDecoder:.decode_[j];io/netty/buffer/AbstractByteBuf:.forEachByteAsc0_[j];io/netty/util/internal/AppendableCharSequence:.append_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/handler/codec/http/HttpObjectDecoder:.decode_[j];io/netty/handler/codec/http/HttpHeaders:.isTransferEncodingChunked_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/handler/codec/http/HttpObjectDecoder:.decode_[j];io/netty/handler/codec/http/HttpObjectDecoder:.findWhitespace_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/handler/codec/http/HttpObjectDecoder:.decode_[j];io/netty/handler/codec/http/HttpObjectDecoder:.readHeaders_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/handler/codec/http/HttpObjectDecoder:.decode_[j];io/netty/handler/codec/http/HttpObjectDecoder:.readHeaders_[j];io/netty/buffer/AbstractByteBuf:.forEachByteAsc0_[j] 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/handler/codec/http/HttpObjectDecoder:.decode_[j];io/netty/handler/codec/http/HttpObjectDecoder:.readHeaders_[j];io/netty/handler/codec/http/HttpHeaders:.hash_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/handler/codec/http/HttpObjectDecoder:.decode_[j];io/netty/handler/codec/http/HttpObjectDecoder:.readHeaders_[j];io/netty/handler/codec/http/HttpObjectDecoder:.splitHeader_[j] 5 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/AbstractChannelHandlerContext:.fireChannelRead_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelRead_[j];io/netty/handler/codec/http/HttpObjectDecoder:.decode_[j];io/netty/handler/codec/http/HttpObjectDecoder:.readHeaders_[j];java/util/Arrays:.fill_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j];sun/nio/ch/SocketChannelImpl:.read_[j];java/nio/channels/spi/AbstractInterruptibleChannel:.end_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j];sun/nio/ch/SocketChannelImpl:.read_[j];sun/nio/ch/FileDispatcherImpl:.read0_[j];read 2 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j];sun/nio/ch/SocketChannelImpl:.read_[j];sun/nio/ch/FileDispatcherImpl:.read0_[j];read;sys_read_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j];sun/nio/ch/SocketChannelImpl:.read_[j];sun/nio/ch/FileDispatcherImpl:.read0_[j];read;system_call_fastpath_[k];sys_read_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j];sun/nio/ch/SocketChannelImpl:.read_[j];sun/nio/ch/FileDispatcherImpl:.read0_[j];read;system_call_fastpath_[k];sys_read_[k];do_sync_read_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j];sun/nio/ch/SocketChannelImpl:.read_[j];sun/nio/ch/FileDispatcherImpl:.read0_[j];read;system_call_fastpath_[k];sys_read_[k];vfs_read_[k];do_sync_read_[k];sock_aio_read_[k];sock_aio_read.part.13_[k];do_sock_read.isra.12_[k];inet_recvmsg_[k];__kfree_skb_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j];sun/nio/ch/SocketChannelImpl:.read_[j];sun/nio/ch/FileDispatcherImpl:.read0_[j];read;system_call_fastpath_[k];sys_read_[k];vfs_read_[k];do_sync_read_[k];sock_aio_read_[k];sock_aio_read.part.13_[k];do_sock_read.isra.12_[k];inet_recvmsg_[k];tcp_rcv_space_adjust_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j];sun/nio/ch/SocketChannelImpl:.read_[j];sun/nio/ch/FileDispatcherImpl:.read0_[j];read;system_call_fastpath_[k];sys_read_[k];vfs_read_[k];do_sync_read_[k];sock_aio_read_[k];sock_aio_read.part.13_[k];do_sock_read.isra.12_[k];inet_recvmsg_[k];tcp_recvmsg_[k];__kfree_skb_[k];skb_release_data_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j];sun/nio/ch/SocketChannelImpl:.read_[j];sun/nio/ch/FileDispatcherImpl:.read0_[j];read;system_call_fastpath_[k];sys_read_[k];vfs_read_[k];do_sync_read_[k];sock_aio_read_[k];sock_aio_read.part.13_[k];do_sock_read.isra.12_[k];inet_recvmsg_[k];tcp_recvmsg_[k];__kfree_skb_[k];skb_release_head_state_[k];dst_release_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j];sun/nio/ch/SocketChannelImpl:.read_[j];sun/nio/ch/FileDispatcherImpl:.read0_[j];read;system_call_fastpath_[k];sys_read_[k];vfs_read_[k];do_sync_read_[k];sock_aio_read_[k];sock_aio_read.part.13_[k];do_sock_read.isra.12_[k];inet_recvmsg_[k];tcp_recvmsg_[k];_raw_spin_lock_bh_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j];sun/nio/ch/SocketChannelImpl:.read_[j];sun/nio/ch/FileDispatcherImpl:.read0_[j];read;system_call_fastpath_[k];sys_read_[k];vfs_read_[k];do_sync_read_[k];sock_aio_read_[k];sock_aio_read.part.13_[k];do_sock_read.isra.12_[k];inet_recvmsg_[k];tcp_recvmsg_[k];skb_copy_datagram_iovec_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j];sun/nio/ch/SocketChannelImpl:.read_[j];sun/nio/ch/FileDispatcherImpl:.read0_[j];read;system_call_fastpath_[k];sys_read_[k];vfs_read_[k];do_sync_read_[k];sock_aio_read_[k];sock_aio_read.part.13_[k];do_sock_read.isra.12_[k];inet_recvmsg_[k];tcp_recvmsg_[k];skb_copy_datagram_iovec_[k];copy_user_enhanced_fast_string_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j];sun/nio/ch/SocketChannelImpl:.read_[j];sun/nio/ch/FileDispatcherImpl:.read0_[j];read;system_call_fastpath_[k];sys_read_[k];vfs_read_[k];do_sync_read_[k];sock_aio_read_[k];sock_aio_read.part.13_[k];do_sock_read.isra.12_[k];inet_recvmsg_[k];tcp_recvmsg_[k];tcp_cleanup_rbuf_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j];sun/nio/ch/SocketChannelImpl:.read_[j];sun/nio/ch/FileDispatcherImpl:.read0_[j];read;system_call_fastpath_[k];sys_read_[k];vfs_read_[k];do_sync_read_[k];sock_aio_read_[k];sock_aio_read.part.13_[k];do_sock_read.isra.12_[k];inet_recvmsg_[k];tcp_recvmsg_[k];tcp_cleanup_rbuf_[k];__tcp_select_window_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j];sun/nio/ch/SocketChannelImpl:.read_[j];sun/nio/ch/FileDispatcherImpl:.read0_[j];read;system_call_fastpath_[k];sys_read_[k];vfs_read_[k];rw_verify_area_[k] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe:.read_[j];io/netty/handler/codec/ByteToMessageDecoder:.channelReadComplete_[j] 1 +java;start_thread;java_start;JavaThread::run;JavaThread::thread_main_inner;thread_entry;JavaCalls::call_virtual;JavaCalls::call_virtual;JavaCalls::call_helper;call_stub_[j];Interpreter_[j];Interpreter_[j];io/netty/channel/nio/NioEventLoop:.run_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeys_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKeysOptimized_[j];io/netty/channel/nio/NioEventLoop:.processSelectedKey_[j];io/netty/channel/socket/nio/NioSocketChannel:.doReadBytes_[j] 1 +java;start_thread;java_start;VMThread::run;VMThread::loop;VMThread::evaluate_operation;VM_Operation::evaluate;VM_ParallelGCFailedAllocation::doit;ParallelScavengeHeap::failed_mem_allocate;PSScavenge::invoke;PSScavenge::invoke_no_policy;PSIsAliveClosure::do_object_b 1 +java;start_thread;java_start;VMThread::run;VMThread::loop;VMThread::evaluate_operation;VM_Operation::evaluate;VM_ParallelGCFailedAllocation::doit;ParallelScavengeHeap::failed_mem_allocate;PSScavenge::invoke;PSScavenge::invoke_no_policy;StringTable::unlink_or_oops_do 2 +java;start_thread;java_start;VMThread::run;VMThread::loop;VMThread::evaluate_operation;VM_Operation::evaluate;VM_ParallelGCFailedAllocation::doit;ParallelScavengeHeap::failed_mem_allocate;PSScavenge::invoke;PSScavenge::invoke_no_policy;pthread_cond_signal@@GLIBC_2.3.2;system_call_fastpath_[k];sys_futex_[k];do_futex_[k];futex_wake_op_[k] 1 +java;write;check_events_[k];hypercall_page_[k] 3 diff --git a/historyserver/dashboard/ray/client/public/speedscope-1.5.3/release.txt b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/release.txt new file mode 100644 index 00000000000..b465301e734 --- /dev/null +++ b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/release.txt @@ -0,0 +1,3 @@ +speedscope@1.5.3 +Thu Jan 16 00:10:56 PST 2020 +707462e9cffec2bda49587c39d621ba89d1b51cb diff --git a/historyserver/dashboard/ray/client/public/speedscope-1.5.3/reset.7ae984ff.css b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/reset.7ae984ff.css new file mode 100644 index 00000000000..f73b094c15b --- /dev/null +++ b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/reset.7ae984ff.css @@ -0,0 +1 @@ +a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}table{border-collapse:collapse;border-spacing:0}html{overflow:hidden}body,html{height:100%}body{overflow:auto} \ No newline at end of file diff --git a/historyserver/dashboard/ray/client/public/speedscope-1.5.3/speedscope.75eb7d8e.js b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/speedscope.75eb7d8e.js new file mode 100644 index 00000000000..97c9f10f32f --- /dev/null +++ b/historyserver/dashboard/ray/client/public/speedscope-1.5.3/speedscope.75eb7d8e.js @@ -0,0 +1,173 @@ +parcelRequire=function(e,r,n,t){var i="function"==typeof parcelRequire&&parcelRequire,o="function"==typeof require&&require;function u(n,t){if(!r[n]){if(!e[n]){var f="function"==typeof parcelRequire&&parcelRequire;if(!t&&f)return f(n,!0);if(i)return i(n,!0);if(o&&"string"==typeof n)return o(n);var c=new Error("Cannot find module '"+n+"'");throw c.code="MODULE_NOT_FOUND",c}p.resolve=function(r){return e[n][1][r]||r};var l=r[n]=new u.Module(n);e[n][0].call(l.exports,p,l,l.exports,this)}return r[n].exports;function p(e){return u(p.resolve(e))}}u.isParcelRequire=!0,u.Module=function(e){this.id=e,this.bundle=u,this.exports={}},u.modules=e,u.cache=r,u.parent=i,u.register=function(r,n){e[r]=[function(e,r){r.exports=n},{}]};for(var f=0;f2;)n.push(arguments[s]);for(i&&null!=i.children&&(n.length||n.push(i.children),delete i.children);n.length;)if((a=n.pop())&&void 0!==a.pop)for(s=a.length;s--;)n.push(a[s]);else"boolean"==typeof a&&(a=null),(p="function"!=typeof r)&&(null==a?a="":"number"==typeof a?a=String(a):"string"!=typeof a&&(p=!1)),p&&l?c[c.length-1]+=a:c===o?c=[a]:c.push(a),l=p;var u=new e;return u.nodeName=r,u.children=c,u.attributes=null==i?void 0:i,u.key=null==i?void 0:i.key,void 0!==t.vnode&&t.vnode(u),u}function i(e,t){for(var n in t)e[n]=t[n];return e}var l="function"==typeof Promise?Promise.resolve().then.bind(Promise.resolve()):setTimeout;function a(e,t){return r(e.nodeName,i(i({},e.attributes),t),arguments.length>2?[].slice.call(arguments,2):e.children)}var p=/acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i,s=[];function c(e){!e._dirty&&(e._dirty=!0)&&1==s.push(e)&&(t.debounceRendering||l)(u)}function u(){var e,t=s;for(s=[];e=t.pop();)e._dirty&&A(e)}function f(e,t,n){return"string"==typeof t||"number"==typeof t?void 0!==e.splitText:"string"==typeof t.nodeName?!e._componentConstructor&&d(e,t.nodeName):n||e._componentConstructor===t.nodeName}function d(e,t){return e.normalizedNodeName===t||e.nodeName.toLowerCase()===t.toLowerCase()}function _(e){var t=i({},e.attributes);t.children=e.children;var n=e.nodeName.defaultProps;if(void 0!==n)for(var o in n)void 0===t[o]&&(t[o]=n[o]);return t}function v(e,t){var n=t?document.createElementNS("http://www.w3.org/2000/svg",e):document.createElement(e);return n.normalizedNodeName=e,n}function m(e){var t=e.parentNode;t&&t.removeChild(e)}function h(e,t,n,o,r){if("className"===t&&(t="class"),"key"===t);else if("ref"===t)n&&n(null),o&&o(e);else if("class"!==t||r)if("style"===t){if(o&&"string"!=typeof o&&"string"!=typeof n||(e.style.cssText=o||""),o&&"object"==typeof o){if("string"!=typeof n)for(var i in n)i in o||(e.style[i]="");for(var i in o)e.style[i]="number"==typeof o[i]&&!1===p.test(i)?o[i]+"px":o[i]}}else if("dangerouslySetInnerHTML"===t)o&&(e.innerHTML=o.__html||"");else if("o"==t[0]&&"n"==t[1]){var l=t!==(t=t.replace(/Capture$/,""));t=t.toLowerCase().substring(2),o?n||e.addEventListener(t,y,l):e.removeEventListener(t,y,l),(e._listeners||(e._listeners={}))[t]=o}else if("list"!==t&&"type"!==t&&!r&&t in e)b(e,t,null==o?"":o),null!=o&&!1!==o||e.removeAttribute(t);else{var a=r&&t!==(t=t.replace(/^xlink\:?/,""));null==o||!1===o?a?e.removeAttributeNS("http://www.w3.org/1999/xlink",t.toLowerCase()):e.removeAttribute(t):"function"!=typeof o&&(a?e.setAttributeNS("http://www.w3.org/1999/xlink",t.toLowerCase(),o):e.setAttribute(t,o))}else e.className=o||""}function b(e,t,n){try{e[t]=n}catch(e){}}function y(e){return this._listeners[e.type](t.event&&t.event(e)||e)}var x=[],C=0,g=!1,N=!1;function k(){for(var e;e=x.pop();)t.afterMount&&t.afterMount(e),e.componentDidMount&&e.componentDidMount()}function w(e,t,n,o,r,i){C++||(g=null!=r&&void 0!==r.ownerSVGElement,N=null!=e&&!("__preactattr_"in e));var l=S(e,t,n,o,i);return r&&l.parentNode!==r&&r.appendChild(l),--C||(N=!1,i||k()),l}function S(e,t,n,o,r){var i=e,l=g;if(null!=t&&"boolean"!=typeof t||(t=""),"string"==typeof t||"number"==typeof t)return e&&void 0!==e.splitText&&e.parentNode&&(!e._component||r)?e.nodeValue!=t&&(e.nodeValue=t):(i=document.createTextNode(t),e&&(e.parentNode&&e.parentNode.replaceChild(i,e),L(e,!0))),i.__preactattr_=!0,i;var a=t.nodeName;if("function"==typeof a)return D(e,t,n,o);if(g="svg"===a||"foreignObject"!==a&&g,a=String(a),(!e||!d(e,a))&&(i=v(a,g),e)){for(;e.firstChild;)i.appendChild(e.firstChild);e.parentNode&&e.parentNode.replaceChild(i,e),L(e,!0)}var p=i.firstChild,s=i.__preactattr_,c=t.children;if(null==s){s=i.__preactattr_={};for(var u=i.attributes,f=u.length;f--;)s[u[f].name]=u[f].value}return!N&&c&&1===c.length&&"string"==typeof c[0]&&null!=p&&void 0!==p.splitText&&null==p.nextSibling?p.nodeValue!=c[0]&&(p.nodeValue=c[0]):(c&&c.length||null!=p)&&U(i,c,n,o,N||null!=s.dangerouslySetInnerHTML),P(i,t.attributes,s),g=l,i}function U(e,t,n,o,r){var i,l,a,p,s,c=e.childNodes,u=[],d={},_=0,v=0,h=c.length,b=0,y=t?t.length:0;if(0!==h)for(var x=0;x0?"Unexpected "+(c.length>1?"keys":"key")+' "'+c.join('", "')+'" found in '+a+'. Expected to find one of the known reducer keys instead: "'+i.join('", "')+'". Unexpected keys will be ignored.':void 0}function f(e){Object.keys(e).forEach(function(t){var r=e[t];if(void 0===r(void 0,{type:n.INIT}))throw new Error('Reducer "'+t+"\" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined. If you don't want to set a value for this reducer, you can use null instead of undefined.");if(void 0===r(void 0,{type:"@@redux/PROBE_UNKNOWN_ACTION_"+Math.random().toString(36).substring(7).split("").join(".")}))throw new Error('Reducer "'+t+"\" returned undefined when probed with a random type. Don't try to handle "+n.INIT+' or other actions in "redux/*" namespace. They are considered private. Instead, you must return the current state for any unknown actions, unless it is undefined, in which case you must return the initial state, regardless of the action type. The initial state may not be undefined, but can be null.')})}function l(e){for(var t=Object.keys(e),r={},n=0;n0&&void 0!==arguments[0]?arguments[0]:{},t=arguments[1];if(u)throw u;for(var n=!1,o={},a=0;a=0||Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n},h=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},b=!1;function y(){b||(b=!0,p(" does not support changing `store` on the fly. It is most likely that you see this error because you updated to Redux 2.x and React Redux 2.x which no longer hot reload reducers automatically. See https://github.com/reactjs/react-redux/releases/tag/v2.0.0 for the migration instructions."))}function v(){var t,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"store",o=arguments[1]||n+"Subscription",i=function(t){function e(r,o){a(this,e);var i=h(this,t.call(this,r,o));return i[n]=r.store,i}return f(e,t),e.prototype.getChildContext=function(){var t;return(t={})[n]=this[n],t[o]=null,t},e.prototype.render=function(){return r.only(this.props.children)},e}(e.Component);return i.prototype.componentWillReceiveProps=function(t){this[n]!==t.store&&y()},i.childContextTypes=((t={})[n]=u.isRequired,t[o]=s,t),i}var m=v(),P={childContextTypes:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},O={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},S=Object.defineProperty,g=Object.getOwnPropertyNames,w=Object.getOwnPropertySymbols,C=Object.getOwnPropertyDescriptor,j=Object.getPrototypeOf,T=j&&j(Object);function x(t,e,n){if("string"!=typeof e){if(T){var r=j(e);r&&r!==T&&x(t,r,n)}var o=g(e);w&&(o=o.concat(w(e)));for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{},i=o.getDisplayName,p=void 0===i?function(t){return"ConnectAdvanced("+t+")"}:i,c=o.methodName,b=void 0===c?"connectAdvanced":c,y=o.renderCountProp,v=void 0===y?void 0:y,m=o.shouldHandleStateChanges,P=void 0===m||m,O=o.storeKey,S=void 0===O?"store":O,g=o.withRef,w=void 0!==g&&g,C=l(o,["getDisplayName","methodName","renderCountProp","shouldHandleStateChanges","storeKey","withRef"]),j=S+"Subscription",T=R++,x=((n={})[S]=u,n[j]=s,n),E=((r={})[j]=s,r);return function(n){q("function"==typeof n,"You must pass a component to the function returned by "+b+". Instead received "+JSON.stringify(n));var r=n.displayName||n.name||"Component",o=p(r),i=d({},C,{getDisplayName:p,methodName:b,renderCountProp:v,shouldHandleStateChanges:P,storeKey:S,withRef:w,displayName:o,wrappedComponentName:r,WrappedComponent:n}),s=function(r){function s(t,e){a(this,s);var n=h(this,r.call(this,t,e));return n.version=T,n.state={},n.renderCount=0,n.store=t[S]||e[S],n.propsMode=Boolean(t[S]),n.setWrappedInstance=n.setWrappedInstance.bind(n),q(n.store,'Could not find "'+S+'" in either the context or props of "'+o+'". Either wrap the root component in a , or explicitly pass "'+S+'" as a prop to "'+o+'".'),n.initSelector(),n.initSubscription(),n}return f(s,r),s.prototype.getChildContext=function(){var t,e=this.propsMode?null:this.subscription;return(t={})[j]=e||this.context[j],t},s.prototype.componentDidMount=function(){P&&(this.subscription.trySubscribe(),this.selector.run(this.props),this.selector.shouldComponentUpdate&&this.forceUpdate())},s.prototype.componentWillReceiveProps=function(t){this.selector.run(t)},s.prototype.shouldComponentUpdate=function(){return this.selector.shouldComponentUpdate},s.prototype.componentWillUnmount=function(){this.subscription&&this.subscription.tryUnsubscribe(),this.subscription=null,this.notifyNestedSubs=W,this.store=null,this.selector.run=W,this.selector.shouldComponentUpdate=!1},s.prototype.getWrappedInstance=function(){return q(w,"To access the wrapped instance, you need to specify { withRef: true } in the options argument of the "+b+"() call."),this.wrappedInstance},s.prototype.setWrappedInstance=function(t){this.wrappedInstance=t},s.prototype.initSelector=function(){var e=t(this.store.dispatch,i);this.selector=F(e,this.store),this.selector.run(this.props)},s.prototype.initSubscription=function(){if(P){var t=(this.propsMode?this.props:this.context)[j];this.subscription=new M(this.store,t,this.onStateChange.bind(this)),this.notifyNestedSubs=this.subscription.notifyNestedSubs.bind(this.subscription)}},s.prototype.onStateChange=function(){this.selector.run(this.props),this.selector.shouldComponentUpdate?(this.componentDidUpdate=this.notifyNestedSubsOnComponentDidUpdate,this.setState(I)):this.notifyNestedSubs()},s.prototype.notifyNestedSubsOnComponentDidUpdate=function(){this.componentDidUpdate=void 0,this.notifyNestedSubs()},s.prototype.isSubscribed=function(){return Boolean(this.subscription)&&this.subscription.isSubscribed()},s.prototype.addExtraProps=function(t){if(!(w||v||this.propsMode&&this.subscription))return t;var e=d({},t);return w&&(e.ref=this.setWrappedInstance),v&&(e[v]=this.renderCount++),this.propsMode&&this.subscription&&(e[j]=this.subscription),e},s.prototype.render=function(){var t=this.selector;if(t.shouldComponentUpdate=!1,t.error)throw t.error;return(0,e.h)(n,this.addExtraProps(t.props))},s}(e.Component);return s.WrappedComponent=n,s.displayName=o,s.childContextTypes=E,s.contextTypes=x,s.prototype.componentWillUpdate=function(){var t=this;if(this.version!==T){this.version=T,this.initSelector();var e=[];this.subscription&&(e=this.subscription.listeners.get(),this.subscription.tryUnsubscribe()),this.initSubscription(),P&&(this.subscription.trySubscribe(),e.forEach(function(e){return t.subscription.listeners.subscribe(e)}))}},N(s,n)}}var _=Object.prototype.hasOwnProperty;function B(t,e){return t===e?0!==t||0!==e||1/t==1/e:t!=t&&e!=e}function H(t,e){if(B(t,e))return!0;if("object"!==(void 0===t?"undefined":c(t))||null===t||"object"!==(void 0===e?"undefined":c(e))||null===e)return!1;var n=Object.keys(t),r=Object.keys(e);if(n.length!==r.length)return!1;for(var o=0;o=0;r--){var o=e[r](t);if(o)return o}return function(e,r){throw new Error("Invalid value of type "+(void 0===t?"undefined":c(t))+" for "+n+" argument when connecting component "+r.wrappedComponentName+".")}}function Wt(t,e){return t===e}function Ft(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.connectHOC,n=void 0===e?A:e,r=t.mapStateToPropsFactories,o=void 0===r?Ct:r,i=t.mapDispatchToPropsFactories,s=void 0===i?St:i,u=t.mergePropsFactories,p=void 0===u?qt:u,c=t.selectorFactory,a=void 0===c?Rt:c;return function(t,e,r){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},u=i.pure,c=void 0===u||u,f=i.areStatesEqual,h=void 0===f?Wt:f,b=i.areOwnPropsEqual,y=void 0===b?H:b,v=i.areStatePropsEqual,m=void 0===v?H:v,P=i.areMergedPropsEqual,O=void 0===P?H:P,S=l(i,["pure","areStatesEqual","areOwnPropsEqual","areStatePropsEqual","areMergedPropsEqual"]),g=It(t,o,"mapStateToProps"),w=It(e,s,"mapDispatchToProps"),C=It(r,p,"mergeProps");return n(a,d({methodName:"connect",getDisplayName:function(t){return"Connect("+t+")"},shouldHandleStateChanges:Boolean(t),initMapStateToProps:g,initMapDispatchToProps:w,initMergeProps:C,pure:c,areStatesEqual:h,areOwnPropsEqual:y,areStatePropsEqual:m,areMergedPropsEqual:O},S))}}var At=Ft(),_t={Provider:m,connect:At,connectAdvanced:A};exports.Provider=m,exports.connect=At,exports.connectAdvanced=A,exports.default=_t; +},{"preact":24,"redux":31}],36:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.StatelessComponent=void 0,exports.actionCreator=n,exports.setter=o,exports.createContainer=s,exports.bindActionCreator=c;var e=require("preact-redux"),t=require("preact");const r=new Set;function n(e){if(r.has(e))throw new Error(`Cannot re-use action type name: ${e}`);const t=(t={})=>({type:e,payload:t});return t.matches=(t=>t.type===e),t}function o(e,t){return(r=t,n)=>e.matches(n)?n.payload:r}function s(t,r){return(0,e.connect)(e=>e,e=>({dispatch:e}),(e,t,n)=>r(e,t.dispatch,n))(t)}class a extends t.Component{}function c(e,t){return r=>{e(t(r))}}exports.StatelessComponent=a; +},{"preact-redux":26,"preact":24}],102:[function(require,module,exports) { +"use strict";function t(t,i,s){return ts?s:t}Object.defineProperty(exports,"__esModule",{value:!0}),exports.clamp=t;class i{constructor(t,i){this.x=t,this.y=i}withX(t){return new i(t,this.y)}withY(t){return new i(this.x,t)}plus(t){return new i(this.x+t.x,this.y+t.y)}minus(t){return new i(this.x-t.x,this.y-t.y)}times(t){return new i(this.x*t,this.y*t)}timesPointwise(t){return new i(this.x*t.x,this.y*t.y)}dividedByPointwise(t){return new i(this.x/t.x,this.y/t.y)}dot(t){return this.x*t.x+this.y*t.y}equals(t){return this.x===t.x&&this.y===t.y}approxEquals(t,i=1e-9){return Math.abs(this.x-t.x){if(t.actions.flamechart.setHoveredNode.matches(a)&&r(a)){const{hover:t}=a.payload.args;return Object.assign({},e,{hover:t})}if(t.actions.flamechart.setSelectedNode.matches(a)&&r(a)){const{selectedNode:t}=a.payload.args;return Object.assign({},e,{selectedNode:t})}if(t.actions.flamechart.setConfigSpaceViewportRect.matches(a)&&r(a)){const{configSpaceViewportRect:t}=a.payload.args;return Object.assign({},e,{configSpaceViewportRect:t})}if(t.actions.flamechart.setLogicalSpaceViewportSize.matches(a)&&r(a)){const{logicalSpaceViewportSize:t}=a.payload.args;return Object.assign({},e,{logicalSpaceViewportSize:t})}return t.actions.setViewMode.matches(a)?Object.assign({},e,{hover:null}):e}}!function(e){e.LEFT_HEAVY="LEFT_HEAVY",e.CHRONO="CHRONO",e.SANDWICH_INVERTED_CALLERS="SANDWICH_INVERTED_CALLERS",e.SANDWICH_CALLEES="SANDWICH_CALLEES"}(a||(exports.FlamechartID=a={})); +},{"../lib/math":102,"./actions":40}],100:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.createSandwichView=l;var e=require("./flamechart-view-state"),a=require("./actions");function l(l){const r=(0,e.createFlamechartViewStateReducer)(e.FlamechartID.SANDWICH_CALLEES,l),t=(0,e.createFlamechartViewStateReducer)(e.FlamechartID.SANDWICH_INVERTED_CALLERS,l);return(e={callerCallee:null},c)=>{if(a.actions.sandwichView.setSelectedFrame.matches(c)&&function(e){const{payload:a}=e;return a.profileIndex===l}(c))return null==c.payload.args?Object.assign({},e,{callerCallee:null}):Object.assign({},e,{callerCallee:{selectedFrame:c.payload.args,calleeFlamegraph:r(void 0,c),invertedCallerFlamegraph:t(void 0,c)}});const{callerCallee:n}=e;if(n){const{calleeFlamegraph:a,invertedCallerFlamegraph:l}=n,i=r(a,c),s=t(l,c);return i===a&&s===l?e:Object.assign({},e,{callerCallee:Object.assign({},n,{calleeFlamegraph:i,invertedCallerFlamegraph:s})})}return e}} +},{"./flamechart-view-state":98,"./actions":40}],70:[function(require,module,exports) { +"use strict";function t(t){return t[t.length-1]||null}function e(t,e){t.sort(function(t,r){return e(t)99?e=">99%":t<.01?e="<0.01%":t<1?e=`${t.toFixed(2)}%`:t<10&&(e=`${t.toFixed(1)}%`),e}function f(t){return t-Math.floor(t)}function h(t){return 2*Math.abs(f(t)-.5)-1}function g(t,e,r,n,o=1){for(console.assert(!isNaN(o)&&!isNaN(n));;){if(e-t<=o)return[t,e];const s=(e+t)/2;r(s){let n;return null==e?(n=t(r),e={args:r,result:n},n):x(e.args,r)?e.result:(e.args=r,e.result=t(r),e.result)}}function y(t){let e=null;return r=>{let n;return null==e?(n=t(r),e={args:r,result:n},n):e.args===r?e.result:(e.args=r,e.result=t(r),e.result)}}function w(t){let e=null;return()=>(null==e&&(e={result:t()}),e.result)}exports.KeyedSet=s;const E=w(()=>{const t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",e=new Map;for(let r=0;r>4,"="!==u&&(o[s++]=(15&c)<<4|f>>2),"="!==a&&(o[s++]=(7&f)<<6|h)}if(s!==n)throw new Error(`Expected to decode ${n} bytes, but only decoded ${s})`);return o} +},{}],52:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.profileGroup=void 0,exports.actionCreatorWithIndex=n;var e=require("./flamechart-view-state"),t=require("./sandwich-view-state"),i=require("../lib/typed-redux"),r=require("./actions"),a=require("../lib/math"),o=require("../lib/utils");function n(e){return(0,i.actionCreator)(e)}function l(i,r){const a=(0,e.createFlamechartViewStateReducer)(e.FlamechartID.CHRONO,r),n=(0,e.createFlamechartViewStateReducer)(e.FlamechartID.LEFT_HEAVY,r),l=(0,t.createSandwichView)(r);return(e,t)=>{if(void 0===e)return{profile:i,chronoViewState:a(void 0,t),leftHeavyViewState:n(void 0,t),sandwichViewState:l(void 0,t)};const r={profile:i,chronoViewState:a(e.chronoViewState,t),leftHeavyViewState:n(e.leftHeavyViewState,t),sandwichViewState:l(e.sandwichViewState,t)};return(0,o.objectsHaveShallowEquality)(e,r)?e:r}}const c=exports.profileGroup=((e=null,t)=>{if(r.actions.setProfileGroup.matches(t)){const{indexToView:e,profiles:i,name:r}=t.payload;return{indexToView:e,name:r,profiles:i.map((e,i)=>l(e,i)(void 0,t))}}if(null!=e){const{indexToView:n,profiles:c}=e,s=(0,a.clamp)((0,i.setter)(r.actions.setProfileIndexToView,0)(n,t),0,c.length-1),u=c.map((e,i)=>l(e.profile,i)(e,t));return n===s&&(0,o.objectsHaveShallowEquality)(c,u)?e:Object.assign({},e,{indexToView:s,profiles:u})}return e}); +},{"./flamechart-view-state":98,"./sandwich-view-state":100,"../lib/typed-redux":36,"./actions":40,"../lib/math":102,"../lib/utils":70}],40:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.actions=void 0;var e=require("../lib/typed-redux"),t=require("./profiles-state"),a=exports.actions=void 0;!function(a){let o,r;a.setProfileGroup=(0,e.actionCreator)("setProfileGroup"),a.setProfileIndexToView=(0,e.actionCreator)("setProfileIndexToView"),a.setGLCanvas=(0,e.actionCreator)("setGLCanvas"),a.setViewMode=(0,e.actionCreator)("setViewMode"),a.setFlattenRecursion=(0,e.actionCreator)("setFlattenRecursion"),a.setDragActive=(0,e.actionCreator)("setDragActive"),a.setLoading=(0,e.actionCreator)("setLoading"),a.setError=(0,e.actionCreator)("setError"),a.setHashParams=(0,e.actionCreator)("setHashParams"),function(a){a.setTableSortMethod=(0,e.actionCreator)("sandwichView.setTableSortMethod"),a.setSelectedFrame=(0,t.actionCreatorWithIndex)("sandwichView.setSelectedFarmr")}(o=a.sandwichView||(a.sandwichView={})),function(e){e.setHoveredNode=(0,t.actionCreatorWithIndex)("flamechart.setHoveredNode"),e.setSelectedNode=(0,t.actionCreatorWithIndex)("flamechart.setSelectedNode"),e.setConfigSpaceViewportRect=(0,t.actionCreatorWithIndex)("flamechart.setConfigSpaceViewportRect"),e.setLogicalSpaceViewportSize=(0,t.actionCreatorWithIndex)("flamechart.setLogicalSpaceViewportSpace")}(r=a.flamechart||(a.flamechart={}))}(a||(exports.actions=a={})); +},{"../lib/typed-redux":36,"./profiles-state":52}],50:[function(require,module,exports) { +"use strict";function t(t=window.location.hash){try{if(!t.startsWith("#"))return{};const e=t.substr(1).split("&"),r={};for(const t of e){let[e,o]=t.split("=");o=decodeURIComponent(o),"profileURL"===e?r.profileURL=o:"title"===e?r.title=o:"localProfilePath"===e&&(r.localProfilePath=o)}return r}catch(t){return console.error("Error when loading hash fragment."),console.error(t),{}}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.getHashParams=t; +},{}],158:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=t;var e=/-webkit-|-moz-|-ms-/;function t(t){return"string"==typeof t&&e.test(t)}module.exports=exports.default; +},{}],123:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=i;var e=require("css-in-js-utils/lib/isPrefixedValue"),t=r(e);function r(e){return e&&e.__esModule?e:{default:e}}var u=["-webkit-","-moz-",""];function i(e,r){if("string"==typeof r&&!(0,t.default)(r)&&r.indexOf("calc(")>-1)return u.map(function(e){return r.replace(/calc\(/g,e+"calc(")})}module.exports=exports.default; +},{"css-in-js-utils/lib/isPrefixedValue":158}],124:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=u;var e=require("css-in-js-utils/lib/isPrefixedValue"),r=t(e);function t(e){return e&&e.__esModule?e:{default:e}}var s=["-webkit-",""];function u(e,t){if("string"==typeof t&&!(0,r.default)(t)&&t.indexOf("cross-fade(")>-1)return s.map(function(e){return t.replace(/cross-fade\(/g,e+"cross-fade(")})}module.exports=exports.default; +},{"css-in-js-utils/lib/isPrefixedValue":158}],125:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=o;var e=["-webkit-","-moz-",""],r={"zoom-in":!0,"zoom-out":!0,grab:!0,grabbing:!0};function o(o,t){if("cursor"===o&&r.hasOwnProperty(t))return e.map(function(e){return e+t})}module.exports=exports.default; +},{}],126:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=u;var e=require("css-in-js-utils/lib/isPrefixedValue"),t=r(e);function r(e){return e&&e.__esModule?e:{default:e}}var i=["-webkit-",""];function u(e,r){if("string"==typeof r&&!(0,t.default)(r)&&r.indexOf("filter(")>-1)return i.map(function(e){return r.replace(/filter\(/g,e+"filter(")})}module.exports=exports.default; +},{"css-in-js-utils/lib/isPrefixedValue":158}],127:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=i;var e={flex:["-webkit-box","-moz-box","-ms-flexbox","-webkit-flex","flex"],"inline-flex":["-webkit-inline-box","-moz-inline-box","-ms-inline-flexbox","-webkit-inline-flex","inline-flex"]};function i(i,l){if("display"===i&&e.hasOwnProperty(l))return e[l]}module.exports=exports.default; +},{}],128:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=s;var e={"space-around":"distribute","space-between":"justify","flex-start":"start","flex-end":"end"},t={alignContent:"msFlexLinePack",alignSelf:"msFlexItemAlign",alignItems:"msFlexAlign",justifyContent:"msFlexPack",order:"msFlexOrder",flexGrow:"msFlexPositive",flexShrink:"msFlexNegative",flexBasis:"msFlexPreferredSize"};function s(s,l,r){t.hasOwnProperty(s)&&(r[t[s]]=e[l]||l)}module.exports=exports.default; +},{}],129:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=i;var e={"space-around":"justify","space-between":"justify","flex-start":"start","flex-end":"end","wrap-reverse":"multiple",wrap:"multiple"},t={alignItems:"WebkitBoxAlign",justifyContent:"WebkitBoxPack",flexWrap:"WebkitBoxLines"};function i(i,r,o){"flexDirection"===i&&"string"==typeof r&&(r.indexOf("column")>-1?o.WebkitBoxOrient="vertical":o.WebkitBoxOrient="horizontal",r.indexOf("reverse")>-1?o.WebkitBoxDirection="reverse":o.WebkitBoxDirection="normal"),t.hasOwnProperty(i)&&(o[t[i]]=e[r]||r)}module.exports=exports.default; +},{}],130:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=n;var e=require("css-in-js-utils/lib/isPrefixedValue"),t=r(e);function r(e){return e&&e.__esModule?e:{default:e}}var i=["-webkit-","-moz-",""],a=/linear-gradient|radial-gradient|repeating-linear-gradient|repeating-radial-gradient/;function n(e,r){if("string"==typeof r&&!(0,t.default)(r)&&a.test(r))return i.map(function(e){return e+r})}module.exports=exports.default; +},{"css-in-js-utils/lib/isPrefixedValue":158}],131:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=u;var e=require("css-in-js-utils/lib/isPrefixedValue"),t=r(e);function r(e){return e&&e.__esModule?e:{default:e}}var i=["-webkit-",""];function u(e,r){if("string"==typeof r&&!(0,t.default)(r)&&r.indexOf("image-set(")>-1)return i.map(function(e){return r.replace(/image-set\(/g,e+"image-set(")})}module.exports=exports.default; +},{"css-in-js-utils/lib/isPrefixedValue":158}],132:[function(require,module,exports) { +"use strict";function e(e,t){if("position"===e&&"sticky"===t)return["-webkit-sticky","sticky"]}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=e,module.exports=exports.default; +},{}],133:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=i;var t=["-webkit-","-moz-",""],e={maxHeight:!0,maxWidth:!0,width:!0,height:!0,columnWidth:!0,minWidth:!0,minHeight:!0},n={"min-content":!0,"max-content":!0,"fill-available":!0,"fit-content":!0,"contain-floats":!0};function i(i,o){if(e.hasOwnProperty(i)&&n.hasOwnProperty(o))return t.map(function(t){return t+o})}module.exports=exports.default; +},{}],181:[function(require,module,exports) { +"use strict";var e=/[A-Z]/g,r=/^ms-/,s={};function t(t){return t in s?s[t]:s[t]=t.replace(e,"-$&").toLowerCase().replace(r,"-ms-")}module.exports=t; +},{}],165:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=u;var e=require("hyphenate-style-name"),t=r(e);function r(e){return e&&e.__esModule?e:{default:e}}function u(e){return(0,t.default)(e)}module.exports=exports.default; +},{"hyphenate-style-name":181}],164:[function(require,module,exports) { +"use strict";function e(e){return e.charAt(0).toUpperCase()+e.slice(1)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=e,module.exports=exports.default; +},{}],134:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=l;var t=require("css-in-js-utils/lib/hyphenateProperty"),e=s(t),r=require("css-in-js-utils/lib/isPrefixedValue"),i=s(r),n=require("../../utils/capitalizeString"),o=s(n);function s(t){return t&&t.__esModule?t:{default:t}}var u={transition:!0,transitionProperty:!0,WebkitTransition:!0,WebkitTransitionProperty:!0,MozTransition:!0,MozTransitionProperty:!0},a={Webkit:"-webkit-",Moz:"-moz-",ms:"-ms-"};function f(t,r){if((0,i.default)(t))return t;for(var n=t.split(/,(?![^()]*(?:\([^()]*\))?\))/g),o=0,s=n.length;o-1&&"order"!==p)for(var d=r[l],c=0,b=d.length;c-1)return s;var a=n.split(/,(?![^()]*(?:\([^()]*\))?\))/g).filter(function(t){return!/-webkit-|-ms-/.test(t)}).join(",");return t.indexOf("Moz")>-1?a:(r["Webkit"+(0,o.default)(t)]=s,r["Moz"+(0,o.default)(t)]=a,n)}}module.exports=exports.default; +},{"css-in-js-utils/lib/hyphenateProperty":165,"css-in-js-utils/lib/isPrefixedValue":158,"../../utils/capitalizeString":164}],144:[function(require,module,exports) { +"use strict";function r(r){for(var t=5381,e=r.length;e;)t=33*t^r.charCodeAt(--e);return t>>>0}module.exports=r; +},{}],168:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=u;var e=require("./capitalizeString"),r=t(e);function t(e){return e&&e.__esModule?e:{default:e}}function u(e,t,u){if(e.hasOwnProperty(t)){for(var o={},a=e[t],n=(0,r.default)(t),f=Object.keys(u),l=0;l0&&(i[s]=d)}else{var x=(0,u.default)(l,s,n,i,t);x&&(i[s]=x),i=(0,r.default)(t,s,i)}}return i}}module.exports=exports.default; +},{"../utils/prefixProperty":168,"../utils/prefixValue":169,"../utils/addNewValuesOnly":170,"../utils/isObject":171}],166:[function(require,module,exports) { +var global = arguments[3]; +var e=arguments[3];function t(e){r.length||(n(),a=!0),r[r.length]=e}module.exports=t;var n,r=[],a=!1,o=0,u=1024;function l(){for(;ou){for(var t=0,n=r.length-o;t4&&void 0!==arguments[4]?arguments[4]:[];if(!pe[e]){var o=ne(t,r,i,ye,n);he(e,o)}},Se=function(){de=[],pe={},me=!1,fe=null},ve=function(){return de},xe=function(){if(me)throw new Error("Cannot buffer while already buffering");me=!0},be=function(){me=!1;var e=de;return de=[],e},ke=function(){return be().join("")},Oe=function(){var e=be();e.length>0&&ce(e)},we=function(){return Object.keys(pe)},Ae=function(e){e.forEach(function(e){pe[e]=!0})},Ce=function e(t,r,n,i){for(var o=0;o0&&void 0!==arguments[0]?arguments[0]:[];Ae(e)}}()},Me="undefined"!=typeof window?null:{renderStatic:function(){return function(e){return Se(),xe(),{html:e(),css:{content:ke(),renderedClassNames:we()}}}}()},qe=null;function Fe(e,t){return{StyleSheet:Object.assign({},Re,{extend:function(){return function(r){var n=r.map(function(e){return e.selectorHandler}).filter(function(e){return e});return Fe(e,t.concat(n))}}()}),StyleSheetServer:Me,StyleSheetTestUtils:qe,minify:function(){return function(e){Ie=e?V:Te}}(),css:function(){return function(){for(var r=arguments.length,n=Array(r),i=0;i{this.viewport=e||null}),this.pendingScroll=0,this.onWindowResize=(()=>{this.recomputeVisibleIndices(this.props)}),this.onViewportScroll=(e=>{this.recomputeVisibleIndices(this.props)}),this.state={firstVisibleIndex:null,lastVisibleIndex:null,invisiblePrefixSize:null,viewportSize:null,cachedTotalSize:e.items.reduce((e,i)=>e+i.size,0)}}recomputeVisibleIndices(e){if(!this.viewport)return;const{items:i}=e,t=this.viewport.getBoundingClientRect().height,s=this.viewport.scrollTop-t/4,o=this.viewport.scrollTop+t+t/4;let l=0,r=0,n=0;for(;n=s)break}const p=n;for(;n=o)break}const c=Math.min(n,i.length-1);this.setState({invisiblePrefixSize:r,firstVisibleIndex:p,lastVisibleIndex:c})}scrollIndexIntoView(e){this.pendingScroll=this.props.items.reduce((i,t,s)=>s>=e?i:i+t.size,0)}applyPendingScroll(){if(!this.viewport)return;const e="y"===this.props.axis?"top":"left";this.viewport.scrollTo({[e]:this.pendingScroll})}componentWillReceiveProps(e){this.props.items!==e.items&&this.recomputeVisibleIndices(e)}componentDidMount(){this.applyPendingScroll(),this.recomputeVisibleIndices(this.props),window.addEventListener("resize",this.onWindowResize)}componentWillUnmount(){window.removeEventListener("resize",this.onWindowResize)}render(){const{cachedTotalSize:i,firstVisibleIndex:t,lastVisibleIndex:s,invisiblePrefixSize:o}=this.state;return(0,e.h)("div",{className:this.props.className,ref:this.viewportRef,onScroll:this.onViewportScroll},(0,e.h)("div",{style:{height:i}},(0,e.h)("div",{style:{transform:`translateY(${o}px)`}},null!=t&&null!=s&&this.props.renderItems(t,s))))}}exports.ScrollableListView=i; +},{"preact":24}],117:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0});class t{constructor(t){this.data=t,this.prev=null,this.next=null}}class e{constructor(){this.head=null,this.tail=null,this.size=0}getHead(){return this.head}getTail(){return this.tail}getSize(){return this.size}append(t){this.tail?(this.tail.next=t,t.prev=this.tail,this.tail=t):this.head=this.tail=t,this.size++}prepend(t){return this.head?(this.head.prev=t,t.next=this.head,this.head=t):this.head=this.tail=t,this.size++,t}pop(){if(this.tail){const t=this.tail;return t.prev?(this.tail=t.prev,this.tail.next=null):this.head=this.tail=null,this.size--,t.prev=null,t}return null}dequeue(){if(this.head){const t=this.head;return t.next?(this.head=t.next,this.head.prev=null):this.head=this.tail=null,this.size--,t.next=null,t}return null}remove(t){null==t.prev?this.dequeue():null==t.next?this.pop():(t.next.prev=t.prev,t.prev.next=t.next,t.next=null,t.prev=null,this.size--)}}exports.List=e;class i{constructor(t){this.capacity=t,this.list=new e,this.map=new Map}has(t){return this.map.has(t)}get(t){const e=this.map.get(t);return e?(this.list.remove(e.listNode),this.list.prepend(e.listNode),e?e.value:null):null}getSize(){return this.list.getSize()}getCapacity(){return this.capacity}insert(e,i){const s=this.map.get(e);for(s&&this.list.remove(s.listNode);this.list.getSize()>=this.capacity;)this.map.delete(this.list.pop().data);const h=this.list.prepend(new t(e));this.map.set(e,{value:i,listNode:h})}getOrInsert(t,e){let i=this.get(t);return null==i&&(i=e(t),this.insert(t,i)),i}removeLRU(){const t=this.list.pop();if(!t)return null;const e=t.data,i=this.map.get(e).value;return this.map.delete(e),[e,i]}clear(){this.list=new e,this.map=new Map}}exports.LRUCache=i; +},{}],96:[function(require,module,exports) { + +var t,e,n=module.exports={};function r(){throw new Error("setTimeout has not been defined")}function o(){throw new Error("clearTimeout has not been defined")}function i(e){if(t===setTimeout)return setTimeout(e,0);if((t===r||!t)&&setTimeout)return t=setTimeout,setTimeout(e,0);try{return t(e,0)}catch(n){try{return t.call(null,e,0)}catch(n){return t.call(this,e,0)}}}function u(t){if(e===clearTimeout)return clearTimeout(t);if((e===o||!e)&&clearTimeout)return e=clearTimeout,clearTimeout(t);try{return e(t)}catch(n){try{return e.call(null,t)}catch(n){return e.call(this,t)}}}!function(){try{t="function"==typeof setTimeout?setTimeout:r}catch(e){t=r}try{e="function"==typeof clearTimeout?clearTimeout:o}catch(t){e=o}}();var c,s=[],l=!1,a=-1;function f(){l&&c&&(l=!1,c.length?s=c.concat(s):a=-1,s.length&&h())}function h(){if(!l){var t=i(f);l=!0;for(var e=s.length;e;){for(c=s,s=[];++a1)for(var n=1;n=0&&e<=31),t.TEXTURE0+e}var h=exports.Graphics=void 0;!function(t){t.Rect=class{constructor(t=0,e=0,i=0,r=0){this.x=t,this.y=e,this.width=i,this.height=r}set(t,e,i,r){this.x=t,this.y=e,this.width=i,this.height=r}equals(t){return this.x===t.x&&this.y===t.y&&this.width===t.width&&this.height===t.height}};class e{constructor(t,e,i,r){this.redF=t,this.greenF=e,this.blueF=i,this.alphaF=r}}let i,r,s,n,h;e.TRANSPARENT=new e(0,0,0,0),t.Color=e,function(t){t[t.ZERO=0]="ZERO",t[t.ONE=1]="ONE",t[t.SOURCE_COLOR=2]="SOURCE_COLOR",t[t.TARGET_COLOR=3]="TARGET_COLOR",t[t.INVERSE_SOURCE_COLOR=4]="INVERSE_SOURCE_COLOR",t[t.INVERSE_TARGET_COLOR=5]="INVERSE_TARGET_COLOR",t[t.SOURCE_ALPHA=6]="SOURCE_ALPHA",t[t.TARGET_ALPHA=7]="TARGET_ALPHA",t[t.INVERSE_SOURCE_ALPHA=8]="INVERSE_SOURCE_ALPHA",t[t.INVERSE_TARGET_ALPHA=9]="INVERSE_TARGET_ALPHA",t[t.CONSTANT=10]="CONSTANT",t[t.INVERSE_CONSTANT=11]="INVERSE_CONSTANT"}(i=t.BlendOperation||(t.BlendOperation={})),function(t){t[t.TRIANGLES=0]="TRIANGLES",t[t.TRIANGLE_STRIP=1]="TRIANGLE_STRIP"}(r=t.Primitive||(t.Primitive={}));function a(t){return t==s.FLOAT?4:1}t.Context=class{setCopyBlendState(){this.setBlendState(i.ONE,i.ZERO)}setAddBlendState(){this.setBlendState(i.ONE,i.ONE)}setPremultipliedBlendState(){this.setBlendState(i.ONE,i.INVERSE_SOURCE_ALPHA)}setUnpremultipliedBlendState(){this.setBlendState(i.SOURCE_ALPHA,i.INVERSE_SOURCE_ALPHA)}},function(t){t[t.FLOAT=0]="FLOAT",t[t.BYTE=1]="BYTE"}(s=t.AttributeType||(t.AttributeType={})),t.attributeByteLength=a;class _{constructor(t,e,i,r){this.name=t,this.type=e,this.count=i,this.byteOffset=r}}t.Attribute=_;t.VertexFormat=class{constructor(){this._attributes=[],this._stride=0}get attributes(){return this._attributes}get stride(){return this._stride}add(t,e,i){return this.attributes.push(new _(t,e,i,this.stride)),this._stride+=i*a(e),this}};t.VertexBuffer=class{uploadFloat32Array(t){this.upload(new Uint8Array(t.buffer),0)}uploadFloats(t){this.uploadFloat32Array(new Float32Array(t))}},function(t){t[t.NEAREST=0]="NEAREST",t[t.LINEAR=1]="LINEAR"}(n=t.PixelFilter||(t.PixelFilter={})),function(t){t[t.REPEAT=0]="REPEAT",t[t.CLAMP=1]="CLAMP"}(h=t.PixelWrap||(t.PixelWrap={}));class o{constructor(t,e,i){this.minFilter=t,this.magFilter=e,this.wrap=i}}o.LINEAR_CLAMP=new o(n.LINEAR,n.LINEAR,h.CLAMP),o.LINEAR_MIN_NEAREST_MAG_CLAMP=new o(n.LINEAR,n.NEAREST,h.CLAMP),o.NEAREST_CLAMP=new o(n.NEAREST,n.NEAREST,h.CLAMP),t.TextureFormat=o}(h||(exports.Graphics=h={}));var a=exports.WebGL=void 0;!function(t){class a extends h.Context{constructor(t=document.createElement("canvas")){super(),this._attributeCount=0,this._blendOperations=0,this._contextResetHandlers=[],this._currentClearColor=h.Color.TRANSPARENT,this._currentRenderTarget=null,this._defaultViewport=new h.Rect,this._forceStateUpdate=!0,this._generation=1,this._height=0,this._oldBlendOperations=0,this._oldRenderTarget=null,this._oldViewport=new h.Rect,this._width=0,this.handleWebglContextRestored=(()=>{this._attributeCount=0,this._currentClearColor=h.Color.TRANSPARENT,this._forceStateUpdate=!0,this._generation++;for(let t of this._contextResetHandlers)t()}),this.ANGLE_instanced_arrays=null,this.ANGLE_instanced_arrays_generation=-1;let e=t.getContext("webgl",{alpha:!1,antialias:!1,depth:!1,preserveDrawingBuffer:!1,stencil:!1});if(null==e)throw new Error("Setup failure");this._gl=e;let i=t.style;t.width=0,t.height=0,i.width=i.height="0",t.addEventListener("webglcontextlost",t=>{t.preventDefault()}),t.addEventListener("webglcontextrestored",this.handleWebglContextRestored),this._blendOperationMap={[h.BlendOperation.ZERO]:this._gl.ZERO,[h.BlendOperation.ONE]:this._gl.ONE,[h.BlendOperation.SOURCE_COLOR]:this._gl.SRC_COLOR,[h.BlendOperation.TARGET_COLOR]:this._gl.DST_COLOR,[h.BlendOperation.INVERSE_SOURCE_COLOR]:this._gl.ONE_MINUS_SRC_COLOR,[h.BlendOperation.INVERSE_TARGET_COLOR]:this._gl.ONE_MINUS_DST_COLOR,[h.BlendOperation.SOURCE_ALPHA]:this._gl.SRC_ALPHA,[h.BlendOperation.TARGET_ALPHA]:this._gl.DST_ALPHA,[h.BlendOperation.INVERSE_SOURCE_ALPHA]:this._gl.ONE_MINUS_SRC_ALPHA,[h.BlendOperation.INVERSE_TARGET_ALPHA]:this._gl.ONE_MINUS_DST_ALPHA,[h.BlendOperation.CONSTANT]:this._gl.CONSTANT_COLOR,[h.BlendOperation.INVERSE_CONSTANT]:this._gl.ONE_MINUS_CONSTANT_COLOR}}get widthInPixels(){return this._width}get heightInPixels(){return this._height}testContextLoss(){this.handleWebglContextRestored()}get gl(){return this._gl}get generation(){return this._generation}addContextResetHandler(t){r(this._contextResetHandlers,t)}removeContextResetHandler(t){s(this._contextResetHandlers,t)}get currentRenderTarget(){return this._currentRenderTarget}beginFrame(){this.setRenderTarget(null)}endFrame(){}setBlendState(t,e){this._blendOperations=a._packBlendModes(t,e)}setViewport(t,e,i,r){(null!=this._currentRenderTarget?this._currentRenderTarget.viewport:this._defaultViewport).set(t,e,i,r)}get viewport(){return null!=this._currentRenderTarget?this._currentRenderTarget.viewport:this._defaultViewport}get renderTargetWidthInPixels(){return null!=this._currentRenderTarget?this._currentRenderTarget.viewport.width:this._width}get renderTargetHeightInPixels(){return null!=this._currentRenderTarget?this._currentRenderTarget.viewport.height:this._height}draw(t,e,i){this._updateRenderTargetAndViewport(),f.from(e).prepare(),R.from(i).prepare(),this._updateFormat(e.format),this._updateBlendState(),this._gl.drawArrays(t==h.Primitive.TRIANGLES?this._gl.TRIANGLES:this._gl.TRIANGLE_STRIP,0,Math.floor(i.byteCount/e.format.stride)),this._forceStateUpdate=!1}resize(t,e,i,r){let s=this._gl.canvas;const n=s.getBoundingClientRect();if(this._width===i&&this._height===e&&n.width===i&&n.height===r)return;let h=s.style;s.width=t,s.height=e,h.width=`${i}px`,h.height=`${r}px`,this.setViewport(0,0,t,e),this._width=t,this._height=e}clear(t){this._updateRenderTargetAndViewport(),this._updateBlendState(),t!=this._currentClearColor&&(this._gl.clearColor(t.redF,t.greenF,t.blueF,t.alphaF),this._currentClearColor=t),this._gl.clear(this._gl.COLOR_BUFFER_BIT)}setRenderTarget(t){this._currentRenderTarget=A.from(t)}createMaterial(t,e,i){let r=new f(this,t,e,i);return r.program,r}createVertexBuffer(t){return i(t>0&&t%4==0),new R(this,t)}createTexture(t,e,i,r){return new p(this,t,e,i,r)}createRenderTarget(t){return new A(this,p.from(t))}getANGLE_instanced_arrays(){if(this.ANGLE_instanced_arrays_generation!==this._generation&&(this.ANGLE_instanced_arrays=null),!this.ANGLE_instanced_arrays&&(this.ANGLE_instanced_arrays=this.gl.getExtension("ANGLE_instanced_arrays"),!this.ANGLE_instanced_arrays))throw new Error("Failed to get extension ANGLE_instanced_arrays");return this.ANGLE_instanced_arrays}_updateRenderTargetAndViewport(){let t=this._currentRenderTarget,e=null!=t?t.viewport:this._defaultViewport,i=this._gl;(this._forceStateUpdate||this._oldRenderTarget!=t)&&(i.bindFramebuffer(i.FRAMEBUFFER,t?t.framebuffer:null),this._oldRenderTarget=t),!this._forceStateUpdate&&this._oldViewport.equals(e)||(i.viewport(e.x,this.renderTargetHeightInPixels-e.y-e.height,e.width,e.height),this._oldViewport.set(e.x,e.y,e.width,e.height))}_updateBlendState(){if(this._forceStateUpdate||this._oldBlendOperations!=this._blendOperations){let t=this._gl,e=this._blendOperations,r=this._oldBlendOperations,s=15&e,n=e>>4;i(s in this._blendOperationMap),i(n in this._blendOperationMap),e==a.COPY_BLEND_OPERATIONS?t.disable(t.BLEND):((this._forceStateUpdate||r==a.COPY_BLEND_OPERATIONS)&&t.enable(t.BLEND),t.blendFunc(this._blendOperationMap[s],this._blendOperationMap[n])),this._oldBlendOperations=e}}_updateFormat(t){let e=this._gl,i=t.attributes,r=i.length;for(let s=0;sr;)this._attributeCount--,e.disableVertexAttribArray(this._attributeCount);this._attributeCount=r}getWebGLInfo(){const t=this.gl.getExtension("WEBGL_debug_renderer_info");return{renderer:t?this.gl.getParameter(t.UNMASKED_RENDERER_WEBGL):null,vendor:t?this.gl.getParameter(t.UNMASKED_VENDOR_WEBGL):null,version:this.gl.getParameter(this.gl.VERSION)}}static from(t){return i(null==t||t instanceof a),t}static _packBlendModes(t,e){return t|e<<4}}a.COPY_BLEND_OPERATIONS=a._packBlendModes(h.BlendOperation.ONE,h.BlendOperation.ZERO),t.Context=a;class _{constructor(t,e,i=0,r=null,s=!0){this._material=t,this._name=e,this._generation=i,this._location=r,this._isDirty=s}get location(){let t=a.from(this._material.context);if(this._generation!=t.generation&&(this._location=t.gl.getUniformLocation(this._material.program,this._name),this._generation=t.generation,!e)){let e=this._material.program,r=t.gl;for(let t=0,s=r.getProgramParameter(e,r.ACTIVE_UNIFORMS);t0&&this._texture.height>0?this._texture.texture:null)}}class f{constructor(t,e,i,r,s={},n=[],h=0,a=null){this._context=t,this._format=e,this._vertexSource=i,this._fragmentSource=r,this._uniformsMap=s,this._uniformsList=n,this._generation=h,this._program=a}get context(){return this._context}get format(){return this._format}get vertexSource(){return this._vertexSource}get fragmentSource(){return this._fragmentSource}setUniformFloat(t,e){let r=this._uniformsMap[t]||null;null==r&&(r=new o(this,t),this._uniformsMap[t]=r,this._uniformsList.push(r)),i(r instanceof o),r.set(e)}setUniformInt(t,e){let r=this._uniformsMap[t]||null;null==r&&(r=new l(this,t),this._uniformsMap[t]=r,this._uniformsList.push(r)),i(r instanceof l),r.set(e)}setUniformVec2(t,e,r){let s=this._uniformsMap[t]||null;null==s&&(s=new u(this,t),this._uniformsMap[t]=s,this._uniformsList.push(s)),i(s instanceof u),s.set(e,r)}setUniformVec3(t,e,r,s){let n=this._uniformsMap[t]||null;null==n&&(n=new c(this,t),this._uniformsMap[t]=n,this._uniformsList.push(n)),i(n instanceof c),n.set(e,r,s)}setUniformVec4(t,e,r,s,n){let h=this._uniformsMap[t]||null;null==h&&(h=new d(this,t),this._uniformsMap[t]=h,this._uniformsList.push(h)),i(h instanceof d),h.set(e,r,s,n)}setUniformMat3(t,e,r,s,n,h,a,_,o,l){let u=this._uniformsMap[t]||null;null==u&&(u=new g(this,t),this._uniformsMap[t]=u,this._uniformsList.push(u)),i(u instanceof g),u.set(e,r,s,n,h,a,_,o,l)}setUniformSampler(t,e,r){let s=this._uniformsMap[t]||null;null==s&&(s=new E(this,t),this._uniformsMap[t]=s,this._uniformsList.push(s)),i(s instanceof E),s.set(e,r)}get program(){let t=this._context.gl;if(this._generation!=this._context.generation){this._program=t.createProgram(),this._compileShader(t,t.VERTEX_SHADER,this.vertexSource),this._compileShader(t,t.FRAGMENT_SHADER,this.fragmentSource);let r=this.format.attributes;for(let e=0;e=0),i(0<=t&&t+r<=this._byteCount),i(0<=e&&e+r<=this._byteCount),this._bytes&&t!=e&&0!=r&&(this._bytes.set(this._bytes.subarray(t,this._byteCount),e),this._growDirtyRegion(Math.min(t,e),Math.max(t,e)+r))}upload(t,e=0){i(0<=e&&e+t.length<=this._byteCount),i(null!=this._bytes),this._bytes.set(t,e),this._growDirtyRegion(e,e+t.length)}free(){this._buffer&&this._context.gl.deleteBuffer(this._buffer),this._generation=0}prepare(){let t=this._context.gl;this._generation!==this._context.generation&&(this._buffer=t.createBuffer(),this._generation=this._context.generation,this._isDirty=!0),t.bindBuffer(t.ARRAY_BUFFER,this._buffer),this._isDirty&&(t.bufferData(t.ARRAY_BUFFER,this._byteCount,t.DYNAMIC_DRAW),this._dirtyMin=this._totalMin,this._dirtyMax=this._totalMax,this._isDirty=!1),this._dirtyMin{const t=e.AffineTransform.betweenRects(i.configSpaceSrcRect,i.physicalSpaceDstRect),r=new e.Vec2(this.gl.viewport.width,this.gl.viewport.height);return e.AffineTransform.withTranslation(new e.Vec2(-1,1)).times(e.AffineTransform.withScale(new e.Vec2(2,-2).dividedByPointwise(r))).times(t)})()),this.gl.setUnpremultipliedBlendState(),this.gl.draw(t.Graphics.Primitive.TRIANGLES,this.material,i.batch.getBuffer())}}exports.RectangleBatchRenderer=c; +},{"../lib/math":102,"./graphics":42,"./utils":119}],76:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Color=void 0;var t=require("./math");class r{constructor(t=0,r=0,e=0,o=1){this.r=t,this.g=r,this.b=e,this.a=o}static fromLumaChromaHue(e,o,s){const i=s/60,a=o*(1-Math.abs(i%2-1)),[h,c,u]=i<1?[o,a,0]:i<2?[a,o,0]:i<3?[0,o,a]:i<4?[0,a,o]:i<5?[a,0,o]:[o,0,a],l=e-(.3*h+.59*c+.11*u);return new r((0,t.clamp)(h+l,0,1),(0,t.clamp)(c+l,0,1),(0,t.clamp)(u+l,0,1),1)}toCSS(){return`rgba(${(255*this.r).toFixed()}, ${(255*this.g).toFixed()}, ${(255*this.b).toFixed()}, ${this.a.toFixed(2)})`}}exports.Color=r; +},{"./math":102}],72:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.RowAtlas=void 0;var e=require("../lib/lru-cache"),t=require("./rectangle-batch-renderer"),r=require("../lib/math"),i=require("../lib/color"),c=require("./graphics"),h=require("./utils");class a{constructor(h,a,s){this.gl=h,this.rectangleBatchRenderer=a,this.textureRenderer=s,this.texture=h.createTexture(c.Graphics.TextureFormat.NEAREST_CLAMP,4096,4096),this.renderTarget=h.createRenderTarget(this.texture),this.rowCache=new e.LRUCache(this.texture.height),this.clearLineBatch=new t.RectangleBatch(h),this.clearLineBatch.addRect(r.Rect.unit,new i.Color(0,0,0,0)),h.addContextResetHandler(()=>{this.rowCache.clear()})}has(e){return this.rowCache.has(e)}getResolution(){return this.texture.width}getCapacity(){return this.texture.height}allocateLine(e){if(this.rowCache.getSize(){for(let i of e){let e=this.rowCache.get(i);if(null!=e)continue;e=this.allocateLine(i);const c=new r.Rect(new r.Vec2(0,e),new r.Vec2(this.texture.width,1));this.rectangleBatchRenderer.render({batch:this.clearLineBatch,configSpaceSrcRect:r.Rect.unit,physicalSpaceDstRect:c}),t(c,i)}})}renderViaAtlas(e,t){let i=this.rowCache.get(e);if(null==i)return!1;const c=new r.Rect(new r.Vec2(0,i),new r.Vec2(this.texture.width,1));return this.textureRenderer.render({texture:this.texture,srcRect:c,dstRect:t}),!0}}exports.RowAtlas=a; +},{"../lib/lru-cache":117,"./rectangle-batch-renderer":118,"../lib/math":102,"../lib/color":76,"./graphics":42,"./utils":119}],120:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.TextureRenderer=void 0;var e=require("../lib/math"),t=require("./graphics"),r=require("./utils");const n="\n uniform mat3 uvTransform;\n uniform mat3 positionTransform;\n\n attribute vec2 position;\n attribute vec2 uv;\n varying vec2 vUv;\n\n void main() {\n vUv = (uvTransform * vec3(uv, 1)).xy;\n gl_Position = vec4((positionTransform * vec3(position, 1)).xy, 0, 1);\n }\n",i="\n precision mediump float;\n\n varying vec2 vUv;\n uniform sampler2D texture;\n\n void main() {\n gl_FragColor = texture2D(texture, vUv);\n }\n";class s{constructor(e){this.gl=e;const r=new t.Graphics.VertexFormat;r.add("position",t.Graphics.AttributeType.FLOAT,2),r.add("uv",t.Graphics.AttributeType.FLOAT,2);const s=[{pos:[-1,1],uv:[0,1]},{pos:[1,1],uv:[1,1]},{pos:[-1,-1],uv:[0,0]},{pos:[1,-1],uv:[1,0]}],o=[];for(let e of s)o.push(e.pos[0]),o.push(e.pos[1]),o.push(e.uv[0]),o.push(e.uv[1]);this.buffer=e.createVertexBuffer(r.stride*s.length),this.buffer.upload(new Uint8Array(new Float32Array(o).buffer)),this.material=e.createMaterial(r,n,i)}render(n){this.material.setUniformSampler("texture",n.texture,0),(0,r.setUniformAffineTransform)(this.material,"uvTransform",(()=>{const{srcRect:t,texture:r}=n,i=e.AffineTransform.withTranslation(new e.Vec2(0,1)).times(e.AffineTransform.withScale(new e.Vec2(1,-1))).times(e.AffineTransform.betweenRects(new e.Rect(e.Vec2.zero,new e.Vec2(r.width,r.height)),e.Rect.unit)).transformRect(t);return e.AffineTransform.betweenRects(e.Rect.unit,i)})()),(0,r.setUniformAffineTransform)(this.material,"positionTransform",(()=>{const{dstRect:t}=n,{viewport:r}=this.gl,i=new e.Vec2(r.width,r.height),s=e.AffineTransform.withScale(new e.Vec2(1,-1)).times(e.AffineTransform.betweenRects(new e.Rect(e.Vec2.zero,i),e.Rect.NDC)).transformRect(t);return e.AffineTransform.betweenRects(e.Rect.NDC,s)})()),this.gl.setUnpremultipliedBlendState(),this.gl.draw(t.Graphics.Primitive.TRIANGLE_STRIP,this.material,this.buffer)}}exports.TextureRenderer=s; +},{"../lib/math":102,"./graphics":42,"./utils":119}],121:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ViewportRectangleRenderer=void 0;var e=require("./graphics"),i=require("./utils");const r=new e.Graphics.VertexFormat;r.add("position",e.Graphics.AttributeType.FLOAT,2);const o="\n attribute vec2 position;\n\n void main() {\n gl_Position = vec4(position, 0, 1);\n }\n",n="\n precision mediump float;\n\n uniform mat3 configSpaceToPhysicalViewSpace;\n uniform vec2 physicalSize;\n uniform vec2 physicalOrigin;\n uniform vec2 configSpaceViewportOrigin;\n uniform vec2 configSpaceViewportSize;\n uniform float framebufferHeight;\n\n void main() {\n vec2 origin = (configSpaceToPhysicalViewSpace * vec3(configSpaceViewportOrigin, 1.0)).xy;\n vec2 size = (configSpaceToPhysicalViewSpace * vec3(configSpaceViewportSize, 0.0)).xy;\n\n vec2 halfSize = physicalSize / 2.0;\n\n float borderWidth = 2.0;\n\n origin = floor(origin * halfSize) / halfSize + borderWidth * vec2(1.0, 1.0);\n size = floor(size * halfSize) / halfSize - 2.0 * borderWidth * vec2(1.0, 1.0);\n\n vec2 coord = gl_FragCoord.xy;\n coord.x = coord.x - physicalOrigin.x;\n coord.y = framebufferHeight - coord.y - physicalOrigin.y;\n vec2 clamped = clamp(coord, origin, origin + size);\n vec2 gap = clamped - coord;\n float maxdist = max(abs(gap.x), abs(gap.y));\n\n // TOOD(jlfwong): Could probably optimize this to use mix somehow.\n if (maxdist == 0.0) {\n // Inside viewport rectangle\n gl_FragColor = vec4(0, 0, 0, 0);\n } else if (maxdist < borderWidth) {\n // Inside viewport rectangle at border\n gl_FragColor = vec4(0.7, 0.7, 0.7, 0.8);\n } else {\n // Outside viewport rectangle\n gl_FragColor = vec4(0.7, 0.7, 0.7, 0.5);\n }\n }\n";class t{constructor(e){this.gl=e;const i=[[-1,1],[1,1],[-1,-1],[1,-1]],t=[];for(let e of i)t.push(e[0]),t.push(e[1]);this.buffer=e.createVertexBuffer(r.stride*i.length),this.buffer.upload(new Uint8Array(new Float32Array(t).buffer)),this.material=e.createMaterial(r,o,n)}render(r){(0,i.setUniformAffineTransform)(this.material,"configSpaceToPhysicalViewSpace",r.configSpaceToPhysicalViewSpace),(0,i.setUniformVec2)(this.material,"configSpaceViewportOrigin",r.configSpaceViewportRect.origin),(0,i.setUniformVec2)(this.material,"configSpaceViewportSize",r.configSpaceViewportRect.size);const o=this.gl.viewport;this.material.setUniformVec2("physicalOrigin",o.x,o.y),this.material.setUniformVec2("physicalSize",o.width,o.height),this.material.setUniformFloat("framebufferHeight",this.gl.renderTargetHeightInPixels),this.gl.setBlendState(e.Graphics.BlendOperation.SOURCE_ALPHA,e.Graphics.BlendOperation.INVERSE_SOURCE_ALPHA),this.gl.draw(e.Graphics.Primitive.TRIANGLE_STRIP,this.material,this.buffer)}}exports.ViewportRectangleRenderer=t; +},{"./graphics":42,"./utils":119}],122:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.FlamechartColorPassRenderer=void 0;var e=require("../lib/math"),t=require("./graphics"),n=require("./utils");const r=new t.Graphics.VertexFormat;r.add("position",t.Graphics.AttributeType.FLOAT,2),r.add("uv",t.Graphics.AttributeType.FLOAT,2);const i="\n uniform mat3 uvTransform;\n uniform mat3 positionTransform;\n\n attribute vec2 position;\n attribute vec2 uv;\n varying vec2 vUv;\n\n void main() {\n vUv = (uvTransform * vec3(uv, 1)).xy;\n gl_Position = vec4((positionTransform * vec3(position, 1)).xy, 0, 1);\n }\n",o="\n precision mediump float;\n\n uniform vec2 uvSpacePixelSize;\n uniform float renderOutlines;\n\n varying vec2 vUv;\n uniform sampler2D colorTexture;\n\n // https://en.wikipedia.org/wiki/HSL_and_HSV#From_luma/chroma/hue\n vec3 hcl2rgb(float H, float C, float L) {\n float hPrime = H / 60.0;\n float X = C * (1.0 - abs(mod(hPrime, 2.0) - 1.0));\n vec3 RGB =\n hPrime < 1.0 ? vec3(C, X, 0) :\n hPrime < 2.0 ? vec3(X, C, 0) :\n hPrime < 3.0 ? vec3(0, C, X) :\n hPrime < 4.0 ? vec3(0, X, C) :\n hPrime < 5.0 ? vec3(X, 0, C) :\n vec3(C, 0, X);\n\n float m = L - dot(RGB, vec3(0.30, 0.59, 0.11));\n return RGB + vec3(m, m, m);\n }\n\n float triangle(float x) {\n return 2.0 * abs(fract(x) - 0.5) - 1.0;\n }\n\n vec3 colorForBucket(float t) {\n float x = triangle(30.0 * t);\n float H = 360.0 * (0.9 * t);\n float C = 0.25 + 0.2 * x;\n float L = 0.80 - 0.15 * x;\n return hcl2rgb(H, C, L);\n }\n\n void main() {\n vec4 here = texture2D(colorTexture, vUv);\n\n if (here.z == 0.0) {\n // Background color\n gl_FragColor = vec4(0, 0, 0, 0);\n return;\n }\n\n // Sample the 4 surrounding pixels in the depth texture to determine\n // if we should draw a boundary here or not.\n vec4 N = texture2D(colorTexture, vUv + vec2(0, uvSpacePixelSize.y));\n vec4 E = texture2D(colorTexture, vUv + vec2(uvSpacePixelSize.x, 0));\n vec4 S = texture2D(colorTexture, vUv + vec2(0, -uvSpacePixelSize.y));\n vec4 W = texture2D(colorTexture, vUv + vec2(-uvSpacePixelSize.x, 0));\n\n // NOTE: For outline checks, we intentionally check both the right\n // and the left to determine if we're an edge. If a rectangle is a single\n // pixel wide, we don't want to render it as an outline, so this method\n // of checking ensures that we don't outline single physical-space\n // pixel width rectangles.\n if (\n renderOutlines > 0.0 &&\n (\n here.y == N.y && here.y != S.y || // Top edge\n here.y == S.y && here.y != N.y || // Bottom edge\n here.x == E.x && here.x != W.x || // Left edge\n here.x == W.x && here.x != E.x\n )\n ) {\n // We're on an edge! Draw transparent.\n gl_FragColor = vec4(0, 0, 0, 0);\n } else {\n // Not on an edge. Draw the appropriate color.\n gl_FragColor = vec4(colorForBucket(here.z), here.a);\n }\n }\n";class a{constructor(e){this.gl=e;const t=[{pos:[-1,1],uv:[0,1]},{pos:[1,1],uv:[1,1]},{pos:[-1,-1],uv:[0,0]},{pos:[1,-1],uv:[1,0]}],n=[];for(let e of t)n.push(e.pos[0]),n.push(e.pos[1]),n.push(e.uv[0]),n.push(e.uv[1]);this.buffer=e.createVertexBuffer(r.stride*t.length),this.buffer.uploadFloats(n),this.material=e.createMaterial(r,i,o)}render(r){const{srcRect:i,rectInfoTexture:o}=r,a=e.AffineTransform.withTranslation(new e.Vec2(0,1)).times(e.AffineTransform.withScale(new e.Vec2(1,-1))).times(e.AffineTransform.betweenRects(new e.Rect(e.Vec2.zero,new e.Vec2(o.width,o.height)),e.Rect.unit)).transformRect(i),s=e.AffineTransform.betweenRects(e.Rect.unit,a),{dstRect:c}=r,l=new e.Vec2(this.gl.viewport.width,this.gl.viewport.height),u=e.AffineTransform.withScale(new e.Vec2(1,-1)).times(e.AffineTransform.betweenRects(new e.Rect(e.Vec2.zero,l),e.Rect.NDC)).transformRect(c),f=e.AffineTransform.betweenRects(e.Rect.NDC,u),h=e.Vec2.unit.dividedByPointwise(new e.Vec2(r.rectInfoTexture.width,r.rectInfoTexture.height));this.material.setUniformSampler("colorTexture",r.rectInfoTexture,0),(0,n.setUniformAffineTransform)(this.material,"uvTransform",s),this.material.setUniformFloat("renderOutlines",r.renderOutlines?1:0),this.material.setUniformVec2("uvSpacePixelSize",h.x,h.y),(0,n.setUniformAffineTransform)(this.material,"positionTransform",f),this.gl.setUnpremultipliedBlendState(),this.gl.draw(t.Graphics.Primitive.TRIANGLE_STRIP,this.material,this.buffer)}}exports.FlamechartColorPassRenderer=a; +},{"../lib/math":102,"./graphics":42,"./utils":119}],74:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.CanvasContext=void 0;var e=require("./graphics"),r=require("./rectangle-batch-renderer"),t=require("./texture-renderer"),i=require("../lib/math"),n=require("./overlay-rectangle-renderer"),s=require("./flamechart-color-pass-renderer");class o{constructor(i){this.animationFrameRequest=null,this.beforeFrameHandlers=new Set,this.onBeforeFrame=(()=>{this.animationFrameRequest=null,this.gl.setViewport(0,0,this.gl.renderTargetWidthInPixels,this.gl.renderTargetHeightInPixels),this.gl.clear(new e.Graphics.Color(1,1,1,1));for(const e of this.beforeFrameHandlers)e()}),this.gl=new e.WebGL.Context(i),this.rectangleBatchRenderer=new r.RectangleBatchRenderer(this.gl),this.textureRenderer=new t.TextureRenderer(this.gl),this.viewportRectangleRenderer=new n.ViewportRectangleRenderer(this.gl),this.flamechartColorPassRenderer=new s.FlamechartColorPassRenderer(this.gl);const o=this.gl.getWebGLInfo();o&&console.log(`WebGL initialized. renderer: ${o.renderer}, vendor: ${o.vendor}, version: ${o.version}`),window.testContextLoss=(()=>{this.gl.testContextLoss()})}addBeforeFrameHandler(e){this.beforeFrameHandlers.add(e)}removeBeforeFrameHandler(e){this.beforeFrameHandlers.delete(e)}requestFrame(){this.animationFrameRequest||(this.animationFrameRequest=requestAnimationFrame(this.onBeforeFrame))}setViewport(e,r){const{origin:t,size:i}=e;let n=this.gl.viewport;this.gl.setViewport(t.x,t.y,i.x,i.y),r();let{x:s,y:o,width:a,height:l}=n;this.gl.setViewport(s,o,a,l)}renderBehind(e,r){const t=e.getBoundingClientRect(),n=new i.Rect(new i.Vec2(t.left*window.devicePixelRatio,t.top*window.devicePixelRatio),new i.Vec2(t.width*window.devicePixelRatio,t.height*window.devicePixelRatio));this.setViewport(n,r)}}exports.CanvasContext=o; +},{"./graphics":42,"./rectangle-batch-renderer":118,"./texture-renderer":120,"../lib/math":102,"./overlay-rectangle-renderer":121,"./flamechart-color-pass-renderer":122}],38:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.getFrameToColorBucket=exports.getProfileToView=exports.getProfileWithRecursionFlattened=exports.getRowAtlas=exports.getCanvasContext=exports.createGetCSSColorForFrame=exports.createGetColorBucketForFrame=void 0;var e=require("../lib/utils"),t=require("../gl/row-atlas"),r=require("../gl/canvas-context"),o=require("../lib/color");const n=exports.createGetColorBucketForFrame=(0,e.memoizeByReference)(e=>t=>e.get(t.key)||0),a=exports.createGetCSSColorForFrame=(0,e.memoizeByReference)(t=>{const r=n(t);return t=>{const n=r(t)/255,a=(0,e.triangle)(30*n),l=.9*n*360,i=.25+.2*a,s=.8-.15*a;return o.Color.fromLumaChromaHue(s,i,l).toCSS()}}),l=exports.getCanvasContext=(0,e.memoizeByReference)(e=>new r.CanvasContext(e)),i=exports.getRowAtlas=(0,e.memoizeByReference)(e=>new t.RowAtlas(e.gl,e.rectangleBatchRenderer,e.textureRenderer)),s=exports.getProfileWithRecursionFlattened=(0,e.memoizeByReference)(e=>e.getProfileWithRecursionFlattened()),c=exports.getProfileToView=(0,e.memoizeByShallowEquality)(({profile:e,flattenRecursion:t})=>t?e.getProfileWithRecursionFlattened():e),u=exports.getFrameToColorBucket=(0,e.memoizeByReference)(e=>{const t=[];function r(e){return(e.file||"")+e.name}e.forEachFrame(e=>t.push(e)),t.sort(function(e,t){return r(e)>r(t)?1:-1});const o=new Map;for(let e=0;e{t.preventDefault();const{sortMethod:o}=this.props;if(o.field==e)this.props.setSortMethod({field:e,direction:o.direction===h.ASCENDING?h.DESCENDING:h.ASCENDING});else switch(e){case n.SYMBOL_NAME:this.props.setSortMethod({field:e,direction:h.ASCENDING});break;case n.SELF:case n.TOTAL:this.props.setSortMethod({field:e,direction:h.DESCENDING})}}),this.getFrameList=(()=>{const{profile:e,sortMethod:t}=this.props,r=[];switch(e.forEachFrame(e=>r.push(e)),t.field){case n.SYMBOL_NAME:(0,o.sortBy)(r,e=>e.name.toLowerCase());break;case n.SELF:(0,o.sortBy)(r,e=>e.getSelfWeight());break;case n.TOTAL:(0,o.sortBy)(r,e=>e.getTotalWeight())}return t.direction===h.DESCENDING&&r.reverse(),r}),this.listView=null,this.listViewRef=(e=>{if(e===this.listView)return;this.listView=e;const{selectedFrame:t}=this.props;if(!t||!e)return;const o=this.getFrameList().indexOf(t);-1!==o&&e.scrollIndexIntoView(o)})}renderRow(r,s){const{profile:l,selectedFrame:a}=this.props,c=r.getTotalWeight(),n=r.getSelfWeight(),h=100*c/l.getTotalNonIdleWeight(),p=100*n/l.getTotalNonIdleWeight(),S=r===a;return(0,e.h)("tr",{key:`${s}`,onClick:this.props.setSelectedFrame.bind(null,r),className:(0,t.css)(E.tableRow,s%2==0&&E.tableRowEven,S&&E.tableRowSelected)},(0,e.h)("td",{className:(0,t.css)(E.numericCell)},l.formatValue(c)," (",(0,o.formatPercent)(h),")",(0,e.h)(d,{perc:h})),(0,e.h)("td",{className:(0,t.css)(E.numericCell)},l.formatValue(n)," (",(0,o.formatPercent)(p),")",(0,e.h)(d,{perc:p})),(0,e.h)("td",{title:r.file,className:(0,t.css)(E.textCell)},(0,e.h)(i.ColorChit,{color:this.props.getCSSColorForFrame(r)}),r.name))}render(){const{sortMethod:o}=this.props,i=this.getFrameList(),l=i.map(e=>({size:r.Sizes.FRAME_HEIGHT}));return(0,e.h)("div",{className:(0,t.css)(r.commonStyle.vbox,E.profileTableView)},(0,e.h)("table",{className:(0,t.css)(E.tableView)},(0,e.h)("thead",{className:(0,t.css)(E.tableHeader)},(0,e.h)("tr",null,(0,e.h)("th",{className:(0,t.css)(E.numericCell),onClick:e=>this.onSortClick(n.TOTAL,e)},(0,e.h)(p,{activeDirection:o.field===n.TOTAL?o.direction:null}),"Total"),(0,e.h)("th",{className:(0,t.css)(E.numericCell),onClick:e=>this.onSortClick(n.SELF,e)},(0,e.h)(p,{activeDirection:o.field===n.SELF?o.direction:null}),"Self"),(0,e.h)("th",{className:(0,t.css)(E.textCell),onClick:e=>this.onSortClick(n.SYMBOL_NAME,e)},(0,e.h)(p,{activeDirection:o.field===n.SYMBOL_NAME?o.direction:null}),"Symbol Name")))),(0,e.h)(s.ScrollableListView,{ref:this.listViewRef,axis:"y",items:l,className:(0,t.css)(E.scrollView),renderItems:(o,r)=>{const s=[];for(let e=o;e<=r;e++)s.push(this.renderRow(i[e],e));return(0,e.h)("table",{className:(0,t.css)(E.tableView)},s)}}))}}exports.ProfileTableView=S;const E=t.StyleSheet.create({profileTableView:{background:r.Colors.WHITE,height:"100%"},scrollView:{overflowY:"auto",overflowX:"hidden"},tableView:{width:"100%",fontSize:r.FontSize.LABEL,background:r.Colors.WHITE},tableHeader:{borderBottom:`2px solid ${r.Colors.LIGHT_GRAY}`,textAlign:"left",color:r.Colors.GRAY,userSelect:"none"},sortIcon:{position:"relative",top:1,marginRight:r.Sizes.FRAME_HEIGHT/4},tableRow:{height:r.Sizes.FRAME_HEIGHT},tableRowEven:{background:r.Colors.OFF_WHITE},tableRowSelected:{background:r.Colors.DARK_BLUE,color:r.Colors.WHITE},numericCell:{textOverflow:"ellipsis",overflow:"hidden",whiteSpace:"nowrap",position:"relative",textAlign:"right",paddingRight:r.Sizes.FRAME_HEIGHT,width:6*r.Sizes.FRAME_HEIGHT,minWidth:6*r.Sizes.FRAME_HEIGHT},textCell:{textOverflow:"ellipsis",overflow:"hidden",whiteSpace:"nowrap",width:"100%",maxWidth:0},hBarDisplay:{position:"absolute",background:r.Colors.TRANSPARENT_GREEN,bottom:2,height:2,width:`calc(100% - ${2*r.Sizes.FRAME_HEIGHT}px)`,right:r.Sizes.FRAME_HEIGHT},hBarDisplayFilled:{height:"100%",position:"absolute",background:r.Colors.GREEN,right:0}}),m=exports.ProfileTableViewContainer=(0,a.createContainer)(S,(e,t,o)=>{const{activeProfileState:r}=o,{profile:i,sandwichViewState:s,index:a}=r;if(!i)throw new Error("profile missing");const{tableSortMethod:n}=e,{callerCallee:h}=s,d=h?h.selectedFrame:null,p=(0,c.getFrameToColorBucket)(i),S=(0,c.createGetCSSColorForFrame)(p);return{profile:i,profileIndex:r.index,selectedFrame:d,getCSSColorForFrame:S,sortMethod:n,setSelectedFrame:e=>{t(l.actions.sandwichView.setSelectedFrame({profileIndex:a,args:e}))},setSortMethod:e=>{t(l.actions.sandwichView.setTableSortMethod(e))}}}); +},{"preact":24,"aphrodite":68,"../lib/utils":70,"./style":79,"./color-chit":106,"./scrollable-list-view":108,"../store/actions":40,"../lib/typed-redux":36,"../store/getters":38}],29:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.canUseXHR=exports.ViewMode=void 0,exports.createApplicationStore=d;var e=require("./actions"),t=require("redux"),r=n(t),o=require("../lib/typed-redux"),s=require("../lib/hash-params"),i=require("./profiles-state"),a=require("../views/profile-table-view");function n(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}var c=exports.ViewMode=void 0;!function(e){e[e.CHRONO_FLAME_CHART=0]="CHRONO_FLAME_CHART",e[e.LEFT_HEAVY_FLAME_GRAPH=1]="LEFT_HEAVY_FLAME_GRAPH",e[e.SANDWICH_VIEW=2]="SANDWICH_VIEW"}(c||(exports.ViewMode=c={}));const l=window.location.protocol,u=exports.canUseXHR="http:"===l||"https:"===l;function d(t){const n=(0,s.getHashParams)(),l=u&&null!=n.profileURL,d=r.combineReducers({profileGroup:i.profileGroup,hashParams:(0,o.setter)(e.actions.setHashParams,n),flattenRecursion:(0,o.setter)(e.actions.setFlattenRecursion,!1),viewMode:(0,o.setter)(e.actions.setViewMode,c.CHRONO_FLAME_CHART),glCanvas:(0,o.setter)(e.actions.setGLCanvas,null),dragActive:(0,o.setter)(e.actions.setDragActive,!1),loading:(0,o.setter)(e.actions.setLoading,l),error:(0,o.setter)(e.actions.setError,!1),tableSortMethod:(0,o.setter)(e.actions.sandwichView.setTableSortMethod,{field:a.SortField.SELF,direction:a.SortDirection.DESCENDING})});return r.createStore(d,t)} +},{"./actions":40,"redux":31,"../lib/typed-redux":36,"../lib/hash-params":50,"./profiles-state":52,"../views/profile-table-view":55}],81:[function(require,module,exports) { +"use strict";function e(e){return e.replace(/\\([a-fA-F0-9]{2})/g,(e,n)=>{const t=parseInt(n,16);return String.fromCharCode(t)})}function n(n){const t=n.split("\n");if(!t.length)return null;if(""===t[t.length-1]&&t.pop(),!t.length)return null;const r=new Map,o=/^(\d+):(.+)$/,s=/^([\$\w]+):([\$\w-]+)$/;for(const n of t){const t=o.exec(n);if(t){r.set(`wasm-function[${t[1]}]`,e(t[2]));continue}const c=s.exec(n);if(!c)return null;r.set(c[1],e(c[2]))}return r}Object.defineProperty(exports,"__esModule",{value:!0}),exports.importEmscriptenSymbolMap=n; +},{}],142:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Flamechart=void 0;var t=require("./utils"),e=require("./math");class r{constructor(e){this.source=e,this.layers=[],this.totalWeight=0,this.minFrameWidth=1;const r=[];this.minFrameWidth=1/0;this.totalWeight=e.getTotalWeight(),e.forEachCall((e,i)=>{const s=(0,t.lastOf)(r),h={node:e,parent:s,children:[],start:i,end:i};s&&s.children.push(h),r.push(h)},(t,e)=>{console.assert(r.length>0);const i=r.pop();if(i.end=e,i.end-i.start==0)return;const s=r.length;for(;this.layers.length<=s;)this.layers.push([]);this.layers[s].push(i),this.minFrameWidth=Math.min(this.minFrameWidth,i.end-i.start)}),isFinite(this.minFrameWidth)||(this.minFrameWidth=1)}getTotalWeight(){return this.totalWeight}getLayers(){return this.layers}getColorBucketForFrame(t){return this.source.getColorBucketForFrame(t)}getMinFrameWidth(){return this.minFrameWidth}formatValue(t){return this.source.formatValue(t)}getClampedViewportWidth(t){const r=this.getTotalWeight(),i=Math.pow(2,40),s=(0,e.clamp)(3*this.getMinFrameWidth(),r/i,r);return(0,e.clamp)(t,s,r)}}exports.Flamechart=r; +},{"./utils":70,"./math":102}],143:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.FlamechartRenderer=exports.FlamechartRowAtlasKey=void 0;var e=require("./rectangle-batch-renderer"),t=require("../lib/math"),r=require("../lib/color"),n=require("../lib/utils"),s=require("./graphics"),o=require("./utils");const c=1e4;class i{constructor(e,t,r){this.batch=e,this.bounds=t,this.numPrecedingRectanglesInRow=r,this.children=[]}getBatch(){return this.batch}getBounds(){return this.bounds}getRectCount(){return this.batch.getRectCount()}getChildren(){return this.children}getParity(){return this.numPrecedingRectanglesInRow%2}forEachLeafNodeWithinBounds(e,t){this.bounds.hasIntersectionWith(e)&&t(this)}}class h{constructor(e){if(this.children=e,this.rectCount=0,0===e.length)throw new Error("Empty interior node");let r=1/0,n=-1/0,s=1/0,o=-1/0;for(let t of e){this.rectCount+=t.getRectCount();const e=t.getBounds();r=Math.min(r,e.left()),n=Math.max(n,e.right()),s=Math.min(s,e.top()),o=Math.max(o,e.bottom())}this.bounds=new t.Rect(new t.Vec2(r,s),new t.Vec2(n-r,o-s))}getBounds(){return this.bounds}getRectCount(){return this.rectCount}getChildren(){return this.children}forEachLeafNodeWithinBounds(e,t){if(this.bounds.hasIntersectionWith(e))for(let r of this.children)r.forEachLeafNodeWithinBounds(e,t)}}class a{get key(){return`${this.stackDepth}_${this.index}_${this.zoomLevel}`}constructor(e){this.stackDepth=e.stackDepth,this.zoomLevel=e.zoomLevel,this.index=e.index}static getOrInsert(e,t){return e.getOrInsert(new a(t))}}exports.FlamechartRowAtlasKey=a;class l{constructor(s,o,a,l,g,d={inverted:!1}){this.gl=s,this.rowAtlas=o,this.flamechart=a,this.rectangleBatchRenderer=l,this.colorPassRenderer=g,this.options=d,this.layers=[],this.rectInfoTexture=null,this.rectInfoRenderTarget=null,this.atlasKeys=new n.KeyedSet;const f=a.getLayers().length;for(let n=0;n=c&&(s.push(new i(u,new t.Rect(new t.Vec2(l,o),new t.Vec2(g-l,1)),R)),l=1/0,g=-1/0,u=new e.RectangleBatch(this.gl));const d=new t.Rect(new t.Vec2(a.start,o),new t.Vec2(a.end-a.start,1));l=Math.min(l,d.left()),g=Math.max(g,d.right());const f=new r.Color((1+h%255)/256,(1+n%255)/256,(1+this.flamechart.getColorBucketForFrame(a.node.frame))/256);u.addRect(d,f),R++}u.getRectCount()>0&&s.push(new i(u,new t.Rect(new t.Vec2(l,o),new t.Vec2(g-l,1)),R)),this.layers.push(new h(s))}}getRectInfoTexture(e,t){if(this.rectInfoTexture){const r=this.rectInfoTexture;r.width==e&&r.height==t||r.resize(e,t)}else this.rectInfoTexture=this.gl.createTexture(s.Graphics.TextureFormat.NEAREST_CLAMP,e,t);return this.rectInfoTexture}getRectInfoRenderTarget(e,t){const r=this.getRectInfoTexture(e,t);return this.rectInfoRenderTarget&&this.rectInfoRenderTarget.texture!=r&&(this.rectInfoRenderTarget.texture.free(),this.rectInfoRenderTarget.setColor(r)),this.rectInfoRenderTarget||(this.rectInfoRenderTarget=this.gl.createRenderTarget(r)),this.rectInfoRenderTarget}free(){this.rectInfoRenderTarget&&this.rectInfoRenderTarget.free(),this.rectInfoTexture&&this.rectInfoTexture.free()}configSpaceBoundsForKey(e){const{stackDepth:r,zoomLevel:n,index:s}=e,o=this.flamechart.getTotalWeight()/Math.pow(2,n),c=this.flamechart.getLayers().length,i=this.options.inverted?c-1-r:r;return new t.Rect(new t.Vec2(o*s,i),new t.Vec2(o,1))}render(e){const{configSpaceSrcRect:r,physicalSpaceDstRect:n}=e,c=[],i=t.AffineTransform.betweenRects(r,n);if(r.isEmpty())return;let h=0;for(;;){const e=a.getOrInsert(this.atlasKeys,{stackDepth:0,zoomLevel:h,index:0}),t=this.configSpaceBoundsForKey(e);if(i.transformRect(t).width(){const r=this.configSpaceBoundsForKey(t);this.layers[t.stackDepth].forEachLeafNodeWithinBounds(r,t=>{this.rectangleBatchRenderer.render({batch:t.getBatch(),configSpaceSrcRect:r,physicalSpaceDstRect:e})})});const T=this.getRectInfoRenderTarget(n.width(),n.height());(0,o.renderInto)(this.gl,T,()=>{this.gl.clear(new s.Graphics.Color(0,0,0,0));const e=new t.Rect(t.Vec2.zero,new t.Vec2(this.gl.viewport.width,this.gl.viewport.height)),n=t.AffineTransform.betweenRects(r,e);for(let e of m){const t=this.configSpaceBoundsForKey(e);this.rowAtlas.renderViaAtlas(e,n.transformRect(t))}for(let e of I){const t=this.configSpaceBoundsForKey(e),r=n.transformRect(t);this.layers[e.stackDepth].forEachLeafNodeWithinBounds(t,e=>{this.rectangleBatchRenderer.render({batch:e.getBatch(),configSpaceSrcRect:t,physicalSpaceDstRect:r})})}});const x=this.getRectInfoTexture(n.width(),n.height());this.colorPassRenderer.render({rectInfoTexture:x,srcRect:new t.Rect(t.Vec2.zero,new t.Vec2(x.width,x.height)),dstRect:n,renderOutlines:e.renderOutlines})}}exports.FlamechartRenderer=l; +},{"./rectangle-batch-renderer":118,"../lib/math":102,"../lib/color":76,"../lib/utils":70,"./graphics":42,"./utils":119}],163:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.style=void 0;var e=require("aphrodite"),o=require("./style");const t=exports.style=e.StyleSheet.create({hoverCount:{color:o.Colors.GREEN},fill:{width:"100%",height:"100%",position:"absolute",left:0,top:0},minimap:{height:o.Sizes.MINIMAP_HEIGHT,borderBottom:`${o.Sizes.SEPARATOR_HEIGHT}px solid ${o.Colors.LIGHT_GRAY}`},panZoomView:{flex:1},detailView:{display:"grid",height:o.Sizes.DETAIL_VIEW_HEIGHT,overflow:"hidden",gridTemplateColumns:"120px 120px 1fr",gridTemplateRows:"repeat(4, 1fr)",borderTop:`${o.Sizes.SEPARATOR_HEIGHT}px solid ${o.Colors.LIGHT_GRAY}`,fontSize:o.FontSize.LABEL,position:"absolute",background:o.Colors.WHITE,width:"100vw",bottom:0},stackTraceViewPadding:{padding:5},stackTraceView:{height:o.Sizes.DETAIL_VIEW_HEIGHT,lineHeight:`${o.FontSize.LABEL+2}px`,overflow:"auto"},stackLine:{whiteSpace:"nowrap"},stackFileLine:{color:o.Colors.LIGHT_GRAY},statsTable:{display:"grid",gridTemplateColumns:"1fr 1fr",gridTemplateRows:`repeat(3, ${o.FontSize.LABEL+10}px)`,gridGap:"1px 1px",textAlign:"center",paddingRight:1},statsTableHeader:{gridColumn:"1 / 3"},statsTableCell:{position:"relative",display:"flex",justifyContent:"center",alignItems:"center"},thisInstanceCell:{background:o.Colors.DARK_BLUE,color:o.Colors.WHITE},allInstancesCell:{background:o.Colors.PALE_DARK_BLUE,color:o.Colors.WHITE},barDisplay:{position:"absolute",top:0,left:0,background:"rgba(0, 0, 0, 0.2)",width:"100%"}}); +},{"aphrodite":68,"./style":79}],173:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ELLIPSIS=void 0,exports.cachedMeasureTextWidth=n,exports.trimTextMid=s;var e=require("./utils");const t=exports.ELLIPSIS="…",r=new Map;let i=-1;function n(e,t){return window.devicePixelRatio!==i&&(r.clear(),i=window.devicePixelRatio),r.has(t)||r.set(t,e.measureText(t).width),r.get(t)}function o(e,r){const i=Math.floor(r/2),n=e.substr(0,i),o=e.substr(e.length-i,i);return n+t+o}function s(t,r,i){if(n(t,r)<=i)return r;const[s]=(0,e.binarySearch)(0,r.length,e=>n(t,o(r,e)),i);return o(r,s)} +},{"./utils":70}],159:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.FlamechartMinimapView=void 0;var e,i=require("preact"),t=require("aphrodite"),o=require("../lib/math"),s=require("./flamechart-style"),n=require("./style"),a=require("../lib/text-utils");!function(e){e[e.DRAW_NEW_VIEWPORT=0]="DRAW_NEW_VIEWPORT",e[e.TRANSLATE_VIEWPORT=1]="TRANSLATE_VIEWPORT"}(e||(e={}));class r extends i.Component{constructor(){super(...arguments),this.container=null,this.containerRef=(e=>{this.container=e||null}),this.overlayCanvas=null,this.overlayCtx=null,this.onWindowResize=(()=>{this.onBeforeFrame()}),this.onBeforeFrame=(()=>{this.maybeClearInteractionLock(),this.resizeOverlayCanvasIfNeeded(),this.renderRects(),this.renderOverlays()}),this.renderCanvas=(()=>{this.props.canvasContext.requestFrame()}),this.frameHadWheelEvent=!1,this.framesWithoutWheelEvents=0,this.interactionLock=null,this.maybeClearInteractionLock=(()=>{this.interactionLock&&(this.frameHadWheelEvent||(this.framesWithoutWheelEvents++,this.framesWithoutWheelEvents>=2&&(this.interactionLock=null,this.framesWithoutWheelEvents=0)),this.props.canvasContext.requestFrame()),this.frameHadWheelEvent=!1}),this.onWheel=(e=>{if(e.preventDefault(),this.frameHadWheelEvent=!0,(e.metaKey||e.ctrlKey)&&"pan"!==this.interactionLock){let i=1+e.deltaY/100;e.ctrlKey&&(i=1+e.deltaY/40),i=(0,o.clamp)(i,.1,10),this.zoom(i)}else"zoom"!==this.interactionLock&&this.pan(new o.Vec2(e.deltaX,e.deltaY));this.renderCanvas()}),this.dragStartConfigSpaceMouse=null,this.dragConfigSpaceViewportOffset=null,this.draggingMode=null,this.onMouseDown=(i=>{const t=this.configSpaceMouse(i);t&&(this.props.configSpaceViewportRect.contains(t)?(this.draggingMode=e.TRANSLATE_VIEWPORT,this.dragConfigSpaceViewportOffset=t.minus(this.props.configSpaceViewportRect.origin)):this.draggingMode=e.DRAW_NEW_VIEWPORT,this.dragStartConfigSpaceMouse=t,window.addEventListener("mousemove",this.onWindowMouseMove),window.addEventListener("mouseup",this.onWindowMouseUp),this.updateCursor(t))}),this.onWindowMouseMove=(i=>{if(!this.dragStartConfigSpaceMouse)return;let t=this.configSpaceMouse(i);if(t)if(this.updateCursor(t),t=new o.Rect(new o.Vec2(0,0),this.configSpaceSize()).closestPointTo(t),this.draggingMode===e.DRAW_NEW_VIEWPORT){const e=this.dragStartConfigSpaceMouse;let i=t;if(!e||!i)return;const s=Math.min(e.x,i.x),n=Math.max(e.x,i.x)-s,a=this.props.configSpaceViewportRect.height();this.props.setConfigSpaceViewportRect(new o.Rect(new o.Vec2(s,i.y-a/2),new o.Vec2(n,a)))}else if(this.draggingMode===e.TRANSLATE_VIEWPORT){if(!this.dragConfigSpaceViewportOffset)return;const e=t.minus(this.dragConfigSpaceViewportOffset);this.props.setConfigSpaceViewportRect(this.props.configSpaceViewportRect.withOrigin(e))}}),this.updateCursor=(i=>{this.draggingMode===e.TRANSLATE_VIEWPORT?(document.body.style.cursor="grabbing",document.body.style.cursor="-webkit-grabbing"):this.draggingMode===e.DRAW_NEW_VIEWPORT?document.body.style.cursor="col-resize":this.props.configSpaceViewportRect.contains(i)?(document.body.style.cursor="grab",document.body.style.cursor="-webkit-grab"):document.body.style.cursor="col-resize"}),this.onMouseLeave=(()=>{null==this.draggingMode&&(document.body.style.cursor="default")}),this.onMouseMove=(e=>{const i=this.configSpaceMouse(e);i&&this.updateCursor(i)}),this.onWindowMouseUp=(e=>{this.draggingMode=null,window.removeEventListener("mousemove",this.onWindowMouseMove),window.removeEventListener("mouseup",this.onWindowMouseUp);const i=this.configSpaceMouse(e);i&&this.updateCursor(i)}),this.overlayCanvasRef=(e=>{e?(this.overlayCanvas=e,this.overlayCtx=this.overlayCanvas.getContext("2d"),this.renderCanvas()):(this.overlayCanvas=null,this.overlayCtx=null)})}physicalViewSize(){return new o.Vec2(this.overlayCanvas?this.overlayCanvas.width:0,this.overlayCanvas?this.overlayCanvas.height:0)}minimapOrigin(){return new o.Vec2(0,n.Sizes.FRAME_HEIGHT*window.devicePixelRatio)}configSpaceSize(){return new o.Vec2(this.props.flamechart.getTotalWeight(),this.props.flamechart.getLayers().length)}configSpaceToPhysicalViewSpace(){const e=this.minimapOrigin();return o.AffineTransform.betweenRects(new o.Rect(new o.Vec2(0,0),this.configSpaceSize()),new o.Rect(e,this.physicalViewSize().minus(e)))}logicalToPhysicalViewSpace(){return o.AffineTransform.withScale(new o.Vec2(window.devicePixelRatio,window.devicePixelRatio))}windowToLogicalViewSpace(){if(!this.container)return new o.AffineTransform;const e=this.container.getBoundingClientRect();return o.AffineTransform.withTranslation(new o.Vec2(-e.left,-e.top))}renderRects(){this.container&&(this.physicalViewSize().x<2||this.props.canvasContext.renderBehind(this.container,()=>{this.props.flamechartRenderer.render({configSpaceSrcRect:new o.Rect(new o.Vec2(0,0),this.configSpaceSize()),physicalSpaceDstRect:new o.Rect(this.minimapOrigin(),this.physicalViewSize().minus(this.minimapOrigin())),renderOutlines:!1}),this.props.canvasContext.viewportRectangleRenderer.render({configSpaceViewportRect:this.props.configSpaceViewportRect,configSpaceToPhysicalViewSpace:this.configSpaceToPhysicalViewSpace()})}))}renderOverlays(){const e=this.overlayCtx;if(!e)return;const i=this.physicalViewSize();e.clearRect(0,0,i.x,i.y);const t=this.configSpaceToPhysicalViewSpace(),s=this.configSpaceSize().x,r=(this.configSpaceToPhysicalViewSpace().inverted()||new o.AffineTransform).times(this.logicalToPhysicalViewSpace()).transformVector(new o.Vec2(200,1)).x,c=n.Sizes.FRAME_HEIGHT*window.devicePixelRatio,h=n.FontSize.LABEL*window.devicePixelRatio,l=(c-h)/2;e.font=`${h}px/${c}px ${n.FontFamily.MONOSPACE}`,e.textBaseline="top";let p=Math.pow(10,Math.floor(Math.log10(r)));r/p>5?p*=5:r/p>2&&(p*=2),e.fillStyle="rgba(255, 255, 255, 0.8)",e.fillRect(0,0,i.x,c),e.textBaseline="top",e.fillStyle=n.Colors.DARK_GRAY;for(let n=Math.ceil(0/p)*p;n ")),i.push(c.name),c.file){let l=c.file;c.line&&(l+=`:${c.line}`,c.col&&(l+=`:${c.col}`)),i.push((0,s.h)("span",{className:(0,e.css)(t.style.stackFileLine)}," (",l,")"))}l.push((0,s.h)("div",{className:(0,e.css)(t.style.stackLine)},i))}return(0,s.h)("div",{className:(0,e.css)(t.style.stackTraceView)},(0,s.h)("div",{className:(0,e.css)(t.style.stackTraceViewPadding)},l))}}class c extends s.Component{render(){const{flamechart:l,selectedNode:a}=this.props,{frame:c}=a;return(0,s.h)("div",{className:(0,e.css)(t.style.detailView)},(0,s.h)(r,{title:"This Instance",cellStyle:t.style.thisInstanceCell,grandTotal:l.getTotalWeight(),selectedTotal:a.getTotalWeight(),selectedSelf:a.getSelfWeight(),formatter:l.formatValue.bind(l)}),(0,s.h)(r,{title:"All Instances",cellStyle:t.style.allInstancesCell,grandTotal:l.getTotalWeight(),selectedTotal:c.getTotalWeight(),selectedSelf:c.getSelfWeight(),formatter:l.formatValue.bind(l)}),(0,s.h)(i,{node:a,getFrameColor:this.props.getCSSColorForFrame}))}}exports.FlamechartDetailView=c; +},{"aphrodite":68,"preact":24,"./flamechart-style":163,"../lib/utils":70,"./color-chit":106}],161:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.FlamechartPanZoomView=void 0;var e=require("../lib/math"),t=require("./style"),i=require("../lib/text-utils"),o=require("./flamechart-style"),s=require("preact"),n=require("aphrodite");class r extends s.Component{constructor(){super(...arguments),this.container=null,this.containerRef=(e=>{this.container=e||null}),this.overlayCanvas=null,this.overlayCtx=null,this.hoveredLabel=null,this.overlayCanvasRef=(e=>{e?(this.overlayCanvas=e,this.overlayCtx=this.overlayCanvas.getContext("2d"),this.renderCanvas()):(this.overlayCanvas=null,this.overlayCtx=null)}),this.LOGICAL_VIEW_SPACE_FRAME_HEIGHT=t.Sizes.FRAME_HEIGHT,this.onWindowResize=(()=>{this.updateConfigSpaceViewport(),this.onBeforeFrame()}),this.frameHadWheelEvent=!1,this.framesWithoutWheelEvents=0,this.interactionLock=null,this.maybeClearInteractionLock=(()=>{this.interactionLock&&(this.frameHadWheelEvent||(this.framesWithoutWheelEvents++,this.framesWithoutWheelEvents>=2&&(this.interactionLock=null,this.framesWithoutWheelEvents=0)),this.props.canvasContext.requestFrame()),this.frameHadWheelEvent=!1}),this.onBeforeFrame=(()=>{this.resizeOverlayCanvasIfNeeded(),this.renderRects(),this.renderOverlays(),this.maybeClearInteractionLock()}),this.renderCanvas=(()=>{this.props.canvasContext.requestFrame()}),this.lastDragPos=null,this.mouseDownPos=null,this.onMouseDown=(t=>{this.mouseDownPos=this.lastDragPos=new e.Vec2(t.offsetX,t.offsetY),this.updateCursor(),window.addEventListener("mouseup",this.onWindowMouseUp)}),this.onMouseDrag=(t=>{if(!this.lastDragPos)return;const i=new e.Vec2(t.offsetX,t.offsetY);this.pan(this.lastDragPos.minus(i)),this.lastDragPos=i,this.hoveredLabel&&this.props.onNodeHover(null)}),this.onDblClick=(t=>{if(this.hoveredLabel){const t=this.hoveredLabel.configSpaceBounds,i=new e.Rect(t.origin.minus(new e.Vec2(0,1)),t.size.withY(this.props.configSpaceViewportRect.height()));this.props.setConfigSpaceViewportRect(i)}}),this.onClick=(t=>{const i=new e.Vec2(t.offsetX,t.offsetY),o=this.mouseDownPos;this.mouseDownPos=null,o&&i.minus(o).length()>5||(this.hoveredLabel?(this.props.onNodeSelect(this.hoveredLabel.node),this.renderCanvas()):this.props.onNodeSelect(null))}),this.onWindowMouseUp=(e=>{this.lastDragPos=null,this.updateCursor(),window.removeEventListener("mouseup",this.onWindowMouseUp)}),this.onMouseMove=(t=>{if(this.updateCursor(),this.lastDragPos)return t.preventDefault(),void this.onMouseDrag(t);this.hoveredLabel=null;const i=new e.Vec2(t.offsetX,t.offsetY),o=this.logicalToPhysicalViewSpace().transformPosition(i),s=this.configSpaceToPhysicalViewSpace().inverseTransformPosition(o);if(!s)return;const n=(t,i=0)=>{const o=t.end-t.start,r=this.props.renderInverted?this.configSpaceSize().y-1-i:i,a=new e.Rect(new e.Vec2(t.start,r),new e.Vec2(o,1));if(s.xa.right())return null;a.contains(s)&&(this.hoveredLabel={configSpaceBounds:a,node:t.node});for(let e of t.children)n(e,i+1)};for(let e of this.props.flamechart.getLayers()[0]||[])n(e);this.hoveredLabel?this.props.onNodeHover({node:this.hoveredLabel.node,event:t}):this.props.onNodeHover(null),this.renderCanvas()}),this.onMouseLeave=(e=>{this.hoveredLabel=null,this.props.onNodeHover(null),this.renderCanvas()}),this.onWheel=(t=>{t.preventDefault(),this.frameHadWheelEvent=!0;const i=t.metaKey||t.ctrlKey;let o=t.deltaY,s=t.deltaX;if(t.deltaMode===t.DOM_DELTA_LINE&&(o*=this.LOGICAL_VIEW_SPACE_FRAME_HEIGHT,s*=this.LOGICAL_VIEW_SPACE_FRAME_HEIGHT),i&&"pan"!==this.interactionLock){let i=1+o/100;t.ctrlKey&&(i=1+o/40),i=(0,e.clamp)(i,.1,10),this.zoom(new e.Vec2(t.offsetX,t.offsetY),i)}else"zoom"!==this.interactionLock&&this.pan(new e.Vec2(s,o));this.renderCanvas()}),this.onWindowKeyPress=(t=>{if(!this.container)return;const{width:i,height:o}=this.container.getBoundingClientRect();"="===t.key||"+"===t.key?(this.zoom(new e.Vec2(i/2,o/2),.5),t.preventDefault()):"-"!==t.key&&"_"!==t.key||(this.zoom(new e.Vec2(i/2,o/2),2),t.preventDefault()),t.ctrlKey||t.shiftKey||t.metaKey||("0"===t.key?this.zoom(new e.Vec2(i/2,o/2),1e9):"ArrowRight"===t.key||"KeyD"===t.code?this.pan(new e.Vec2(100,0)):"ArrowLeft"===t.key||"KeyA"===t.code?this.pan(new e.Vec2(-100,0)):"ArrowUp"===t.key||"KeyW"===t.code?this.pan(new e.Vec2(0,-100)):"ArrowDown"===t.key||"KeyS"===t.code?this.pan(new e.Vec2(0,100)):"Escape"===t.key&&(this.props.onNodeSelect(null),this.renderCanvas()))})}setConfigSpaceViewportRect(e){this.props.setConfigSpaceViewportRect(e)}configSpaceSize(){return new e.Vec2(this.props.flamechart.getTotalWeight(),this.props.flamechart.getLayers().length)}physicalViewSize(){return new e.Vec2(this.overlayCanvas?this.overlayCanvas.width:0,this.overlayCanvas?this.overlayCanvas.height:0)}physicalBounds(){if(this.props.renderInverted){const t=this.physicalViewSize().y,i=(this.configSpaceSize().y+1)*this.LOGICAL_VIEW_SPACE_FRAME_HEIGHT*window.devicePixelRatio;if(i{const f=t.end-t.start,w=this.props.renderInverted?this.configSpaceSize().y-1-d:d,u=new e.Rect(new e.Vec2(t.start,w),new e.Vec2(f,1));if(!(fthis.props.configSpaceViewportRect.right()||u.right()this.props.configSpaceViewportRect.bottom())return;if(u.hasIntersectionWith(this.props.configSpaceViewportRect)){let e=s.transformRect(u);if(e.left()<0&&(e=e.withOrigin(e.origin.withX(0)).withSize(e.size.withX(e.size.x+e.left()))),e.right()>a.x&&(e=e.withSize(e.size.withX(a.x-e.left()))),e.width()>h){const s=(0,i.trimTextMid)(o,t.node.frame.name,e.width()-2*l);o.fillText(s,e.left()+l,Math.round(e.bottom()-(r-n)/2))}}for(let e of t.children)p(e,d+1)}};for(let e of this.props.flamechart.getLayers()[0]||[])p(e);const d=2*window.devicePixelRatio;o.strokeStyle=t.Colors.PALE_DARK_BLUE,o.lineWidth=d;const f=(s.inverseTransformVector(new e.Vec2(1,0))||new e.Vec2(0,0)).x,w=(i,n=0)=>{if(!this.props.selectedNode)return;const r=i.end-i.start,a=this.props.renderInverted?this.configSpaceSize().y-1-n:n,h=new e.Rect(new e.Vec2(i.start,a),new e.Vec2(r,1));if(!(rthis.props.configSpaceViewportRect.right()||h.right()this.props.configSpaceViewportRect.bottom())){if(h.hasIntersectionWith(this.props.configSpaceViewportRect)){const e=s.transformRect(h);i.node.frame===this.props.selectedNode.frame&&(i.node===this.props.selectedNode?o.strokeStyle!==t.Colors.DARK_BLUE&&(o.stroke(),o.beginPath(),o.strokeStyle=t.Colors.DARK_BLUE):o.strokeStyle!==t.Colors.PALE_DARK_BLUE&&(o.stroke(),o.beginPath(),o.strokeStyle=t.Colors.PALE_DARK_BLUE),o.rect(Math.round(e.left()+1+d/2),Math.round(e.top()+1+d/2),Math.round(Math.max(0,e.width()-2-d)),Math.round(Math.max(0,e.height()-2-d))))}for(let e of i.children)w(e,n+1)}};o.beginPath();for(let e of this.props.flamechart.getLayers()[0]||[])w(e);o.stroke(),this.renderTimeIndicators()}renderTimeIndicators(){const o=this.overlayCtx;if(!o)return;const s=this.LOGICAL_VIEW_SPACE_FRAME_HEIGHT*window.devicePixelRatio,n=this.physicalViewSize(),r=this.configSpaceToPhysicalViewSpace(),a=(s-t.FontSize.LABEL*window.devicePixelRatio)/2,h=this.props.configSpaceViewportRect.left(),c=this.props.configSpaceViewportRect.right(),l=(this.configSpaceToPhysicalViewSpace().inverted()||new e.AffineTransform).times(this.logicalToPhysicalViewSpace()).transformVector(new e.Vec2(200,1)).x;let p=Math.pow(10,Math.floor(Math.log10(l)));l/p>5?p*=5:l/p>2&&(p*=2);{const l=this.props.renderInverted?n.y-s:0;o.fillStyle="rgba(255, 255, 255, 0.8)",o.fillRect(0,l,n.x,s),o.fillStyle=t.Colors.DARK_GRAY,o.textBaseline="top";for(let t=Math.ceil(h/p)*p;t{this.props.flamechartRenderer.render({physicalSpaceDstRect:this.physicalBounds(),configSpaceSrcRect:this.props.configSpaceViewportRect,renderOutlines:!0})}))}pan(t){this.interactionLock="pan";const i=this.logicalToPhysicalViewSpace().transformVector(t),o=this.configSpaceToPhysicalViewSpace().inverseTransformVector(i);this.hoveredLabel&&this.props.onNodeHover(null),o&&this.props.transformViewport(e.AffineTransform.withTranslation(o))}zoom(t,i){this.interactionLock="zoom";const o=this.logicalToPhysicalViewSpace().transformPosition(t),s=this.configSpaceToPhysicalViewSpace().inverseTransformPosition(o);if(!s)return;const n=e.AffineTransform.withTranslation(s.times(-1)).scaledBy(new e.Vec2(i,1)).translatedBy(s);this.props.transformViewport(n)}updateCursor(){this.lastDragPos?(document.body.style.cursor="grabbing",document.body.style.cursor="-webkit-grabbing"):document.body.style.cursor="default"}shouldComponentUpdate(){return!1}componentWillReceiveProps(e){this.props.flamechart!==e.flamechart?(this.hoveredLabel=null,this.renderCanvas()):this.props.selectedNode!==e.selectedNode?this.renderCanvas():this.props.configSpaceViewportRect!==e.configSpaceViewportRect&&this.renderCanvas()}componentDidMount(){this.props.canvasContext.addBeforeFrameHandler(this.onBeforeFrame),window.addEventListener("resize",this.onWindowResize),window.addEventListener("keydown",this.onWindowKeyPress)}componentWillUnmount(){this.props.canvasContext.removeBeforeFrameHandler(this.onBeforeFrame),window.removeEventListener("resize",this.onWindowResize),window.removeEventListener("keydown",this.onWindowKeyPress)}render(){return(0,s.h)("div",{className:(0,n.css)(o.style.panZoomView,t.commonStyle.vbox),onMouseDown:this.onMouseDown,onMouseMove:this.onMouseMove,onMouseLeave:this.onMouseLeave,onClick:this.onClick,onDblClick:this.onDblClick,onWheel:this.onWheel,ref:this.containerRef},(0,s.h)("canvas",{width:1,height:1,ref:this.overlayCanvasRef,className:(0,n.css)(o.style.fill)}))}}exports.FlamechartPanZoomView=r; +},{"../lib/math":102,"./style":79,"../lib/text-utils":173,"./flamechart-style":163,"preact":24,"aphrodite":68}],162:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Hovertip=void 0;var e=require("./style"),o=require("aphrodite"),t=require("preact");class i extends t.Component{render(){const{containerSize:i,offset:r}=this.props,n=i.x,p=i.y,d={};return r.x+7+e.Sizes.TOOLTIP_WIDTH_MAX{const t=a.Sizes.DETAIL_VIEW_HEIGHT/a.Sizes.FRAME_HEIGHT,i=this.configSpaceSize(),o=this.props.flamechart.getClampedViewportWidth(e.size.x),s=e.size.withX(o),c=r.Vec2.clamp(e.origin,new r.Vec2(0,-1),r.Vec2.max(r.Vec2.zero,i.minus(s).plus(new r.Vec2(0,t+1))));this.props.setConfigSpaceViewportRect(new r.Rect(c,e.size.withX(o)))}),this.setLogicalSpaceViewportSize=(e=>{this.props.setLogicalSpaceViewportSize(e)}),this.transformViewport=(e=>{const t=e.transformRect(this.props.configSpaceViewportRect);this.setConfigSpaceViewportRect(t)}),this.onNodeHover=(e=>{this.props.setNodeHover(e)}),this.onNodeClick=(e=>{this.props.setSelectedNode(e)}),this.container=null,this.containerRef=(e=>{this.container=e||null})}configSpaceSize(){return new r.Vec2(this.props.flamechart.getTotalWeight(),this.props.flamechart.getLayers().length)}formatValue(e){const t=100*e/this.props.flamechart.getTotalWeight(),r=(0,i.formatPercent)(t);return`${this.props.flamechart.formatValue(e)} (${r})`}renderTooltip(){if(!this.container)return null;const{hover:i}=this.props;if(!i)return null;const{width:o,height:a,left:c,top:p}=this.container.getBoundingClientRect(),h=new r.Vec2(i.event.clientX-c,i.event.clientY-p);return(0,e.h)(n.Hovertip,{containerSize:new r.Vec2(o,a),offset:h},(0,e.h)("span",{className:(0,t.css)(s.style.hoverCount)},this.formatValue(i.node.getTotalWeight()))," ",i.node.frame.name)}render(){return(0,e.h)("div",{className:(0,t.css)(s.style.fill,a.commonStyle.vbox),ref:this.containerRef},(0,e.h)(o.FlamechartMinimapView,{configSpaceViewportRect:this.props.configSpaceViewportRect,transformViewport:this.transformViewport,flamechart:this.props.flamechart,flamechartRenderer:this.props.flamechartRenderer,canvasContext:this.props.canvasContext,setConfigSpaceViewportRect:this.setConfigSpaceViewportRect}),(0,e.h)(p.FlamechartPanZoomView,{canvasContext:this.props.canvasContext,flamechart:this.props.flamechart,flamechartRenderer:this.props.flamechartRenderer,renderInverted:!1,onNodeHover:this.onNodeHover,onNodeSelect:this.onNodeClick,selectedNode:this.props.selectedNode,transformViewport:this.transformViewport,configSpaceViewportRect:this.props.configSpaceViewportRect,setConfigSpaceViewportRect:this.setConfigSpaceViewportRect,logicalSpaceViewportSize:this.props.logicalSpaceViewportSize,setLogicalSpaceViewportBounds:this.setLogicalSpaceViewportSize}),this.renderTooltip(),this.props.selectedNode&&(0,e.h)(c.FlamechartDetailView,{flamechart:this.props.flamechart,getCSSColorForFrame:this.props.getCSSColorForFrame,selectedNode:this.props.selectedNode}))}}exports.FlamechartView=l; +},{"preact":24,"aphrodite":68,"../lib/math":102,"../lib/utils":70,"./flamechart-minimap-view":159,"./flamechart-style":163,"./style":79,"./flamechart-detail-view":160,"./flamechart-pan-zoom-view":161,"./hovertip":162,"../lib/typed-redux":36}],62:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.LeftHeavyFlamechartView=exports.getLeftHeavyFlamechart=exports.ChronoFlamechartView=exports.createMemoizedFlamechartRenderer=exports.getChronoViewFlamechart=void 0,exports.createFlamechartSetters=n;var e=require("../store/flamechart-view-state"),t=require("../lib/flamechart"),r=require("../gl/flamechart-renderer"),a=require("../lib/typed-redux"),o=require("../lib/utils"),l=require("./flamechart-view"),c=require("../store/getters"),i=require("../store/actions");function n(e,t,r){function a(a,o){return l=>{const c=Object.assign({},o(l),{id:t});e(a({profileIndex:r,args:c}))}}const{setHoveredNode:o,setLogicalSpaceViewportSize:l,setConfigSpaceViewportRect:c,setSelectedNode:n}=i.actions.flamechart;return{setNodeHover:a(o,e=>({hover:e})),setLogicalSpaceViewportSize:a(l,e=>({logicalSpaceViewportSize:e})),setConfigSpaceViewportRect:a(c,e=>({configSpaceViewportRect:e})),setSelectedNode:a(n,e=>({selectedNode:e}))}}const m=exports.getChronoViewFlamechart=(0,o.memoizeByShallowEquality)(({profile:e,getColorBucketForFrame:r})=>new t.Flamechart({getTotalWeight:e.getTotalWeight.bind(e),forEachCall:e.forEachCall.bind(e),formatValue:e.formatValue.bind(e),getColorBucketForFrame:r})),s=exports.createMemoizedFlamechartRenderer=(e=>(0,o.memoizeByShallowEquality)(({canvasContext:t,flamechart:a})=>new r.FlamechartRenderer(t.gl,(0,c.getRowAtlas)(t),a,t.rectangleBatchRenderer,t.flamechartColorPassRenderer,e))),h=s(),F=exports.ChronoFlamechartView=(0,a.createContainer)(l.FlamechartView,(t,r,a)=>{const{activeProfileState:o,glCanvas:l}=a,{index:i,profile:s,chronoViewState:F}=o,C=(0,c.getCanvasContext)(l),f=(0,c.getFrameToColorBucket)(s),g=(0,c.createGetColorBucketForFrame)(f),d=(0,c.createGetCSSColorForFrame)(f),u=m({profile:s,getColorBucketForFrame:g}),p=h({canvasContext:C,flamechart:u});return Object.assign({renderInverted:!1,flamechart:u,flamechartRenderer:p,canvasContext:C,getCSSColorForFrame:d},n(r,e.FlamechartID.CHRONO,i),F)}),C=exports.getLeftHeavyFlamechart=(0,o.memoizeByShallowEquality)(({profile:e,getColorBucketForFrame:r})=>new t.Flamechart({getTotalWeight:e.getTotalNonIdleWeight.bind(e),forEachCall:e.forEachCallGrouped.bind(e),formatValue:e.formatValue.bind(e),getColorBucketForFrame:r})),f=s(),g=exports.LeftHeavyFlamechartView=(0,a.createContainer)(l.FlamechartView,(t,r,a)=>{const{activeProfileState:o,glCanvas:l}=a,{index:i,profile:m,leftHeavyViewState:s}=o,h=(0,c.getCanvasContext)(l),F=(0,c.getFrameToColorBucket)(m),g=(0,c.createGetColorBucketForFrame)(F),d=(0,c.createGetCSSColorForFrame)(F),u=C({profile:m,getColorBucketForFrame:g}),p=f({canvasContext:h,flamechart:u});return Object.assign({renderInverted:!1,flamechart:u,flamechartRenderer:p,canvasContext:h,getCSSColorForFrame:d},n(r,e.FlamechartID.LEFT_HEAVY,i),s)}); +},{"../store/flamechart-view-state":98,"../lib/flamechart":142,"../gl/flamechart-renderer":143,"../lib/typed-redux":36,"../lib/utils":70,"./flamechart-view":115,"../store/getters":38,"../store/actions":40}],167:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.style=exports.FlamechartWrapper=void 0;var e=require("aphrodite"),t=require("preact"),r=require("./style"),o=require("../lib/math"),i=require("./flamechart-pan-zoom-view"),s=require("../lib/utils"),a=require("./hovertip"),n=require("../lib/typed-redux");class p extends n.StatelessComponent{constructor(){super(...arguments),this.setConfigSpaceViewportRect=(e=>{this.props.setConfigSpaceViewportRect(this.clampViewportToFlamegraph(e))}),this.setLogicalSpaceViewportSize=(e=>{this.props.setLogicalSpaceViewportSize(e)}),this.transformViewport=(e=>{this.setConfigSpaceViewportRect(e.transformRect(this.props.configSpaceViewportRect))}),this.container=null,this.containerRef=(e=>{this.container=e||null}),this.setNodeHover=(e=>{this.props.setNodeHover(e)})}clampViewportToFlamegraph(e){const{flamechart:t,renderInverted:r}=this.props,i=new o.Vec2(t.getTotalWeight(),t.getLayers().length),s=this.props.flamechart.getClampedViewportWidth(e.size.x),a=e.size.withX(s),n=o.Vec2.clamp(e.origin,new o.Vec2(0,r?0:-1),o.Vec2.max(o.Vec2.zero,i.minus(a).plus(new o.Vec2(0,1))));return new o.Rect(n,e.size.withX(s))}formatValue(e){const t=100*e/this.props.flamechart.getTotalWeight(),r=(0,s.formatPercent)(t);return`${this.props.flamechart.formatValue(e)} (${r})`}renderTooltip(){if(!this.container)return null;const{hover:r}=this.props;if(!r)return null;const{width:i,height:s,left:n,top:p}=this.container.getBoundingClientRect(),l=new o.Vec2(r.event.clientX-n,r.event.clientY-p);return(0,t.h)(a.Hovertip,{containerSize:new o.Vec2(i,s),offset:l},(0,t.h)("span",{className:(0,e.css)(c.hoverCount)},this.formatValue(r.node.getTotalWeight()))," ",r.node.frame.name)}render(){return(0,t.h)("div",{className:(0,e.css)(r.commonStyle.fillY,r.commonStyle.fillX,r.commonStyle.vbox),ref:this.containerRef},(0,t.h)(i.FlamechartPanZoomView,{selectedNode:null,onNodeHover:this.setNodeHover,onNodeSelect:s.noop,configSpaceViewportRect:this.props.configSpaceViewportRect,setConfigSpaceViewportRect:this.setConfigSpaceViewportRect,transformViewport:this.transformViewport,flamechart:this.props.flamechart,flamechartRenderer:this.props.flamechartRenderer,canvasContext:this.props.canvasContext,renderInverted:this.props.renderInverted,logicalSpaceViewportSize:this.props.logicalSpaceViewportSize,setLogicalSpaceViewportBounds:this.setLogicalSpaceViewportSize}),this.renderTooltip())}}exports.FlamechartWrapper=p;const c=exports.style=e.StyleSheet.create({hoverCount:{color:r.Colors.GREEN}}); +},{"aphrodite":68,"preact":24,"./style":79,"../lib/math":102,"./flamechart-pan-zoom-view":161,"../lib/utils":70,"./hovertip":162,"../lib/typed-redux":36}],137:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.InvertedCallerFlamegraphView=void 0;var e=require("../lib/utils"),r=require("../lib/flamechart"),t=require("./flamechart-view-container"),a=require("../lib/typed-redux"),l=require("../store/getters"),o=require("../store/flamechart-view-state"),i=require("./flamechart-wrapper");const n=(0,e.memoizeByShallowEquality)(({profile:e,frame:r,flattenRecursion:t})=>{let a=e.getInvertedProfileForCallersOf(r);return t?a.getProfileWithRecursionFlattened():a}),c=(0,e.memoizeByShallowEquality)(({invertedCallerProfile:e,getColorBucketForFrame:t})=>new r.Flamechart({getTotalWeight:e.getTotalNonIdleWeight.bind(e),forEachCall:e.forEachCallGrouped.bind(e),formatValue:e.formatValue.bind(e),getColorBucketForFrame:t})),s=(0,t.createMemoizedFlamechartRenderer)({inverted:!0}),m=exports.InvertedCallerFlamegraphView=(0,a.createContainer)(i.FlamechartWrapper,(e,r,a)=>{const{activeProfileState:i}=a;let{profile:m,sandwichViewState:f,index:d}=i,{flattenRecursion:u,glCanvas:C}=e;if(!m)throw new Error("profile missing");if(!C)throw new Error("glCanvas missing");const{callerCallee:h}=f;if(!h)throw new Error("callerCallee missing");const{selectedFrame:F}=h;m=u?(0,l.getProfileWithRecursionFlattened)(m):m;const g=(0,l.getFrameToColorBucket)(m),v=(0,l.createGetColorBucketForFrame)(g),p=(0,l.createGetCSSColorForFrame)(g),w=(0,l.getCanvasContext)(C),S=c({invertedCallerProfile:n({profile:m,frame:F,flattenRecursion:u}),getColorBucketForFrame:v}),E=s({canvasContext:w,flamechart:S});return Object.assign({renderInverted:!0,flamechart:S,flamechartRenderer:E,canvasContext:w,getCSSColorForFrame:p},(0,t.createFlamechartSetters)(r,o.FlamechartID.SANDWICH_INVERTED_CALLERS,d),{setSelectedNode:()=>{}},h.invertedCallerFlamegraph)}); +},{"../lib/utils":70,"../lib/flamechart":142,"./flamechart-view-container":62,"../lib/typed-redux":36,"../store/getters":38,"../store/flamechart-view-state":98,"./flamechart-wrapper":167}],138:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.CalleeFlamegraphView=void 0;var e=require("../lib/utils"),r=require("../lib/flamechart"),t=require("./flamechart-view-container"),a=require("../lib/typed-redux"),l=require("../store/getters"),o=require("../store/flamechart-view-state"),i=require("./flamechart-wrapper");const c=(0,e.memoizeByShallowEquality)(({profile:e,frame:r,flattenRecursion:t})=>{let a=e.getProfileForCalleesOf(r);return t?a.getProfileWithRecursionFlattened():a}),n=(0,e.memoizeByShallowEquality)(({calleeProfile:e,getColorBucketForFrame:t})=>new r.Flamechart({getTotalWeight:e.getTotalNonIdleWeight.bind(e),forEachCall:e.forEachCallGrouped.bind(e),formatValue:e.formatValue.bind(e),getColorBucketForFrame:t})),s=(0,t.createMemoizedFlamechartRenderer)(),m=exports.CalleeFlamegraphView=(0,a.createContainer)(i.FlamechartWrapper,(e,r,a)=>{const{activeProfileState:i}=a,{index:m,profile:f,sandwichViewState:u}=i,{flattenRecursion:h,glCanvas:C}=e;if(!f)throw new Error("profile missing");if(!C)throw new Error("glCanvas missing");const{callerCallee:F}=u;if(!F)throw new Error("callerCallee missing");const{selectedFrame:g}=F,d=(0,l.getFrameToColorBucket)(f),p=(0,l.createGetColorBucketForFrame)(d),w=(0,l.createGetCSSColorForFrame)(d),v=(0,l.getCanvasContext)(C),S=n({calleeProfile:c({profile:f,frame:g,flattenRecursion:h}),getColorBucketForFrame:p}),q=s({canvasContext:v,flamechart:S});return Object.assign({renderInverted:!1,flamechart:S,flamechartRenderer:q,canvasContext:v,getCSSColorForFrame:w},(0,t.createFlamechartSetters)(r,o.FlamechartID.SANDWICH_CALLEES,m),{setSelectedNode:()=>{}},F.calleeFlamegraph)}); +},{"../lib/utils":70,"../lib/flamechart":142,"./flamechart-view-container":62,"../lib/typed-redux":36,"../store/getters":38,"../store/flamechart-view-state":98,"./flamechart-wrapper":167}],60:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.SandwichViewContainer=void 0;var e=require("aphrodite"),t=require("./profile-table-view"),a=require("preact"),l=require("./style"),r=require("../store/actions"),s=require("../lib/typed-redux"),i=require("./inverted-caller-flamegraph-view"),o=require("./callee-flamegraph-view");class n extends s.StatelessComponent{constructor(){super(...arguments),this.setSelectedFrame=(e=>{this.props.setSelectedFrame(e)}),this.onWindowKeyPress=(e=>{"Escape"===e.key&&this.setSelectedFrame(null)})}componentDidMount(){window.addEventListener("keydown",this.onWindowKeyPress)}componentWillUnmount(){window.removeEventListener("keydown",this.onWindowKeyPress)}render(){const{selectedFrame:r}=this.props;let s=null;return r&&(s=(0,a.h)("div",{className:(0,e.css)(l.commonStyle.fillY,c.callersAndCallees,l.commonStyle.vbox)},(0,a.h)("div",{className:(0,e.css)(l.commonStyle.hbox,c.panZoomViewWraper)},(0,a.h)("div",{className:(0,e.css)(c.flamechartLabelParent)},(0,a.h)("div",{className:(0,e.css)(c.flamechartLabel)},"Callers")),(0,a.h)(i.InvertedCallerFlamegraphView,{glCanvas:this.props.glCanvas,activeProfileState:this.props.activeProfileState})),(0,a.h)("div",{className:(0,e.css)(c.divider)}),(0,a.h)("div",{className:(0,e.css)(l.commonStyle.hbox,c.panZoomViewWraper)},(0,a.h)("div",{className:(0,e.css)(c.flamechartLabelParent,c.flamechartLabelParentBottom)},(0,a.h)("div",{className:(0,e.css)(c.flamechartLabel,c.flamechartLabelBottom)},"Callees")),(0,a.h)(o.CalleeFlamegraphView,{glCanvas:this.props.glCanvas,activeProfileState:this.props.activeProfileState})))),(0,a.h)("div",{className:(0,e.css)(l.commonStyle.hbox,l.commonStyle.fillY)},(0,a.h)("div",{className:(0,e.css)(c.tableView)},(0,a.h)(t.ProfileTableViewContainer,{activeProfileState:this.props.activeProfileState})),s)}}const c=e.StyleSheet.create({tableView:{flex:1},panZoomViewWraper:{flex:1},flamechartLabelParent:{display:"flex",flexDirection:"column",justifyContent:"flex-end",alignItems:"flex-start",fontSize:l.FontSize.TITLE,width:1.2*l.FontSize.TITLE,borderRight:`1px solid ${l.Colors.LIGHT_GRAY}`},flamechartLabelParentBottom:{justifyContent:"flex-start"},flamechartLabel:{transform:"rotate(-90deg)",transformOrigin:"50% 50% 0",width:1.2*l.FontSize.TITLE,flexShrink:1},flamechartLabelBottom:{transform:"rotate(-90deg)",display:"flex",justifyContent:"flex-end"},callersAndCallees:{flex:1,borderLeft:`${l.Sizes.SEPARATOR_HEIGHT}px solid ${l.Colors.LIGHT_GRAY}`},divider:{height:2,background:l.Colors.LIGHT_GRAY}}),d=exports.SandwichViewContainer=(0,s.createContainer)(n,(e,t,a)=>{const{activeProfileState:l,glCanvas:s}=a,{sandwichViewState:i,index:o}=l,{callerCallee:n}=i;return{activeProfileState:l,glCanvas:s,setSelectedFrame:e=>{t(r.actions.sandwichView.setSelectedFrame({profileIndex:o,args:e}))},selectedFrame:n?n.selectedFrame:null,profileIndex:o}}); +},{"aphrodite":68,"./profile-table-view":55,"preact":24,"./style":79,"../store/actions":40,"../lib/typed-redux":36,"./inverted-caller-flamegraph-view":137,"./callee-flamegraph-view":138}],140:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ByteFormatter=exports.TimeFormatter=exports.RawValueFormatter=void 0;var t=require("./utils");class e{constructor(){this.unit="none"}format(t){return t.toLocaleString()}}exports.RawValueFormatter=e;class r{constructor(t){this.unit=t,this.multiplier="nanoseconds"===t?1e-9:"microseconds"===t?1e-6:"milliseconds"===t?.001:1}formatUnsigned(e){const r=e*this.multiplier;if(r/60>=1){const e=Math.floor(r/60),o=Math.floor(r-60*e).toString();return`${e}:${(0,t.zeroPad)(o,2)}`}return r/1>=1?`${r.toFixed(2)}s`:r/.001>=1?`${(r/.001).toFixed(2)}ms`:r/1e-6>=1?`${(r/1e-6).toFixed(2)}µs`:`${(r/1e-9).toFixed(2)}ns`}format(t){return`${t<0?"-":""}${this.formatUnsigned(Math.abs(t))}`}}exports.TimeFormatter=r;class o{constructor(){this.unit="bytes"}format(t){return t<1024?`${t.toFixed(0)} B`:(t/=1024)<1024?`${t.toFixed(2)} KB`:(t/=1024)<1024?`${t.toFixed(2)} MB`:`${(t/=1024).toFixed(2)} GB`}}exports.ByteFormatter=o; +},{"./utils":70}],145:[function(require,module,exports) { +var t=null;function r(){return t||(t=e()),t}function e(){try{throw new Error}catch(r){var t=(""+r.stack).match(/(https?|file|ftp):\/\/[^)\n]+/g);if(t)return n(t[0])}return"/"}function n(t){return(""+t).replace(/^((?:https?|file|ftp):\/\/.+)\/[^\/]+$/,"$1")+"/"}exports.getBundleURL=r,exports.getBaseURL=n; +},{}],66:[function(require,module,exports) { +var r=require("./bundle-url").getBundleURL;function e(r){Array.isArray(r)||(r=[r]);var e=r[r.length-1];try{return Promise.resolve(require(e))}catch(n){if("MODULE_NOT_FOUND"===n.code)return new u(function(n,i){t(r.slice(0,-1)).then(function(){return require(e)}).then(n,i)});throw n}}function t(r){return Promise.all(r.map(s))}var n={};function i(r,e){n[r]=e}module.exports=exports=e,exports.load=t,exports.register=i;var o={};function s(e){var t;if(Array.isArray(e)&&(t=e[1],e=e[0]),o[e])return o[e];var i=(e.substring(e.lastIndexOf(".")+1,e.length)||e).toLowerCase(),s=n[i];return s?o[e]=s(r()+e).then(function(r){return r&&module.bundle.register(t,r),r}):void 0}function u(r){this.executor=r,this.promise=null}u.prototype.then=function(r,e){return null===this.promise&&(this.promise=new Promise(this.executor)),this.promise.then(r,e)},u.prototype.catch=function(r){return null===this.promise&&(this.promise=new Promise(this.executor)),this.promise.catch(r)}; +},{"./bundle-url":145}],139:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.CallTreeProfileBuilder=exports.StackListProfileBuilder=exports.Profile=exports.CallTreeNode=exports.Frame=exports.HasWeights=void 0;var e=require("./utils"),t=require("./value-formatters"),s=function(e,t,s,r){return new(s||(s=Promise))(function(a,i){function l(e){try{h(r.next(e))}catch(e){i(e)}}function o(e){try{h(r.throw(e))}catch(e){i(e)}}function h(e){e.done?a(e.value):new s(function(t){t(e.value)}).then(l,o)}h((r=r.apply(e,t||[])).next())})};const r=require("_bundle_loader")(require.resolve("./demangle-cpp"));r.then(()=>{});class a{constructor(){this.selfWeight=0,this.totalWeight=0}getSelfWeight(){return this.selfWeight}getTotalWeight(){return this.totalWeight}addToTotalWeight(e){this.totalWeight+=e}addToSelfWeight(e){this.selfWeight+=e}overwriteWeightWith(e){this.selfWeight=e.selfWeight,this.totalWeight=e.totalWeight}}exports.HasWeights=a;class i extends a{constructor(e){super(),this.key=e.key,this.name=e.name,this.file=e.file,this.line=e.line,this.col=e.col}static getOrInsert(e,t){return e.getOrInsert(new i(t))}}exports.Frame=i,i.root=new i({key:"(speedscope root)",name:"(speedscope root)"});class l extends a{constructor(e,t){super(),this.frame=e,this.parent=t,this.children=[],this.frozen=!1}isRoot(){return this.frame===i.root}isFrozen(){return this.frozen}freeze(){this.frozen=!0}}exports.CallTreeNode=l;class o{constructor(s=0){this.name="",this.frames=new e.KeyedSet,this.appendOrderCalltreeRoot=new l(i.root,null),this.groupedCalltreeRoot=new l(i.root,null),this.samples=[],this.weights=[],this.valueFormatter=new t.RawValueFormatter,this.totalNonIdleWeight=null,this.totalWeight=s}getAppendOrderCalltreeRoot(){return this.appendOrderCalltreeRoot}getGroupedCalltreeRoot(){return this.groupedCalltreeRoot}formatValue(e){return this.valueFormatter.format(e)}setValueFormatter(e){this.valueFormatter=e}getWeightUnit(){return this.valueFormatter.unit}getName(){return this.name}setName(e){this.name=e}getTotalWeight(){return this.totalWeight}getTotalNonIdleWeight(){return null===this.totalNonIdleWeight&&(this.totalNonIdleWeight=this.groupedCalltreeRoot.children.reduce((e,t)=>e+t.getTotalWeight(),0)),this.totalNonIdleWeight}forEachCallGrouped(e,t){!function s(r,a){r.frame!==i.root&&e(r,a);let l=0;const o=[...r.children];o.sort((e,t)=>e.getTotalWeight()>t.getTotalWeight()?-1:1),o.forEach(function(e){s(e,a+l),l+=e.getTotalWeight()}),r.frame!==i.root&&t(r,a+r.getTotalWeight())}(this.groupedCalltreeRoot,0)}forEachCall(t,s){let r=[],a=0,l=0;for(let o of this.samples){let h=null;for(h=o;h&&h.frame!=i.root&&-1===r.indexOf(h);h=h.parent);for(;r.length>0&&(0,e.lastOf)(r)!=h;){s(r.pop(),a)}const n=[];for(let e=o;e&&e.frame!=i.root&&e!=h;e=e.parent)n.push(e);n.reverse();for(let e of n)t(e,a);r=r.concat(n),a+=this.weights[l++]}for(let e=r.length-1;e>=0;e--)s(r[e],a)}forEachFrame(e){this.frames.forEach(e)}forEachSample(e){for(let t=0;t{r.frames.getOrInsert(e).overwriteWeightWith(e)}),r}getInvertedProfileForCallersOf(e){const t=i.getOrInsert(this.frames,e),s=new h,r=[];!function e(s){if(s.frame===t)r.push(s);else for(let t of s.children)e(t)}(this.appendOrderCalltreeRoot);for(let e of r){const t=[];for(let s=e;null!=s&&s.frame!==i.root;s=s.parent)t.push(s.frame);s.appendSampleWithWeight(t,e.getTotalWeight())}const a=s.build();return a.name=this.name,a.valueFormatter=this.valueFormatter,a}getProfileForCalleesOf(e){const t=i.getOrInsert(this.frames,e),s=new h;!function e(r){if(r.frame===t)!function(e){const t=[];!function e(r){t.push(r.frame),s.appendSampleWithWeight(t,r.getSelfWeight());for(let t of r.children)e(t);t.pop()}(e)}(r);else for(let t of r.children)e(t)}(this.appendOrderCalltreeRoot);const r=s.build();return r.name=this.name,r.valueFormatter=this.valueFormatter,r}demangle(){return s(this,void 0,void 0,function*(){let e=null;for(let t of this.frames)t.name.startsWith("__Z")&&(e||(e=(yield r).demangleCpp),t.name=e(t.name))})}remapNames(e){for(let t of this.frames)t.name=e(t.name)}}exports.Profile=o;class h extends o{constructor(){super(...arguments),this.pendingSample=null}_appendSample(t,s,r){if(isNaN(s))throw new Error("invalid weight");let a=r?this.appendOrderCalltreeRoot:this.groupedCalltreeRoot,o=new Set;for(let h of t){const t=i.getOrInsert(this.frames,h),n=r?(0,e.lastOf)(a.children):a.children.find(e=>e.frame===t);if(n&&!n.isFrozen()&&n.frame==t)a=n;else{const e=a;a=new l(t,a),e.children.push(a)}a.addToTotalWeight(s),o.add(a.frame)}if(a.addToSelfWeight(s),r)for(let e of a.children)e.freeze();if(r){a.frame.addToSelfWeight(s);for(let e of o)e.addToTotalWeight(s);a===(0,e.lastOf)(this.samples)?this.weights[this.weights.length-1]+=s:(this.samples.push(a),this.weights.push(s))}}appendSampleWithWeight(e,t){if(0!==t){if(t<0)throw new Error("Samples must have positive weights");this._appendSample(e,t,!0),this._appendSample(e,t,!1)}}appendSampleWithTimestamp(e,t){if(this.pendingSample){if(t0?this.appendSampleWithWeight(this.pendingSample.stack,this.pendingSample.centralTimestamp-this.pendingSample.startTimestamp):(this.appendSampleWithWeight(this.pendingSample.stack,1),this.setValueFormatter(new t.RawValueFormatter))),this.totalWeight=Math.max(this.totalWeight,this.weights.reduce((e,t)=>e+t,0)),this}}exports.StackListProfileBuilder=h;class n extends o{constructor(){super(...arguments),this.appendOrderStack=[this.appendOrderCalltreeRoot],this.groupedOrderStack=[this.groupedCalltreeRoot],this.framesInStack=new Map,this.stack=[],this.lastValue=0}addWeightsToFrames(t){const s=t-this.lastValue;for(let e of this.framesInStack.keys())e.addToTotalWeight(s);const r=(0,e.lastOf)(this.stack);r&&r.addToSelfWeight(s)}addWeightsToNodes(t,s){const r=t-this.lastValue;for(let e of s)e.addToTotalWeight(r);const a=(0,e.lastOf)(s);a&&a.addToSelfWeight(r)}_enterFrame(t,s,r){let a=r?this.appendOrderStack:this.groupedOrderStack;this.addWeightsToNodes(s,a);let i=(0,e.lastOf)(a);if(i){if(r){const e=s-this.lastValue;if(e>0)this.samples.push(i),this.weights.push(s-this.lastValue);else if(e<0)throw new Error(`Samples must be provided in increasing order of cumulative value. Last sample was ${this.lastValue}, this sample was ${s}`)}const o=r?(0,e.lastOf)(i.children):i.children.find(e=>e.frame===t);let h;o&&!o.isFrozen()&&o.frame==t?h=o:(h=new l(t,i),i.children.push(h)),a.push(h)}}enterFrame(e,t){const s=i.getOrInsert(this.frames,e);this.addWeightsToFrames(t),this._enterFrame(s,t,!0),this._enterFrame(s,t,!1),this.stack.push(s);const r=this.framesInStack.get(s)||0;this.framesInStack.set(s,r+1),this.lastValue=t}_leaveFrame(e,t,s){let r=s?this.appendOrderStack:this.groupedOrderStack;if(this.addWeightsToNodes(t,r),s){const s=this.appendOrderStack.pop();if(null==s)throw new Error(`Trying to leave ${e.key} when stack is empty`);if(null==this.lastValue)throw new Error(`Trying to leave a ${e.key} before any have been entered`);s.freeze();const r=t-this.lastValue;if(r>0)this.samples.push(s),this.weights.push(t-this.lastValue);else if(r<0)throw new Error(`Samples must be provided in increasing order of cumulative value. Last sample was ${this.lastValue}, this sample was ${t}`)}else this.groupedOrderStack.pop()}leaveFrame(e,t){const s=i.getOrInsert(this.frames,e);this.addWeightsToFrames(t),this._leaveFrame(s,t,!0),this._leaveFrame(s,t,!1),this.stack.pop();const r=this.framesInStack.get(s);null!=r&&(1===r?this.framesInStack.delete(s):this.framesInStack.set(s,r-1),this.lastValue=t,this.totalWeight=Math.max(this.totalWeight,this.lastValue))}build(){if(this.appendOrderStack.length>1||this.groupedOrderStack.length>1)throw new Error("Tried to complete profile construction with a non-empty stack");return this}}exports.CallTreeProfileBuilder=n; +},{"./utils":70,"./value-formatters":140,"_bundle_loader":66,"./demangle-cpp":[["demangle-cpp.8a387750.js",180],"demangle-cpp.8a387750.map",180]}],141:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=exports.FileFormat=void 0;!function(e){let t,o;!function(e){e.EVENTED="evented",e.SAMPLED="sampled"}(t=e.ProfileType||(e.ProfileType={})),function(e){e.OPEN_FRAME="O",e.CLOSE_FRAME="C"}(o=e.EventType||(e.EventType={}))}(e||(exports.FileFormat=e={})); +},{}],19:[function(require,module,exports) { +module.exports={name:"speedscope",version:"1.5.3",description:"",repository:"jlfwong/speedscope",main:"index.js",bin:{speedscope:"./bin/cli.js"},scripts:{deploy:"./scripts/deploy.sh",prepack:"./scripts/build-release.sh",prettier:"prettier --write 'src/**/*.ts' 'src/**/*.tsx'",lint:"eslint 'src/**/*.ts' 'src/**/*.tsx'",jest:"./scripts/test-setup.sh && jest --runInBand",coverage:"npm run jest -- --coverage && coveralls < coverage/lcov.info",test:"tsc --noEmit && npm run lint && npm run coverage",serve:"parcel assets/index.html --open --no-autoinstall"},files:["bin/cli.js","dist/release/**","!*.map"],browserslist:["last 2 Chrome versions","last 2 Firefox versions"],author:"",license:"MIT",devDependencies:{"@types/jest":"22.2.3","@types/jszip":"3.1.4","@types/node":"10.1.4","@types/pako":"1.0.0",aphrodite:"2.1.0",coveralls:"3.0.1",eslint:"4.19.1","eslint-plugin-prettier":"2.6.0",jest:"24.3.0",jsverify:"0.8.3",jszip:"3.1.5",pako:"1.0.6","parcel-bundler":"1.9.2",preact:"8.2.7","preact-redux":"jlfwong/preact-redux#a56dcc4",prettier:"1.12.0",protobufjs:"6.8.8",quicktype:"15.0.209",redux:"^4.0.0","ts-jest":"24.3.0",typescript:"3.2.4","typescript-eslint-parser":"17.0.1","uglify-es":"3.2.2"},jest:{transform:{"^.+\\.tsx?$":"ts-jest"},testRegex:"\\.test\\.tsx?$",collectCoverageFrom:["**/*.{ts,tsx}","!**/*.d.{ts,tsx}"],moduleFileExtensions:["ts","tsx","js","jsx","json"]},dependencies:{opn:"5.3.0"}}; +},{}],83:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.exportProfileGroup=r,exports.importSpeedscopeProfiles=s,exports.saveToFile=l;var e=require("./profile"),t=require("./value-formatters"),n=require("./file-format-spec");function r(e){const t=[],n=new Map;function r(e){let r=n.get(e);if(null==r){const o={name:e.name};null!=e.file&&(o.file=e.file),null!=e.line&&(o.line=e.line),null!=e.col&&(o.col=e.col),r=t.length,n.set(e,r),t.push(o)}return r}const a={exporter:`speedscope@${require("../../package.json").version}`,name:e.name,activeProfileIndex:e.indexToView,$schema:"https://www.speedscope.app/file-format-schema.json",shared:{frames:t},profiles:[]};for(let t of e.profiles)a.profiles.push(o(t,r));return a}function o(e,t){const r={type:n.FileFormat.ProfileType.EVENTED,name:e.getName(),unit:e.getWeightUnit(),startValue:0,endValue:e.getTotalWeight(),events:[]};return e.forEachCall((e,o)=>{r.events.push({type:n.FileFormat.EventType.OPEN_FRAME,frame:t(e.frame),at:o})},(e,o)=>{r.events.push({type:n.FileFormat.EventType.CLOSE_FRAME,frame:t(e.frame),at:o})}),r}function a(r,o){function a(e){const{name:n,unit:o}=r;switch(o){case"nanoseconds":case"microseconds":case"milliseconds":case"seconds":e.setValueFormatter(new t.TimeFormatter(o));break;case"bytes":e.setValueFormatter(new t.ByteFormatter);break;case"none":e.setValueFormatter(new t.RawValueFormatter)}e.setName(n)}switch(r.type){case n.FileFormat.ProfileType.EVENTED:return function(t){const{startValue:r,endValue:s,events:l}=t,i=new e.CallTreeProfileBuilder(s-r);a(i);const c=o.map((e,t)=>Object.assign({key:t},e));for(let e of l)switch(e.type){case n.FileFormat.EventType.OPEN_FRAME:i.enterFrame(c[e.frame],e.at-r);break;case n.FileFormat.EventType.CLOSE_FRAME:i.leaveFrame(c[e.frame],e.at-r)}return i.build()}(r);case n.FileFormat.ProfileType.SAMPLED:return function(t){const{startValue:n,endValue:r,samples:s,weights:l}=t,i=new e.StackListProfileBuilder(r-n);a(i);const c=o.map((e,t)=>Object.assign({key:t},e));if(s.length!==l.length)throw new Error(`Expected samples.length (${s.length}) to equal weights.length (${l.length})`);for(let e=0;ec[e]),n)}return i.build()}(r)}}function s(e){return{name:e.name||e.profiles[0].name||"profile",indexToView:e.activeProfileIndex||0,profiles:e.profiles.map(t=>a(t,e.shared.frames))}}function l(e){const t=r(e),n=new Blob([JSON.stringify(t)],{type:"text/json"}),o=`${(t.name?t.name.split(".")[0]:"profile").replace(/\W+/g,"_")}.speedscope.json`;console.log("Saving",o);const a=document.createElement("a");a.download=o,a.href=window.URL.createObjectURL(n),a.dataset.downloadurl=["text/json",a.download,a.href].join(":"),document.body.appendChild(a),a.click(),document.body.removeChild(a)} +},{"./profile":139,"./value-formatters":140,"./file-format-spec":141,"../../package.json":19}],64:[function(require,module,exports) { +module.exports="perf-vertx-stacks-01-collapsed-all.3e0a632c.txt"; +},{}],34:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Application=exports.GLCanvas=exports.Toolbar=void 0;var e=require("preact"),t=require("aphrodite"),o=require("./style"),i=require("../lib/emscripten"),s=require("./sandwich-view"),r=require("../lib/file-format"),n=require("../store"),a=require("../lib/typed-redux"),l=require("./flamechart-view-container"),c=require("../gl/graphics"),d=function(e,t,o,i){return new(o||(o=Promise))(function(s,r){function n(e){try{l(i.next(e))}catch(e){r(e)}}function a(e){try{l(i.throw(e))}catch(e){r(e)}}function l(e){e.done?s(e.value):new o(function(t){t(e.value)}).then(n,a)}l((i=i.apply(e,t||[])).next())})};const p=require("_bundle_loader")(require.resolve("../import"));function h(e,t){return d(this,void 0,void 0,function*(){return(yield p).importProfileGroupFromText(e,t)})}function f(e,t){return d(this,void 0,void 0,function*(){return(yield p).importProfileGroupFromBase64(e,t)})}function m(e,t){return d(this,void 0,void 0,function*(){return(yield p).importProfilesFromArrayBuffer(e,t)})}function u(e){return d(this,void 0,void 0,function*(){return(yield p).importProfilesFromFile(e)})}function v(e){return d(this,void 0,void 0,function*(){return(yield p).importFromFileSystemDirectoryEntry(e)})}p.then(()=>{});const g=require("../../sample/profiles/stackcollapse/perf-vertx-stacks-01-collapsed-all.txt");class w extends a.StatelessComponent{constructor(){super(...arguments),this.setTimeOrder=(()=>{this.props.setViewMode(n.ViewMode.CHRONO_FLAME_CHART)}),this.setLeftHeavyOrder=(()=>{this.props.setViewMode(n.ViewMode.LEFT_HEAVY_FLAME_GRAPH)}),this.setSandwichView=(()=>{this.props.setViewMode(n.ViewMode.SANDWICH_VIEW)})}renderLeftContent(){return this.props.activeProfileState?(0,e.h)("div",{className:(0,t.css)(y.toolbarLeft)},(0,e.h)("div",{className:(0,t.css)(y.toolbarTab,this.props.viewMode===n.ViewMode.CHRONO_FLAME_CHART&&y.toolbarTabActive),onClick:this.setTimeOrder},(0,e.h)("span",{className:(0,t.css)(y.emoji)},"🕰"),"Time Order"),(0,e.h)("div",{className:(0,t.css)(y.toolbarTab,this.props.viewMode===n.ViewMode.LEFT_HEAVY_FLAME_GRAPH&&y.toolbarTabActive),onClick:this.setLeftHeavyOrder},(0,e.h)("span",{className:(0,t.css)(y.emoji)},"⬅️"),"Left Heavy"),(0,e.h)("div",{className:(0,t.css)(y.toolbarTab,this.props.viewMode===n.ViewMode.SANDWICH_VIEW&&y.toolbarTabActive),onClick:this.setSandwichView},(0,e.h)("span",{className:(0,t.css)(y.emoji)},"🥪"),"Sandwich")):null}renderCenterContent(){const{activeProfileState:o,profileGroup:i}=this.props;if(o&&i){const{index:r}=o;if(1===i.profiles.length)return o.profile.getName();{function s(o,i,s){return(0,e.h)("button",{disabled:i,onClick:s,className:(0,t.css)(y.emoji,y.toolbarProfileNavButton,i&&y.toolbarProfileNavButtonDisabled)},o)}const n=s("⬅️",0===r,()=>this.props.setProfileIndexToView(r-1)),a=s("➡️",r>=i.profiles.length-1,()=>this.props.setProfileIndexToView(r+1));return(0,e.h)("div",{className:(0,t.css)(y.toolbarCenter)},n,o.profile.getName()," ",(0,e.h)("span",{className:(0,t.css)(y.toolbarProfileIndex)},"(",o.index+1,"/",i.profiles.length,")"),a)}}return"🔬speedscope"}renderRightContent(){const o=(0,e.h)("div",{className:(0,t.css)(y.toolbarTab),onClick:this.props.browseForFile},(0,e.h)("span",{className:(0,t.css)(y.emoji)},"⤵️"),"Import"),i=(0,e.h)("div",{className:(0,t.css)(y.toolbarTab)},(0,e.h)("a",{href:"https://github.com/jlfwong/speedscope#usage",className:(0,t.css)(y.noLinkStyle),target:"_blank"},(0,e.h)("span",{className:(0,t.css)(y.emoji)},"❓"),"Help"));return(0,e.h)("div",{className:(0,t.css)(y.toolbarRight)},this.props.activeProfileState&&(0,e.h)("div",{className:(0,t.css)(y.toolbarTab),onClick:this.props.saveFile},(0,e.h)("span",{className:(0,t.css)(y.emoji)},"⤴️"),"Export"),o,i)}render(){return(0,e.h)("div",{className:(0,t.css)(y.toolbar)},this.renderLeftContent(),this.renderCenterContent(),this.renderRightContent())}}exports.Toolbar=w;class b extends e.Component{constructor(){super(...arguments),this.canvas=null,this.ref=(e=>{e instanceof HTMLCanvasElement?this.canvas=e:this.canvas=null,this.props.setGLCanvas(this.canvas)}),this.container=null,this.containerRef=(e=>{e instanceof HTMLElement?this.container=e:this.container=null}),this.maybeResize=(()=>{if(!this.container)return;if(!this.props.canvasContext)return;let{width:e,height:t}=this.container.getBoundingClientRect();const o=e,i=t,s=e*window.devicePixelRatio,r=t*window.devicePixelRatio;this.props.canvasContext.gl.resize(s,r,o,i),this.props.canvasContext.gl.clear(new c.Graphics.Color(1,1,1,1))}),this.onWindowResize=(()=>{this.props.canvasContext&&this.props.canvasContext.requestFrame()})}componentWillReceiveProps(e){this.props.canvasContext!==e.canvasContext&&(this.props.canvasContext&&this.props.canvasContext.removeBeforeFrameHandler(this.maybeResize),e.canvasContext&&(e.canvasContext.addBeforeFrameHandler(this.maybeResize),e.canvasContext.requestFrame()))}componentDidMount(){window.addEventListener("resize",this.onWindowResize)}componentWillUnmount(){this.props.canvasContext&&this.props.canvasContext.removeBeforeFrameHandler(this.maybeResize),window.removeEventListener("resize",this.onWindowResize)}render(){return(0,e.h)("div",{ref:this.containerRef,className:(0,t.css)(y.glCanvasView)},(0,e.h)("canvas",{ref:this.ref,width:1,height:1}))}}exports.GLCanvas=b;class C extends a.StatelessComponent{constructor(){super(...arguments),this.loadExample=(()=>{this.loadProfile(()=>d(this,void 0,void 0,function*(){return yield h("perf-vertx-stacks-01-collapsed-all.txt",yield fetch(g).then(e=>e.text()))}))}),this.onDrop=(e=>{if(this.props.setDragActive(!1),e.preventDefault(),!e.dataTransfer)return;const t=e.dataTransfer.items[0];if("webkitGetAsEntry"in t){const e=t.webkitGetAsEntry();if(e.isDirectory&&e.name.endsWith(".trace"))return console.log("Importing as Instruments.app .trace file"),void this.loadProfile(()=>d(this,void 0,void 0,function*(){return yield v(e)}))}let o=e.dataTransfer.files.item(0);o&&this.loadFromFile(o)}),this.onDragOver=(e=>{this.props.setDragActive(!0),e.preventDefault()}),this.onDragLeave=(e=>{this.props.setDragActive(!1),e.preventDefault()}),this.onWindowKeyPress=(e=>d(this,void 0,void 0,function*(){if("1"===e.key)this.props.setViewMode(n.ViewMode.CHRONO_FLAME_CHART);else if("2"===e.key)this.props.setViewMode(n.ViewMode.LEFT_HEAVY_FLAME_GRAPH);else if("3"===e.key)this.props.setViewMode(n.ViewMode.SANDWICH_VIEW);else if("r"===e.key){const{flattenRecursion:e}=this.props;this.props.setFlattenRecursion(!e)}else if("n"===e.key){const{activeProfileState:e}=this.props;e&&this.props.setProfileIndexToView(e.index+1)}else if("p"===e.key){const{activeProfileState:e}=this.props;e&&this.props.setProfileIndexToView(e.index-1)}})),this.saveFile=(()=>{if(this.props.profileGroup){const{name:e,indexToView:t,profiles:o}=this.props.profileGroup,i={name:e,indexToView:t,profiles:o.map(e=>e.profile)};(0,r.saveToFile)(i)}}),this.browseForFile=(()=>{const e=document.createElement("input");e.type="file",e.addEventListener("change",this.onFileSelect),e.click()}),this.onWindowKeyDown=(e=>d(this,void 0,void 0,function*(){"s"===e.key&&(e.ctrlKey||e.metaKey)?(e.preventDefault(),this.saveFile()):"o"===e.key&&(e.ctrlKey||e.metaKey)&&(e.preventDefault(),this.browseForFile())})),this.onDocumentPaste=(e=>{e.preventDefault(),e.stopPropagation();const t=e.clipboardData;if(!t)return;const o=t.getData("text");this.loadProfile(()=>d(this,void 0,void 0,function*(){return yield h("From Clipboard",o)}))}),this.onFileSelect=(e=>{const t=e.target.files.item(0);t&&this.loadFromFile(t)})}loadProfile(e){return d(this,void 0,void 0,function*(){if(this.props.setLoading(!0),yield new Promise(e=>setTimeout(e,0)),!this.props.glCanvas)return;console.time("import");let t=null;try{t=yield e()}catch(e){return console.log("Failed to load format",e),void this.props.setError(!0)}if(null==t)return alert("Unrecognized format! See documentation about supported formats."),void this.props.setLoading(!1);if(0===t.profiles.length)return alert("Successfully imported profile, but it's empty!"),void this.props.setLoading(!1);this.props.hashParams.title&&(t=Object.assign({name:this.props.hashParams.title},t)),document.title=`${t.name} - speedscope`;for(let e of t.profiles)yield e.demangle();for(let e of t.profiles){const t=this.props.hashParams.title||e.getName();e.setName(t)}console.timeEnd("import"),this.props.setProfileGroup(t),this.props.setLoading(!1)})}loadFromFile(e){this.loadProfile(()=>d(this,void 0,void 0,function*(){const t=yield u(e);if(t){for(let o of t.profiles)o.getName()||o.setName(e.name);return t}if(this.props.profileGroup&&this.props.activeProfileState){const t=new FileReader,o=new Promise(e=>{t.addEventListener("loadend",()=>{if("string"!=typeof t.result)throw new Error("Expected reader.result to be a string");e(t.result)})});t.readAsText(e);const s=yield o,r=(0,i.importEmscriptenSymbolMap)(s);if(r){const{profile:e,index:t}=this.props.activeProfileState;return console.log("Importing as emscripten symbol map"),e.remapNames(e=>r.get(e)||e),{name:this.props.profileGroup.name||"profile",indexToView:t,profiles:[e]}}}return null}))}componentDidMount(){window.addEventListener("keydown",this.onWindowKeyDown),window.addEventListener("keypress",this.onWindowKeyPress),document.addEventListener("paste",this.onDocumentPaste),this.maybeLoadHashParamProfile()}componentWillUnmount(){window.removeEventListener("keydown",this.onWindowKeyDown),window.removeEventListener("keypress",this.onWindowKeyPress),document.removeEventListener("paste",this.onDocumentPaste)}maybeLoadHashParamProfile(){return d(this,void 0,void 0,function*(){if(this.props.hashParams.profileURL){if(!n.canUseXHR)return void alert(`Cannot load a profile URL when loading from "${window.location.protocol}" URL protocol`);this.loadProfile(()=>d(this,void 0,void 0,function*(){const e=yield fetch(this.props.hashParams.profileURL);let t=new URL(this.props.hashParams.profileURL).pathname;return t.includes("/")&&(t=t.slice(t.lastIndexOf("/")+1)),yield m(t,yield e.arrayBuffer())}))}else if(this.props.hashParams.localProfilePath){window.speedscope={loadFileFromBase64:(e,t)=>{this.loadProfile(()=>f(e,t))}};const e=document.createElement("script");e.src=`file:///${this.props.hashParams.localProfilePath}`,document.head.appendChild(e)}})}renderLanding(){return(0,e.h)("div",{className:(0,t.css)(y.landingContainer)},(0,e.h)("div",{className:(0,t.css)(y.landingMessage)},(0,e.h)("p",{className:(0,t.css)(y.landingP)},"👋 Hi there! Welcome to 🔬speedscope, an interactive"," ",(0,e.h)("a",{className:(0,t.css)(y.link),href:"http://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html"},"flamegraph")," ","visualizer. Use it to help you make your software faster."),n.canUseXHR?(0,e.h)("p",{className:(0,t.css)(y.landingP)},"Drag and drop a profile file onto this window to get started, click the big blue button below to browse for a profile to explore, or"," ",(0,e.h)("a",{tabIndex:0,className:(0,t.css)(y.link),onClick:this.loadExample},"click here")," ","to load an example profile."):(0,e.h)("p",{className:(0,t.css)(y.landingP)},"Drag and drop a profile file onto this window to get started, or click the big blue button below to browse for a profile to explore."),(0,e.h)("div",{className:(0,t.css)(y.browseButtonContainer)},(0,e.h)("input",{type:"file",name:"file",id:"file",onChange:this.onFileSelect,className:(0,t.css)(y.hide)}),(0,e.h)("label",{for:"file",className:(0,t.css)(y.browseButton),tabIndex:0},"Browse")),(0,e.h)("p",{className:(0,t.css)(y.landingP)},"See the"," ",(0,e.h)("a",{className:(0,t.css)(y.link),href:"https://github.com/jlfwong/speedscope#usage",target:"_blank"},"documentation")," ","for information about supported file formats, keyboard shortcuts, and how to navigate around the profile."),(0,e.h)("p",{className:(0,t.css)(y.landingP)},"speedscope is open source. Please"," ",(0,e.h)("a",{className:(0,t.css)(y.link),target:"_blank",href:"https://github.com/jlfwong/speedscope/issues"},"report any issues on GitHub"),".")))}renderError(){return(0,e.h)("div",{className:(0,t.css)(y.error)},(0,e.h)("div",null,"😿 Something went wrong."),(0,e.h)("div",null,"Check the JS console for more details."))}renderLoadingBar(){return(0,e.h)("div",{className:(0,t.css)(y.loading)})}renderContent(){const{viewMode:t,activeProfileState:o,error:i,loading:r,glCanvas:a}=this.props;if(i)return this.renderError();if(r)return this.renderLoadingBar();if(!o||!a)return this.renderLanding();switch(t){case n.ViewMode.CHRONO_FLAME_CHART:return(0,e.h)(l.ChronoFlamechartView,{activeProfileState:o,glCanvas:a});case n.ViewMode.LEFT_HEAVY_FLAME_GRAPH:return(0,e.h)(l.LeftHeavyFlamechartView,{activeProfileState:o,glCanvas:a});case n.ViewMode.SANDWICH_VIEW:return(0,e.h)(s.SandwichViewContainer,{activeProfileState:o,glCanvas:a})}}render(){return(0,e.h)("div",{onDrop:this.onDrop,onDragOver:this.onDragOver,onDragLeave:this.onDragLeave,className:(0,t.css)(y.root,this.props.dragActive&&y.dragTargetRoot)},(0,e.h)(b,{setGLCanvas:this.props.setGLCanvas,canvasContext:this.props.canvasContext}),(0,e.h)(w,Object.assign({saveFile:this.saveFile,browseForFile:this.browseForFile},this.props)),(0,e.h)("div",{className:(0,t.css)(y.contentContainer)},this.renderContent()),this.props.dragActive&&(0,e.h)("div",{className:(0,t.css)(y.dragTarget)}))}}exports.Application=C;const y=t.StyleSheet.create({glCanvasView:{position:"absolute",width:"100vw",height:"100vh",zIndex:-1,pointerEvents:"none"},error:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",height:"100%"},loading:{height:3,marginBottom:-3,background:o.Colors.DARK_BLUE,transformOrigin:"0% 50%",animationName:[{from:{transform:"scaleX(0)"},to:{transform:"scaleX(1)"}}],animationTimingFunction:"cubic-bezier(0, 1, 0, 1)",animationDuration:"30s"},root:{width:"100vw",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",position:"relative",fontFamily:o.FontFamily.MONOSPACE,lineHeight:"20px"},dragTargetRoot:{cursor:"copy"},dragTarget:{boxSizing:"border-box",position:"absolute",top:0,left:0,width:"100%",height:"100%",border:`5px dashed ${o.Colors.DARK_BLUE}`,pointerEvents:"none"},contentContainer:{position:"relative",display:"flex",overflow:"hidden",flexDirection:"column",flex:1},landingContainer:{display:"flex",alignItems:"center",justifyContent:"center",flex:1},landingMessage:{maxWidth:600},landingP:{marginBottom:16},hide:{display:"none"},browseButtonContainer:{display:"flex",alignItems:"center",justifyContent:"center"},browseButton:{marginBottom:16,height:72,flex:1,maxWidth:256,textAlign:"center",fontSize:o.FontSize.BIG_BUTTON,lineHeight:"72px",background:o.Colors.DARK_BLUE,color:o.Colors.WHITE,transition:`all ${o.Duration.HOVER_CHANGE} ease-in`,":hover":{background:o.Colors.BRIGHT_BLUE}},link:{color:o.Colors.BRIGHT_BLUE,cursor:"pointer",textDecoration:"none"},toolbar:{height:o.Sizes.TOOLBAR_HEIGHT,flexShrink:0,background:o.Colors.BLACK,color:o.Colors.WHITE,textAlign:"center",fontFamily:o.FontFamily.MONOSPACE,fontSize:o.FontSize.TITLE,lineHeight:`${o.Sizes.TOOLBAR_TAB_HEIGHT}px`,userSelect:"none"},toolbarLeft:{position:"absolute",height:o.Sizes.TOOLBAR_HEIGHT,overflow:"hidden",top:0,left:0,marginRight:2,textAlign:"left"},toolbarCenter:{paddingTop:1,height:o.Sizes.TOOLBAR_HEIGHT},toolbarRight:{height:o.Sizes.TOOLBAR_HEIGHT,overflow:"hidden",position:"absolute",top:0,right:0,marginRight:2,textAlign:"right"},toolbarProfileIndex:{color:o.Colors.LIGHT_GRAY},toolbarProfileNavButton:{opacity:.8,fontSize:o.FontSize.TITLE,lineHeight:`${o.Sizes.TOOLBAR_TAB_HEIGHT}px`,":hover":{opacity:1},background:"none",border:"none",padding:0,marginLeft:"0.3em",marginRight:"0.3em",transition:`all ${o.Duration.HOVER_CHANGE} ease-in`},toolbarProfileNavButtonDisabled:{opacity:.5,":hover":{opacity:.5}},toolbarTab:{background:o.Colors.DARK_GRAY,marginTop:o.Sizes.SEPARATOR_HEIGHT,height:o.Sizes.TOOLBAR_TAB_HEIGHT,lineHeight:`${o.Sizes.TOOLBAR_TAB_HEIGHT}px`,paddingLeft:2,paddingRight:8,display:"inline-block",marginLeft:2,transition:`all ${o.Duration.HOVER_CHANGE} ease-in`,":hover":{background:o.Colors.GRAY}},toolbarTabActive:{background:o.Colors.BRIGHT_BLUE,":hover":{background:o.Colors.BRIGHT_BLUE}},noLinkStyle:{textDecoration:"none",color:"inherit"},emoji:{display:"inline-block",verticalAlign:"middle",paddingTop:"0px",marginRight:"0.3em"}}); +},{"preact":24,"aphrodite":68,"./style":79,"../lib/emscripten":81,"./sandwich-view":60,"../lib/file-format":83,"../store":29,"../lib/typed-redux":36,"./flamechart-view-container":62,"../gl/graphics":42,"_bundle_loader":66,"../import":[["import.a03c2bef.js",104],"import.a03c2bef.map",104],"../../sample/profiles/stackcollapse/perf-vertx-stacks-01-collapsed-all.txt":64}],21:[function(require,module,exports) { +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ApplicationContainer=void 0;var e=require("../lib/typed-redux"),t=require("./application"),i=require("../store/getters"),o=require("../store/actions"),n=require("../gl/graphics");const r=exports.ApplicationContainer=(0,e.createContainer)(t.Application,(t,r)=>{const{flattenRecursion:s,profileGroup:a}=t;let l=null;if(a&&a.profiles.length>a.indexToView){const e=a.indexToView,t=a.profiles[e];l=Object.assign({},a.profiles[a.indexToView],{profile:(0,i.getProfileToView)({profile:t.profile,flattenRecursion:s}),index:a.indexToView})}function c(t){return(0,e.bindActionCreator)(r,t)}const p={setGLCanvas:c(o.actions.setGLCanvas),setLoading:c(o.actions.setLoading),setError:c(o.actions.setError),setProfileGroup:c(o.actions.setProfileGroup),setDragActive:c(o.actions.setDragActive),setViewMode:c(o.actions.setViewMode),setFlattenRecursion:c(o.actions.setFlattenRecursion),setProfileIndexToView:c(o.actions.setProfileIndexToView)};return Object.assign({activeProfileState:l,dispatch:r,canvasContext:t.glCanvas?(0,i.getCanvasContext)(t.glCanvas):null,resizeCanvas:(e,o,r,s)=>{if(t.glCanvas){const a=(0,i.getCanvasContext)(t.glCanvas).gl;a.resize(e,o,r,s),a.clear(new n.Graphics.Color(1,1,1,1))}}},p,t)}); +},{"../lib/typed-redux":36,"./application":34,"../store/getters":38,"../store/actions":40,"../gl/graphics":42}],13:[function(require,module,exports) { +"use strict";var e=require("preact"),o=require("./store"),t=require("preact-redux"),r=require("./views/application-container");console.log(`speedscope v${require("../package.json").version}`),module.hot&&(module.hot.dispose(()=>{(0,e.render)((0,e.h)("div",null),document.body,document.body.lastElementChild||void 0)}),module.hot.accept());const i=window.store,d=(0,o.createApplicationStore)(i?i.getState():{});window.store=d,(0,e.render)((0,e.h)(t.Provider,{store:d},(0,e.h)(r.ApplicationContainer,null)),document.body,document.body.lastElementChild||void 0); +},{"preact":24,"./store":29,"preact-redux":26,"./views/application-container":21,"../package.json":19}],215:[function(require,module,exports) { +module.exports=function(n){return new Promise(function(e,o){var r=document.createElement("script");r.async=!0,r.type="text/javascript",r.charset="utf-8",r.src=n,r.onerror=function(n){r.onerror=r.onload=null,o(n)},r.onload=function(){r.onerror=r.onload=null,e()},document.getElementsByTagName("head")[0].appendChild(r)})}; +},{}],0:[function(require,module,exports) { +var b=require(66);b.register("js",require(215)); +},{}]},{},[0,13], null) +//# sourceMappingURL=speedscope.9ee942dd.map \ No newline at end of file diff --git a/historyserver/dashboard/ray/client/src/App.tsx b/historyserver/dashboard/ray/client/src/App.tsx new file mode 100644 index 00000000000..0121da73267 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/App.tsx @@ -0,0 +1,315 @@ +import { CssBaseline } from "@mui/material"; +import { StyledEngineProvider, ThemeProvider } from "@mui/material/styles"; +import dayjs from "dayjs"; +import duration from "dayjs/plugin/duration"; +import React, { Suspense, useEffect, useState } from "react"; +import { HashRouter, Navigate, Route, Routes } from "react-router-dom"; +import ActorDetailPage, { ActorDetailLayout } from "./pages/actor/ActorDetail"; +import { ActorLayout } from "./pages/actor/ActorLayout"; +import Loading from "./pages/exception/Loading"; +import JobList, { JobsLayout } from "./pages/job"; +import { JobDetailChartsPage } from "./pages/job/JobDetail"; +import { + JobDetailActorDetailWrapper, + JobDetailActorsPage, +} from "./pages/job/JobDetailActorPage"; +import { JobDetailInfoPage } from "./pages/job/JobDetailInfoPage"; +import { JobDetailLayout, JobPage } from "./pages/job/JobDetailLayout"; +import { MainNavLayout } from "./pages/layout/MainNavLayout"; +import { SideTabPage } from "./pages/layout/SideTabLayout"; +import { + LogsLayout, + StateApiLogsListPage, + StateApiLogViewerPage, +} from "./pages/log/Logs"; +import { Metrics } from "./pages/metrics"; +import { DashboardUids, getMetricsInfo } from "./pages/metrics/utils"; +import Nodes, { ClusterMainPageLayout } from "./pages/node"; +import { ClusterDetailInfoPage } from "./pages/node/ClusterDetailInfoPage"; +import { ClustersPage } from "./pages/clusters/ClustersPage"; +import { ClusterLayout } from "./pages/node/ClusterLayout"; +import NodeDetailPage from "./pages/node/NodeDetail"; +import { OverviewPage } from "./pages/overview/OverviewPage"; +import { + ServeApplicationDetailLayout, + ServeApplicationDetailPage, +} from "./pages/serve/ServeApplicationDetailPage"; +import { + ServeDeploymentDetailLayout, + ServeDeploymentDetailPage, +} from "./pages/serve/ServeDeploymentDetailPage"; +import { ServeDeploymentsListPage } from "./pages/serve/ServeDeploymentsListPage"; +import { ServeLayout, ServeSideTabLayout } from "./pages/serve/ServeLayout"; +import { ServeReplicaDetailLayout } from "./pages/serve/ServeReplicaDetailLayout"; +import { ServeReplicaDetailPage } from "./pages/serve/ServeReplicaDetailPage"; +import { + ServeControllerDetailPage, + ServeProxyDetailPage, +} from "./pages/serve/ServeSystemActorDetailPage"; +import { + ServeSystemDetailLayout, + ServeSystemDetailPage, +} from "./pages/serve/ServeSystemDetailPage"; +import { TaskPage } from "./pages/task/TaskPage"; +import { getNodeList } from "./service/node"; +import { lightTheme } from "./theme"; + +dayjs.extend(duration); + +// lazy loading fro prevent loading too much code at once +const Actors = React.lazy(() => import("./pages/actor")); +const CMDResult = React.lazy(() => import("./pages/cmd/CMDResult")); + +// a global map for relations +export type GlobalContextType = { + nodeMap: { [key: string]: string }; + nodeMapByIp: { [key: string]: string }; + namespaceMap: { [key: string]: string[] }; + /** + * Whether the initial metrics context has been fetched or not. + * This can be used to determine the difference between Grafana + * not being set up vs the status not being fetched yet. + */ + metricsContextLoaded: boolean; + /** + * The host that is serving grafana. Only set if grafana is + * running as detected by the grafana healthcheck endpoint. + */ + grafanaHost: string | undefined; + /** + * The uids of the dashboards that ray exports that powers the various metrics UIs. + */ + dashboardUids: DashboardUids | undefined; + /** + * Whether prometheus is runing or not + */ + prometheusHealth: boolean | undefined; + /** + * The name of the currently running ray session. + */ + sessionName: string | undefined; + /** + * The name of the current selected datasource. + */ + dashboardDatasource: string | undefined; +}; +export const GlobalContext = React.createContext({ + nodeMap: {}, + nodeMapByIp: {}, + namespaceMap: {}, + metricsContextLoaded: false, + grafanaHost: undefined, + dashboardUids: undefined, + prometheusHealth: undefined, + sessionName: undefined, + dashboardDatasource: undefined, +}); + +const App = () => { + const [context, setContext] = useState({ + nodeMap: {}, + nodeMapByIp: {}, + namespaceMap: {}, + metricsContextLoaded: false, + grafanaHost: undefined, + dashboardUids: undefined, + prometheusHealth: undefined, + sessionName: undefined, + dashboardDatasource: undefined, + }); + useEffect(() => { + getNodeList().then((res) => { + if (res?.data?.data?.summary) { + const nodeMap = {} as { [key: string]: string }; + const nodeMapByIp = {} as { [key: string]: string }; + res.data.data.summary.forEach(({ hostname, raylet, ip }) => { + nodeMap[hostname] = raylet.nodeId; + nodeMapByIp[ip] = raylet.nodeId; + }); + setContext((existingContext) => ({ + ...existingContext, + nodeMap, + nodeMapByIp, + namespaceMap: {}, + })); + } + }); + }, []); + + // Detect if grafana is running + useEffect(() => { + const doEffect = async () => { + const { + grafanaHost, + sessionName, + prometheusHealth, + dashboardUids, + dashboardDatasource, + } = await getMetricsInfo(); + setContext((existingContext) => ({ + ...existingContext, + metricsContextLoaded: true, + grafanaHost, + dashboardUids, + sessionName, + prometheusHealth, + dashboardDatasource, + })); + }; + doEffect(); + }, [context.sessionName]); + + return ( + + + + + + + + {/* Redirect people hitting the /new path to root. TODO(aguo): Delete this redirect in ray 2.5 */} + } path="/" /> + } path="/clusters" /> + } path="/clusters/:clusterName/:sessionName"> + } path="" /> + } path="overview" /> + } path="cluster"> + } path=""> + + + + } + path="info" + /> + + + + } + path="" + /> + + } path="nodes/:id" /> + + } path="jobs"> + } path="" /> + } path=":id"> + } path=""> + + + + } + path="info" + /> + + + + } + path="" + /> + + + + } + path="actors" + /> + + + + + } + path="actors/:actorId" + > + } path="" /> + } path="tasks/:taskId" /> + + } path="tasks/:taskId" /> + + + } path="actors"> + } path="" /> + } path=":actorId"> + } path="" /> + } path="tasks/:taskId" /> + + + } path="metrics" /> + } path="serve"> + } path=""> + + + + } + path="system" + /> + + + + } + path="" + /> + + } path="system"> + } + path="controller" + /> + } + path="proxies/:proxyId" + /> + + } + path="applications/:applicationName" + > + } path="" /> + } + path=":deploymentName" + > + } + path="" + /> + } + path=":replicaId" + > + } path="" /> + } /> + + + + + } path="logs"> + } path="" /> + } path="viewer" /> + + + } path="/cmd/:cmd/:ip/:pid" /> + + + + + + + ); +}; + +export default App; diff --git a/historyserver/dashboard/ray/client/src/common/AlertDialog.tsx b/historyserver/dashboard/ray/client/src/common/AlertDialog.tsx new file mode 100644 index 00000000000..7a0353b8233 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/AlertDialog.tsx @@ -0,0 +1,52 @@ +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, +} from "@mui/material"; +import React, { PropsWithChildren } from "react"; +import { ClassNameProps } from "./props"; + +type AlertDialogProps = PropsWithChildren< + { + open: boolean; + handleClose: any; + onAgree: any; + title: string; + contents: string; + } & ClassNameProps +>; + +export const AlertDialog = ({ + open, + handleClose, + onAgree, + title, + contents, +}: AlertDialogProps) => { + return ( +
+ + {title} + + + {contents} + + + + + + + +
+ ); +}; diff --git a/historyserver/dashboard/ray/client/src/common/CodeDialogButton/CodeDialogButton.component.test.tsx b/historyserver/dashboard/ray/client/src/common/CodeDialogButton/CodeDialogButton.component.test.tsx new file mode 100644 index 00000000000..435692d2b4b --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/CodeDialogButton/CodeDialogButton.component.test.tsx @@ -0,0 +1,81 @@ +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import React from "react"; +import { TEST_APP_WRAPPER } from "../../util/test-utils"; +import { + CodeDialogButton, + CodeDialogButtonWithPreview, +} from "./CodeDialogButton"; + +describe("CodeDialogButton", () => { + it("renders with code as JSON", async () => { + expect.assertions(4); + + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + + const user = userEvent.setup(); + + await screen.findByText("View"); + expect(screen.getByText("View")).toBeVisible(); + await user.click(screen.getByText("View")); + + await screen.findByText("Test title"); + expect(screen.getByText("Test title")).toBeVisible(); + expect(screen.getByText(/foo: 1/)).toBeVisible(); + expect(screen.getByText(/bar: bar/)).toBeVisible(); + }); + + it("renders with custom button text and code as a string", async () => { + expect.assertions(4); + + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + + const user = userEvent.setup(); + + await screen.findByText("CustomButton"); + expect(screen.getByText("CustomButton")).toBeVisible(); + await user.click(screen.getByText("CustomButton")); + + await screen.findByText("Test title"); + expect(screen.getByText("Test title")).toBeVisible(); + expect(screen.getByText(/import ray/)).toBeVisible(); + expect(screen.getByText(/ray.init\(\)/)).toBeVisible(); + }); +}); + +describe("CodeDialogButtonWithPreview", () => { + it("renders", async () => { + expect.assertions(5); + + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + + const user = userEvent.setup(); + + await screen.findByText("Expand"); + // Preview of the code should be visible + expect(screen.getByText(/foo: 1/)).toBeVisible(); + expect(screen.getByText("Expand")).toBeVisible(); + await user.click(screen.getByText("Expand")); + + await screen.findByText("Test title"); + expect(screen.getByText("Test title")).toBeVisible(); + expect(screen.getAllByText(/foo: 1/)[1]).toBeVisible(); + expect(screen.getAllByText(/bar: bar/)[1]).toBeVisible(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/common/CodeDialogButton/CodeDialogButton.tsx b/historyserver/dashboard/ray/client/src/common/CodeDialogButton/CodeDialogButton.tsx new file mode 100644 index 00000000000..291390e315c --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/CodeDialogButton/CodeDialogButton.tsx @@ -0,0 +1,125 @@ +import { Box, Card, Link, SxProps, Theme, Typography } from "@mui/material"; +import yaml from "js-yaml"; +import React, { useState } from "react"; +import DialogWithTitle from "../DialogWithTitle"; +import { ClassNameProps } from "../props"; + +export type CodeDialogButtonProps = { + /** + * Title of the dialog box + */ + title: string; + /** + * Text for the button. By default it's "View" + */ + buttonText?: string; + /** + * Code to show in the dialog. If an object is passed in, that object will be stringified to yaml. + */ + code: string | object; + sx?: SxProps; +}; + +/** + * A button that when clicked, will pop up a dialog with the full code text with proper formatting. + */ +export const CodeDialogButton = ({ + title, + buttonText = "View", + code, +}: CodeDialogButtonProps) => { + const [showConfigDialog, setShowConfigDialog] = useState(false); + + const handleConfigClick = () => { + setShowConfigDialog(true); + }; + + return ( + + + {buttonText} + + {showConfigDialog && ( + { + setShowConfigDialog(false); + }} + > + + + {typeof code === "string" ? code : yaml.dump(code, { indent: 2 })} + + + + )} + + ); +}; + +type CodeDialogButtonWithPreviewProps = CodeDialogButtonProps & ClassNameProps; +/** + * Similar to CodeDialogButton but also shows a snippet of the expanded text next to the button. + */ +export const CodeDialogButtonWithPreview = ({ + code, + buttonText, + className, + sx, + ...props +}: CodeDialogButtonWithPreviewProps) => { + const codeText = + typeof code === "string" + ? code + : yaml.dump(code, { indent: 2, sortKeys: true }); + + const buttonTextToPass = buttonText ?? "Expand"; + + return ( + + + {codeText} + + + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/common/CodeDialogButton/index.ts b/historyserver/dashboard/ray/client/src/common/CodeDialogButton/index.ts new file mode 100644 index 00000000000..0f19699717b --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/CodeDialogButton/index.ts @@ -0,0 +1 @@ +export * from "./CodeDialogButton"; diff --git a/historyserver/dashboard/ray/client/src/common/CollapsibleSection.tsx b/historyserver/dashboard/ray/client/src/common/CollapsibleSection.tsx new file mode 100644 index 00000000000..c99d31dc915 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/CollapsibleSection.tsx @@ -0,0 +1,152 @@ +import { Box, SxProps, Theme, Typography } from "@mui/material"; +import React, { + forwardRef, + PropsWithChildren, + useEffect, + useState, +} from "react"; +import { RiArrowDownSLine, RiArrowRightSLine } from "react-icons/ri"; +import { ClassNameProps } from "./props"; + +type CollapsibleSectionProps = PropsWithChildren< + { + /** + * Allows the parent component to control if this section is expanded. + * If undefined, the child wil own the expansion state + */ + expanded?: boolean; + onExpandButtonClick?: () => void; + title: string; + startExpanded?: boolean; + /** + * Icon to show to the right of the title. + */ + icon?: React.ReactNode; + /** + * An optimization to not avoid re-rendering the contents of the collapsible section. + * When enabled, we will keep the content around when collapsing but hide it via css. + */ + keepRendered?: boolean; + sx?: SxProps; + } & ClassNameProps +>; + +export const CollapsibleSection = forwardRef< + HTMLDivElement, + CollapsibleSectionProps +>( + ( + { + title, + expanded, + onExpandButtonClick, + startExpanded = false, + className, + children, + keepRendered, + icon, + sx, + }, + ref, + ) => { + const [internalExpanded, setInternalExpanded] = useState(startExpanded); + const finalExpanded = expanded !== undefined ? expanded : internalExpanded; + + const handleExpandClick = () => { + onExpandButtonClick?.(); + setInternalExpanded(!finalExpanded); + }; + + return ( + + + + {finalExpanded ? ( + + ) : ( + + )} + {title} + + {icon} + + + {children} + + + ); + }, +); + +type HideableBlockProps = PropsWithChildren< + { + visible: boolean; + /** + * An optimization to not avoid re-rendering the contents of the collapsible section. + * When enabled, we will keep the content around when collapsing but hide it via css. + */ + keepRendered?: boolean; + } & ClassNameProps +>; + +/** + * Component that can be hidden depending on a passed in prop. Supports an optimization + * to keep the component rendered (but not visible) when hidden to avoid re-rendering + * when component is shown again. + */ +export const HideableBlock = ({ + visible, + keepRendered, + children, +}: HideableBlockProps) => { + // visible represents whether the component is viewable in the browser. + // Rendered represents whether the DOM elements exist in the DOM tree. + // If !visible && rendered, then the elements are in the DOM but are + // not drawn via CSS visibility rules. + const [rendered, setRendered] = useState(visible); + + useEffect(() => { + if (visible) { + setRendered(true); + } + }, [visible]); + + // Optimization to keep the component rendered (but not visible) when hidden + // to avoid re-rendering when component is shown again. + return visible || (keepRendered && rendered) ? ( + + {children} + + ) : null; +}; diff --git a/historyserver/dashboard/ray/client/src/common/CustomTypography.tsx b/historyserver/dashboard/ray/client/src/common/CustomTypography.tsx new file mode 100644 index 00000000000..00e8ac24f8c --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/CustomTypography.tsx @@ -0,0 +1,5 @@ +import { styled, Typography } from "@mui/material"; + +export const RightPaddedTypography = styled(Typography)(({ theme }) => ({ + paddingRight: theme.spacing(1), +})); diff --git a/historyserver/dashboard/ray/client/src/common/DialogWithTitle.tsx b/historyserver/dashboard/ray/client/src/common/DialogWithTitle.tsx new file mode 100644 index 00000000000..57b812210fb --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/DialogWithTitle.tsx @@ -0,0 +1,53 @@ +import CloseIcon from "@mui/icons-material/Close"; +import { Dialog, IconButton, Theme, Typography } from "@mui/material"; +import React, { PropsWithChildren } from "react"; + +type Props = { + handleClose: () => void; + title: string; +}; + +class DialogWithTitle extends React.Component> { + render() { + const { handleClose, title } = this.props; + return ( + + ({ + position: "absolute", + right: theme.spacing(1.5), + top: theme.spacing(1.5), + zIndex: 1, + })} + onClick={handleClose} + size="large" + > + + + ({ + borderBottomColor: theme.palette.divider, + borderBottomStyle: "solid", + borderBottomWidth: 1, + fontSize: "1.5rem", + lineHeight: 1, + marginBottom: 3, + paddingBottom: 3, + })} + > + {title} + + {this.props.children} + + ); + } +} + +export default DialogWithTitle; diff --git a/historyserver/dashboard/ray/client/src/common/DurationText/DurationText.component.test.tsx b/historyserver/dashboard/ray/client/src/common/DurationText/DurationText.component.test.tsx new file mode 100644 index 00000000000..e4e7f4bd21b --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/DurationText/DurationText.component.test.tsx @@ -0,0 +1,108 @@ +import { render, screen } from "@testing-library/react"; +import MockDate from "mockdate"; +import React from "react"; +import { act } from "react-dom/test-utils"; +import { DurationText } from "./DurationText"; + +describe("DurationText", () => { + it("renders", async () => { + const { rerender } = render( + , + ); + + expect(await screen.findByText("5s")).toBeInTheDocument(); + rerender( + , + ); + expect(await screen.findByText("10s")).toBeInTheDocument(); + rerender( + , + ); + expect(await screen.findByText("1m 40s")).toBeInTheDocument(); + rerender( + , + ); + expect(await screen.findByText("1h 21m")).toBeInTheDocument(); + // > 1 day + rerender( + , + ); + expect(await screen.findByText("1d 13h")).toBeInTheDocument(); + + // > 1 month + rerender( + , + ); + expect(await screen.findByText("1M 4d")).toBeInTheDocument(); + + // > 1 year + rerender( + , + ); + expect(await screen.findByText("1y 1M 10d")).toBeInTheDocument(); + }); + + it("automatically re-renders when endTime is null", async () => { + jest.useFakeTimers(); + + const startTime = new Date(100000); + const mockDate1 = new Date(105000); + const mockDate2 = new Date(106000); + const mockDate3 = new Date(200000); + const mockDate4 = new Date(5000000); + const mockDate5 = new Date(5060000); + const endTime = new Date(5120000); + + MockDate.set(mockDate1); + const { rerender } = render(); + expect(await screen.findByText("5s")).toBeInTheDocument(); + + MockDate.set(mockDate2); + act(() => { + jest.advanceTimersByTime(1000); + }); + expect(await screen.findByText("6s")).toBeInTheDocument(); + + MockDate.set(mockDate3); + act(() => { + jest.advanceTimersByTime(1000); + }); + expect(await screen.findByText("1m 40s")).toBeInTheDocument(); + + MockDate.set(mockDate4); + act(() => { + jest.advanceTimersByTime(1000); + }); + expect(await screen.findByText("1h 21m")).toBeInTheDocument(); + + MockDate.set(mockDate5); + // After 1 hr, don't expect dates to re-render every second + act(() => { + jest.advanceTimersByTime(1000); + }); + // date should not have changed + expect(await screen.findByText("1h 21m")).toBeInTheDocument(); + act(() => { + jest.advanceTimersByTime(60000); + }); + expect(await screen.findByText("1h 22m")).toBeInTheDocument(); + + rerender(); + expect(await screen.findByText("1h 23m")).toBeInTheDocument(); + + MockDate.reset(); + jest.runOnlyPendingTimers(); + jest.useRealTimers(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/common/DurationText/DurationText.tsx b/historyserver/dashboard/ray/client/src/common/DurationText/DurationText.tsx new file mode 100644 index 00000000000..b22aabcb7a7 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/DurationText/DurationText.tsx @@ -0,0 +1,65 @@ +import { Typography } from "@mui/material"; +import dayjs from "dayjs"; +import React, { useEffect, useState } from "react"; + +type DurationTextProps = { + startTime: Date | number; + endTime?: Date | number | null; +}; + +export const getDurationVal = ({ startTime, endTime }: DurationTextProps) => { + // Helper to get duration value for DurationText component + // Assume current time, if end time is nullish + const endTimeToRender = endTime ? endTime : new Date(); + const durationTime = dayjs(endTimeToRender).diff(dayjs(startTime)); + return durationTime; +}; + +/** + * Component that shows an incrementing duration text. + * This component will smartly rerender more often depending on the size of the duration. + */ +export const DurationText = ({ startTime, endTime }: DurationTextProps) => { + // Increments to force a re-render. + const [, setRerenderCounter] = useState(0); + + const duration = dayjs.duration(getDurationVal({ startTime, endTime })); + + let durationText: string; + let refreshInterval = 1000; + if (duration.asMinutes() < 1) { + durationText = duration.format("s[s]"); + } else if (duration.asHours() < 1) { + durationText = duration.format("m[m] s[s]"); + } else if (duration.asDays() < 1) { + // Only refresh once per minute + durationText = duration.format("H[h] m[m]"); + refreshInterval = 1000 * 60; + } else if (duration.asMonths() < 1) { + // Only refresh once per minute + durationText = duration.format("D[d] H[h]"); + refreshInterval = 1000 * 60; + } else if (duration.asYears() < 1) { + // Only refresh once per hour + durationText = duration.format("M[M] D[d]"); + refreshInterval = 1000 * 60 * 60; + } else { + // Only refresh once per hour + durationText = duration.format("Y[y] M[M] D[d]"); + refreshInterval = 1000 * 60 * 60; + } + + useEffect(() => { + if (!endTime) { + // Only refresh if this is running job + const timeout = setInterval(() => { + setRerenderCounter((counter) => counter + 1); + }, refreshInterval); + return () => { + clearInterval(timeout); + }; + } + }, [endTime, refreshInterval]); + + return {durationText}; +}; diff --git a/historyserver/dashboard/ray/client/src/common/DurationText/index.ts b/historyserver/dashboard/ray/client/src/common/DurationText/index.ts new file mode 100644 index 00000000000..2d5f80a41c8 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/DurationText/index.ts @@ -0,0 +1 @@ +export * from "./DurationText"; diff --git a/historyserver/dashboard/ray/client/src/common/ExpandControls.tsx b/historyserver/dashboard/ray/client/src/common/ExpandControls.tsx new file mode 100644 index 00000000000..2506f556b4f --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/ExpandControls.tsx @@ -0,0 +1,19 @@ +import ExpandLessIcon from "@mui/icons-material/ExpandLess"; +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import React from "react"; + +type MinimizerProps = { + onClick: React.MouseEventHandler; +}; + +type ExpanderProps = { + onClick: React.MouseEventHandler; +}; + +export const Minimizer: React.FC = ({ onClick }) => ( + +); + +export const Expander: React.FC = ({ onClick }) => ( + +); diff --git a/historyserver/dashboard/ray/client/src/common/JobStatus.tsx b/historyserver/dashboard/ray/client/src/common/JobStatus.tsx new file mode 100644 index 00000000000..1768f03db4d --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/JobStatus.tsx @@ -0,0 +1,129 @@ +import { Box, keyframes, SxProps, Theme } from "@mui/material"; +import React from "react"; +import { + RiCheckboxCircleFill, + RiCloseCircleFill, + RiLoader4Line, + RiStopCircleFill, +} from "react-icons/ri"; +import { StatusChip } from "../components/StatusChip"; +import { JobStatus, UnifiedJob } from "../type/job"; +import { ClassNameProps } from "./props"; + +const spinner = keyframes` +from { + transform: rotate(0deg) +}, +to { + transform: rotate(360deg) +}`; + +type JobRunningIconProps = { + title?: string; + small?: boolean; + sx?: SxProps; +} & ClassNameProps; + +export const JobRunningIcon = ({ + className, + title, + small = false, + sx = [], + ...props +}: JobRunningIconProps) => { + return ( + + ); +}; + +type JobStatusIconProps = { + job: UnifiedJob; + small?: boolean; + sx?: SxProps; +} & ClassNameProps; + +export const JobStatusIcon = ({ + job, + small = false, + className, + sx, +}: JobStatusIconProps) => { + switch (job.status) { + case JobStatus.SUCCEEDED: + return ( + theme.palette.success.main, + }, + ...(Array.isArray(sx) ? sx : [sx]), + ]} + /> + ); + case JobStatus.FAILED: + return ( + theme.palette.error.main, + }, + ...(Array.isArray(sx) ? sx : [sx]), + ]} + /> + ); + case JobStatus.STOPPED: + return ( + + ); + default: + return ; + } +}; + +type JobStatusWithIconProps = { + job: UnifiedJob; +}; + +export const JobStatusWithIcon = ({ job }: JobStatusWithIconProps) => { + return ( + + } + /> + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/common/LabeledDatum.tsx b/historyserver/dashboard/ray/client/src/common/LabeledDatum.tsx new file mode 100644 index 00000000000..21faa47680c --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/LabeledDatum.tsx @@ -0,0 +1,42 @@ +import { Box, Grid, Tooltip } from "@mui/material"; +import React, { ReactChild } from "react"; + +type LabeledDatumProps = { + label: ReactChild; + datum: any; + tooltip?: string; +}; + +const LabeledDatum: React.FC = ({ + label, + datum, + tooltip, +}) => { + const innerHtml = ( + + + + {label} + + + + {datum} + + + ); + return tooltip ? {innerHtml} : innerHtml; +}; + +export default LabeledDatum; diff --git a/historyserver/dashboard/ray/client/src/common/MultiTabLogViewer.tsx b/historyserver/dashboard/ray/client/src/common/MultiTabLogViewer.tsx new file mode 100644 index 00000000000..f47275e4536 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/MultiTabLogViewer.tsx @@ -0,0 +1,257 @@ +import { Box, IconButton, Tab, Tabs, Typography } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { RiExternalLinkLine, RiSortAsc, RiSortDesc } from "react-icons/ri"; +import { Link } from "react-router-dom"; +import { useLocalStorage } from "usehooks-ts"; +import { useStateApiLogs } from "../pages/log/hooks"; +import { LogViewer } from "../pages/log/LogViewer"; +import { HideableBlock } from "./CollapsibleSection"; +import { ClassNameProps } from "./props"; + +export type MultiTabLogViewerTabDetails = { + title: string; +} & LogViewerData; + +export type MultiTabLogViewerProps = { + tabs: MultiTabLogViewerTabDetails[]; + otherLogsLink?: string; + /** + * If set, this multi-tab log viewer will remember the last selected tab and start on that tab + * the next time this component is rendered. + * + * Different string values to provide different contexts for this memory. For example, if you + * want all multi-tab log viewers in the actor detail page to share one memory, they should have + * the same string value here. + */ + contextKey?: string; +} & ClassNameProps; + +export const MultiTabLogViewer = ({ + tabs, + otherLogsLink, + contextKey, + className, +}: MultiTabLogViewerProps) => { + // DO NOT use `cachedTab` or `setCachedTab` when `contextKey` is undefined! + const [cachedTab, setCachedTab] = useLocalStorage( + `MultiTabLogViewer-tabMemory-${contextKey}`, + null, + ); + + const [value, setValue] = useState( + contextKey && cachedTab ? cachedTab : tabs[0]?.title, + ); + const [expanded, setExpanded] = useState(false); + + useEffect(() => { + // If current tab value is not valid, reset to first tab. + if (!tabs.some((tab) => tab.title === value)) { + setValue(tabs[0]?.title); + } + }, [tabs, value]); + + const currentTab = tabs.find((tab) => tab.title === value); + + if (tabs.length === 0) { + return No logs to display.; + } + + return ( +
+ + + {(tabs.length > 1 || otherLogsLink) && ( + `1px solid ${theme.palette.divider}`, + }} + value={value} + onChange={(_, newValue) => { + if (contextKey) { + setCachedTab(newValue); + } + setValue(newValue); + }} + indicatorColor="primary" + > + {tabs.map(({ title }) => ( + + ))} + {otherLogsLink && ( + + Other logs   + + } + onClick={(event) => { + // Prevent the tab from changing by setting value to the current value + setValue(value); + }} + component={Link} + to={otherLogsLink} + target="_blank" + rel="noopener noreferrer" + /> + )} + + )} + + {!currentTab ? ( + Please select a tab. + ) : ( + tabs.map((tab) => { + const { title, ...data } = tab; + return ( + + + + ); + }) + )} + + { + setExpanded(!expanded); + }} + size="large" + > + {expanded ? : } + + +
+ ); +}; + +type TextData = { + contents: string; +}; +type FileData = { + nodeId: string | null; + filename?: string; +}; +type ActorData = { + actorId: string | null; + suffix: "out" | "err"; +}; +type TaskData = { + taskId: string | null; + suffix: "out" | "err"; +}; + +type LogViewerData = TextData | FileData | ActorData | TaskData; + +const isLogViewerDataText = (data: LogViewerData): data is TextData => + "contents" in data; + +const isLogViewerDataActor = (data: LogViewerData): data is ActorData => + "actorId" in data; + +const isLogViewerDataTask = (data: LogViewerData): data is TaskData => + "taskId" in data; + +export type StateApiLogViewerProps = { + height?: number; + data: LogViewerData; +}; + +export const StateApiLogViewer = ({ + height = 300, + data, +}: StateApiLogViewerProps) => { + if (isLogViewerDataText(data)) { + return ; + } else if (isLogViewerDataActor(data)) { + return ; + } else if (isLogViewerDataTask(data)) { + return ; + } else { + return ; + } +}; + +const TextLogViewer = ({ + height = 300, + contents, +}: { + height: number; + contents: string; +}) => { + return ; +}; + +const FileLogViewer = ({ + height = 300, + nodeId, + filename, +}: { + height: number; +} & FileData) => { + const apiData = useStateApiLogs({ nodeId, filename }, filename); + return ; +}; + +const ActorLogViewer = ({ + height = 300, + actorId, + suffix, +}: { + height: number; +} & ActorData) => { + const apiData = useStateApiLogs( + { actorId, suffix }, + `actor-log-${actorId}.${suffix}`, + ); + return ; +}; + +const TaskLogViewer = ({ + height = 300, + taskId, + suffix, +}: { + height: number; +} & TaskData) => { + const apiData = useStateApiLogs( + { taskId, suffix }, + `task-log-${taskId}.${suffix}`, + ); + return ; +}; + +const ApiLogViewer = ({ + apiData: { downloadUrl, log, path, refresh }, + height = 300, +}: { + apiData: ReturnType; + height: number; +}) => { + return typeof log === "string" ? ( + + ) : ( + Failed to load + ); +}; diff --git a/historyserver/dashboard/ray/client/src/common/NumberedLines.tsx b/historyserver/dashboard/ray/client/src/common/NumberedLines.tsx new file mode 100644 index 00000000000..ee999993e95 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/NumberedLines.tsx @@ -0,0 +1,48 @@ +import { styled, Table, TableBody, TableCell, TableRow } from "@mui/material"; +import React from "react"; + +const StyledTableCell = styled(TableCell)(() => ({ + borderWidth: 0, + fontFamily: "SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace", + padding: 0, + "&:last-child": { + paddingRight: 0, + }, +})); + +type NumberedLinesProps = { + lines: string[]; +}; + +const NumberedLines = ({ lines }: NumberedLinesProps) => { + return ( + + + {lines.map((line, index) => ( + + ({ + color: theme.palette.text.secondary, + paddingRight: 2, + textAlign: "right", + verticalAlign: "top", + width: "1%", + // Use a ::before pseudo-element for the line number so that it won't + // interact with user selections or searching. + "&::before": { + content: "attr(data-line-number)", + }, + })} + data-line-number={index + 1} + /> + + {line} + + + ))} + +
+ ); +}; + +export default NumberedLines; diff --git a/historyserver/dashboard/ray/client/src/common/ProfilingLink.component.test.tsx b/historyserver/dashboard/ray/client/src/common/ProfilingLink.component.test.tsx new file mode 100644 index 00000000000..84434cedd89 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/ProfilingLink.component.test.tsx @@ -0,0 +1,71 @@ +import { render, screen, waitFor } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import React from "react"; +import "@testing-library/jest-dom"; +import { TEST_APP_WRAPPER } from "../util/test-utils"; +import { ProfilerButton } from "./ProfilingLink"; + +describe("ProfilerButton", () => { + const mockProps = { + profilerUrl: "http://localhost:3000/worker/memory_profile", + }; + it("renders button correctly", () => { + render(, { wrapper: TEST_APP_WRAPPER }); + const button = screen.getByLabelText(/Memory Profiling/); + expect(button).toBeInTheDocument(); + }); + + it("opens the dialog when the button is clicked", async () => { + const user = userEvent.setup(); + render(, { wrapper: TEST_APP_WRAPPER }); + const button = screen.getByLabelText(/Memory Profiling/); + + user.click(button); + + // check all components exist in dialog + await waitFor(() => { + const dialogTitle = screen.getByText("Memory Profiling Config"); + expect(dialogTitle).toBeInTheDocument(); + const reportButton = screen.getByText(/Generate report/); + expect(reportButton).toBeInTheDocument(); + const durationInput = screen.getByLabelText(/Duration/); + expect(durationInput).toBeInTheDocument(); + const leaksCheckbox = screen.getByText(/Leaks/); + expect(leaksCheckbox).toBeInTheDocument(); + const nativeCheckbox = screen.getByText(/Native/); + expect(nativeCheckbox).toBeInTheDocument(); + const allocatorCheckbox = screen.getByText(/Python Allocator Tracing/); + expect(allocatorCheckbox).toBeInTheDocument(); + }); + }); + + it("closes the dialog when the cancel button is clicked", async () => { + const user = userEvent.setup(); + render(, { wrapper: TEST_APP_WRAPPER }); + const button = screen.getByLabelText(/Memory Profiling/); + + await user.click(button); + + const cancelButton = screen.getByRole("button", { name: /Cancel/ }); + await user.click(cancelButton); + + await waitFor(() => { + const dialogTitle = screen.queryByText(/Memory Profiling Config/); + expect(dialogTitle).not.toBeInTheDocument(); + }); + }); + + it('selects "flamegraph" as the default format', async () => { + const user = userEvent.setup(); + render(, { wrapper: TEST_APP_WRAPPER }); + const button = screen.getByLabelText(/Memory Profiling/); + await user.click(button); + + const formatSelect = screen.getByLabelText(/flamegraph/); + expect(formatSelect).toBeInTheDocument(); + expect(screen.getByText(/Generate report/)).toHaveAttribute( + "href", + `${mockProps.profilerUrl}&format=flamegraph&duration=5&leaks=1&native=0&trace_python_allocators=0`, + ); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/common/ProfilingLink.tsx b/historyserver/dashboard/ray/client/src/common/ProfilingLink.tsx new file mode 100644 index 00000000000..5c44c4547a6 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/ProfilingLink.tsx @@ -0,0 +1,308 @@ +import { + Box, + Button, + Checkbox, + Dialog, + DialogContent, + DialogTitle, + FormControlLabel, + InputLabel, + Link, + MenuItem, + Select, + TextField, + Typography, +} from "@mui/material"; +import React, { PropsWithChildren, useState } from "react"; +import { HelpInfo } from "../components/Tooltip"; +import { ClassNameProps } from "./props"; + +type CpuProfilingLinkProps = PropsWithChildren< + { + pid: string | number | null | undefined; + ip: string | null | undefined; + type: string | null; + } & ClassNameProps +>; + +type TaskProfilingStackTraceProps = { + taskId: string | null | undefined; + attemptNumber: number; + nodeId: string; +}; + +type MemoryProfilingProps = PropsWithChildren< + { + pid: string | number | null | undefined; + ip: string | null | undefined; + type?: string | null; + } & ClassNameProps +>; + +type TaskMemoryProfilingProps = { + taskId: string | null | undefined; + attemptNumber: number; + nodeId: string; +}; + +type MemoryProfilingButtonProps = { + profilerUrl: string; + type?: string | null; +}; + +export const TaskCpuProfilingLink = ({ + taskId, + attemptNumber, + nodeId, +}: TaskProfilingStackTraceProps) => { + if (!taskId) { + return null; + } + return ( + + CPU Flame Graph + + ); +}; + +export const TaskCpuStackTraceLink = ({ + taskId, + attemptNumber, + nodeId, +}: TaskProfilingStackTraceProps) => { + if (!taskId) { + return null; + } + return ( + + Stack Trace + + ); +}; + +export const CpuStackTraceLink = ({ + pid, + ip, + type = "", +}: CpuProfilingLinkProps) => { + if (!pid || !ip || typeof pid === "undefined" || typeof ip === "undefined") { + return
; + } + return ( + + Stack Trace{type ? ` (${type})` : ""} + + ); +}; + +export const CpuProfilingLink = ({ + pid, + ip, + type = "", +}: CpuProfilingLinkProps) => { + if (!pid || !ip) { + return
; + } + + return ( + + CPU Flame Graph{type ? ` (${type})` : ""} + + ); +}; + +export const ProfilerButton = ({ + profilerUrl, + type, +}: MemoryProfilingButtonProps) => { + const [duration, setDuration] = useState(5); + const [leaks, setLeaks] = useState(true); + const [native, setNative] = useState(false); + const [allocator, setAllocator] = useState(false); + const [open, setOpen] = useState(false); + const [format, setFormat] = useState("flamegraph"); + + const handleOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + }; + + return ( +
+ + Memory Profiling{type ? ` (${type})` : ""} + + + + Memory Profiling Config + + Format + + setDuration(parseInt(e.target.value, 10))} + required + /> +
+ setLeaks(e.target.checked)} + /> + } + label={ +
+ Leaks + + + Enable memory leaks, instead of peak memory usage. Refer to + Memray documentation for more details. + + +
+ } + /> +
+ setNative(e.target.checked)} + /> + } + label={ +
+ Native + + + Track native (C/C++) stack frames. Refer to Memray + documentation for more details. + + +
+ } + /> +
+ setAllocator(e.target.checked)} + /> + } + label={ +
+ + Python Allocator Tracing + + + + Record allocations made by the pymalloc allocator. Refer to + Memray documentation for more details. + + +
+ } + /> +
+ + + + +
+
+ ); +}; + +export const MemoryProfilingButton = ({ + pid, + ip, + type = "", +}: MemoryProfilingProps) => { + if (!pid || !ip) { + return
; + } + const profilerUrl = `memory_profile?pid=${pid}&ip=${ip}`; + + return ; +}; + +export const TaskMemoryProfilingButton = ({ + taskId, + attemptNumber, + nodeId, +}: TaskMemoryProfilingProps) => { + if (!taskId) { + return null; + } + const profilerUrl = `memory_profile?task_id=${taskId}&attempt_number=${attemptNumber}&node_id=${nodeId}`; + + return ; +}; diff --git a/historyserver/dashboard/ray/client/src/common/RowStyles.tsx b/historyserver/dashboard/ray/client/src/common/RowStyles.tsx new file mode 100644 index 00000000000..2149fd79751 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/RowStyles.tsx @@ -0,0 +1,18 @@ +const rowStyles = { + idCol: { + display: "block", + width: "50px", + overflow: "hidden", + textOverflow: "ellipsis", + whiteSpace: "nowrap", + }, + OverflowCol: { + display: "block", + width: "100px", + overflow: "hidden", + textOverflow: "ellipsis", + whiteSpace: "nowrap", + }, +}; + +export default rowStyles; diff --git a/historyserver/dashboard/ray/client/src/common/Section.tsx b/historyserver/dashboard/ray/client/src/common/Section.tsx new file mode 100644 index 00000000000..12e423e4121 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/Section.tsx @@ -0,0 +1,37 @@ +import { Box, BoxProps, Paper, Typography } from "@mui/material"; +import React, { PropsWithChildren } from "react"; +import { ClassNameProps } from "./props"; + +type SectionProps = { + title?: string; + noTopPadding?: boolean; +} & ClassNameProps & + BoxProps; + +export const Section = ({ + title, + children, + className, + noTopPadding = false, + ...props +}: PropsWithChildren) => { + return ( + + {title && ( + + {title} + + )} + + {children} + + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/common/ServeStatus.component.test.tsx b/historyserver/dashboard/ray/client/src/common/ServeStatus.component.test.tsx new file mode 100644 index 00000000000..13e6d967ff7 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/ServeStatus.component.test.tsx @@ -0,0 +1,47 @@ +import { render, screen } from "@testing-library/react"; +import React from "react"; +import { ServeDeployment, ServeDeploymentStatus } from "../type/serve"; +import { TEST_APP_WRAPPER } from "../util/test-utils"; +import { ServeStatusIcon } from "./ServeStatus"; + +const DEPLOYMENT: ServeDeployment = { + name: "MyServeDeployment", + deployment_config: {} as any, + message: "Running", + replicas: [], + status: ServeDeploymentStatus.HEALTHY, +}; + +describe("ServeStatusIcon", () => { + it("renders HEALTHY status", async () => { + render(, { + wrapper: TEST_APP_WRAPPER, + }); + + await screen.findByTitle("Healthy"); + }); + + it("renders UNHEALTHY status", async () => { + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + + await screen.findByTitle("Unhealthy"); + }); + + it("renders UPDATING status", async () => { + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + + await screen.findByTitle("Updating"); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/common/ServeStatus.tsx b/historyserver/dashboard/ray/client/src/common/ServeStatus.tsx new file mode 100644 index 00000000000..dbf4455bb6f --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/ServeStatus.tsx @@ -0,0 +1,64 @@ +import { Box, SxProps, Theme } from "@mui/material"; +import React from "react"; +import { RiCloseCircleFill, RiRecordCircleFill } from "react-icons/ri"; +import { ServeDeployment } from "../type/serve"; +import { JobRunningIcon } from "./JobStatus"; +import { ClassNameProps } from "./props"; + +type ServeStatusIconProps = { + deployment: ServeDeployment; + small: boolean; + sx?: SxProps; +} & ClassNameProps; + +export const ServeStatusIcon = ({ + deployment, + small, + className, + sx, +}: ServeStatusIconProps) => { + switch (deployment.status) { + case "HEALTHY": + return ( + theme.palette.success.main, + }, + ...(Array.isArray(sx) ? sx : [sx]), + ]} + title="Healthy" + /> + ); + case "UNHEALTHY": + return ( + theme.palette.error.main, + }, + ...(Array.isArray(sx) ? sx : [sx]), + ]} + title="Unhealthy" + /> + ); + default: + // UPDATING + return ( + + ); + } +}; diff --git a/historyserver/dashboard/ray/client/src/common/SortableTableHead.tsx b/historyserver/dashboard/ray/client/src/common/SortableTableHead.tsx new file mode 100644 index 00000000000..49b1858f657 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/SortableTableHead.tsx @@ -0,0 +1,83 @@ +import { Box, TableHead, TableRow, TableSortLabel } from "@mui/material"; +import React from "react"; +import { StyledTableCell } from "./TableCell"; +import { Order } from "./tableUtils"; + +export type HeaderInfo = { + sortable: boolean; + id: T; + label: string; + numeric: boolean; +}; + +type SortableTableHeadProps = { + onRequestSort: (event: React.MouseEvent, id: T) => void; + order: Order; + orderBy: T | null; + headerInfo: HeaderInfo[]; + firstColumnEmpty: boolean; +}; + +const SortableTableHead = (props: SortableTableHeadProps) => { + const { order, orderBy, onRequestSort, headerInfo, firstColumnEmpty } = props; + const createSortHandler = (id: T) => (event: React.MouseEvent) => { + onRequestSort(event, id); + }; + return ( + + + {firstColumnEmpty && } + {headerInfo.map((headerInfo) => { + if (headerInfo.sortable) { + return ( + + + {headerInfo.label} + {orderBy === headerInfo.id ? ( + + {order === "desc" + ? "sorted descending" + : "sorted ascending"} + + ) : null} + + + ); + } else { + return ( + + {headerInfo.label} + + ); + } + })} + + + ); +}; + +export default SortableTableHead; diff --git a/historyserver/dashboard/ray/client/src/common/SpanButton.tsx b/historyserver/dashboard/ray/client/src/common/SpanButton.tsx new file mode 100644 index 00000000000..6ae0f0434d8 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/SpanButton.tsx @@ -0,0 +1,11 @@ +import { styled } from "@mui/material"; + +export const SpanButton = styled("span")(({ theme }) => ({ + button: { + color: theme.palette.primary.main, + "&:hover": { + cursor: "pointer", + textDecoration: "underline", + }, + }, +})); diff --git a/historyserver/dashboard/ray/client/src/common/TableCell.tsx b/historyserver/dashboard/ray/client/src/common/TableCell.tsx new file mode 100644 index 00000000000..840c0b2d9f5 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/TableCell.tsx @@ -0,0 +1,13 @@ +import { TableCell } from "@mui/material"; +import { styled } from "@mui/material/styles"; + +export const StyledTableCell = styled(TableCell)(({ theme }) => ({ + padding: theme.spacing(1), + textAlign: "center", +})); + +export const ExpandableStyledTableCell = styled(TableCell)(({ theme }) => ({ + padding: theme.spacing(1), + textAlign: "center", + cursor: "pointer", +})); diff --git a/historyserver/dashboard/ray/client/src/common/UsageBar.tsx b/historyserver/dashboard/ray/client/src/common/UsageBar.tsx new file mode 100644 index 00000000000..8b8c17cddd6 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/UsageBar.tsx @@ -0,0 +1,65 @@ +import { Box, Typography } from "@mui/material"; +import React from "react"; + +const blend = ( + [r1, g1, b1]: number[], + [r2, g2, b2]: number[], + ratio: number, +) => [ + r1 * (1 - ratio) + r2 * ratio, + g1 * (1 - ratio) + g2 * ratio, + b1 * (1 - ratio) + b2 * ratio, +]; + +type UsageBarProps = { + percent: number; + text: string; +}; + +const UsageBar: React.FC = ({ percent, text }) => { + const safePercent = Math.max(Math.min(percent, 100), 0); + const minColor = [0, 255, 0]; + const maxColor = [255, 0, 0]; + + const leftColor = minColor; + const rightColor = blend(minColor, maxColor, safePercent / 100); + const alpha = 0.2; + + const gradient = ` + linear-gradient( + to right, + rgba(${leftColor.join(",")}, ${alpha}) 0%, + rgba(${rightColor.join(",")}, ${alpha}) ${safePercent}%, + transparent ${safePercent}% + ) + `; + + // Use a nested `span` here because the right border is affected by the + // gradient background otherwise. + return ( + theme.palette.divider, + borderStyle: "solid", + borderWidth: 1, + display: "flex", + flexGrow: 1, + }} + > + + {text} + + + ); +}; + +export default UsageBar; diff --git a/historyserver/dashboard/ray/client/src/common/UsageStatsAlert.tsx b/historyserver/dashboard/ray/client/src/common/UsageStatsAlert.tsx new file mode 100644 index 00000000000..5dd2a569457 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/UsageStatsAlert.tsx @@ -0,0 +1,37 @@ +import { Alert, Link } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { getUsageStatsEnabled } from "../service/global"; + +export const UsageStatsAlert = () => { + const [usageStatsPromptEnabled, setUsageStatsPromptEnabled] = useState(false); + const [usageStatsEnabled, setUsageStatsEnabled] = useState(false); + useEffect(() => { + getUsageStatsEnabled().then(({ data }) => { + setUsageStatsPromptEnabled(data.usageStatsPromptEnabled); + setUsageStatsEnabled(data.usageStatsEnabled); + }); + }, []); + + return usageStatsPromptEnabled ? ( + + {usageStatsEnabled ? ( + + Usage stats collection is enabled. To disable this, add + `--disable-usage-stats` to the command that starts the cluster, or run + the following command: `ray disable-usage-stats` before starting the + cluster. See{" "} + + https://docs.ray.io/en/master/cluster/usage-stats.html + {" "} + for more details. + + ) : ( + Usage stats collection is disabled. + )} + + ) : null; +}; diff --git a/historyserver/dashboard/ray/client/src/common/clusterslinks.tsx b/historyserver/dashboard/ray/client/src/common/clusterslinks.tsx new file mode 100644 index 00000000000..70b8a555568 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/clusterslinks.tsx @@ -0,0 +1,42 @@ +import { Link, SxProps, Theme } from "@mui/material"; +import React, { PropsWithChildren, useState } from "react"; +import { Link as RouterLink } from "react-router-dom"; +import { ClassNameProps } from "./props"; +import { GlobalContext } from "../App"; + +type ClusterLinkProps = PropsWithChildren< + { + clusterName: string; + sessionName: string; + /** + * This can be provided to override where we link to. + */ + to?: string; + sx?: SxProps; + } & ClassNameProps +>; +export const generateClusterLink = (clusterName: string, sessionName: string) => `/clusters/${clusterName}/${sessionName}`; + +/** + * A link to the top-level Cluster detail page. + */ +export const ClusterLink = ({ + clusterName, + sessionName, + to, + children, + className, + sx, +}: ClusterLinkProps) => { + return ( + + {children ?? clusterName} + + ); +}; + diff --git a/historyserver/dashboard/ray/client/src/common/constants.ts b/historyserver/dashboard/ray/client/src/common/constants.ts new file mode 100644 index 00000000000..395ba8f97a1 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/constants.ts @@ -0,0 +1,3 @@ +export const API_REFRESH_INTERVAL_MS = 4000; +// Per job page refresh interval. +export const PER_JOB_PAGE_REFRESH_INTERVAL_MS = 10000; diff --git a/historyserver/dashboard/ray/client/src/common/formatUtils.ts b/historyserver/dashboard/ray/client/src/common/formatUtils.ts new file mode 100644 index 00000000000..03610fd8255 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/formatUtils.ts @@ -0,0 +1,64 @@ +import dayjs from "dayjs"; + +export const formatByteAmount = ( + amount: number, + unit: "mebibyte" | "gibibyte", +) => + `${( + amount / (unit === "mebibyte" ? Math.pow(1024, 2) : Math.pow(1024, 3)) + ).toFixed(1)} ${unit === "mebibyte" ? "MiB" : "GiB"}`; + +export const formatUsage = ( + used_b: number, + total_b: number, + unit: "mebibyte" | "gibibyte", + includePercentage: boolean, +) => { + const usedFormatted = formatByteAmount(used_b, unit); + const totalFormatted = formatByteAmount(total_b, unit); + const percent = (100 * used_b) / total_b; + const ratioStr = `${usedFormatted} / ${totalFormatted}`; + if (includePercentage) { + return `${ratioStr} (${percent.toFixed(0)}%)`; + } + return ratioStr; +}; + +// Formats, e.g. 400 and 6000 as "400 MiB / 6000 MiB (6.7%)" +export const MiBRatio = (used: number, total: number) => + `${used} MiB / ${total} MiB (${(100 * (used / total)).toFixed(1)}%)`; + +export const MiBRatioNoPercent = (used: number, total: number) => + `${used} MiB / ${total} MiB`; + +export const formatDuration = (durationInSeconds: number) => { + const durationSeconds = Math.floor(durationInSeconds) % 60; + const durationMinutes = Math.floor(durationInSeconds / 60) % 60; + const durationHours = Math.floor(durationInSeconds / 60 / 60) % 24; + const durationDays = Math.floor(durationInSeconds / 60 / 60 / 24); + const pad = (value: number) => value.toString().padStart(2, "0"); + return [ + durationDays ? `${durationDays}d` : "", + `${pad(durationHours)}h`, + `${pad(durationMinutes)}m`, + `${pad(durationSeconds)}s`, + ].join(" "); +}; + +export const formatValue = (rawFloat: number) => { + try { + const decimals = rawFloat.toString().split(".")[1].length || 0; + if (decimals <= 3) { + return rawFloat.toString(); + } // Few decimals + if (Math.abs(rawFloat.valueOf()) >= 1.0) { + return rawFloat.toPrecision(5); + } // Values >= 1 + return rawFloat.toExponential(); // Values in (-1; 1) + } catch (e) { + return rawFloat.toString(); + } +}; + +export const formatDateFromTimeMs = (time: number) => + dayjs(time).format("YYYY/MM/DD HH:mm:ss"); diff --git a/historyserver/dashboard/ray/client/src/common/links.tsx b/historyserver/dashboard/ray/client/src/common/links.tsx new file mode 100644 index 00000000000..30246fa6387 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/links.tsx @@ -0,0 +1,75 @@ +import { Link, SxProps, Theme } from "@mui/material"; +import React, { PropsWithChildren } from "react"; +import { Link as RouterLink } from "react-router-dom"; +import { ClassNameProps } from "./props"; + +type ActorLinkProps = PropsWithChildren< + { + actorId: string; + /** + * This can be provided to override where we link to. + */ + to?: string; + sx?: SxProps; + } & ClassNameProps +>; + +export const generateActorLink = (actorId: string) => `/actors/${actorId}`; + +/** + * A link to the top-level actors detail page. + */ +export const ActorLink = ({ + actorId, + to, + children, + className, + sx, +}: ActorLinkProps) => { + return ( + + {children ?? actorId} + + ); +}; + +type NodeLinkProps = PropsWithChildren< + { + nodeId: string; + /** + * This can be provided to override where we link to. + */ + to?: string; + sx?: SxProps; + } & ClassNameProps +>; + +export const generateNodeLink = (nodeId: string) => `/cluster/nodes/${nodeId}`; + +/** + * A link to the top-level Cluster node detail page. + */ +export const NodeLink = ({ + nodeId, + to, + children, + className, + sx, +}: NodeLinkProps) => { + return ( + + {children ?? nodeId} + + ); +}; + diff --git a/historyserver/dashboard/ray/client/src/common/props.d.ts b/historyserver/dashboard/ray/client/src/common/props.d.ts new file mode 100644 index 00000000000..8c5d047e127 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/props.d.ts @@ -0,0 +1,7 @@ +export type ClassNameProps = { + className?: string; +}; + +export type DataTestIdProps = { + "data-testid"?: string; +}; diff --git a/historyserver/dashboard/ray/client/src/common/tableUtils.ts b/historyserver/dashboard/ray/client/src/common/tableUtils.ts new file mode 100644 index 00000000000..7cd4392ff99 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/tableUtils.ts @@ -0,0 +1,61 @@ +export const descendingComparator = (a: T, b: T, orderBy: keyof T) => { + if (b[orderBy] < a[orderBy]) { + return -1; + } + if (b[orderBy] > a[orderBy]) { + return 1; + } + return 0; +}; + +const descendingComparatorFnAccessor = ( + a: T, + b: T, + orderByFn: Accessor, +) => { + const aVal = orderByFn(a); + const bVal = orderByFn(b); + if (bVal < aVal) { + return -1; + } + if (bVal > aVal) { + return 1; + } + return 0; +}; + +export type Order = "asc" | "desc"; +export type Comparator = (a: T, b: T) => number; +export type Accessor = (a: T) => number | string; + +export const getComparator = ( + order: Order, + orderBy: Key, +): (( + a: { [key in Key]: number | string }, + b: { [key in Key]: number | string }, +) => number) => { + return order === "desc" + ? (a, b) => descendingComparator(a, b, orderBy) + : (a, b) => -descendingComparator(a, b, orderBy); +}; + +export const getFnComparator = + (order: Order, orderByFn: Accessor) => + (a: T, b: T): number => { + return order === "desc" + ? descendingComparatorFnAccessor(a, b, orderByFn) + : -descendingComparatorFnAccessor(a, b, orderByFn); + }; + +export const stableSort = (array: T[], comparator: Comparator) => { + const stabilizedThis = array.map((el, index) => [el, index] as [T, number]); + stabilizedThis.sort((a, b) => { + const order = comparator(a[0], b[0]); + if (order !== 0) { + return order; + } + return a[1] - b[1]; + }); + return stabilizedThis.map((el) => el[0]); +}; diff --git a/historyserver/dashboard/ray/client/src/common/util.ts b/historyserver/dashboard/ray/client/src/common/util.ts new file mode 100644 index 00000000000..c0fe05389fc --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/util.ts @@ -0,0 +1,56 @@ +import _ from "lodash"; + +export const getWeightedAverage = ( + input: { + weight: number; + value: number; + }[], +) => { + if (input.length === 0) { + return 0; + } + + let totalWeightTimesValue = 0; + let totalWeight = 0; + for (const { weight, value } of input) { + totalWeightTimesValue += weight * value; + totalWeight += weight; + } + return totalWeightTimesValue / totalWeight; +}; + +export const sum = (vals: number[]) => vals.reduce((acc, val) => acc + val, 0); + +export const filterObj = (obj: Record, filterFn: any) => + Object.fromEntries(Object.entries(obj).filter(filterFn)); + +export const mapObj = (obj: Record, filterFn: any) => + Object.fromEntries(Object.entries(obj).map(filterFn) as any[]); + +export const filterRuntimeEnvSystemVariables = ( + runtime_env: Record, +): Record => { + const out = _.pickBy(runtime_env, (_, key) => { + if (key.startsWith("_")) { + return false; + } + return true; + }); + return out; +}; + +export const sliceToPage = ( + items: T[], + pageNo: number, + pageSize = 10, +): { items: T[]; constrainedPage: number; maxPage: number } => { + const maxPage = Math.ceil(items.length / pageSize); + const constrainedPage = Math.min(maxPage, Math.max(1, pageNo)); + const start = (constrainedPage - 1) * pageSize; + const end = constrainedPage * pageSize; + return { + items: items.slice(start, end), + constrainedPage, + maxPage, + }; +}; diff --git a/historyserver/dashboard/ray/client/src/common/util.unit.test.ts b/historyserver/dashboard/ray/client/src/common/util.unit.test.ts new file mode 100644 index 00000000000..86c1758d48b --- /dev/null +++ b/historyserver/dashboard/ray/client/src/common/util.unit.test.ts @@ -0,0 +1,34 @@ +import { filterRuntimeEnvSystemVariables } from "./util"; + +describe("filterRuntimeEnvSystemVariables", () => { + it("filters out system variables", () => { + expect( + filterRuntimeEnvSystemVariables({ + pip: { + pip_check: true, + packages: ["chess", "foo", "bar"], + pip_version: "1.2.3", + }, + env_vars: { + FOO: "foo", + BAR: "5", + }, + working_dir: ".", + _ray_release: "2.3.1", + _ray_commit: "12345abc", + _inject_current_ray: false, + }), + ).toEqual({ + pip: { + pip_check: true, + packages: ["chess", "foo", "bar"], + pip_version: "1.2.3", + }, + env_vars: { + FOO: "foo", + BAR: "5", + }, + working_dir: ".", + }); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/components/ActorTable.component.test.tsx b/historyserver/dashboard/ray/client/src/components/ActorTable.component.test.tsx new file mode 100644 index 00000000000..cbb8f8a18c1 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/ActorTable.component.test.tsx @@ -0,0 +1,382 @@ +import { render, screen, within } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import React from "react"; +import { ActorDetail } from "../type/actor"; +import { TEST_APP_WRAPPER } from "../util/test-utils"; +import ActorTable from "./ActorTable"; + +const MOCK_ACTORS: { [actorId: string]: ActorDetail } = { + ACTOR_1: { + actorId: "ACTOR_1", + jobId: "01000000", + address: { + rayletId: "426854e68e4225b3941deaf03c8dcfcb1daacc69a92711d370dbb0e1", + ipAddress: "172.31.11.178", + port: 10003, + workerId: "b8b276a03612644098ed7a929c3b0e50f5bde894eb0d8cab288fbb6d", + }, + state: "ALIVE", + numRestarts: "0", + name: "", + pid: 25321, + startTime: 1679010689148, + endTime: 0, + actorClass: "Counter", + exitDetail: "-", + requiredResources: {}, + placementGroupId: "123", + reprName: ",", + workerId: "b8b276a03612644098ed7a929c3b0e50f5bde894eb0d8cab288fbb6d", + numPendingTasks: 0, + taskQueueLength: 0, + numExecutedTasks: 0, + numInPlasma: 0, + numLocalObjects: 0, + numObjectRefsInScope: 0, + gpus: [], + processStats: { + cmdline: [], + cpuPercent: 0, + cpuTimes: { + user: 0, + system: 0, + childrenUser: 0, + childrenUystem: 0, + iowait: 0, + }, + createTime: 0, + memoryInfo: { + rss: 0, + vms: 0, + pfaults: 0, + pageins: 0, + }, + pid: 25321, + }, + }, + ACTOR_2: { + actorId: "ACTOR_2", + jobId: "01000000", + address: { + rayletId: "426854e68e4225b3941deaf03c8dcfcb1daacc69a92711d370dbb0e1", + ipAddress: "172.31.11.178", + port: 10003, + workerId: "b8b276a03612644098ed7a929c3b0e50f5bde894eb0d8cab288fbb6d", + }, + state: "DEAD", + numRestarts: "0", + name: "", + pid: 25322, + startTime: 1679010689150, + endTime: 0, + actorClass: "Counter", + exitDetail: "-", + requiredResources: {}, + placementGroupId: "123", + reprName: ",", + workerId: "b8b276a03612644098ed7a929c3b0e50f5bde894eb0d8cab288fbb6d", + numPendingTasks: 0, + taskQueueLength: 0, + numExecutedTasks: 0, + numInPlasma: 0, + numLocalObjects: 0, + numObjectRefsInScope: 0, + gpus: [], + processStats: { + cmdline: [], + cpuPercent: 0, + cpuTimes: { + user: 0, + system: 0, + childrenUser: 0, + childrenUystem: 0, + iowait: 0, + }, + createTime: 0, + memoryInfo: { + rss: 0, + vms: 0, + pfaults: 0, + pageins: 0, + }, + pid: 25322, + }, + }, +}; + +// For some reason these tests are really slow, so we need to increase the timeout +jest.setTimeout(20000); + +describe("ActorTable", () => { + it("renders a table of actors filtered by node ID", async () => { + const RUNNING_ACTORS = { + ...MOCK_ACTORS, + ACTOR_2: { + ...MOCK_ACTORS.ACTOR_2, + address: { + rayletId: "426854e68e4225b3941deaf03c8dcfcb1daacc69a92711d370dbb0e2", + ipAddress: "172.31.11.178", + port: 10003, + workerId: "b8b276a03612644098ed7a929c3b0e50f5bde894eb0d8cab288fbb6e", + }, + }, + }; + + const user = userEvent.setup(); + render(, { + wrapper: TEST_APP_WRAPPER, + }); + + const nodeIdFilter = screen.getByTestId("nodeIdFilter"); + const input = within(nodeIdFilter).getByRole("combobox"); + + // Filter by node ID of ACTOR_2 + await user.type( + input, + "426854e68e4225b3941deaf03c8dcfcb1daacc69a92711d370dbb0e2", + ); + await screen.findAllByText("Actor ID"); + + expect(screen.queryByText("ACTOR_1")).not.toBeInTheDocument(); + expect(screen.queryByText("ACTOR_2")).toBeInTheDocument(); + }); + + it("renders a table of actors sorted by state", () => { + const { getByRole } = render(, { + wrapper: TEST_APP_WRAPPER, + }); + + const actor1Row = getByRole("row", { + name: /ACTOR_1/, + }); + const actor2Row = getByRole("row", { + name: /ACTOR_2/, + }); + + expect(within(actor1Row).getByText("ACTOR_1")).toBeInTheDocument(); + expect(within(actor2Row).getByText("ACTOR_2")).toBeInTheDocument(); + + expect(actor1Row.compareDocumentPosition(actor2Row)).toBe( + Node.DOCUMENT_POSITION_FOLLOWING, + ); // actor2Row appear after actor1Row + }); + + it("renders a table of actors sorted by startTime desc when states are the same", () => { + const RUNNING_ACTORS = { + ...MOCK_ACTORS, + ACTOR_2: { + ...MOCK_ACTORS.ACTOR_2, + state: "ALIVE", + }, + }; + + const { getByRole } = render(, { + wrapper: TEST_APP_WRAPPER, + }); + const actor1Row = getByRole("row", { + name: /ACTOR_1/, + }); + const actor2Row = getByRole("row", { + name: /ACTOR_2/, + }); + + expect(within(actor1Row).getByText("ACTOR_1")).toBeInTheDocument(); + expect(within(actor2Row).getByText("ACTOR_2")).toBeInTheDocument(); + + expect(actor2Row.compareDocumentPosition(actor1Row)).toBe( + Node.DOCUMENT_POSITION_FOLLOWING, + ); // actor1Row appear after actor2Row + }); + + it("renders a table of actors sorted by startTime desc when states are the same, actor1 appears first", () => { + const RUNNING_ACTORS = { + ...MOCK_ACTORS, + ACTOR_2: { + ...MOCK_ACTORS.ACTOR_2, + state: "ALIVE", + startTime: 1679010689146, + }, + }; + + const { getByRole } = render(, { + wrapper: TEST_APP_WRAPPER, + }); + const actor1Row = getByRole("row", { + name: /ACTOR_1/, + }); + const actor2Row = getByRole("row", { + name: /ACTOR_2/, + }); + + expect(within(actor1Row).getByText("ACTOR_1")).toBeInTheDocument(); + expect(within(actor2Row).getByText("ACTOR_2")).toBeInTheDocument(); + + expect(actor1Row.compareDocumentPosition(actor2Row)).toBe( + Node.DOCUMENT_POSITION_FOLLOWING, + ); // actor1Row appear before actor2Row + }); + + it("renders a table of actors with same state sorted by resource utilization", async () => { + /* + When sorted by + - CPU: Actor 2 CPU > Actor 1 CPU --> Actor 2 row before Actor 1 row + - Used memory: Actor 1 memory > Actor 2 memory --> Actor 1 row before Actor 2 row + - Uptime: Actor 2 uptime < Actor 1 uptime --> Actor 2 row before Actor 1 row + - GPU Utilization: Actor 1 GPU > Actor 2 GPU --> Actor 1 row before Actor 2 row + - GRAM Utilization: Actor 2 GRAM > Actor 1 GRAM --> Actor 2 row before Actor 1 row + */ + const RUNNING_ACTORS = { + ...MOCK_ACTORS, + ACTOR_1: { + ...MOCK_ACTORS.ACTOR_1, + state: "ALIVE", + startTime: 0, + processStats: { + cmdline: [], + cpuPercent: 0, + cpuTimes: { + user: 0, + system: 0, + childrenUser: 0, + childrenUystem: 0, + iowait: 0, + }, + createTime: 0, + memoryInfo: { + rss: 10, + vms: 0, + pfaults: 0, + pageins: 0, + }, + pid: 25321, + }, + gpus: [ + { + uuid: "mock_gpu_uuid1", + index: 0, + name: "mock_gpu_name1", + utilizationGpu: 50, + memoryUsed: 0, + memoryTotal: 20, + processesPids: [{ pid: 25321, gpuMemoryUsage: 0 }], + }, + ], + }, + ACTOR_2: { + ...MOCK_ACTORS.ACTOR_2, + state: "ALIVE", + startTime: 1, + processStats: { + cmdline: [], + cpuPercent: 20, + cpuTimes: { + user: 0, + system: 0, + childrenUser: 0, + childrenUystem: 0, + iowait: 0, + }, + createTime: 0, + memoryInfo: { + rss: 0, + vms: 0, + pfaults: 0, + pageins: 0, + }, + pid: 25322, + }, + gpus: [ + { + uuid: "mock_gpu_uuid2", + index: 0, + name: "mock_gpu_name2", + utilizationGpu: 0, + memoryUsed: 10, + memoryTotal: 20, + processesPids: [{ pid: 25322, gpuMemoryUsage: 10 }], + }, + ], + }, + }; + + const user = userEvent.setup(); + render(, { + wrapper: TEST_APP_WRAPPER, + }); + + // Sort by CPU utilization + await user.click(screen.getByRole("combobox", { name: /Sort By/ })); + await user.click(screen.getByRole("option", { name: /CPU/ })); + const actor1CPURow = screen.getByRole("row", { + name: /ACTOR_1/, + }); + const actor2CPURow = screen.getByRole("row", { + name: /ACTOR_2/, + }); + expect(within(actor1CPURow).getByText("ACTOR_1")).toBeInTheDocument(); + expect(within(actor2CPURow).getByText("ACTOR_2")).toBeInTheDocument(); + expect(actor2CPURow.compareDocumentPosition(actor1CPURow)).toBe( + Node.DOCUMENT_POSITION_FOLLOWING, + ); // actor2Row appear before actor1Row + + // Sort by used memory + await user.click(screen.getByRole("combobox", { name: /Sort By/ })); + await user.click(screen.getByRole("option", { name: /Used Memory/ })); + const actor1MemRow = screen.getByRole("row", { + name: /ACTOR_1/, + }); + const actor2MemRow = screen.getByRole("row", { + name: /ACTOR_2/, + }); + expect(within(actor1MemRow).getByText("ACTOR_1")).toBeInTheDocument(); + expect(within(actor2MemRow).getByText("ACTOR_2")).toBeInTheDocument(); + expect(actor1MemRow.compareDocumentPosition(actor2MemRow)).toBe( + Node.DOCUMENT_POSITION_FOLLOWING, + ); // actor1Row appear before actor2Row + + // Sort by uptime + await user.click(screen.getByRole("combobox", { name: /Sort By/ })); + await user.click(screen.getByRole("option", { name: /Uptime/ })); + const actor1UptimeRow = screen.getByRole("row", { + name: /ACTOR_1/, + }); + const actor2UptimeRow = screen.getByRole("row", { + name: /ACTOR_2/, + }); + expect(within(actor1UptimeRow).getByText("ACTOR_1")).toBeInTheDocument(); + expect(within(actor2UptimeRow).getByText("ACTOR_2")).toBeInTheDocument(); + expect(actor2UptimeRow.compareDocumentPosition(actor1UptimeRow)).toBe( + Node.DOCUMENT_POSITION_FOLLOWING, + ); // actor2Row appear before actor1Row + + // Sort by GPU utilization + await user.click(screen.getByRole("combobox", { name: /Sort By/ })); + await user.click(screen.getByRole("option", { name: /GPU Utilization/ })); + const actor1GPURow = screen.getByRole("row", { + name: /ACTOR_1/, + }); + const actor2GPURow = screen.getByRole("row", { + name: /ACTOR_2/, + }); + expect(within(actor1GPURow).getByText("ACTOR_1")).toBeInTheDocument(); + expect(within(actor2GPURow).getByText("ACTOR_2")).toBeInTheDocument(); + expect(actor1GPURow.compareDocumentPosition(actor2GPURow)).toBe( + Node.DOCUMENT_POSITION_FOLLOWING, + ); // actor1Row appear before actor2Row + + // Sort by GRAM usage + await user.click(screen.getByRole("combobox", { name: /Sort By/ })); + await user.click(screen.getByRole("option", { name: /GRAM Usage/ })); + const actor1GRAMRow = screen.getByRole("row", { + name: /ACTOR_1/, + }); + const actor2GRAMRow = screen.getByRole("row", { + name: /ACTOR_2/, + }); + expect(within(actor1GRAMRow).getByText("ACTOR_1")).toBeInTheDocument(); + expect(within(actor2GRAMRow).getByText("ACTOR_2")).toBeInTheDocument(); + expect(actor2GRAMRow.compareDocumentPosition(actor1GRAMRow)).toBe( + Node.DOCUMENT_POSITION_FOLLOWING, + ); // actor2Row appear before actor1Row + }); +}); diff --git a/historyserver/dashboard/ray/client/src/components/ActorTable.tsx b/historyserver/dashboard/ray/client/src/components/ActorTable.tsx new file mode 100644 index 00000000000..d1bde03f0bf --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/ActorTable.tsx @@ -0,0 +1,736 @@ +import { SearchOutlined } from "@mui/icons-material"; +import { + Box, + InputAdornment, + Link, + Switch, + Table, + TableBody, + TableCell, + TableHead, + TableRow, + TextField, + TextFieldProps, + Tooltip, + Typography, +} from "@mui/material"; +import Autocomplete from "@mui/material/Autocomplete"; +import { orange } from "@mui/material/colors"; +import Pagination from "@mui/material/Pagination"; +import _ from "lodash"; +import React, { useMemo, useState } from "react"; +import { Link as RouterLink } from "react-router-dom"; +import { DurationText, getDurationVal } from "../common/DurationText"; +import { ActorLink, generateNodeLink } from "../common/links"; +import { + CpuProfilingLink, + CpuStackTraceLink, + MemoryProfilingButton, +} from "../common/ProfilingLink"; +import rowStyles from "../common/RowStyles"; +import { sliceToPage } from "../common/util"; +import { getSumGpuUtilization, WorkerGpuRow } from "../pages/node/GPUColumn"; +import { getSumGRAMUsage, WorkerGRAM } from "../pages/node/GRAMColumn"; +import { ActorDetail, ActorEnum } from "../type/actor"; +import { Worker } from "../type/worker"; +import { memoryConverter } from "../util/converter"; +import { useFilter, useSorter } from "../util/hook"; +import PercentageBar from "./PercentageBar"; +import { SearchSelect } from "./SearchComponent"; +import StateCounter from "./StatesCounter"; +import { StatusChip } from "./StatusChip"; +import { HelpInfo } from "./Tooltip"; +import RayletWorkerTable, { ExpandableTableRow } from "./WorkerTable"; + +export type ActorTableProps = { + actors: { [actorId: string]: ActorDetail }; + workers?: Worker[]; + jobId?: string | null; + filterToActorId?: string; + onFilterChange?: () => void; + detailPathPrefix?: string; +}; + +const SEQUENCE = { + FIRST: 1, + MIDDLE: 2, + LAST: 3, +}; + +type StateOrder = { + [key in ActorEnum]: number; +}; + +const stateOrder: StateOrder = { + [ActorEnum.ALIVE]: SEQUENCE.FIRST, + [ActorEnum.DEPENDENCIES_UNREADY]: SEQUENCE.MIDDLE, + [ActorEnum.PENDING_CREATION]: SEQUENCE.MIDDLE, + [ActorEnum.RESTARTING]: SEQUENCE.MIDDLE, + [ActorEnum.DEAD]: SEQUENCE.LAST, +}; +//type predicate for ActorEnum +const isActorEnum = (state: unknown): state is ActorEnum => { + return Object.values(ActorEnum).includes(state as ActorEnum); +}; + +const ActorTable = ({ + actors = {}, + workers = [], + jobId = null, + filterToActorId, + onFilterChange, + detailPathPrefix = "", +}: ActorTableProps) => { + const [pageNo, setPageNo] = useState(1); + const { changeFilter, filterFunc } = useFilter({ + overrideFilters: + filterToActorId !== undefined + ? [{ key: "actorId", val: filterToActorId }] + : undefined, + onFilterChange, + }); + const [actorIdFilterValue, setActorIdFilterValue] = useState(filterToActorId); + const [pageSize, setPageSize] = useState(10); + + const uptimeSorterKey = "fake_uptime_attr"; + const gpuUtilizationSorterKey = "fake_gpu_attr"; + const gramUsageSorterKey = "fake_gram_attr"; + + const defaultSorterKey = uptimeSorterKey; + const { sorterFunc, setOrderDesc, setSortKey, sorterKey, descVal } = + useSorter(defaultSorterKey); + + //We get a filtered and sorted actor list to render from prop actors + const sortedActors = useMemo(() => { + const aggregateUserSortKeys = [ + uptimeSorterKey, + gpuUtilizationSorterKey, + gramUsageSorterKey, + ]; + const actorList = Object.values(actors || {}).filter(filterFunc); + let actorsSortedUserKey = actorList; + if (aggregateUserSortKeys.includes(sorterKey)) { + // Uptime, GPU utilization, and GRAM usage are user specified sort keys but require an aggregate function + // over the actor attribute, so sorting with sortBy + actorsSortedUserKey = _.sortBy(actorList, (actor) => { + const descMultiplier = descVal ? 1 : -1; + switch (sorterKey) { + case uptimeSorterKey: + // Note: Sort by uptime only is re-sorted on re-render (not as uptime value changes) + const startTime = actor.startTime; + const endTime = actor.endTime; + // If actor doesn't have startTime, set uptime to infinity for sort so it appears at the bottom of + // the table by default + const uptime = + startTime && startTime > 0 + ? getDurationVal({ startTime, endTime }) + : Number.POSITIVE_INFINITY; + // Default sort for uptime should be ascending (default for all others is descending) + // so multiply by -1 + return uptime * -1 * descMultiplier; + case gpuUtilizationSorterKey: + const sumGpuUtilization = getSumGpuUtilization( + actor.pid, + actor.gpus, + ); + return sumGpuUtilization * descMultiplier; + case gramUsageSorterKey: + const sumGRAMUsage = getSumGRAMUsage(actor.pid, actor.gpus); + return sumGRAMUsage * descMultiplier; + default: + return 0; + } + }); + } else { + actorsSortedUserKey = actorList.sort(sorterFunc); + } + return _.sortBy(actorsSortedUserKey, (actor) => { + // Always show ALIVE actors at top + const actorOrder = isActorEnum(actor.state) ? stateOrder[actor.state] : 0; + return actorOrder; + }); + }, [actors, sorterKey, sorterFunc, filterFunc, descVal]); + + const { + items: list, + constrainedPage, + maxPage, + } = sliceToPage(sortedActors, pageNo, pageSize ?? 10); + + const columns = [ + { label: "" }, + { label: "ID" }, + { + label: "Class", + helpInfo: ( + + The class name of the actor. For example, the below actor has a class + name "Actor". +
+
+ @ray.remote +
+ class Actor: +
+  pass +
+
+ ), + }, + { + label: "Name", + helpInfo: ( + + The name of the actor given by the "name" argument. For example, this + actor's name is "unique_name". +
+
+ Actor.options(name="unique_name").remote() +
+ ), + }, + { + label: "Repr", + helpInfo: ( + + The repr name of the actor instance defined by __repr__. For example, + this actor will have repr "Actor1" +
+
+ @ray.remote +
+ class Actor: +
+  def __repr__(self): +
+   return "Actor1" +
+
+ ), + }, + { + label: "State", + helpInfo: ( + + The state of the actor. States are documented as a "ActorState" in the + "gcs.proto" file. + + ), + }, + { + label: "Actions", + helpInfo: ( + + A list of actions performable on this actor. +
+ - Log: view log messages of this actor. Only available if a node is + alive. +
+ - Stack Trace: Get a stacktrace of the alive actor. +
- CPU Flame Graph: Get a flamegraph for the next 5 seconds of an + alive actor. +
+ ), + }, + { label: "Uptime" }, + { label: "Job ID" }, + { label: "PID" }, + { label: "IP" }, + { label: "Node ID" }, + { + label: "CPU", + helpInfo: ( + + Hardware CPU usage of this Actor (from Worker Process). +
+
+ Node’s CPU usage is calculated against all CPU cores. Worker Process’s + CPU usage is calculated against 1 CPU core. As a result, the sum of + CPU usage from all Worker Processes is not equal to the Node’s CPU + usage. +
+ ), + }, + { + label: "Memory", + helpInfo: ( + + Actor's RAM usage (from Worker Process).
+
+ ), + }, + { + label: "GPU", + helpInfo: ( + + Usage of each GPU device. If no GPU usage is detected, here are the + potential root causes: +
+ 1. non-GPU Ray image is used on this node. Switch to a GPU Ray image + and try again.
+ 2. Non Nvidia GPUs are being used. Non Nvidia GPUs' utilizations are + not currently supported. +
+ 3. pynvml module raises an exception. +
+ ), + }, + { + label: "GRAM", + helpInfo: ( + + Actor's GRAM usage (from Worker Process).
+
+ ), + }, + { + label: "Restarted", + helpInfo: ( + + The total number of the count this actor has been restarted. + + ), + }, + { + label: "Placement group ID", + helpInfo: ( + + The ID of the placement group this actor is scheduled to. +
+
+ ), + }, + { + label: "Required resources", + helpInfo: ( + + The required Ray resources to start an actor. +
+ For example, this actor has GPU:1 required resources. +
+
+ @ray.remote(num_gpus=1) +
+ class Actor: +
+  pass +
+
+ ), + }, + { + label: "Exit detail", + helpInfo: ( + + The detail of an actor exit. Only available when an actor is dead. + + ), + }, + ]; + + return ( + + + e.state)), + )} + onInputChange={(_: any, value: string) => { + changeFilter("state", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + e.jobId)), + )} + onInputChange={(_: any, value: string) => { + changeFilter("jobId", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + e.address?.ipAddress)), + )} + onInputChange={(_: any, value: string) => { + changeFilter("address.ipAddress", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + e.address?.rayletId)), + )} + onInputChange={(_: any, value: string) => { + changeFilter("address.rayletId", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + { + changeFilter("pid", value.trim()); + }, + endAdornment: ( + + + + ), + }} + /> + + + { + changeFilter("name", value.trim()); + }, + endAdornment: ( + + + + ), + }} + /> + { + changeFilter("actorClass", value.trim()); + }, + endAdornment: ( + + + + ), + }} + /> + { + changeFilter("reprName", value.trim()); + }, + endAdornment: ( + + + + ), + }} + /> + { + changeFilter("actorId", value.trim()); + setActorIdFilterValue(value); + }, + endAdornment: ( + + + + ), + }} + /> + { + setPageSize(Math.min(Number(value), 500) || undefined); + }, + endAdornment: ( + Per Page + ), + }} + /> +
+ setSortKey(val)} + showAllOption={false} + defaultValue={defaultSorterKey} + /> +
+ + Reverse: + setOrderDesc(checked)} /> + +
+
+
+ setPageNo(num)} + count={maxPage} + /> +
+
+ +
+
+ + + + + {columns.map(({ label, helpInfo }) => ( + + + {label} + {helpInfo && ( + {helpInfo} + )} + + + ))} + + + + {list.map( + ({ + actorId, + actorClass, + reprName, + jobId, + placementGroupId, + pid, + address, + state, + name, + numRestarts, + startTime, + endTime, + exitDetail, + requiredResources, + gpus, + processStats, + mem, + }) => ( + + e.pid === pid && + address.ipAddress === e.coreWorkerStats[0].ipAddress, + ).length + } + expandComponent={ + + e.pid === pid && + address.ipAddress === e.coreWorkerStats[0].ipAddress, + )} + mini + /> + } + key={actorId} + > + + + + + + + + {actorClass} + {name ? name : "-"} + + {reprName ? reprName : "-"} + + + + + + + + Log + +
+ +
+ +
+ +
+
+ + {startTime && startTime > 0 ? ( + + ) : ( + "-" + )} + + {jobId} + {pid ? pid : "-"} + + {address?.ipAddress ? address?.ipAddress : "-"} + + + {address?.rayletId ? ( + + + + {address?.rayletId} + + + + ) : ( + "-" + )} + + + + {processStats?.cpuPercent} + + + + {mem && ( + + {memoryConverter(processStats?.memoryInfo.rss)}/ + {memoryConverter(mem[0])}( + {( + (processStats?.memoryInfo.rss / mem[0]) * + 100 + ).toFixed(1)} + %) + + )} + + + + + + + + 0 ? orange[500] : "inherit", + }} + > + {numRestarts} + + + + + {placementGroupId ? placementGroupId : "-"} + + + + + ( +
+ {key}: {val} +
+ ), + )} + arrow + > + + {Object.entries(requiredResources || {}) + .map(([key, val]) => `${key}: ${val}`) + .join(", ")} + +
+
+ + + {exitDetail} + + +
+ ), + )} +
+
+
+
+ ); +}; + +export default ActorTable; diff --git a/historyserver/dashboard/ray/client/src/components/AutoscalerStatusCards.tsx b/historyserver/dashboard/ray/client/src/components/AutoscalerStatusCards.tsx new file mode 100644 index 00000000000..544e44467a7 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/AutoscalerStatusCards.tsx @@ -0,0 +1,99 @@ +import { Box, Typography } from "@mui/material"; +import React from "react"; +import { RayStatusResp } from "../service/status"; + +const formatNodeStatus = (clusterStatus?: string) => { + // ==== auto scaling status + // Node status + // .... + // Resources + // .... + if (!clusterStatus) { + return "No cluster status."; + } + try { + // Try to parse the node status. + const sections = clusterStatus.split("Resources"); + return formatClusterStatus( + "Node Status", + sections[0].split("Node status")[1], + ); + } catch (e) { + return "No cluster status."; + } +}; + +const formatResourcesStatus = (clusterStatus?: string) => { + // ==== auto scaling status + // Node status + // .... + // Resources + // .... + if (!clusterStatus) { + return "No cluster status."; + } + try { + const sections = clusterStatus.split("Resources"); + return formatClusterStatus("Resource Status", sections[1]); + } catch (e) { + return "No cluster status."; + } +}; + +const formatClusterStatus = (title: string, clusterStatus: string) => { + const clusterStatusRows = clusterStatus.split("\n"); + + return ( +
+ + {title} + + {clusterStatusRows.map((i, key) => { + // Format the output. + // See format_info_string in util.py + if (i.startsWith("-----") || i.startsWith("=====") || i === "") { + // Ignore separators + return null; + } else if (i.endsWith(":")) { + return ( +
+ {i} +
+ ); + } else { + return
{i}
; + } + })} +
+ ); +}; + +type StatusCardProps = { + clusterStatus: RayStatusResp | undefined; +}; + +export const NodeStatusCard = ({ clusterStatus }: StatusCardProps) => { + return ( + + {formatNodeStatus(clusterStatus?.data.clusterStatus)} + + ); +}; + +export const ResourceStatusCard = ({ clusterStatus }: StatusCardProps) => { + return ( + + {formatResourcesStatus(clusterStatus?.data.clusterStatus)} + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/components/DataOverviewTable.tsx b/historyserver/dashboard/ray/client/src/components/DataOverviewTable.tsx new file mode 100644 index 00000000000..c52bdee0c28 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/DataOverviewTable.tsx @@ -0,0 +1,268 @@ +import { + Box, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + TextField, + TextFieldProps, + Typography, +} from "@mui/material"; +import Autocomplete from "@mui/material/Autocomplete"; +import Pagination from "@mui/material/Pagination"; +import React, { useState } from "react"; +import { RiArrowDownSLine, RiArrowRightSLine } from "react-icons/ri"; +import { formatDateFromTimeMs } from "../common/formatUtils"; +import { sliceToPage } from "../common/util"; +import { TaskProgressBar } from "../pages/job/TaskProgressBar"; +import { DatasetMetrics, OperatorMetrics } from "../type/data"; +import { memoryConverter } from "../util/converter"; +import { useFilter } from "../util/hook"; +import StateCounter from "./StatesCounter"; +import { StatusChip } from "./StatusChip"; +import { HelpInfo } from "./Tooltip"; + +const columns = [ + { label: "" }, // Empty column for dropdown icons + { label: "Dataset / Operator Name", align: "start" }, + { + label: "Blocks Outputted", + helpInfo: Blocks outputted by output operator., + }, + { label: "State", align: "center" }, + { label: "Rows Outputted" }, + { + label: "Memory Usage (current / max)", + helpInfo: ( + + Amount of object store memory used by a dataset. Includes spilled + objects. + + ), + }, + { + label: "Bytes Spilled", + helpInfo: ( + + Set + "ray.data.context.DataContext.get_current().enable_get_object_locations_for_metrics + = True" to collect spill stats. + + ), + }, + { + label: "Logical CPU Cores (current / max)", + align: "center", + }, + { + label: "Logical GPU Cores (current / max)", + align: "center", + }, + { label: "Start Time", align: "center" }, + { label: "End Time", align: "center" }, +]; + +const DataOverviewTable = ({ + datasets = [], +}: { + datasets: DatasetMetrics[]; +}) => { + const [pageNo, setPageNo] = useState(1); + const { changeFilter, filterFunc } = useFilter(); + const pageSize = 10; + const datasetList = datasets.filter(filterFunc); + const [expandedDatasets, setExpandedDatasets] = useState< + Record + >({}); + + const { + items: list, + constrainedPage, + maxPage, + } = sliceToPage(datasetList, pageNo, pageSize); + + return ( +
+
+ e.dataset)))} + onInputChange={(_: any, value: string) => { + changeFilter("dataset", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> +
+
+
+ setPageNo(num)} + count={maxPage} + /> +
+
+ +
+
+ + + + + {columns.map(({ label, helpInfo, align }) => ( + + + {label} + {helpInfo && ( + {helpInfo} + )} + + + ))} + + + + {list.map((dataset) => ( + { + const copy = { + ...expandedDatasets, + [dataset.dataset]: isExpanded, + }; + setExpandedDatasets(copy); + }} + key={dataset.dataset} + /> + ))} + +
+
+
+ ); +}; + +const DataRow = ({ + datasetMetrics, + operatorMetrics, + isExpanded, + setIsExpanded, +}: { + datasetMetrics?: DatasetMetrics; + operatorMetrics?: OperatorMetrics; + isExpanded?: boolean; + setIsExpanded?: CallableFunction; +}) => { + const isDatasetRow = datasetMetrics !== undefined; + const isOperatorRow = operatorMetrics !== undefined; + const data = datasetMetrics || operatorMetrics; + if ((isDatasetRow && isOperatorRow) || data === undefined) { + throw new Error( + "Exactly one of datasetMetrics or operatorMetrics musts be given.", + ); + } + return ( + + + {isDatasetRow && + setIsExpanded !== undefined && + (isExpanded ? ( + setIsExpanded(false)} + /> + ) : ( + setIsExpanded(true)} + /> + ))} + + + {isDatasetRow && datasetMetrics.dataset} + {isOperatorRow && operatorMetrics.operator} + + + + + + + + {data.ray_data_output_rows.max} + + {memoryConverter(Number(data.ray_data_current_bytes.value))}/ + {memoryConverter(Number(data.ray_data_current_bytes.max))} + + + {memoryConverter(Number(data.ray_data_spilled_bytes.max))} + + + {data.ray_data_cpu_usage_cores.value}/ + {data.ray_data_cpu_usage_cores.max} + + + {data.ray_data_gpu_usage_cores.value}/ + {data.ray_data_gpu_usage_cores.max} + + + {isDatasetRow && formatDateFromTimeMs(datasetMetrics.start_time * 1000)} + + + {isDatasetRow && + datasetMetrics.end_time && + formatDateFromTimeMs(datasetMetrics.end_time * 1000)} + + + ); +}; + +const DatasetTable = ({ + datasetMetrics, + isExpanded, + setIsExpanded, +}: { + datasetMetrics: DatasetMetrics; + isExpanded: boolean; + setIsExpanded: CallableFunction; +}) => { + const operatorRows = + isExpanded && + datasetMetrics.operators.map((operator) => ( + + )); + return ( + + + {operatorRows} + + ); +}; + +export default DataOverviewTable; diff --git a/historyserver/dashboard/ray/client/src/components/EventTable.tsx b/historyserver/dashboard/ray/client/src/components/EventTable.tsx new file mode 100644 index 00000000000..af0f7c54cd7 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/EventTable.tsx @@ -0,0 +1,348 @@ +import { SearchOutlined } from "@mui/icons-material"; +import { + Box, + Button, + Chip, + Grid, + InputAdornment, + LinearProgress, + TextField, + TextFieldProps, + Tooltip, +} from "@mui/material"; +import Autocomplete from "@mui/material/Autocomplete"; +import Pagination from "@mui/material/Pagination"; +import dayjs from "dayjs"; +import React, { useContext, useEffect, useState } from "react"; +import { Link } from "react-router-dom"; +import { GlobalContext } from "../App"; +import { sliceToPage } from "../common/util"; +import { getEvents, getGlobalEvents } from "../service/event"; +import { Event } from "../type/event"; +import { useFilter } from "../util/hook"; +import { StatusChip } from "./StatusChip"; + +type EventTableProps = { + job_id?: string; +}; + +const useEventTable = (props: EventTableProps) => { + const { job_id } = props; + const { nodeMap } = useContext(GlobalContext); + const [loading, setLoading] = useState(true); + const { changeFilter: _changeFilter, filterFunc } = useFilter(); + const [events, setEvents] = useState([]); + const [pagination, setPagination] = useState({ + pageNo: 1, + pageSize: 10, + total: 0, + }); + const changePage = (key: string, value: number) => { + setPagination({ ...pagination, [key]: value }); + }; + const realLen = events.filter(filterFunc).length; + const { pageSize } = pagination; + const changeFilter: typeof _changeFilter = (...params) => { + _changeFilter(...params); + setPagination({ + ...pagination, + pageNo: 1, + }); + }; + + useEffect(() => { + const getEvent = async () => { + try { + if (job_id) { + const rsp = await getEvents(job_id); + if (rsp?.data?.data?.events) { + setEvents( + rsp.data.data.events.sort( + (a, b) => Number(b.timestamp) - Number(a.timestamp), + ), + ); + } + } else { + const rsp = await getGlobalEvents(); + if (rsp?.data?.data?.events) { + setEvents( + Object.values(rsp.data.data.events) + .reduce((a, b) => a.concat(b)) + .sort((a, b) => Number(b.timestamp) - Number(a.timestamp)), + ); + } + } + } catch (e) { + } finally { + setLoading(false); + } + }; + + getEvent(); + }, [job_id]); + + useEffect(() => { + setPagination((p) => ({ + ...p, + total: Math.ceil(realLen / p.pageSize), + pageNo: 1, + })); + }, [realLen, pageSize]); + + return { + events: sliceToPage( + events.filter(filterFunc), + pagination.pageNo, + pagination.pageSize, + ).items, + changeFilter, + pagination, + changePage, + labelOptions: Array.from(new Set(events.map((e) => e.label))), + hostOptions: Array.from( + new Set(events.map((e) => e.sourceHostname || e.hostName)), + ), + sourceOptions: Array.from(new Set(events.map((e) => e.sourceType))), + severityOptions: Array.from(new Set(events.map((e) => e.severity))), + loading, + reverseEvents: () => { + setEvents([...events.reverse()]); + }, + nodeMap, + }; +}; + +const EventTable = (props: EventTableProps) => { + const { + events, + changeFilter, + pagination, + changePage, + labelOptions, + hostOptions, + sourceOptions, + severityOptions, + loading, + reverseEvents, + nodeMap, + } = useEventTable(props); + + if (loading) { + return ; + } + + return ( +
+ + { + changeFilter("label", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + { + changeFilter("sourceHostname", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + { + changeFilter("sourceType", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + { + changeFilter("severity", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + { + changeFilter("message", value.trim()); + }, + endAdornment: ( + + + + ), + }} + /> + { + changePage("pageSize", Math.min(Number(value), 500) || 10); + }, + endAdornment: ( + Per Page + ), + }} + /> + + +
+ , value: number) => { + changePage("pageNo", value); + }} + /> +
+ + {!events.length + ? "No Events Yet." + : events.map( + ({ + label, + message, + timestamp, + timeStamp, + sourceType, + sourceHostname, + hostName, + sourcePid, + pid, + eventId, + jobId, + jobName, + nodeId, + severity, + customFields, + }) => { + const realTimestamp = + timeStamp || + dayjs(Math.floor(timestamp * 1000)).format( + "YYYY-MM-DD HH:mm:ss", + ); + const hostname = sourceHostname || hostName; + const realPid = pid || sourcePid; + return ( + ({ + color: theme.palette.text.secondary, + fontSize: 12, + })} + key={eventId} + > + + + + + {realTimestamp} + {customFields && ( + + + {JSON.stringify(customFields, null, 2)} + + } + > + + + + )} + + + + severity: {severity} + + + source: {sourceType} + + + hostname:{" "} + {nodeMap[hostname] ? ( + + {hostname} + + ) : ( + hostname + )} + + + pid: {realPid} + + {jobId && ( + + jobId: {jobId} + + )} + {jobName && ( + + jobId: {jobName} + + )} + {eventId && ( + + eventId: {eventId} + + )} + {nodeId && ( + + nodeId: {nodeId} + + )} + +
{message}
+
+ ); + }, + )} +
+
+ , value: number) => { + changePage("pageNo", value); + }} + /> +
+
+ ); +}; + +export default EventTable; diff --git a/historyserver/dashboard/ray/client/src/components/ListItemCard.tsx b/historyserver/dashboard/ray/client/src/components/ListItemCard.tsx new file mode 100644 index 00000000000..d9cb9218471 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/ListItemCard.tsx @@ -0,0 +1,133 @@ +import { Box, Link, SxProps, Theme, Typography } from "@mui/material"; +import React, { ReactNode } from "react"; +import { Link as RouterLink } from "react-router-dom"; +import { ClassNameProps } from "../common/props"; +import { + LinkWithArrow, + OverviewCard, +} from "../pages/overview/cards/OverviewCard"; + +type ListItemCardProps = { + headerTitle: string; + items: ListItemProps[]; + emptyListText: string; + footerText: string; + footerLink: string; + sx?: SxProps; +} & ClassNameProps; + +type ListItemProps = { + title: string | undefined; + subtitle: string; + link: string | undefined; + icon: ReactNode; + sx?: SxProps; +} & ClassNameProps; + +export const ListItemCard = ({ + className, + headerTitle, + items, + emptyListText: itemEmptyTip, + footerText, + footerLink, + sx, +}: ListItemCardProps) => { + return ( + + {headerTitle} + + {items.map((item: ListItemProps) => ( + + ))} + {items.length === 0 && ( + {itemEmptyTip} + )} + + + + ); +}; + +const listItemStyles = { + root: { + display: "flex", + flexDirection: "row", + flexWrap: "nowrap", + alignItems: "center", + textDecoration: "none", + }, +}; + +const ListItem = ({ + icon, + title, + subtitle, + className, + link, + sx, +}: ListItemProps) => { + const cardContent = ( + + {icon} + ({ + flex: "1 1 auto", + width: `calc(100% - calc(${theme.spacing(1)} + 20px))`, + })} + > + + {title} + + + {subtitle} + + + + ); + return ( + + {link !== undefined ? ( + + {cardContent} + + ) : ( + {cardContent} + )} + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/components/Loading.tsx b/historyserver/dashboard/ray/client/src/components/Loading.tsx new file mode 100644 index 00000000000..bbb16a8db9b --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/Loading.tsx @@ -0,0 +1,7 @@ +import { CircularProgress } from "@mui/material"; +import React from "react"; + +const Loading = ({ loading }: { loading: boolean }) => + loading ? : null; + +export default Loading; diff --git a/historyserver/dashboard/ray/client/src/components/LogView/LogVirtualView.tsx b/historyserver/dashboard/ray/client/src/components/LogView/LogVirtualView.tsx new file mode 100644 index 00000000000..2d860f1e877 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/LogView/LogVirtualView.tsx @@ -0,0 +1,382 @@ +import { Box, Typography } from "@mui/material"; +import dayjs from "dayjs"; +import prolog from "highlight.js/lib/languages/prolog"; +import { lowlight } from "lowlight"; +import React, { + MutableRefObject, + useCallback, + useEffect, + useRef, + useState, +} from "react"; +import { FixedSizeList as List } from "react-window"; +import DialogWithTitle from "../../common/DialogWithTitle"; +import "./darcula.css"; +import "./github.css"; +import "./index.css"; +import { MAX_LINES_FOR_LOGS } from "../../service/log"; + +lowlight.registerLanguage("prolog", prolog); + +const uniqueKeySelector = () => Math.random().toString(16).slice(-8); + +const timeReg = + /(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)\s+([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]/; + +const value2react = ( + { type, tagName, properties, children, value = "" }: any, + key: string, + keywords = "", +) => { + switch (type) { + case "element": + return React.createElement( + tagName, + { + className: properties.className[0], + key: `${key}line${uniqueKeySelector()}`, + }, + children.map((e: any, i: number) => + value2react(e, `${key}-${i}`, keywords), + ), + ); + case "text": + if (keywords && value.includes(keywords)) { + const afterChildren = []; + const vals = value.split(keywords); + let tmp = vals.shift(); + if (!tmp) { + return React.createElement( + "span", + { className: "find-kws" }, + keywords, + ); + } + while (typeof tmp === "string") { + if (tmp !== "") { + afterChildren.push(tmp); + } else { + afterChildren.push( + React.createElement("span", { className: "find-kws" }, keywords), + ); + } + + tmp = vals.shift(); + if (tmp) { + afterChildren.push( + React.createElement("span", { className: "find-kws" }, keywords), + ); + } + } + return afterChildren; + } + return value; + default: + return []; + } +}; + +export type LogVirtualViewProps = { + content: string; + width?: number; + height?: number; + fontSize?: number; + theme?: "light" | "dark"; + language?: string; + focusLine?: number; + keywords?: string; + style?: { [key: string]: string | number }; + listRef?: MutableRefObject; + onScrollBottom?: (event: Event) => void; + revert?: boolean; + startTime?: string; + endTime?: string; +}; + +type LogLineDetailDialogProps = { + formattedLogLine: string | null; + message: string; + onClose: () => void; +}; + +const LogLineDetailDialog = ({ + formattedLogLine, + message, + onClose, +}: LogLineDetailDialogProps) => { + return ( + + + + {formattedLogLine !== null && ( + + + Raw log line + + ({ + padding: 1, + bgcolor: "#EEEEEE", + borderRadius: 1, + border: `1px solid ${theme.palette.divider}`, + marginBottom: 2, + })} + > + + {formattedLogLine} + + + + )} + + Formatted message + + ({ + padding: 1, + bgcolor: "#EEEEEE", + borderRadius: 1, + border: `1px solid ${theme.palette.divider}`, + })} + > + + {message} + + + + + + ); +}; + +const LogVirtualView: React.FC = ({ + content, + width = "100%", + height, + fontSize = 12, + theme = "light", + keywords = "", + language = "dos", + focusLine = 1, + style = {}, + listRef, + onScrollBottom, + revert = false, + startTime, + endTime, +}) => { + const [logs, setLogs] = useState<{ i: number; origin: string }[]>([]); + const total = logs.length; + const timmer = useRef>(); + const el = useRef(null); + const outter = useRef(null); + if (listRef) { + listRef.current = outter.current; + } + const [selectedLogLine, setSelectedLogLine] = + useState<[string | null, string]>(); + const handleLogLineClick = useCallback( + (logLine: string | null, message: string) => { + setSelectedLogLine([logLine, message]); + }, + [], + ); + + const itemRenderer = ({ index, style }: { index: number; style: any }) => { + const { i, origin } = logs[revert ? logs.length - 1 - index : index]; + + let message = origin; + let formattedLogLine: string | null = null; + try { + const parsedOrigin = JSON.parse(origin); + // Iff the parsed origin has a message field, use it as the message. + if (parsedOrigin.message) { + message = parsedOrigin.message; + // If levelname exist on the structured logs, put it in front of the message. + if (parsedOrigin.levelname) { + message = `${parsedOrigin.levelname} ${message}`; + } + // If asctime exist on the structured logs, use it as the prefix of the message. + if (parsedOrigin.asctime) { + message = `${parsedOrigin.asctime}\t${message}`; + } + } + formattedLogLine = JSON.stringify(parsedOrigin, null, 2); + } catch (e) { + // Keep the `origin` as message, if json parsing failed. + // If formattedLogLine is null, then the log line is not JSON and we will + // not show the raw json dialog pop up. + } + + return ( + { + if ((window.getSelection()?.toString().length ?? 0) === 0) { + // Only open if user is not selecting text + handleLogLineClick(formattedLogLine, message); + } + }} + > + {lowlight + .highlight(language, message) + .children.map((v) => value2react(v, index.toString(), keywords))} +
+
+ ); + }; + + useEffect(() => { + const originContent = content.split("\n"); + if (timmer.current) { + clearTimeout(timmer.current); + } + timmer.current = setTimeout(() => { + setLogs( + originContent + .map((e, i) => ({ + i, + origin: e, + time: (e?.match(timeReg) || [""])[0], + })) + .filter((e) => { + let bool = e.origin.includes(keywords); + if ( + e.time && + startTime && + !dayjs(e.time).isAfter(dayjs(startTime)) + ) { + bool = false; + } + if (e.time && endTime && !dayjs(e.time).isBefore(dayjs(endTime))) { + bool = false; + } + return bool; + }) + .map((e) => ({ + ...e, + })), + ); + }, 500); + }, [content, keywords, language, startTime, endTime]); + + useEffect(() => { + if (el.current) { + el.current?.scrollTo((focusLine - 1) * (fontSize + 6)); + } + }, [focusLine, fontSize]); + + useEffect(() => { + let outterCurrentValue: any = null; + if (outter.current) { + const scrollFunc = (event: any) => { + const { target } = event; + if ( + target && + target.scrollTop + target.clientHeight === target.scrollHeight + ) { + if (onScrollBottom) { + onScrollBottom(event); + } + } + outterCurrentValue = outter.current; + }; + outter.current.addEventListener("scroll", scrollFunc); + return () => { + if (outterCurrentValue) { + outterCurrentValue.removeEventListener("scroll", scrollFunc); + } + }; + } + }, [onScrollBottom]); + + return ( +
+ {logs && logs.length > MAX_LINES_FOR_LOGS && ( + theme.palette.error.main }}> + [Truncation warning] This log has been truncated and only the latest{" "} + {MAX_LINES_FOR_LOGS} lines are displayed. Click "Download" button + above to see the full log + + )} + + {itemRenderer} + + {selectedLogLine && ( + { + setSelectedLogLine(undefined); + }} + /> + )} +
+ ); +}; + +export default LogVirtualView; diff --git a/historyserver/dashboard/ray/client/src/components/LogView/darcula.css b/historyserver/dashboard/ray/client/src/components/LogView/darcula.css new file mode 100644 index 00000000000..8564bf89570 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/LogView/darcula.css @@ -0,0 +1,59 @@ +/* +Dracula Theme v1.2.0 +https://github.com/zenorocha/dracula-theme +Copyright 2015, All rights reserved +Code licensed under the MIT license +http://zenorocha.mit-license.org +@author Éverton Ribeiro +@author Zeno Rocha +*/ +.hljs-dark { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #f8f8f2; +} +.hljs-dark .hljs-number, +.hljs-dark .hljs-keyword, +.hljs-dark .hljs-selector-tag, +.hljs-dark .hljs-literal, +.hljs-dark .hljs-section, +.hljs-dark .hljs-link { + color: #8be9fd; +} +.hljs-dark .hljs-function .hljs-keyword { + color: #ff79c6; +} +.hljs-dark .hljs-string, +.hljs-dark .hljs-title, +.hljs-dark .hljs-name, +.hljs-dark .hljs-type, +.hljs-dark .hljs-attribute, +.hljs-dark .hljs-symbol, +.hljs-dark .hljs-bullet, +.hljs-dark .hljs-addition, +.hljs-dark .hljs-variable, +.hljs-dark .hljs-template-tag, +.hljs-dark .hljs-template-variable { + color: #f1fa8c; +} +.hljs-dark .hljs-comment, +.hljs-dark .hljs-quote, +.hljs-dark .hljs-deletion, +.hljs-dark .hljs-meta { + color: #6272a4; +} +.hljs-dark .hljs-keyword, +.hljs-dark .hljs-selector-tag, +.hljs-dark .hljs-literal, +.hljs-dark .hljs-title, +.hljs-dark .hljs-section, +.hljs-dark .hljs-doctag, +.hljs-dark .hljs-type, +.hljs-dark .hljs-name, +.hljs-dark .hljs-strong { + font-weight: bold; +} +.hljs-dark .hljs-emphasis { + font-style: italic; +} diff --git a/historyserver/dashboard/ray/client/src/components/LogView/github.css b/historyserver/dashboard/ray/client/src/components/LogView/github.css new file mode 100644 index 00000000000..ca16d3f7393 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/LogView/github.css @@ -0,0 +1,96 @@ +/* +github.com style (c) Vasily Polovnyov +*/ + +.hljs-light { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; +} + +.hljs-light .hljs-comment, +.hljs-light .hljs-quote { + color: #998; + font-style: italic; +} + +.hljs-light .hljs-keyword, +.hljs-light .hljs-selector-tag, +.hljs-light .hljs-subst { + color: #333; + font-weight: bold; +} + +.hljs-light .hljs-number, +.hljs-light .hljs-literal, +.hljs-light .hljs-variable, +.hljs-light .hljs-template-variable, +.hljs-light .hljs-tag .hljs-attr { + color: #008080; +} + +.hljs-light .hljs-string, +.hljs-light .hljs-doctag { + color: #d14; +} + +.hljs-light .hljs-title, +.hljs-light .hljs-section, +.hljs-light .hljs-selector-id { + color: #900; + font-weight: bold; +} + +.hljs-light .hljs-subst { + font-weight: normal; +} + +.hljs-light .hljs-type, +.hljs-light .hljs-class .hljs-title { + color: #458; + font-weight: bold; +} + +.hljs-light .hljs-tag, +.hljs-light .hljs-name, +.hljs-light .hljs-attribute { + color: #000080; + font-weight: normal; +} + +.hljs-light .hljs-regexp, +.hljs-light .hljs-link { + color: #009926; +} + +.hljs-light .hljs-symbol, +.hljs-light .hljs-bullet { + color: #990073; +} + +.hljs-light .hljs-built_in, +.hljs-light .hljs-builtin-name { + color: #0086b3; +} + +.hljs-light .hljs-meta { + color: #999; + font-weight: bold; +} + +.hljs-light .hljs-deletion { + background: #fdd; +} + +.hljs-light .hljs-addition { + background: #dfd; +} + +.hljs-light .hljs-emphasis { + font-style: italic; +} + +.hljs-light .hljs-strong { + font-weight: bold; +} diff --git a/historyserver/dashboard/ray/client/src/components/LogView/index.css b/historyserver/dashboard/ray/client/src/components/LogView/index.css new file mode 100644 index 00000000000..32e5f884f2b --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/LogView/index.css @@ -0,0 +1,3 @@ +span.find-kws { + background-color: #ffd800; +} diff --git a/historyserver/dashboard/ray/client/src/components/MetadataSection/MetadataSection.component.test.tsx b/historyserver/dashboard/ray/client/src/components/MetadataSection/MetadataSection.component.test.tsx new file mode 100644 index 00000000000..5833ce76bc6 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/MetadataSection/MetadataSection.component.test.tsx @@ -0,0 +1,103 @@ +import { render, screen } from "@testing-library/react"; +import React from "react"; + +import { TEST_APP_WRAPPER } from "../../util/test-utils"; +import { MetadataContentField } from "./MetadataSection"; + +const CONTENT_VALUE = "test_string"; +const LINK_VALUE = "https://docs.ray.com/"; +const COPYABLE_VALUE = "Copyable value"; +const COPY_BUTTON_LABEL = "copy"; + +describe("MetadataContentField", () => { + it("renders the content string", () => { + expect.assertions(4); + + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + + expect(screen.getByText(CONTENT_VALUE)).toBeInTheDocument(); + expect(screen.getByText(CONTENT_VALUE)).not.toHaveAttribute("href"); + expect(screen.queryByLabelText(COPY_BUTTON_LABEL)).not.toBeInTheDocument(); + expect( + screen.getByTestId("metadata-content-for-test-label"), + ).toBeInTheDocument(); + }); + + it("renders the content string if link is undefined", () => { + expect.assertions(4); + + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + + expect(screen.getByText(CONTENT_VALUE)).toBeInTheDocument(); + expect(screen.getByText(CONTENT_VALUE)).not.toHaveAttribute("href"); + expect(screen.queryByLabelText(COPY_BUTTON_LABEL)).not.toBeInTheDocument(); + expect( + screen.getByTestId("metadata-content-for-test-label"), + ).toBeInTheDocument(); + }); + + it("renders the content string with label", () => { + expect.assertions(4); + + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + + expect(screen.getByText(CONTENT_VALUE)).toBeInTheDocument(); + expect(screen.getByText(CONTENT_VALUE)).toHaveAttribute("href", LINK_VALUE); + expect(screen.queryByLabelText(COPY_BUTTON_LABEL)).not.toBeInTheDocument(); + expect( + screen.getByTestId("metadata-content-for-test-label"), + ).toBeInTheDocument(); + }); + + it("renders the content string with copyable value", () => { + expect.assertions(4); + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + expect(screen.getByText(CONTENT_VALUE)).toBeInTheDocument(); + expect(screen.getByText(CONTENT_VALUE)).not.toHaveAttribute("href"); + expect(screen.getByLabelText(COPY_BUTTON_LABEL)).toBeInTheDocument(); + expect( + screen.getByTestId("metadata-content-for-test-label"), + ).toBeInTheDocument(); + }); + + it("renders the content string with a JSX element", () => { + expect.assertions(3); + + const CUSTOM_TEST_ID = "custom-test-id"; + const customElement =

Test

; + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + + expect(screen.queryByLabelText(COPY_BUTTON_LABEL)).not.toBeInTheDocument(); + expect(screen.getByTestId(CUSTOM_TEST_ID)).toBeInTheDocument(); + expect( + screen.getByTestId("metadata-content-for-test-label"), + ).toBeInTheDocument(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/components/MetadataSection/MetadataSection.tsx b/historyserver/dashboard/ray/client/src/components/MetadataSection/MetadataSection.tsx new file mode 100644 index 00000000000..21a5c020e3a --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/MetadataSection/MetadataSection.tsx @@ -0,0 +1,193 @@ +import { Box, IconButton, Link, Tooltip, Typography } from "@mui/material"; +import copy from "copy-to-clipboard"; +import React, { useState } from "react"; +import { RiFileCopyLine } from "react-icons/ri"; +import { Link as RouterLink } from "react-router-dom"; +import { Section } from "../../common/Section"; +import { HelpInfo } from "../Tooltip"; + +export type StringOnlyMetadataContent = { + readonly value: string; +}; + +type LinkableMetadataContent = StringOnlyMetadataContent & { + readonly link: string; +}; + +type CopyableMetadataContent = StringOnlyMetadataContent & { + /** + * The "copyable value" may be different from "value" + * in case we want to render a more readable text. + */ + readonly copyableValue: string; +}; + +type CopyAndLinkableMetadataContent = LinkableMetadataContent & + CopyableMetadataContent; + +export type Metadata = { + readonly label: string; + readonly labelTooltip?: string | JSX.Element; + + // If content is undefined, we display "-" as the placeholder. + readonly content?: + | StringOnlyMetadataContent + | LinkableMetadataContent + | CopyableMetadataContent + | CopyAndLinkableMetadataContent + | JSX.Element; + + /** + * This flag will determine this metadata field will show in the UI. + * Defaults to true. + */ + readonly isAvailable?: boolean; +}; + +const styles = { + contentContainer: { + display: "flex", + alignItems: "center", + }, + content: { + display: "block", + textOverflow: "ellipsis", + overflow: "hidden", + whiteSpace: "nowrap", + }, +}; + +/** + * We style the metadata content based on the type supplied. + * + * A default style will be applied if content is MetadataContent type. + * If content is undefined, we display "-" as the placeholder. + */ +export const MetadataContentField: React.FC<{ + content: Metadata["content"]; + label: string; +}> = ({ content, label }) => { + const [copyIconClicked, setCopyIconClicked] = useState(false); + + const copyElement = content && "copyableValue" in content && ( + + { + setCopyIconClicked(true); + copy(content.copyableValue); + }} + // Set up mouse events to avoid text changing while tooltip is visible + onMouseEnter={() => setCopyIconClicked(false)} + onMouseLeave={() => setTimeout(() => setCopyIconClicked(false), 333)} + size="small" + sx={{ color: "black", marginLeft: 0.5 }} + > + + + + ); + + if (content === undefined || "value" in content) { + return content === undefined || + !("link" in content) || + content.link === undefined ? ( + + + {content?.value ?? "-"} + + {copyElement} + + ) : content.link.startsWith("http") ? ( + + + {content.value} + + {copyElement} + + ) : ( + + + {content.value} + + {copyElement} + + ); + } + return
{content}
; +}; + +/** + * Renders the metadata list in a column format. + */ +const MetadataList: React.FC<{ + metadataList: Metadata[]; +}> = ({ metadataList }) => { + const filteredMetadataList = metadataList.filter( + ({ isAvailable }) => isAvailable ?? true, + ); + return ( + + {filteredMetadataList.map(({ label, labelTooltip, content }, idx) => ( + + + theme.palette.text.secondary }} + variant="body2" + > + {label} + + {labelTooltip && ( + {labelTooltip} + )} + + + + ))} + + ); +}; + +/** + * Renders the Metadata UI with the header and metadata in a 3-column format. + */ +export const MetadataSection = ({ + header, + metadataList, + footer, +}: { + header?: string; + metadataList: Metadata[]; + footer?: JSX.Element; +}) => { + return ( +
+ + {footer} +
+ ); +}; diff --git a/historyserver/dashboard/ray/client/src/components/MetadataSection/index.ts b/historyserver/dashboard/ray/client/src/components/MetadataSection/index.ts new file mode 100644 index 00000000000..bb37ba4269a --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/MetadataSection/index.ts @@ -0,0 +1 @@ +export * from "./MetadataSection"; diff --git a/historyserver/dashboard/ray/client/src/components/PercentageBar.tsx b/historyserver/dashboard/ray/client/src/components/PercentageBar.tsx new file mode 100644 index 00000000000..3f7839c1fc8 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/PercentageBar.tsx @@ -0,0 +1,56 @@ +import { Box } from "@mui/material"; +import React, { PropsWithChildren } from "react"; + +const PercentageBar = ( + props: PropsWithChildren<{ num: number; total: number }>, +) => { + const { num, total } = props; + const per = Math.round((num / total) * 100); + + return ( + + ({ + background: theme.palette.background.paper, + position: "absolute", + right: 0, + height: 18, + transition: "0.5s width", + borderRadius: "2px", + borderTopLeftRadius: 0, + borderBottomLeftRadius: 0, + border: "2px solid transparent", + boxSizing: "border-box", + width: `${Math.min(Math.max(0, 100 - per), 100)}%`, + })} + /> + ({ + fontSize: 12, + zIndex: 2, + position: "relative", + color: theme.palette.text.primary, + width: "100%", + textAlign: "center", + whiteSpace: "nowrap", + })} + > + {props.children} + + + ); +}; + +export default PercentageBar; diff --git a/historyserver/dashboard/ray/client/src/components/PlacementGroupTable.tsx b/historyserver/dashboard/ray/client/src/components/PlacementGroupTable.tsx new file mode 100644 index 00000000000..a686f52aeef --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/PlacementGroupTable.tsx @@ -0,0 +1,212 @@ +import { + Box, + InputAdornment, + SxProps, + Table, + TableBody, + TableCell, + TableHead, + TableRow, + TextField, + TextFieldProps, + Theme, + Tooltip, +} from "@mui/material"; +import Autocomplete from "@mui/material/Autocomplete"; +import Pagination from "@mui/material/Pagination"; +import React, { useState } from "react"; +import rowStyles from "../common/RowStyles"; +import { sliceToPage } from "../common/util"; +import { Bundle, PlacementGroup } from "../type/placementGroup"; +import { useFilter } from "../util/hook"; +import StateCounter from "./StatesCounter"; +import { StatusChip } from "./StatusChip"; + +const BundleResourceRequirements = ({ + bundles, + sx, +}: { + bundles: Bundle[]; + sx?: SxProps; +}) => { + return ( + + {bundles.map(({ unit_resources }, index) => { + return `{${Object.entries(unit_resources || {}) + .map(([key, val]) => `${key}: ${val}`) + .join(", ")}}, `; + })} + + ); +}; + +const PlacementGroupTable = ({ + placementGroups = [], + jobId = null, +}: { + placementGroups: PlacementGroup[]; + jobId?: string | null; +}) => { + const [pageNo, setPageNo] = useState(1); + const { changeFilter, filterFunc } = useFilter(); + const [pageSize, setPageSize] = useState(10); + const placementGroupList = placementGroups.filter(filterFunc); + const { + items: list, + constrainedPage, + maxPage, + } = sliceToPage(placementGroupList, pageNo, pageSize); + + const columns = [ + { label: "ID" }, + { label: "Name" }, + { label: "Job Id" }, + { label: "State" }, + { label: "Reserved Resources" }, + { label: "Scheduling Detail" }, + ]; + + return ( +
+
+ e.placement_group_id)), + )} + onInputChange={(_: any, value: string) => { + changeFilter("placement_group_id", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + e.state)))} + onInputChange={(_: any, value: string) => { + changeFilter("state", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + e.creator_job_id)), + )} + onInputChange={(_: any, value: string) => { + changeFilter("creator_job_id", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + e.name)))} + onInputChange={(_: any, value: string) => { + changeFilter("name", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + { + setPageSize(Math.min(Number(value), 500) || 10); + }, + endAdornment: ( + Per Page + ), + }} + /> +
+
+
+ setPageNo(num)} + count={maxPage} + /> +
+
+ +
+
+ + + + + {columns.map(({ label }) => ( + + + {label} + + + ))} + + + + {list.map( + ({ + placement_group_id, + name, + creator_job_id, + state, + stats, + bundles, + }) => ( + + + + {placement_group_id} + + + {name ? name : "-"} + {creator_job_id} + + + + + } + arrow + > + + + + + {stats ? stats.scheduling_state : "-"} + + + ), + )} + +
+
+
+ ); +}; + +export default PlacementGroupTable; diff --git a/historyserver/dashboard/ray/client/src/components/ProgressBar/ProgressBar.component.test.tsx b/historyserver/dashboard/ray/client/src/components/ProgressBar/ProgressBar.component.test.tsx new file mode 100644 index 00000000000..7d8facb741e --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/ProgressBar/ProgressBar.component.test.tsx @@ -0,0 +1,38 @@ +import { render, screen } from "@testing-library/react"; +import React from "react"; +import { TEST_APP_WRAPPER } from "../../util/test-utils"; +import { ProgressBar } from "./ProgressBar"; + +describe("ProgressBar", () => { + it("renders", async () => { + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + + await screen.findByText(/error/); + expect(screen.getByText(/in progress/)).toBeInTheDocument(); + expect(screen.getByText(/success/)).toBeInTheDocument(); + + const segments = screen.getAllByTestId("progress-bar-segment"); + expect(segments).toHaveLength(3); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/components/ProgressBar/ProgressBar.tsx b/historyserver/dashboard/ray/client/src/components/ProgressBar/ProgressBar.tsx new file mode 100644 index 00000000000..2e23e01cdc6 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/ProgressBar/ProgressBar.tsx @@ -0,0 +1,326 @@ +import { Box, TooltipProps, Typography } from "@mui/material"; +import React from "react"; +import { RiArrowDownSLine, RiArrowRightSLine } from "react-icons/ri"; +import { HelpInfo, StyledTooltip } from "../Tooltip"; + +export type ProgressBarSegment = { + /** + * Number of items in this segment + */ + value: number; + /** + * Name of this segment + */ + label: string; + /** + * Text to show to explain the segment better. + */ + hint?: string; + /** + * A CSS color used to represent the segment. + */ + color: string; +}; + +export type ProgressBarProps = { + /** + * The different segments to the progress bar. + * The order determines the order of which we show the segments on the page. + * Ex: [Succeeded: 5, Running: 2, Pending: 10] + */ + progress: ProgressBarSegment[]; + /** + * The expected total number of items. If not provided, we calculate the total + * from the sum of the segments. + * + * If the sum of the values from each segment is less than total, then we create + * an additional segment for unaccounted items. This additional segment is placed + * at the end. + */ + total?: number; + /** + * Label for unaccounted for items i.e. items that are not part of a `progress` segment. + */ + unaccountedLabel?: string; + /** + * Whether a legend is shown. Default to true. + */ + showLegend?: boolean; + /** + * Whether to show the a legend as a tooltip. + */ + showTooltip?: boolean; + /** + * Whether to show the total progress to the right of the progress bar. + * Example: 5 / 20 + * This should be set to the number that should be shown in the left side of the fraction. + * If this is undefined, don't show it. + */ + showTotalProgress?: number; + /** + * If true, we show an expanded icon to the left of the progress bar. + * If false, we show an unexpanded icon to the left of the progress bar. + * If undefined, we don't show any icon. + */ + expanded?: boolean; + onClick?: () => void; + /** + * Controls that can be put to the right of the legend. + */ + controls?: JSX.Element; +}; + +export const ProgressBar = ({ + progress, + total, + unaccountedLabel, + showLegend = true, + showTooltip = false, + showTotalProgress, + expanded, + onClick, + controls, +}: ProgressBarProps) => { + const segmentTotal = progress.reduce((acc, { value }) => acc + value, 0); + const finalTotal = total ?? segmentTotal; + + // TODO(aguo): Handle total being > segmentTotal + const segments = + segmentTotal < finalTotal + ? [ + ...progress, + { + value: finalTotal - segmentTotal, + label: unaccountedLabel ?? "Unaccounted", + hint: "Unaccounted tasks can happen when there are too many tasks. Ray drops older tasks to conserve memory.", + color: "#EEEEEE", + }, + ] + : progress; + + const filteredSegments = segments.filter(({ value }) => value); + + return ( + + {(showLegend || controls) && ( + + {showLegend && ( + + + + Total: {finalTotal} + + {filteredSegments.map(({ value, label, hint, color }) => ( + + + + {label}: {value} + + {hint && {hint}} + + ))} + + )} + {controls && controls} + + )} + + {expanded !== undefined && + (expanded ? ( + + ) : ( + + ))} + + + {filteredSegments.map(({ color, label, value }) => ( + + ))} + + + {showTotalProgress !== undefined && ( + + {showTotalProgress} / {finalTotal} + + )} + + + ); +}; + +type LegendTooltipProps = { + showTooltip: boolean; + segments: ProgressBarSegment[]; + total: number; + children: TooltipProps["children"]; +}; + +const LegendTooltip = ({ + showTooltip, + segments, + total, + children, +}: LegendTooltipProps) => { + if (showTooltip) { + return ( + + + + Total: {total} + + {segments.map(({ value, label, color }) => ( + + + + {label}: {value} + + + ))} + + } + > + {children} + + ); + } + + return children; +}; diff --git a/historyserver/dashboard/ray/client/src/components/ProgressBar/index.ts b/historyserver/dashboard/ray/client/src/components/ProgressBar/index.ts new file mode 100644 index 00000000000..a550d58d84d --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/ProgressBar/index.ts @@ -0,0 +1 @@ +export * from "./ProgressBar"; diff --git a/historyserver/dashboard/ray/client/src/components/SearchComponent.tsx b/historyserver/dashboard/ray/client/src/components/SearchComponent.tsx new file mode 100644 index 00000000000..8cfc426c681 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/SearchComponent.tsx @@ -0,0 +1,79 @@ +import { SearchOutlined } from "@mui/icons-material"; +import { InputAdornment, MenuItem, TextField } from "@mui/material"; +import React from "react"; + +export const SearchInput = ({ + label, + onChange, + defaultValue, +}: { + label: string; + defaultValue?: string; + onChange?: (value: string) => void; +}) => { + return ( + { + if (onChange) { + onChange(value); + } + }, + defaultValue, + endAdornment: ( + + + + ), + }} + /> + ); +}; + +export const SearchSelect = ({ + label, + onChange, + options, + showAllOption, + defaultValue, +}: { + label: string; + onChange?: (value: string) => void; + options: (string | [string, string])[]; + showAllOption: boolean; + defaultValue?: string; +}) => { + return ( + { + if (onChange) { + onChange(value as string); + } + }, + style: { + width: 100, + }, + }} + defaultValue={defaultValue || ""} + > + {showAllOption ? All : null} + {options.map((e) => + typeof e === "string" ? ( + + {e} + + ) : ( + + {e[1]} + + ), + )} + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/components/StatesCounter.tsx b/historyserver/dashboard/ray/client/src/components/StatesCounter.tsx new file mode 100644 index 00000000000..95917bd1539 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/StatesCounter.tsx @@ -0,0 +1,31 @@ +import { Grid } from "@mui/material"; +import React from "react"; +import { StatusChip } from "./StatusChip"; + +const StateCounter = ({ + type, + list, +}: { + type: string; + list: { state: string }[]; +}) => { + const stateMap = {} as { [state: string]: number }; + list.forEach(({ state }) => { + stateMap[state] = stateMap[state] + 1 || 1; + }); + + return ( + + + + + {Object.entries(stateMap).map(([s, num]) => ( + + + + ))} + + ); +}; + +export default StateCounter; diff --git a/historyserver/dashboard/ray/client/src/components/StatusChip.tsx b/historyserver/dashboard/ray/client/src/components/StatusChip.tsx new file mode 100644 index 00000000000..c2ef7b34e3d --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/StatusChip.tsx @@ -0,0 +1,153 @@ +import { Box, Color } from "@mui/material"; +import { blue, blueGrey, cyan, green, red } from "@mui/material/colors"; +import React, { CSSProperties, ReactNode } from "react"; +import { TaskStatus } from "../pages/job/hook/useJobProgress"; +import { ActorEnum } from "../type/actor"; +import { JobStatus } from "../type/job"; +import { PlacementGroupState } from "../type/placementGroup"; +import { + ServeApplicationStatus, + ServeDeploymentStatus, + ServeReplicaState, + ServeSystemActorStatus, +} from "../type/serve"; + +const orange = "#DB6D00"; +const grey = "#5F6469"; + +const colorMap = { + node: { + ALIVE: green, + DEAD: grey, + }, + worker: { + ALIVE: green, + DEAD: grey, + }, + actor: { + [ActorEnum.ALIVE]: green, + [ActorEnum.DEAD]: grey, + [ActorEnum.DEPENDENCIES_UNREADY]: orange, + [ActorEnum.PENDING_CREATION]: orange, + [ActorEnum.RESTARTING]: orange, + }, + task: { + [TaskStatus.FAILED]: red, + [TaskStatus.FINISHED]: green, + [TaskStatus.RUNNING]: blue, + [TaskStatus.SUBMITTED_TO_WORKER]: orange, + [TaskStatus.PENDING_NODE_ASSIGNMENT]: orange, + [TaskStatus.PENDING_ARGS_AVAIL]: orange, + [TaskStatus.UNKNOWN]: grey, + }, + job: { + [JobStatus.PENDING]: orange, + [JobStatus.RUNNING]: blue, + [JobStatus.STOPPED]: grey, + [JobStatus.SUCCEEDED]: green, + [JobStatus.FAILED]: red, + }, + placementGroup: { + [PlacementGroupState.PENDING]: orange, + [PlacementGroupState.CREATED]: green, + [PlacementGroupState.REMOVED]: grey, + [PlacementGroupState.RESCHEDULING]: orange, + }, + serveApplication: { + [ServeApplicationStatus.NOT_STARTED]: grey, + [ServeApplicationStatus.DEPLOYING]: orange, + [ServeApplicationStatus.RUNNING]: green, + [ServeApplicationStatus.DEPLOY_FAILED]: red, + [ServeApplicationStatus.DELETING]: orange, + [ServeApplicationStatus.UNHEALTHY]: red, + }, + serveDeployment: { + [ServeDeploymentStatus.UPDATING]: orange, + [ServeDeploymentStatus.HEALTHY]: green, + [ServeDeploymentStatus.UNHEALTHY]: red, + }, + serveReplica: { + [ServeReplicaState.STARTING]: orange, + [ServeReplicaState.UPDATING]: orange, + [ServeReplicaState.RECOVERING]: orange, + [ServeReplicaState.RUNNING]: green, + [ServeReplicaState.STOPPING]: red, + }, + serveProxy: { + [ServeSystemActorStatus.HEALTHY]: green, + [ServeSystemActorStatus.UNHEALTHY]: red, + [ServeSystemActorStatus.STARTING]: orange, + [ServeSystemActorStatus.DRAINING]: blueGrey, + }, + serveController: { + [ServeSystemActorStatus.HEALTHY]: green, + [ServeSystemActorStatus.UNHEALTHY]: red, + [ServeSystemActorStatus.STARTING]: orange, + }, +} as { + [key: string]: { + [key: string]: Color | string; + }; +}; + +const typeMap = { + deps: blue, + INFO: cyan, + ERROR: red, +} as { + [key: string]: Color; +}; + +export type StatusChipProps = { + type: keyof typeof colorMap; + status: string | ActorEnum | ReactNode; + suffix?: ReactNode; + icon?: ReactNode; +}; + +export const StatusChip = ({ type, status, suffix, icon }: StatusChipProps) => { + let color: Color | string = blueGrey; + + if (typeMap[type]) { + color = typeMap[type]; + } else if ( + typeof status === "string" && + colorMap[type] && + colorMap[type][status] + ) { + color = colorMap[type][status]; + } + + const colorValue = typeof color === "string" ? color : color[500]; + + const style: CSSProperties = {}; + style.color = colorValue; + style.borderColor = colorValue; + if (color !== blueGrey) { + style.backgroundColor = `${colorValue}20`; + } + + return ( + + {icon} + + {status} + + {suffix} + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/components/TaskTable.tsx b/historyserver/dashboard/ray/client/src/components/TaskTable.tsx new file mode 100644 index 00000000000..c9308611ed4 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/TaskTable.tsx @@ -0,0 +1,377 @@ +import { + Box, + InputAdornment, + Link, + Table, + TableBody, + TableCell, + TableHead, + TableRow, + TextField, + TextFieldProps, + Tooltip, + Typography, +} from "@mui/material"; +import Autocomplete from "@mui/material/Autocomplete"; +import Pagination from "@mui/material/Pagination"; +import React, { useState } from "react"; +import { Link as RouterLink } from "react-router-dom"; +import { CodeDialogButton } from "../common/CodeDialogButton"; +import { DurationText } from "../common/DurationText"; +import { ActorLink, NodeLink } from "../common/links"; +import { + TaskCpuProfilingLink, + TaskCpuStackTraceLink, + TaskMemoryProfilingButton, +} from "../common/ProfilingLink"; +import rowStyles from "../common/RowStyles"; +import { sliceToPage } from "../common/util"; +import { Task } from "../type/task"; +import { useFilter } from "../util/hook"; +import StateCounter from "./StatesCounter"; +import { StatusChip } from "./StatusChip"; +import { HelpInfo } from "./Tooltip"; +export type TaskTableProps = { + tasks: Task[]; + jobId?: string; + filterToTaskId?: string; + onFilterChange?: () => void; + actorId?: string; +}; + +const TaskTable = ({ + tasks = [], + jobId, + filterToTaskId, + onFilterChange, + actorId, +}: TaskTableProps) => { + const [pageNo, setPageNo] = useState(1); + const { changeFilter, filterFunc } = useFilter({ + overrideFilters: + filterToTaskId !== undefined + ? [{ key: "task_id", val: filterToTaskId }] + : undefined, + onFilterChange, + }); + const [taskIdFilterValue, setTaskIdFilterValue] = useState(filterToTaskId); + const [pageSize, setPageSize] = useState(10); + const taskList = tasks.filter(filterFunc); + const { + items: list, + constrainedPage, + maxPage, + } = sliceToPage(taskList, pageNo, pageSize); + + const columns = [ + { label: "ID" }, + { label: "Name" }, + { label: "Job ID" }, + { label: "State" }, + { + label: "Actions", + helpInfo: ( + + A list of actions performable on this task. +
+ - Log: view log messages of the worker that ran this task. You can + only view all the logs of the worker and a worker can run multiple + tasks. +
- Error: For tasks that have failed, show a stack trace for the + faiure. +
Stack Trace: Get a stacktrace of the worker process where the + task is running. +
- CPU Flame Graph: Get a flame graph of the next 5 seconds of + the worker process where the task is running. +
+ ), + }, + { label: "Duration" }, + { label: "Function or class name" }, + { label: "Node ID" }, + { label: "Actor ID" }, + { label: "Worker ID" }, + { label: "Type" }, + { label: "Placement group ID" }, + { label: "Required resources" }, + ]; + + return ( +
+
+ e.task_id)))} + onInputChange={(_: any, value: string) => { + changeFilter("task_id", value.trim()); + setTaskIdFilterValue(value); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + e.state)))} + onInputChange={(_: any, value: string) => { + changeFilter("state", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + e.job_id)))} + onInputChange={(_: any, value: string) => { + changeFilter("job_id", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + (e.actor_id ? e.actor_id : ""))), + )} + onInputChange={(_: any, value: string) => { + changeFilter("actor_id", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + e.name)))} + onInputChange={(_: any, value: string) => { + changeFilter("name", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + e.func_or_class_name)))} + onInputChange={(_: any, value: string) => { + changeFilter("func_or_class_name", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + { + setPageSize(Math.min(Number(value), 500) || 10); + }, + endAdornment: ( + Per Page + ), + }} + /> +
+
+
+ setPageNo(num)} + count={maxPage} + /> +
+
+ +
+
+ + + + + {columns.map(({ label, helpInfo }) => ( + + + {label} + {helpInfo && ( + {helpInfo} + )} + + + ))} + + + + {list.map((task) => { + const { + task_id, + name, + job_id, + state, + func_or_class_name, + node_id, + actor_id, + placement_group_id, + type, + required_resources, + start_time_ms, + end_time_ms, + worker_id, + } = task; + return ( + + + + + {task_id} + + + + {name ? name : "-"} + {job_id} + + + + + + + + {start_time_ms && start_time_ms > 0 ? ( + + ) : ( + "-" + )} + + {func_or_class_name} + + + {node_id ? ( + + ) : ( + - + )} + + + + + {actor_id ? ( + + ) : ( + - + )} + + + + + + {worker_id ? worker_id : "-"} + + + + {type} + + + + {placement_group_id ? placement_group_id : "-"} + + + + + {Object.entries(required_resources || {}).length > 0 ? ( + + ) : ( + "{}" + )} + + + ); + })} + +
+
+
+ ); +}; + +export default TaskTable; + +type TaskTableActionsProps = { + task: Task; +}; + +const TaskTableActions = ({ task }: TaskTableActionsProps) => { + const errorDetails = + task.error_type !== null && task.error_message !== null + ? `Error Type: ${task.error_type}\n\n${task.error_message}` + : undefined; + + const isTaskActive = task.state === "RUNNING" && task.worker_id; + + return ( + + + Log + + {isTaskActive && ( + +
+ +
+ +
+ +
+ )} +
+ + {errorDetails && ( + + )} +
+ ); +}; diff --git a/historyserver/dashboard/ray/client/src/components/TitleCard.tsx b/historyserver/dashboard/ray/client/src/components/TitleCard.tsx new file mode 100644 index 00000000000..c3f304b041f --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/TitleCard.tsx @@ -0,0 +1,35 @@ +import { Box, Paper } from "@mui/material"; +import React, { PropsWithChildren, ReactNode } from "react"; + +const TitleCard = ({ + title, + children, +}: PropsWithChildren<{ title?: ReactNode | string }>) => { + return ( + + {title && ( + ({ + fontSize: theme.typography.fontSize + 2, + fontWeight: 500, + color: theme.palette.text.secondary, + marginBottom: 1, + })} + > + {title} + + )} + {children} + + ); +}; + +export default TitleCard; diff --git a/historyserver/dashboard/ray/client/src/components/Tooltip.tsx b/historyserver/dashboard/ray/client/src/components/Tooltip.tsx new file mode 100644 index 00000000000..569f9357848 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/Tooltip.tsx @@ -0,0 +1,41 @@ +import HelpOutlineIcon from "@mui/icons-material/HelpOutline"; +import { SxProps, Theme, Tooltip, TooltipProps } from "@mui/material"; +import React, { ReactNode } from "react"; + +export const StyledTooltip = (props: TooltipProps) => { + return ( + ({ + backgroundColor: theme.palette.background.paper, + border: "1px solid #dadde9", + color: theme.palette.text.primary, + padding: 1, + }), + }, + }} + {...props} + /> + ); +}; + +type HelpInfoProps = { + children: NonNullable; + className?: string; + sx?: SxProps; +}; + +export const HelpInfo = ({ children, className, sx }: HelpInfoProps) => { + return ( + + theme.palette.grey[500] }, + ...(Array.isArray(sx) ? sx : [sx]), + ]} + /> + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/components/WorkerTable.tsx b/historyserver/dashboard/ray/client/src/components/WorkerTable.tsx new file mode 100644 index 00000000000..522b07dcc1f --- /dev/null +++ b/historyserver/dashboard/ray/client/src/components/WorkerTable.tsx @@ -0,0 +1,330 @@ +import { KeyboardArrowDown, KeyboardArrowRight } from "@mui/icons-material"; +import { + Button, + Grid, + IconButton, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, +} from "@mui/material"; +import React, { + PropsWithChildren, + ReactNode, + useContext, + useEffect, + useState, +} from "react"; +import { Link } from "react-router-dom"; +import { GlobalContext } from "../App"; +import { formatDateFromTimeMs } from "../common/formatUtils"; +import { ActorDetail } from "../type/actor"; +import { CoreWorkerStats, Worker } from "../type/worker"; +import { memoryConverter } from "../util/converter"; +import { longTextCut } from "../util/func"; + +import { useFilter } from "../util/hook"; +import ActorTable from "./ActorTable"; +import PercentageBar from "./PercentageBar"; +import { SearchInput } from "./SearchComponent"; + +export const ExpandableTableRow = ({ + children, + expandComponent, + length, + stateKey = "", + ...otherProps +}: PropsWithChildren<{ + expandComponent: ReactNode; + length: number; + stateKey?: string; +}>) => { + const [isExpanded, setIsExpanded] = React.useState(false); + + useEffect(() => { + if (stateKey.startsWith("ON")) { + setIsExpanded(true); + } else if (stateKey.startsWith("OFF")) { + setIsExpanded(false); + } + }, [stateKey]); + + if (length < 1) { + return ( + + + {children} + + ); + } + + return ( + + + + setIsExpanded(!isExpanded)} + size="large" + > + {length} + {isExpanded ? : } + + + {children} + + {isExpanded && ( + + {expandComponent} + + )} + + ); +}; + +const WorkerDetailTable = ({ + actorMap, + coreWorkerStats, +}: { + actorMap: { [actorId: string]: ActorDetail }; + coreWorkerStats: CoreWorkerStats[]; +}) => { + const actors = {} as { [actorId: string]: ActorDetail }; + (coreWorkerStats || []) + .filter((e) => actorMap[e.actorId]) + .forEach((e) => (actors[e.actorId] = actorMap[e.actorId])); + + if (!Object.values(actors).length) { + return

The Worker Haven't Had Related Actor Yet.

; + } + + return ( + + + + ); +}; + +const RayletWorkerTable = ({ + workers = [], + actorMap, + mini, +}: { + workers: Worker[]; + actorMap: { [actorId: string]: ActorDetail }; + mini?: boolean; +}) => { + const { changeFilter, filterFunc } = useFilter(); + const [key, setKey] = useState(""); + const { nodeMapByIp } = useContext(GlobalContext); + const open = () => setKey(`ON${Math.random()}`); + const close = () => setKey(`OFF${Math.random()}`); + + return ( + + {!mini && ( +
+ changeFilter("pid", value)} + /> + + +
+ )}{" "} + + + + {[ + "", + "Pid", + "CPU", + "CPU Times", + "Memory", + "CMD Line", + "Create Time", + "Log", + "Ops", + "IP", + "Tasks", + "Objects", + ].map((col) => ( + + {col} + + ))} + + + + {workers + .filter(filterFunc) + .sort((aWorker, bWorker) => { + const a = + (aWorker.coreWorkerStats || []).filter( + (e) => actorMap[e.actorId], + ).length || 0; + const b = + (bWorker.coreWorkerStats || []).filter( + (e) => actorMap[e.actorId], + ).length || 0; + return b - a; + }) + .map( + ({ + pid, + cpuPercent, + cpuTimes, + memoryInfo, + cmdline, + createTime, + coreWorkerStats = [], + language, + }) => ( + + } + length={ + (coreWorkerStats || []).filter((e) => actorMap[e.actorId]) + .length + } + key={pid} + stateKey={key} + > + {pid} + + + {cpuPercent}% + + + +
+ {Object.entries(cpuTimes || {}).map(([key, val]) => ( +
+ {key}:{val}% +
+ ))} +
+
+ +
+ {Object.entries(memoryInfo || {}).map(([key, val]) => ( +
+ {key}:{memoryConverter(val)} +
+ ))} +
+
+ + {cmdline && longTextCut(cmdline.filter((e) => e).join(" "))} + + + {formatDateFromTimeMs(createTime * 1000)} + + + + {coreWorkerStats[0] && ( + + + Log + + + )} + + + + {language === "JAVA" ? ( +
+ {" "} + + +
+ ) : ( + "N/A" + )} +
+ + {nodeMapByIp[coreWorkerStats[0]?.ipAddress] ? ( + + {coreWorkerStats[0]?.ipAddress} + + ) : ( + coreWorkerStats[0]?.ipAddress + )} + + +
+ Pending tasks: {coreWorkerStats[0]?.numPendingTasks} +
+
+ Executed tasks: {coreWorkerStats[0]?.numExecutedTasks} +
+
+ +
+ ObjectRefs in scope:{" "} + {coreWorkerStats[0]?.numObjectRefsInScope} +
+
+ Objects in local memory store:{" "} + {coreWorkerStats[0]?.numLocalObjects} +
+
+ Objects in plasma store: {coreWorkerStats[0]?.numInPlasma} +
+
+ Object store Memory used (MiB):{" "} + {coreWorkerStats[0]?.usedObjectStoreMemory} +
+
+
+ ), + )} +
+
+
+ ); +}; + +export default RayletWorkerTable; diff --git a/historyserver/dashboard/ray/client/src/index.tsx b/historyserver/dashboard/ray/client/src/index.tsx new file mode 100644 index 00000000000..646b6f42f04 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/index.tsx @@ -0,0 +1,12 @@ +import React from "react"; +import { createRoot } from "react-dom/client"; +import "typeface-roboto"; +import App from "./App"; + +const rootElement = document.getElementById("root"); +if (rootElement !== null) { + const root = createRoot(rootElement); + root.render(); +} else { + console.error("Could not find root element."); +} diff --git a/historyserver/dashboard/ray/client/src/logo.svg b/historyserver/dashboard/ray/client/src/logo.svg new file mode 100644 index 00000000000..70be9ee548c --- /dev/null +++ b/historyserver/dashboard/ray/client/src/logo.svg @@ -0,0 +1,34 @@ + + + + +Ray Logo + + + + + + + + + + diff --git a/historyserver/dashboard/ray/client/src/pages/actor/ActorDetail.tsx b/historyserver/dashboard/ray/client/src/pages/actor/ActorDetail.tsx new file mode 100644 index 00000000000..60e8fc8ec8a --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/actor/ActorDetail.tsx @@ -0,0 +1,215 @@ +import { Box } from "@mui/material"; +import React from "react"; +import { Outlet } from "react-router-dom"; +import { CollapsibleSection } from "../../common/CollapsibleSection"; +import { DurationText } from "../../common/DurationText"; +import { formatDateFromTimeMs } from "../../common/formatUtils"; +import { generateNodeLink } from "../../common/links"; +import { + CpuProfilingLink, + CpuStackTraceLink, + MemoryProfilingButton, +} from "../../common/ProfilingLink"; +import { Section } from "../../common/Section"; +import Loading from "../../components/Loading"; +import { MetadataSection } from "../../components/MetadataSection"; +import { StatusChip } from "../../components/StatusChip"; +import TitleCard from "../../components/TitleCard"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import TaskList from "../state/task"; +import { ActorLogs } from "./ActorLogs"; +import { useActorDetail } from "./hook/useActorDetail"; + +export const ActorDetailLayout = () => { + const { params, actorDetail } = useActorDetail(); + + return ( +
+ + +
+ ); +}; + +const ActorDetailPage = () => { + const { params, actorDetail, msg, isLoading } = useActorDetail(); + + if (isLoading || actorDetail === undefined) { + return ( + + + + +
+ Request Status: {msg}
+
+
+ ); + } + + return ( + + , + }, + { + label: "ID", + content: actorDetail.actorId + ? { + value: actorDetail.actorId, + copyableValue: actorDetail.actorId, + } + : { value: "-" }, + }, + { + label: "Name", + content: actorDetail.name + ? { + value: actorDetail.name, + } + : { value: "-" }, + }, + { + label: "Class Name", + content: actorDetail.actorClass + ? { + value: actorDetail.actorClass, + } + : { value: "-" }, + }, + { + label: "Repr", + content: actorDetail.reprName + ? { + value: actorDetail.reprName, + } + : { value: "-" }, + }, + { + label: "Job ID", + content: actorDetail.jobId + ? { + value: actorDetail.jobId, + copyableValue: actorDetail.jobId, + } + : { value: "-" }, + }, + { + label: "Node ID", + content: actorDetail.address?.rayletId + ? { + value: actorDetail.address?.rayletId, + copyableValue: actorDetail.address?.rayletId, + link: actorDetail.address.rayletId + ? generateNodeLink(actorDetail.address.rayletId) + : undefined, + } + : { value: "-" }, + }, + { + label: "Worker ID", + content: actorDetail.address?.workerId + ? { + value: actorDetail.address?.workerId, + copyableValue: actorDetail.address?.workerId, + } + : { value: "-" }, + }, + { + label: "Started at", + content: { + value: actorDetail.startTime + ? formatDateFromTimeMs(actorDetail.startTime) + : "-", + }, + }, + { + label: "Ended at", + content: { + value: actorDetail.endTime + ? formatDateFromTimeMs(actorDetail.endTime) + : "-", + }, + }, + { + label: "Uptime", + content: actorDetail.startTime ? ( + + ) : ( + - + ), + }, + { + label: "Restarted", + content: { value: actorDetail.numRestarts }, + }, + { + label: "Exit Detail", + content: actorDetail.exitDetail + ? { + value: actorDetail.exitDetail, + } + : { value: "-" }, + }, + { + label: "Actions", + content: ( +
+ +
+ +
+ +
+ ), + }, + ]} + /> + +
+ +
+
+ +
+ +
+
+
+ ); +}; + +export default ActorDetailPage; diff --git a/historyserver/dashboard/ray/client/src/pages/actor/ActorLayout.tsx b/historyserver/dashboard/ray/client/src/pages/actor/ActorLayout.tsx new file mode 100644 index 00000000000..7033a12a57c --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/actor/ActorLayout.tsx @@ -0,0 +1,18 @@ +import React from "react"; +import { Outlet } from "react-router-dom"; +import { MainNavPageInfo } from "../layout/mainNavContext"; + +export const ActorLayout = () => { + return ( +
+ + +
+ ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/actor/ActorList.tsx b/historyserver/dashboard/ray/client/src/pages/actor/ActorList.tsx new file mode 100644 index 00000000000..4aa43c9ee87 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/actor/ActorList.tsx @@ -0,0 +1,32 @@ +import React from "react"; +import ActorTable, { ActorTableProps } from "../../components/ActorTable"; +import { ActorDetail } from "../../type/actor"; +import { useActorList } from "./hook/useActorList"; + +/** + * Represent the embedable actors page. + */ +const ActorList = ({ + jobId = null, + detailPathPrefix = "", + ...actorTableProps +}: { + jobId?: string | null; + detailPathPrefix?: string; +} & Pick) => { + const data: { [actorId: string]: ActorDetail } | undefined = useActorList(); + const actors: { [actorId: string]: ActorDetail } = data ? data : {}; + + return ( +
+ +
+ ); +}; + +export default ActorList; diff --git a/historyserver/dashboard/ray/client/src/pages/actor/ActorLogs.tsx b/historyserver/dashboard/ray/client/src/pages/actor/ActorLogs.tsx new file mode 100644 index 00000000000..5191001d955 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/actor/ActorLogs.tsx @@ -0,0 +1,38 @@ +import React from "react"; +import { + MultiTabLogViewer, + MultiTabLogViewerTabDetails, +} from "../../common/MultiTabLogViewer"; +import { ActorDetail } from "../../type/actor"; + +export type ActorLogsProps = { + actor: Pick; +}; + +export const ActorLogs = ({ + actor: { + actorId, + pid, + address: { workerId, rayletId }, + }, +}: ActorLogsProps) => { + const tabs: MultiTabLogViewerTabDetails[] = [ + { + title: "stderr", + actorId, + suffix: "err", + }, + { + title: "stdout", + actorId, + suffix: "out", + }, + { + title: "system", + nodeId: rayletId, + // TODO(aguo): Have API return the log file name. + filename: `python-core-worker-${workerId}_${pid}.log`, + }, + ]; + return ; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/actor/hook/mockedUseActorList.ts b/historyserver/dashboard/ray/client/src/pages/actor/hook/mockedUseActorList.ts new file mode 100644 index 00000000000..2063b68fc77 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/actor/hook/mockedUseActorList.ts @@ -0,0 +1,113 @@ +import { Actor } from "../../../type/actor"; + +const MOCK_ACTORS: { [actorId: string]: Actor } = { + ACTOR_1: { + actorId: "ACTOR_1", + jobId: "01000000", + address: { + rayletId: "426854e68e4225b3941deaf03c8dcfcb1daacc69a92711d370dbb0e1", + ipAddress: "172.31.11.178", + port: 10003, + workerId: "b8b276a03612644098ed7a929c3b0e50f5bde894eb0d8cab288fbb6d", + }, + state: "ALIVE", + numRestarts: "0", + name: "", + pid: 25321, + startTime: 1679010689148, + endTime: 0, + actorClass: "Counter", + exitDetail: "-", + requiredResources: {}, + placementGroupId: "123", + reprName: ",", + }, + ACTOR_2: { + actorId: "ACTOR_2", + jobId: "01000000", + address: { + rayletId: "426854e68e4225b3941deaf03c8dcfcb1daacc69a92711d370dbb0e1", + ipAddress: "172.31.11.178", + port: 10003, + workerId: "b8b276a03612644098ed7a929c3b0e50f5bde894eb0d8cab288fbb6d", + }, + state: "DEAD", + numRestarts: "0", + name: "", + pid: 25322, + startTime: 1679010689150, + endTime: 0, + actorClass: "Counter", + exitDetail: "-", + requiredResources: {}, + placementGroupId: "123", + reprName: ",", + }, + ACTOR_3: { + actorId: "ACTOR_3", + jobId: "01000000", + address: { + rayletId: "426854e68e4225b3941deaf03c8dcfcb1daacc69a92711d370dbb0e1", + ipAddress: "172.31.11.178", + port: 10003, + workerId: "b8b276a03612644098ed7a929c3b0e50f5bde894eb0d8cab288fbb6d", + }, + state: "DEPENDENCIES_UNREADY", + numRestarts: "0", + name: "", + pid: 25323, + startTime: 1679010689152, + endTime: 0, + actorClass: "Counter", + exitDetail: "-", + requiredResources: {}, + placementGroupId: "123", + reprName: ",", + }, + ACTOR_4: { + actorId: "ACTOR_4", + jobId: "01000000", + address: { + rayletId: "426854e68e4225b3941deaf03c8dcfcb1daacc69a92711d370dbb0e1", + ipAddress: "172.31.11.178", + port: 10003, + workerId: "b8b276a03612644098ed7a929c3b0e50f5bde894eb0d8cab288fbb6d", + }, + state: "PENDING_CREATION", + numRestarts: "0", + name: "", + pid: 25324, + startTime: 1679010689154, + endTime: 0, + actorClass: "Counter", + exitDetail: "-", + requiredResources: {}, + placementGroupId: "123", + reprName: ",", + }, + ACTOR_5: { + actorId: "ACTOR_5", + jobId: "01000000", + address: { + rayletId: "426854e68e4225b3941deaf03c8dcfcb1daacc69a92711d370dbb0e1", + ipAddress: "172.31.11.178", + port: 10003, + workerId: "b8b276a03612644098ed7a929c3b0e50f5bde894eb0d8cab288fbb6d", + }, + state: "RESTARTING", + numRestarts: "1", + name: "", + pid: 25325, + startTime: 1679010689156, + endTime: 0, + actorClass: "Counter", + exitDetail: "-", + requiredResources: {}, + placementGroupId: "123", + reprName: ",", + }, +}; + +export const useActorList = (): { [actorId: string]: Actor } => { + return MOCK_ACTORS; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/actor/hook/useActorDetail.ts b/historyserver/dashboard/ray/client/src/pages/actor/hook/useActorDetail.ts new file mode 100644 index 00000000000..ec51d6a53ef --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/actor/hook/useActorDetail.ts @@ -0,0 +1,56 @@ +import { useContext, useState } from "react"; +import { useParams } from "react-router-dom"; +import useSWR from "swr"; +import { GlobalContext } from "../../../App"; +import { API_REFRESH_INTERVAL_MS } from "../../../common/constants"; +import { ActorResp, getActor } from "../../../service/actor"; + +export const useFetchActor = (actorId: string | null) => { + return useSWR( + actorId ? ["useActorDetail", actorId] : null, + async ([_, actorId]) => { + const actor_resp = await getActor(actorId); + const data: ActorResp = actor_resp?.data; + const { data: rspData } = data; + + if (rspData.detail) { + return rspData.detail; + } + }, + ); +}; + +export const useActorDetail = () => { + const params = useParams() as { actorId: string }; + const [msg, setMsg] = useState("Loading the actor infos..."); + const { namespaceMap } = useContext(GlobalContext); + + const { data: actorDetail, isLoading } = useSWR( + ["useActorDetail", params.actorId], + async ([_, actorId]) => { + const actor_resp = await getActor(actorId); + const data: ActorResp = actor_resp?.data; + const { data: rspData, msg, result } = data; + if (msg) { + setMsg(msg); + } + + if (result === false) { + setMsg("Actor Query Error Please Check Actor Id"); + } + + if (rspData.detail) { + return rspData.detail; + } + }, + { refreshInterval: API_REFRESH_INTERVAL_MS }, + ); + + return { + params, + actorDetail, + msg, + isLoading, + namespaceMap, + }; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/actor/hook/useActorList.ts b/historyserver/dashboard/ray/client/src/pages/actor/hook/useActorList.ts new file mode 100644 index 00000000000..f372c22c59b --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/actor/hook/useActorList.ts @@ -0,0 +1,21 @@ +import useSWR from "swr"; +import { PER_JOB_PAGE_REFRESH_INTERVAL_MS } from "../../../common/constants"; +import { getActors } from "../../../service/actor"; + +export const useActorList = () => { + const { data } = useSWR( + "useActorList", + async () => { + const rsp = await getActors(); + + if (rsp?.data?.data?.actors) { + return rsp.data.data.actors; + } else { + return {}; + } + }, + { refreshInterval: PER_JOB_PAGE_REFRESH_INTERVAL_MS }, + ); + + return data; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/actor/index.tsx b/historyserver/dashboard/ray/client/src/pages/actor/index.tsx new file mode 100644 index 00000000000..2414128df9c --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/actor/index.tsx @@ -0,0 +1,22 @@ +import { Box } from "@mui/material"; +import React from "react"; +import ActorList from "./ActorList"; + +/** + * Represent the standalone actors page. + */ +const Actors = () => { + return ( + + + + ); +}; + +export default Actors; diff --git a/historyserver/dashboard/ray/client/src/pages/clusters/ClustersPage.tsx b/historyserver/dashboard/ray/client/src/pages/clusters/ClustersPage.tsx new file mode 100644 index 00000000000..8aee755df51 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/clusters/ClustersPage.tsx @@ -0,0 +1,154 @@ +import { + Box, + Button, + ButtonGroup, + Grid, IconButton, Link, + Switch, + Table, TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, Tooltip, Typography, +} from "@mui/material"; +import Pagination from "@mui/material/Pagination"; +import React from "react"; +import {RiArrowDownSLine, RiArrowRightSLine} from "react-icons/ri"; +import {Link as RouterLink, Outlet} from "react-router-dom"; +import {CodeDialogButtonWithPreview} from "../../common/CodeDialogButton"; +import {ClusterLink} from "../../common/clusterslinks"; +import Loading from "../../components/Loading"; +import { MetadataSection } from "../../components/MetadataSection"; +import PercentageBar from "../../components/PercentageBar"; +import {SearchInput, SearchSelect} from "../../components/SearchComponent"; +import StateCounter from "../../components/StatesCounter"; +import { StatusChip } from "../../components/StatusChip"; +import TitleCard from "../../components/TitleCard"; +import {HelpInfo} from "../../components/Tooltip"; +import {NodeDetail} from "../../type/node"; +import {memoryConverter} from "../../util/converter"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import {NodeCard} from "../node"; +import {NodeGPUView} from "../node/GPUColumn"; +import {NodeGRAM} from "../node/GRAMColumn"; +import {NodeRows} from "../node/NodeRow"; +import {useClusterList} from "./hook/useClusterList"; + +const TEXT_COL_MIN_WIDTH = 100; + + +type Cluster = { + name: string; + createTime: string; + sessionName: string; +} + + +export const ClusterRow = ( {name, createTime, sessionName}:Cluster) => { + + return ( + + + {/*{name} */} + +
+ +
+
+
+ + {createTime} + +
+ ); +}; + +const columns = [ + { + label: "ClusterName", + helpInfo: ( + + RayClusterName +
+
+ ), + }, + { + label: "createTime", + helpInfo: ( + + RayCluster CreateTime.
+
+ ), + }, +]; + +export const ClustersPage = () => { + + const {clustersList} = useClusterList() + + return ( + + + + {/* + + + changeFilter("hostname", value.trim())} + /> + + + setPage("pageSize", Math.min(Number(value), 500) || 10)} + /> + + + */} +
+
+ + + + + {columns.map(({ label, helpInfo }) => ( + + + {label} + {helpInfo && ( + {helpInfo} + )} + + + ))} + + + + + {clustersList.map((cluster) => ( + + ))} + + +
+
+
+
+ +
+ ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/clusters/hook/useClusterList.ts b/historyserver/dashboard/ray/client/src/pages/clusters/hook/useClusterList.ts new file mode 100644 index 00000000000..f70c0b267c5 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/clusters/hook/useClusterList.ts @@ -0,0 +1,23 @@ +import _ from "lodash"; +import { useState } from "react"; +import useSWR from "swr"; +import { API_REFRESH_INTERVAL_MS } from "../../../common/constants"; +import { getClusterList } from "../../../service/clusters"; +import { useSorter } from "../../../util/hook"; + +export const useClusterList = () => { +// const [isRefreshing, setRefresh] = useState(true); + + const { data } = useSWR( + "useClusterList", + async () => { + const { data } = await getClusterList(); + return data; + }, + // { refreshInterval: isRefreshing ? API_REFRESH_INTERVAL_MS : 0 }, + ); + + return { + clustersList: data ?? [], + }; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/cmd/CMDResult.tsx b/historyserver/dashboard/ray/client/src/pages/cmd/CMDResult.tsx new file mode 100644 index 00000000000..0a7c0311cd2 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/cmd/CMDResult.tsx @@ -0,0 +1,110 @@ +import { Box, Button, Grid, MenuItem, Select } from "@mui/material"; +import React, { useCallback, useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; +import LogVirtualView from "../../components/LogView/LogVirtualView"; +import TitleCard from "../../components/TitleCard"; +import { getJmap, getJstack, getJstat } from "../../service/util"; + +const CMDResult = () => { + const { cmd, ip, pid } = useParams() as { + cmd: string; + ip: string; + pid: string; + }; + const [result, setResult] = useState(); + const [option, setOption] = useState("gcutil"); + const executeJstat = useCallback( + () => + getJstat(ip, pid, option) + .then((rsp) => { + if (rsp.data.result) { + setResult(rsp.data.data.output); + } else { + setResult(rsp.data.msg); + } + }) + .catch((err) => setResult(err.toString())), + [ip, pid, option], + ); + + useEffect(() => { + switch (cmd) { + case "jstack": + getJstack(ip, pid) + .then((rsp) => { + if (rsp.data.result) { + setResult(rsp.data.data.output); + } else { + setResult(rsp.data.msg); + } + }) + .catch((err) => setResult(err.toString())); + break; + case "jmap": + getJmap(ip, pid) + .then((rsp) => { + if (rsp.data.result) { + setResult(rsp.data.data.output); + } else { + setResult(rsp.data.msg); + } + }) + .catch((err) => setResult(err.toString())); + break; + case "jstat": + executeJstat(); + break; + default: + setResult(`Command ${cmd} is not supported.`); + break; + } + }, [cmd, executeJstat, ip, pid]); + + return ( + + + {cmd === "jstat" && ( + + + + + + + + + + + )} + + + + + + ); +}; + +export default CMDResult; diff --git a/historyserver/dashboard/ray/client/src/pages/data/DataOverview.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/data/DataOverview.component.test.tsx new file mode 100644 index 00000000000..12cd1979292 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/data/DataOverview.component.test.tsx @@ -0,0 +1,124 @@ +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import React from "react"; +import { TEST_APP_WRAPPER } from "../../util/test-utils"; +import DataOverview from "./DataOverview"; + +describe("DataOverview", () => { + it("renders table with dataset metrics", async () => { + const datasets = [ + { + dataset: "test_ds1", + job_id: "test_job_id1", + state: "RUNNING", + progress: 50, + total: 100, + start_time: 0, + end_time: undefined, + ray_data_output_rows: { + max: 10, + }, + ray_data_spilled_bytes: { + max: 20, + }, + ray_data_current_bytes: { + value: 30, + max: 40, + }, + ray_data_cpu_usage_cores: { + value: 50, + max: 60, + }, + ray_data_gpu_usage_cores: { + value: 70, + max: 80, + }, + operators: [ + { + operator: "test_ds1_op1", + state: "RUNNING", + progress: 99, + total: 101, + ray_data_output_rows: { + max: 11, + }, + ray_data_spilled_bytes: { + max: 21, + }, + ray_data_current_bytes: { + value: 31, + max: 41, + }, + ray_data_cpu_usage_cores: { + value: 51, + max: 61, + }, + ray_data_gpu_usage_cores: { + value: 71, + max: 81, + }, + }, + ], + }, + { + dataset: "test_ds2", + job_id: "test_job_id2", + state: "FINISHED", + progress: 200, + total: 200, + start_time: 1, + end_time: 2, + ray_data_output_rows: { + max: 50, + }, + ray_data_spilled_bytes: { + max: 60, + }, + ray_data_current_bytes: { + value: 70, + max: 80, + }, + ray_data_cpu_usage_cores: { + value: 90, + max: 100, + }, + ray_data_gpu_usage_cores: { + value: 110, + max: 120, + }, + operators: [], + }, + ]; + const user = userEvent.setup(); + + render(, { wrapper: TEST_APP_WRAPPER }); + + // First Dataset + expect(screen.getByText("test_ds1")).toBeVisible(); + expect(screen.getByText("50 / 100")).toBeVisible(); + expect(screen.getByText("1969/12/31 16:00:00")).toBeVisible(); + expect(screen.getByText("10")).toBeVisible(); + expect(screen.getByText("20.0000B")).toBeVisible(); + expect(screen.getByText("30.0000B/40.0000B")).toBeVisible(); + expect(screen.getByText("50/60")).toBeVisible(); + expect(screen.getByText("70/80")).toBeVisible(); + + // Operator dropdown + expect(screen.queryByText("test_ds1_op1")).toBeNull(); + await user.click(screen.getByTitle("Expand Dataset test_ds1")); + expect(screen.getByText("test_ds1_op1")).toBeVisible(); + await user.click(screen.getByTitle("Collapse Dataset test_ds1")); + expect(screen.queryByText("test_ds1_op1")).toBeNull(); + + // Second Dataset + expect(screen.getByText("test_ds2")).toBeVisible(); + expect(screen.getByText("200 / 200")).toBeVisible(); + expect(screen.getByText("1969/12/31 16:00:01")).toBeVisible(); + expect(screen.getByText("1969/12/31 16:00:02")).toBeVisible(); + expect(screen.getByText("50")).toBeVisible(); + expect(screen.getByText("60.0000B")).toBeVisible(); + expect(screen.getByText("70.0000B/80.0000B")).toBeVisible(); + expect(screen.getByText("90/100")).toBeVisible(); + expect(screen.getByText("110/120")).toBeVisible(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/data/DataOverview.tsx b/historyserver/dashboard/ray/client/src/pages/data/DataOverview.tsx new file mode 100644 index 00000000000..e3059ec24af --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/data/DataOverview.tsx @@ -0,0 +1,13 @@ +import React from "react"; +import DataOverviewTable from "../../components/DataOverviewTable"; +import { DatasetMetrics } from "../../type/data"; + +const DataOverview = ({ datasets = [] }: { datasets: DatasetMetrics[] }) => { + return ( +
+ +
+ ); +}; + +export default DataOverview; diff --git a/historyserver/dashboard/ray/client/src/pages/error/404.tsx b/historyserver/dashboard/ray/client/src/pages/error/404.tsx new file mode 100644 index 00000000000..ca432708eb3 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/error/404.tsx @@ -0,0 +1,32 @@ +import { HelpOutlineOutlined } from "@mui/icons-material"; +import { Typography } from "@mui/material"; +import React from "react"; + +const Error404 = () => { + return ( +
+
+ + + + 404 NOT FOUND +

+ We can't provide the page you wanted yet, better try with another path + next time. +

+
+
+ ); +}; + +export default Error404; diff --git a/historyserver/dashboard/ray/client/src/pages/exception/Loading.tsx b/historyserver/dashboard/ray/client/src/pages/exception/Loading.tsx new file mode 100644 index 00000000000..15426f37c4d --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/exception/Loading.tsx @@ -0,0 +1,21 @@ +import React, { ReactNode } from "react"; +import Logo from "../../logo.svg"; + +const fn: ReactNode = ( +
+
+ Loading +
+ Loading... +
+
+); + +export default fn; diff --git a/historyserver/dashboard/ray/client/src/pages/job/AdvancedProgressBar/AdvancedProgressBar.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/job/AdvancedProgressBar/AdvancedProgressBar.component.test.tsx new file mode 100644 index 00000000000..8b7727b3309 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/AdvancedProgressBar/AdvancedProgressBar.component.test.tsx @@ -0,0 +1,144 @@ +import { Table, TableBody } from "@mui/material"; +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import React, { PropsWithChildren } from "react"; +import { TypeTaskType } from "../../../type/task"; +import { STYLE_WRAPPER } from "../../../util/test-utils"; +import { AdvancedProgressBarSegment } from "./AdvancedProgressBar"; + +const Wrapper = ({ children }: PropsWithChildren<{}>) => { + return ( + + + {children} +
+
+ ); +}; + +describe("AdvancedProgressBarSegment", () => { + it("renders without children", async () => { + expect.assertions(2); + render( + , + { wrapper: Wrapper }, + ); + await screen.findByText(/group 1/); + expect(screen.getByText(/1 \/ 10/)).toBeVisible(); + expect(screen.getByTitle("Expand").parentElement).not.toBeVisible(); + }); + + it("renders with children", async () => { + expect.assertions(7); + const user = userEvent.setup(); + + render( + , + { wrapper: Wrapper }, + ); + await screen.findByText(/group 1/); + expect(screen.getByTitle("Expand").parentElement).toBeVisible(); + expect(screen.getByText(/^1 \/ 10$/)).toBeVisible(); + await user.click(screen.getByTitle("Expand")); + await screen.findByText(/child/); + screen.getByText(/child/); + expect(screen.getByTitle("Collapse").parentElement).toBeVisible(); + expect(screen.getAllByTitle("Expand")).toHaveLength(1); // There should only be one for the child segment + expect(screen.getByText(/^1 \/ 1$/)).toBeVisible(); + await user.click(screen.getByTitle("Collapse")); + expect(screen.queryByText(/child/)).toBeNull(); + expect(screen.queryByText(/^1 \/ 1$/)).toBeNull(); + }); + + it("renders with GROUP and children", async () => { + expect.assertions(12); + const user = userEvent.setup(); + + render( + , + { wrapper: Wrapper }, + ); + await screen.findByText(/group 1/); + expect(screen.getByTitle("Expand").parentElement).toBeVisible(); + expect(screen.getByText(/^3 \/ 10$/)).toBeVisible(); + await user.click(screen.getByTitle("Expand")); + await screen.findByText(/child/); + screen.getByText(/child/); + expect(screen.getByTitle("Collapse group").parentElement).toBeVisible(); + expect(screen.getAllByTitle("Expand")).toHaveLength(1); // There should only be one for the child segment + expect(screen.getByText(/^3 \/ 3$/)).toBeVisible(); + await user.click(screen.getByTitle("Expand")); + await screen.findByText(/grandchild/); + expect(screen.getByTitle("Collapse group").parentElement).toBeVisible(); + expect(screen.getByTitle("Collapse").parentElement).toBeVisible(); // Collapse on the child segment + expect(screen.getAllByTitle("Expand")).toHaveLength(1); // There should only be one for the grand child segment + expect(screen.getByText(/^1 \/ 1$/)).toBeVisible(); + await user.click(screen.getByTitle("Collapse group")); + expect(screen.getByText(/^3 \/ 10$/)).toBeVisible(); + expect(screen.queryByText(/^3 \/ 3$/)).toBeNull(); + expect(screen.queryByText(/^1 \/ 1$/)).toBeNull(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/job/AdvancedProgressBar/AdvancedProgressBar.tsx b/historyserver/dashboard/ray/client/src/pages/job/AdvancedProgressBar/AdvancedProgressBar.tsx new file mode 100644 index 00000000000..8c4b29aea9a --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/AdvancedProgressBar/AdvancedProgressBar.tsx @@ -0,0 +1,215 @@ +import { + Box, + Link, + SxProps, + Table, + TableBody, + TableCell, + TableRow, + Theme, +} from "@mui/material"; +import React, { useState } from "react"; +import { + RiAddLine, + RiArrowDownSLine, + RiArrowRightSLine, + RiCloseLine, + RiSubtractLine, +} from "react-icons/ri"; +import { Link as RouterLink } from "react-router-dom"; +import { ClassNameProps } from "../../../common/props"; +import { JobProgressGroup, NestedJobProgressLink } from "../../../type/job"; +import { MiniTaskProgressBar } from "../TaskProgressBar"; + +export type AdvancedProgressBarProps = { + progressGroups: JobProgressGroup[] | undefined; + sx?: SxProps; +} & ClassNameProps & + Pick; + +export const AdvancedProgressBar = ({ + progressGroups, + className, + sx, + ...segmentProps +}: AdvancedProgressBarProps) => { + return ( + + + {progressGroups !== undefined ? ( + progressGroups.map((group) => ( + + )) + ) : ( + + Loading... + + )} + +
+ ); +}; + +export type AdvancedProgressBarSegmentProps = { + jobProgressGroup: JobProgressGroup; + /** + * Whether the segment should be expanded or not. + * Only applies to this segment and not it's children. + */ + startExpanded?: boolean; + /** + * How nested this segment is. + * By default, we assume this is a top level segment. + */ + nestedIndex?: number; + /** + * Whether to show a collapse button to the left. Used to collapse the parent. + * This is a special case for "GROUP"s + */ + showParentCollapseButton?: boolean; + onParentCollapseButtonPressed?: () => void; + onClickLink?: (link: NestedJobProgressLink) => void; +}; + +export const AdvancedProgressBarSegment = ({ + jobProgressGroup: { name, progress, children, type, link }, + startExpanded = false, + nestedIndex = 1, + showParentCollapseButton = false, + onParentCollapseButtonPressed, + onClickLink, +}: AdvancedProgressBarSegmentProps) => { + const [expanded, setExpanded] = useState(startExpanded); + const isGroup = type === "GROUP"; + + const IconComponent = isGroup + ? expanded + ? RiSubtractLine + : RiAddLine + : expanded + ? RiArrowDownSLine + : RiArrowRightSLine; + + const showCollapse = isGroup && expanded; + const handleCollapse = showCollapse + ? () => { + setExpanded(false); + } + : undefined; + + return ( + + {/* Don't show the "GROUP" type rows if it's expanded. We only show the children */} + {isGroup && expanded ? null : ( + + { + setExpanded(!expanded); + }} + > + {showParentCollapseButton && ( + + )} + + {link ? ( + link.type === "actor" ? ( + { + onClickLink?.(link); + event.stopPropagation(); + }} + > + {name} + + ) : ( + + {name} + + ) + ) : ( + name + )} + {isGroup && ( + + + {"("} + {children.length} + {")"} + + )} + + + + + + )} + {expanded && + children.map((child, index) => ( + + ))} + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/job/AdvancedProgressBar/index.ts b/historyserver/dashboard/ray/client/src/pages/job/AdvancedProgressBar/index.ts new file mode 100644 index 00000000000..ce041fba6cc --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/AdvancedProgressBar/index.ts @@ -0,0 +1 @@ +export * from "./AdvancedProgressBar"; diff --git a/historyserver/dashboard/ray/client/src/pages/job/JobDetail.tsx b/historyserver/dashboard/ray/client/src/pages/job/JobDetail.tsx new file mode 100644 index 00000000000..29236bda537 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/JobDetail.tsx @@ -0,0 +1,221 @@ +import { Box } from "@mui/material"; +import React, { useRef, useState } from "react"; +import useSWR from "swr"; +import { CollapsibleSection } from "../../common/CollapsibleSection"; +import { Section } from "../../common/Section"; +import { + NodeStatusCard, + ResourceStatusCard, +} from "../../components/AutoscalerStatusCards"; +import Loading from "../../components/Loading"; +import { StatusChip } from "../../components/StatusChip"; +import TitleCard from "../../components/TitleCard"; +import { getDataDatasets } from "../../service/data"; +import { NestedJobProgressLink } from "../../type/job"; +import ActorList from "../actor/ActorList"; +import DataOverview from "../data/DataOverview"; +import { NodeCountCard } from "../overview/cards/NodeCountCard"; +import PlacementGroupList from "../state/PlacementGroup"; +import TaskList from "../state/task"; +import { useRayStatus } from "./hook/useClusterStatus"; +import { useJobDetail } from "./hook/useJobDetail"; +import { JobMetadataSection } from "./JobDetailInfoPage"; +import { JobDriverLogs } from "./JobDriverLogs"; +import { JobProgressBar } from "./JobProgressBar"; +import { TaskTimeline } from "./TaskTimeline"; + +export const JobDetailChartsPage = () => { + const { job, msg, isLoading, params } = useJobDetail(); + + const [taskListFilter, setTaskListFilter] = useState(); + const [taskTableExpanded, setTaskTableExpanded] = useState(false); + const taskTableRef = useRef(null); + + const [actorListFilter, setActorListFilter] = useState(); + const [actorTableExpanded, setActorTableExpanded] = useState(false); + const actorTableRef = useRef(null); + const { clusterStatus } = useRayStatus(); + + const { data } = useSWR( + job?.job_id ? ["useDataDatasets", job.job_id] : null, + async ([_, jobId]) => { + // Only display details for Ray Datasets that belong to this job. + const rsp = await getDataDatasets(jobId); + + if (rsp) { + return rsp.data; + } + }, + { refreshInterval: 5000 }, + ); + + if (!job) { + return ( + + + + +
+ Request Status: {msg}
+
+
+ ); + } + + const handleClickLink = (link: NestedJobProgressLink) => { + if (link.type === "task") { + setTaskListFilter(link.id); + if (!taskTableExpanded) { + setTaskTableExpanded(true); + setTimeout(() => { + // Wait a few ms to give the collapsible view some time to render. + taskTableRef.current?.scrollIntoView(); + }, 50); + } else { + taskTableRef.current?.scrollIntoView(); + } + } else if (link.type === "actor") { + setActorListFilter(link.id); + if (!actorTableExpanded) { + setActorTableExpanded(true); + setTimeout(() => { + // Wait a few ms to give the collapsible view some time to render. + actorTableRef.current?.scrollIntoView(); + }, 50); + } else { + actorTableRef.current?.scrollIntoView(); + } + } + }; + + const handleTaskListFilterChange = () => { + setTaskListFilter(undefined); + }; + + const handleActorListFilterChange = () => { + setActorListFilter(undefined); + }; + + return ( + + + + {data?.datasets && data.datasets.length > 0 && ( + +
+ +
+
+ )} + + +
+ +
+
+ + +
+ +
+
+ + {job.job_id && ( + +
+ +
+
+ )} + + + ({ + flexWrap: "wrap", + [theme.breakpoints.up("md")]: { + flexWrap: "nowrap", + }, + })} + > + +
+ +
+
+ +
+
+
+ + {job.job_id && ( + + { + setTaskTableExpanded(!taskTableExpanded); + }} + sx={{ marginBottom: 4 }} + > +
+ +
+
+ + { + setActorTableExpanded(!actorTableExpanded); + }} + sx={{ marginBottom: 4 }} + > +
+ +
+
+ + +
+ +
+
+
+ )} +
+ ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/job/JobDetailActorPage.tsx b/historyserver/dashboard/ray/client/src/pages/job/JobDetailActorPage.tsx new file mode 100644 index 00000000000..d7eeb06891c --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/JobDetailActorPage.tsx @@ -0,0 +1,43 @@ +import { Box } from "@mui/material"; +import React, { PropsWithChildren } from "react"; + +import { Section } from "../../common/Section"; +import ActorList from "../actor/ActorList"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import { useJobDetail } from "./hook/useJobDetail"; + +export const JobDetailActorsPage = () => { + const { params } = useJobDetail(); + + return ( + + +
+ +
+
+ ); +}; + +export const JobDetailActorDetailWrapper = ({ + children, +}: PropsWithChildren<{}>) => { + return ( +
+ + {children} +
+ ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/job/JobDetailInfoPage.tsx b/historyserver/dashboard/ray/client/src/pages/job/JobDetailInfoPage.tsx new file mode 100644 index 00000000000..112b19ed5df --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/JobDetailInfoPage.tsx @@ -0,0 +1,196 @@ +import { Box, Typography } from "@mui/material"; +import React from "react"; +import { + CodeDialogButton, + CodeDialogButtonWithPreview, +} from "../../common/CodeDialogButton"; +import { DurationText } from "../../common/DurationText"; +import { formatDateFromTimeMs } from "../../common/formatUtils"; +import { JobStatusWithIcon } from "../../common/JobStatus"; +import { + CpuProfilingLink, + CpuStackTraceLink, + MemoryProfilingButton, +} from "../../common/ProfilingLink"; +import { filterRuntimeEnvSystemVariables } from "../../common/util"; +import Loading from "../../components/Loading"; +import { MetadataSection } from "../../components/MetadataSection"; +import { StatusChip } from "../../components/StatusChip"; +import TitleCard from "../../components/TitleCard"; +import { UnifiedJob } from "../../type/job"; +import { MainNavPageInfo } from "../layout/mainNavContext"; + +import { useJobDetail } from "./hook/useJobDetail"; + +export const JobDetailInfoPage = () => { + // TODO(aguo): Add more content to this page! + + const { job, msg, isLoading, params } = useJobDetail(); + + if (!job) { + return ( + + + + + +
+ Request Status: {msg}
+
+
+ ); + } + + return ( + + + {job.job_id} + + + ); +}; + +type JobMetadataSectionProps = { + job: UnifiedJob; +}; + +export const JobMetadataSection = ({ job }: JobMetadataSectionProps) => { + return ( + + {" "} + {job.message && ( + + )} + + ), + }, + { + label: "Job ID", + content: job.job_id + ? { + value: job.job_id, + copyableValue: job.job_id, + } + : { value: "-" }, + }, + { + label: "Submission ID", + content: job.submission_id + ? { + value: job.submission_id, + copyableValue: job.submission_id, + } + : { + value: "-", + }, + }, + { + label: "Duration", + content: job.start_time ? ( + + ) : ( + - + ), + }, + { + label: "Started at", + content: { + value: job.start_time ? formatDateFromTimeMs(job.start_time) : "-", + }, + }, + { + label: "Ended at", + content: { + value: job.end_time ? formatDateFromTimeMs(job.end_time) : "-", + }, + }, + { + label: "Runtime environment", + ...(job.runtime_env + ? { + content: ( + + ), + } + : { + content: { + value: "-", + }, + }), + }, + ...(job.type === "SUBMISSION" + ? [ + { + label: "User-provided metadata", + content: + job.metadata && Object.keys(job.metadata).length ? ( + + ) : undefined, + }, + ] + : []), + { + label: "Actions", + content: ( +
+ +
+ +
+ +
+ ), + }, + ]} + /> + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/job/JobDetailLayout.tsx b/historyserver/dashboard/ray/client/src/pages/job/JobDetailLayout.tsx new file mode 100644 index 00000000000..0d4119eda36 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/JobDetailLayout.tsx @@ -0,0 +1,54 @@ +import React from "react"; +import { + RiGradienterLine, + RiInformationLine, + RiLineChartLine, +} from "react-icons/ri"; +import { Outlet } from "react-router-dom"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import { SideTabLayout, SideTabRouteLink } from "../layout/SideTabLayout"; +import { useJobDetail } from "./hook/useJobDetail"; + +export const JobPage = () => { + const { job, params } = useJobDetail(); + + const jobId = job?.job_id ?? job?.submission_id; + const pageInfo = jobId + ? { + title: jobId ?? "Job", + pageTitle: jobId ? `${jobId} | Job` : undefined, + id: "job-detail", + path: jobId, + } + : { + title: "Job", + id: "job-detail", + path: params.id, + }; + return ( +
+ + +
+ ); +}; + +export const JobDetailLayout = () => { + return ( + + + + + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/job/JobDriverLogs.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/job/JobDriverLogs.component.test.tsx new file mode 100644 index 00000000000..46e49e723ea --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/JobDriverLogs.component.test.tsx @@ -0,0 +1,53 @@ +import { render, screen } from "@testing-library/react"; +import React from "react"; +import { MAX_LINES_FOR_LOGS } from "../../service/log"; +import { get } from "../../service/requestHandlers"; +import { TEST_APP_WRAPPER } from "../../util/test-utils"; +import { JobDriverLogs } from "./JobDriverLogs"; + +jest.mock("../../service/requestHandlers"); + +const mockedGet = jest.mocked(get); + +describe("JobDriverLogs", () => { + it("renders", async () => { + expect.assertions(6); + + mockedGet.mockResolvedValue({ + headers: { + "content-type": "text/plain", + }, + data: "1log line\nthis is a line\nHi\n10\nfoo", + }); + + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + + await screen.findByText(/log line/); + expect(screen.getByText(/log line/)).toBeVisible(); + expect(screen.getByText(/this is a line/)).toBeVisible(); + expect(screen.getByText(/Hi/)).toBeVisible(); + expect(screen.getByText(/10/)).toBeVisible(); + expect(screen.getByText(/foo/)).toBeVisible(); + + expect(mockedGet).toBeCalledWith( + `api/v0/logs/file?node_id=node-id-0&filename=job-driver-raysubmit_12345.log&lines=${MAX_LINES_FOR_LOGS}&format=leading_1`, + ); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/job/JobDriverLogs.tsx b/historyserver/dashboard/ray/client/src/pages/job/JobDriverLogs.tsx new file mode 100644 index 00000000000..7e6ca064bab --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/JobDriverLogs.tsx @@ -0,0 +1,68 @@ +import React, { useContext } from "react"; +import { GlobalContext } from "../../App"; +import { MultiTabLogViewer } from "../../common/MultiTabLogViewer"; +import { UnifiedJob } from "../../type/job"; + +type JobDriverLogsProps = { + job: Pick< + UnifiedJob, + | "job_id" + | "driver_node_id" + | "submission_id" + | "driver_agent_http_address" + | "driver_info" + | "type" + >; +}; + +export const JobDriverLogs = ({ job }: JobDriverLogsProps) => { + const { driver_node_id, submission_id, type } = job; + const filename = submission_id + ? `job-driver-${submission_id}.log` + : undefined; + + const { nodeMapByIp } = useContext(GlobalContext); + + let link: string | undefined; + + if (job.driver_node_id) { + link = `/logs/?nodeId=${encodeURIComponent(job.driver_node_id)}`; + } else if (job.driver_info?.node_id) { + link = `/logs/?nodeId=${encodeURIComponent(job.driver_info.node_id)}`; + } else if (job.driver_info?.node_ip_address) { + link = `/logs/?nodeId=${encodeURIComponent( + nodeMapByIp[job.driver_info.node_ip_address], + )}`; + } + + if (link && job.job_id) { + link += `&fileName=${job.job_id}`; + } else { + // Don't show "other logs" link if link is not available + // or job_id does not exist. + link = undefined; + } + + return ( + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/job/JobProgressBar.tsx b/historyserver/dashboard/ray/client/src/pages/job/JobProgressBar.tsx new file mode 100644 index 00000000000..09efc0b8ff5 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/JobProgressBar.tsx @@ -0,0 +1,112 @@ +import { Checkbox, FormControlLabel, LinearProgress } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { UnifiedJob } from "../../type/job"; +import { + AdvancedProgressBar, + AdvancedProgressBarProps, +} from "./AdvancedProgressBar"; +import { useJobProgress, useJobProgressByLineage } from "./hook/useJobProgress"; +import { TaskProgressBar } from "./TaskProgressBar"; + +type JobProgressBarProps = { + jobId: string | undefined; + job: Pick; +} & Pick; + +export const JobProgressBar = ({ + jobId, + job, + ...advancedProgressBarProps +}: JobProgressBarProps) => { + // Controls the first time we fetch the advanced progress bar data + const [advancedProgressBarRendered, setAdvancedProgressBarRendered] = + useState(false); + // Controls whether we continue to fetch the advanced progress bar data + const [advancedProgressBarExpanded, setAdvancedProgressBarExpanded] = + useState(false); + + const [showFinishedTasks, setShowFinishedTasks] = useState(true); + + useEffect(() => { + if (advancedProgressBarExpanded) { + setAdvancedProgressBarRendered(true); + } + }, [advancedProgressBarExpanded]); + + const { + progress, + isLoading: progressLoading, + driverExists, + totalTasks, + latestFetchTimestamp: progressTimestamp, + } = useJobProgress(jobId, advancedProgressBarExpanded); + const { + progressGroups, + isLoading: progressGroupsLoading, + total, + totalTasks: advancedTotalTasks, + latestFetchTimestamp: totalTimestamp, + } = useJobProgressByLineage( + advancedProgressBarRendered ? jobId : undefined, + !advancedProgressBarExpanded, + showFinishedTasks, + ); + + if (!driverExists) { + return ; + } + + if ( + progressLoading && + (progressGroupsLoading || !advancedProgressBarRendered) + ) { + return ; + } + + const { status } = job; + // Use whichever data was received the most recently + // Note these values may disagree in some way. It might better to consistently use one endpoint. + const [totalProgress, finalTotalTasks] = + total === undefined || + advancedTotalTasks === undefined || + progressTimestamp > totalTimestamp + ? [progress, totalTasks] + : [total, advancedTotalTasks]; + + return ( +
+ + setAdvancedProgressBarExpanded(!advancedProgressBarExpanded) + } + controls={ + { + setShowFinishedTasks(!checked); + }} + /> + } + label="Hide finished" + sx={{ marginRight: 0 }} + /> + } + /> + {advancedProgressBarExpanded && ( + + )} +
+ ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/job/JobRow.tsx b/historyserver/dashboard/ray/client/src/pages/job/JobRow.tsx new file mode 100644 index 00000000000..8440dcc26ed --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/JobRow.tsx @@ -0,0 +1,144 @@ +import { Box, Link, TableCell, TableRow, Tooltip } from "@mui/material"; +import React from "react"; +import { Link as RouterLink } from "react-router-dom"; +import { CodeDialogButtonWithPreview } from "../../common/CodeDialogButton"; +import { DurationText } from "../../common/DurationText"; +import { formatDateFromTimeMs } from "../../common/formatUtils"; +import { JobStatusWithIcon } from "../../common/JobStatus"; +import { + CpuProfilingLink, + CpuStackTraceLink, + MemoryProfilingButton, +} from "../../common/ProfilingLink"; +import { UnifiedJob } from "../../type/job"; +import { useJobProgress } from "./hook/useJobProgress"; +import { MiniTaskProgressBar } from "./TaskProgressBar"; + +type JobRowProps = { + job: UnifiedJob; +}; + +export const JobRow = ({ job }: JobRowProps) => { + const { + job_id, + submission_id, + driver_info, + status, + message, + start_time, + end_time, + entrypoint, + } = job; + const { progress, error, driverExists } = useJobProgress(job_id ?? undefined); + + const progressBar = (() => { + if (!driverExists) { + return ; + } + if (!progress || error) { + return "unavailable"; + } + if (status === "SUCCEEDED" || status === "FAILED") { + // TODO(aguo): Show failed tasks in progress bar once supported. + return ; + } else { + return ; + } + })(); + + const jobId = job_id ? job_id : submission_id; + + return ( + + + {job_id ? ( + + {job_id} + + ) : submission_id ? ( + + (no ray driver) + + ) : ( + "(no ray driver)" + )} + + {submission_id ?? "-"} + + + + {entrypoint} + + + + + + + + {message ? ( + + ) : ( + "-" + )} + + + {start_time && start_time > 0 ? ( + + ) : ( + "-" + )} + + {progressBar} + + {jobId && ( + + + Log + +
+
+ )} + +
+ +
+ +
+ + {start_time ? formatDateFromTimeMs(start_time) : "-"} + + + {end_time && end_time > 0 ? formatDateFromTimeMs(end_time) : "-"} + + {driver_info?.pid ?? "-"} +
+ ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/job/JobTaskNameProgressTable/JobTaskNameProgressTable.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/job/JobTaskNameProgressTable/JobTaskNameProgressTable.component.test.tsx new file mode 100644 index 00000000000..62f2a3fa806 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/JobTaskNameProgressTable/JobTaskNameProgressTable.component.test.tsx @@ -0,0 +1,45 @@ +import { render, screen } from "@testing-library/react"; +import React from "react"; +import { STYLE_WRAPPER } from "../../../util/test-utils"; +import { useJobProgressByTaskName } from "../hook/useJobProgress"; +import { JobTaskNameProgressTable } from "./JobTaskNameProgressTable"; + +jest.mock("../hook/useJobProgress"); + +describe("JobTaskNameProgressTable", () => { + it("renders", async () => { + (useJobProgressByTaskName as jest.Mock).mockReturnValue({ + progress: [ + { + name: "task_a", + progress: { + numRunning: 5, + numFailed: 5, + }, + }, + { + name: "task_b", + progress: { + numRunning: 5, + numFinished: 2, + }, + }, + ], + page: { pageNo: 1, pageSize: 10 }, + setPage: () => { + // purposefully empty + }, + total: 2, + } as any); + + render( + + + , + ); + + await screen.findByText("Task name"); + expect(screen.getByText("task_a")).toBeInTheDocument(); + expect(screen.getByText("task_b")).toBeInTheDocument(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/job/JobTaskNameProgressTable/JobTaskNameProgressTable.tsx b/historyserver/dashboard/ray/client/src/pages/job/JobTaskNameProgressTable/JobTaskNameProgressTable.tsx new file mode 100644 index 00000000000..55ce60bbe99 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/JobTaskNameProgressTable/JobTaskNameProgressTable.tsx @@ -0,0 +1,79 @@ +import { + Box, + Pagination, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, +} from "@mui/material"; +import React, { ReactElement } from "react"; +import { ClassNameProps } from "../../../common/props"; +import { HelpInfo } from "../../../components/Tooltip"; +import { useJobProgressByTaskName } from "../hook/useJobProgress"; +import { MiniTaskProgressBar } from "../TaskProgressBar"; + +const columns: { label: string; helpInfo?: ReactElement }[] = [ + { label: "Task name" }, + { label: "Failed" }, + { label: "Active" }, + { label: "Finished" }, + { label: "Tasks" }, +]; + +export type JobTaskNameProgressTableProps = { + jobId: string; +} & ClassNameProps; + +export const JobTaskNameProgressTable = ({ + jobId, + className, +}: JobTaskNameProgressTableProps) => { + const { progress, page, setPage, total } = useJobProgressByTaskName(jobId); + + return ( + +
+ setPage(pageNo)} + /> +
+ + + + {columns.map(({ label, helpInfo }) => ( + + + {label} + {helpInfo && ( + {helpInfo} + )} + + + ))} + + + + {progress.map( + ({ name, progress, numFailed, numActive, numFinished }) => { + return ( + + {name} + {numFailed} + {numActive} + {numFinished} + + + + + ); + }, + )} + +
+
+ ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/job/JobTaskNameProgressTable/index.ts b/historyserver/dashboard/ray/client/src/pages/job/JobTaskNameProgressTable/index.ts new file mode 100644 index 00000000000..4b78bb818bb --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/JobTaskNameProgressTable/index.ts @@ -0,0 +1 @@ +export * from "./JobTaskNameProgressTable"; diff --git a/historyserver/dashboard/ray/client/src/pages/job/TaskProgressBar.tsx b/historyserver/dashboard/ray/client/src/pages/job/TaskProgressBar.tsx new file mode 100644 index 00000000000..676840fbe16 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/TaskProgressBar.tsx @@ -0,0 +1,183 @@ +import { Theme, useTheme } from "@mui/material"; +import React from "react"; +import { ProgressBar, ProgressBarSegment } from "../../components/ProgressBar"; +import { TaskProgress } from "../../type/job"; + +export type TaskProgressBarProps = TaskProgress & { + showAsComplete?: boolean; + showLegend?: boolean; + showTooltip?: boolean; + expanded?: boolean; + onClick?: () => void; + total?: number; + controls?: JSX.Element; +}; + +export const TaskProgressBar = ({ + numFinished = 0, + numRunning = 0, + numPendingArgsAvail = 0, + numPendingNodeAssignment = 0, + numSubmittedToWorker = 0, + numFailed = 0, + numCancelled = 0, + numUnknown = 0, + showAsComplete = false, + showLegend = true, + showTooltip = true, + expanded, + onClick, + total, + controls, +}: TaskProgressBarProps) => { + const theme = useTheme(); + const progress: ProgressBarSegment[] = [ + { + label: "Finished", + value: numFinished, + color: theme.palette.success.main, + }, + { + label: "Failed", + value: numFailed, + color: theme.palette.error.main, + }, + { + label: "Running", + value: numRunning, + color: theme.palette.primary.main, + }, + { + label: "Waiting for scheduling", + value: numPendingNodeAssignment + numSubmittedToWorker, + color: "#cfcf08", + }, + { + label: "Waiting for dependencies", + value: numPendingArgsAvail, + color: "#f79e02", + }, + { + label: "Cancelled", + value: numCancelled, + color: theme.palette.grey.A100, + }, + { + label: "Unknown", + value: numUnknown, + color: "#5f6469", + }, + ]; + return ( + + ); +}; + +export type MiniTaskProgressBarProps = TaskProgress & { + /** + * Whether to color the entire progress bar as complete. + * For example, when the job is complete. + */ + showAsComplete?: boolean; + /** + * Whether to show tooltip. + */ + showTooltip?: boolean; + /** + * Whether to show the total finished to the right of the progress bar. + */ + showTotal?: boolean; +}; + +export const MiniTaskProgressBar = ({ + numFinished = 0, + numRunning = 0, + numPendingArgsAvail = 0, + numPendingNodeAssignment = 0, + numSubmittedToWorker = 0, + numUnknown = 0, + numFailed = 0, + showAsComplete = false, + showTooltip = true, + showTotal = false, +}: MiniTaskProgressBarProps) => { + const theme = useTheme(); + if (showAsComplete) { + const total = + numFinished + + numRunning + + numPendingArgsAvail + + numPendingNodeAssignment + + numSubmittedToWorker + + numFailed + + numUnknown; + return ( + + ); + } else { + const progress: ProgressBarSegment[] = [ + { + label: "Finished", + value: numFinished, + color: theme.palette.success.main, + }, + { + label: "Failed", + value: numFailed, + color: theme.palette.error.main, + }, + { + label: "Running", + value: numRunning, + color: theme.palette.primary.main, + }, + { + label: "Waiting for scheduling", + value: numPendingNodeAssignment + numSubmittedToWorker, + color: "#cfcf08", + }, + { + label: "Waiting for dependencies", + value: numPendingArgsAvail, + color: "#f79e02", + }, + { + label: "Unknown", + value: numUnknown, + color: "#5f6469", + }, + ]; + return ( + + ); + } +}; diff --git a/historyserver/dashboard/ray/client/src/pages/job/TaskTimeline.tsx b/historyserver/dashboard/ray/client/src/pages/job/TaskTimeline.tsx new file mode 100644 index 00000000000..40a2cf6cdab --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/TaskTimeline.tsx @@ -0,0 +1,53 @@ +import { Button, Link, SxProps, Theme, Typography } from "@mui/material"; +import React from "react"; +import { RiDownload2Line } from "react-icons/ri"; +import { ClassNameProps } from "../../common/props"; +import { downloadTaskTimelineHref } from "../../service/task"; + +type TaskTimelineProps = { + jobId: string; +}; + +export const TaskTimeline = ({ jobId }: TaskTimelineProps) => { + return ( +
+ {/* TODO(aguo): Add link to external documentation about Timeline view. */} + + Timeline view shows how tasks are executed across different nodes and + worker processes. +
+ Download the trace file and analyze it by uploading it to tools like{" "} + + Perfetto UI + {" "} + or if you are using chrome,{" "} + chrome://tracing. You can use the + tool by visiting chrome://tracing using your address bar. +
+ +
+ ); +}; + +type TimelineDownloadButtonProps = { + jobId: string; + sx?: SxProps; +} & ClassNameProps; + +const TimelineDownloadButton = ({ + jobId, + className, + sx, +}: TimelineDownloadButtonProps) => { + return ( + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/job/hook/mockedUseJobList.ts b/historyserver/dashboard/ray/client/src/pages/job/hook/mockedUseJobList.ts new file mode 100644 index 00000000000..e343379a015 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/hook/mockedUseJobList.ts @@ -0,0 +1,29 @@ +import { JobStatus } from "../../../type/job"; + +export const JOB_LIST = [ + { + job_id: "01000000", + submission_id: "raysubmit_12345", + status: JobStatus.PENDING, + }, + { + job_id: "02000000", + submission_id: null, + status: JobStatus.FAILED, + }, + { + job_id: null, + submission_id: "raysubmit_23456", + status: JobStatus.RUNNING, + }, + { + job_id: "04000000", + submission_id: "raysubmit_34567", + status: JobStatus.STOPPED, + }, + { + job_id: "05000000", + submission_id: "raysubmit_45678", + status: JobStatus.SUCCEEDED, + }, +] as any; diff --git a/historyserver/dashboard/ray/client/src/pages/job/hook/useClusterStatus.ts b/historyserver/dashboard/ray/client/src/pages/job/hook/useClusterStatus.ts new file mode 100644 index 00000000000..ec34f1ca072 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/hook/useClusterStatus.ts @@ -0,0 +1,24 @@ +import useSWR from "swr"; +import { API_REFRESH_INTERVAL_MS } from "../../../common/constants"; +import { getRayStatus } from "../../../service/status"; + +export const useRayStatus = () => { + const { data: clusterStatus } = useSWR( + "useClusterStatus", + async () => { + try { + const rsp = await getRayStatus(); + return rsp.data; + } catch (e) { + console.error( + "Cluster Status Error. Couldn't get the cluster status data from the dashboard server.", + ); + } + }, + { refreshInterval: API_REFRESH_INTERVAL_MS }, + ); + + return { + clusterStatus, + }; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/job/hook/useJobDetail.ts b/historyserver/dashboard/ray/client/src/pages/job/hook/useJobDetail.ts new file mode 100644 index 00000000000..f26ff1f6de2 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/hook/useJobDetail.ts @@ -0,0 +1,31 @@ +import { useState } from "react"; +import { useParams } from "react-router-dom"; +import useSWR from "swr"; +import { API_REFRESH_INTERVAL_MS } from "../../../common/constants"; +import { getJobDetail } from "../../../service/job"; + +export const useJobDetail = () => { + const params = useParams() as { id: string }; + const [msg, setMsg] = useState("Loading the job detail"); + const [refreshing, setRefresh] = useState(true); + const { data: job, isLoading } = useSWR( + ["useJobDetail", params.id], + async ([_, jobId]) => { + try { + const rsp = await getJobDetail(jobId); + return rsp.data; + } catch (e) { + setMsg("Job Query Error Please Check JobId"); + setRefresh(false); + } + }, + { refreshInterval: refreshing ? API_REFRESH_INTERVAL_MS : 0 }, + ); + + return { + job, + isLoading, + msg, + params, + }; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/job/hook/useJobList.ts b/historyserver/dashboard/ray/client/src/pages/job/hook/useJobList.ts new file mode 100644 index 00000000000..f415bb09008 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/hook/useJobList.ts @@ -0,0 +1,61 @@ +import { useRef, useState } from "react"; +import useSWR from "swr"; +import { API_REFRESH_INTERVAL_MS } from "../../../common/constants"; +import { getJobList } from "../../../service/job"; + +export const useJobList = () => { + const [page, setPage] = useState({ pageSize: 10, pageNo: 1 }); + const [msg, setMsg] = useState("Loading the job list..."); + const [isRefreshing, setRefresh] = useState(true); + const [filter, setFilter] = useState< + { + key: "job_id" | "status"; + val: string; + }[] + >([]); + const refreshRef = useRef(isRefreshing); + const changeFilter = (key: "job_id" | "status", val: string) => { + const f = filter.find((e) => e.key === key); + if (f) { + f.val = val; + } else { + filter.push({ key, val }); + } + setFilter([...filter]); + }; + const onSwitchChange = (event: React.ChangeEvent) => { + setRefresh(event.target.checked); + }; + refreshRef.current = isRefreshing; + + const { data, isLoading } = useSWR( + "useJobList", + async () => { + const rsp = await getJobList(); + + if (rsp) { + setMsg("Fetched jobs"); + return rsp.data.sort( + (a, b) => (b.start_time ?? 0) - (a.start_time ?? 0), + ); + } + }, + { refreshInterval: isRefreshing ? API_REFRESH_INTERVAL_MS : 0 }, + ); + + const jobList = data ?? []; + + return { + jobList: jobList.filter((node) => + filter.every((f) => node[f.key] && (node[f.key] ?? "").includes(f.val)), + ), + msg, + isLoading, + isRefreshing, + onSwitchChange, + changeFilter, + page, + originalJobs: jobList, + setPage: (key: string, val: number) => setPage({ ...page, [key]: val }), + }; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/job/hook/useJobProgress.ts b/historyserver/dashboard/ray/client/src/pages/job/hook/useJobProgress.ts new file mode 100644 index 00000000000..02cb5666df1 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/hook/useJobProgress.ts @@ -0,0 +1,335 @@ +import _ from "lodash"; +import { useState } from "react"; +import useSWR from "swr"; +import { API_REFRESH_INTERVAL_MS } from "../../../common/constants"; +import { sliceToPage } from "../../../common/util"; +import { + getStateApiJobProgressByLineage, + getStateApiJobProgressByTaskName, +} from "../../../service/job"; +import { + JobProgressGroup, + NestedJobProgress, + StateApiJobProgressByTaskName, + StateApiNestedJobProgress, + TaskProgress, +} from "../../../type/job"; +import { TypeTaskStatus } from "../../../type/task"; + +export enum TaskStatus { + PENDING_ARGS_AVAIL = "PENDING_ARGS_AVAIL", + PENDING_NODE_ASSIGNMENT = "PENDING_NODE_ASSIGNMENT", + SUBMITTED_TO_WORKER = "SUBMITTED_TO_WORKER", + RUNNING = "RUNNING", + FINISHED = "FINISHED", + FAILED = "FAILED", + UNKNOWN = "UNKNOWN", +} + +const TASK_STATE_NAME_TO_PROGRESS_KEY: Record = { + [TypeTaskStatus.PENDING_ARGS_AVAIL]: TaskStatus.PENDING_ARGS_AVAIL, + [TypeTaskStatus.PENDING_NODE_ASSIGNMENT]: TaskStatus.PENDING_NODE_ASSIGNMENT, + [TypeTaskStatus.PENDING_OBJ_STORE_MEM_AVAIL]: + TaskStatus.PENDING_NODE_ASSIGNMENT, + [TypeTaskStatus.PENDING_ARGS_FETCH]: TaskStatus.PENDING_NODE_ASSIGNMENT, + [TypeTaskStatus.SUBMITTED_TO_WORKER]: TaskStatus.SUBMITTED_TO_WORKER, + [TypeTaskStatus.RUNNING]: TaskStatus.RUNNING, + [TypeTaskStatus.RUNNING_IN_RAY_GET]: TaskStatus.RUNNING, + [TypeTaskStatus.RUNNING_IN_RAY_WAIT]: TaskStatus.RUNNING, + [TypeTaskStatus.FINISHED]: TaskStatus.FINISHED, + [TypeTaskStatus.FAILED]: TaskStatus.FAILED, + [TypeTaskStatus.NIL]: TaskStatus.UNKNOWN, +}; + +export const TaskStatusToTaskProgressMapping: Record< + TaskStatus, + keyof TaskProgress +> = { + [TaskStatus.PENDING_ARGS_AVAIL]: "numPendingArgsAvail", + [TaskStatus.PENDING_NODE_ASSIGNMENT]: "numPendingNodeAssignment", + [TaskStatus.SUBMITTED_TO_WORKER]: "numSubmittedToWorker", + [TaskStatus.RUNNING]: "numRunning", + [TaskStatus.FINISHED]: "numFinished", + [TaskStatus.FAILED]: "numFailed", + [TaskStatus.UNKNOWN]: "numUnknown", +}; + +const useFetchStateApiProgressByTaskName = ( + jobId: string | undefined, + isRefreshing: boolean, + setMsg: (msg: string) => void, + setError: (error: boolean) => void, + setRefresh: (refresh: boolean) => void, + disableRefresh: boolean, + setLatestFetchTimestamp?: (time: number) => void, +) => { + return useSWR( + jobId ? ["useJobProgressByTaskName", jobId] : null, + async ([_, jobId]) => { + const rsp = await getStateApiJobProgressByTaskName(jobId); + setMsg(rsp.data.msg); + + if (rsp.data.result) { + setLatestFetchTimestamp?.(new Date().getTime()); + const summary = formatSummaryToTaskProgress( + rsp.data.data.result.result, + ); + return { summary, totalTasks: rsp.data.data.result.num_filtered }; + } else { + setError(true); + setRefresh(false); + } + }, + { + refreshInterval: + isRefreshing && !disableRefresh ? API_REFRESH_INTERVAL_MS : 0, + revalidateOnFocus: false, + }, + ); +}; + +/** + * Hook for fetching a job's task progress. + * Refetches every 4 seconds unless refresh switch is toggled off. + * + * If jobId is undefined, we will not fetch the job progress. + * @param jobId The id of the job whose task progress to fetch or undefined + * to fetch all progress for all jobs + */ +export const useJobProgress = ( + jobId: string | undefined, + disableRefresh = false, +) => { + const [msg, setMsg] = useState("Loading progress..."); + const [error, setError] = useState(false); + const [isRefreshing, setRefresh] = useState(true); + const [latestFetchTimestamp, setLatestFetchTimestamp] = useState(0); + const { data, isLoading } = useFetchStateApiProgressByTaskName( + jobId, + isRefreshing, + setMsg, + setError, + setRefresh, + disableRefresh, + setLatestFetchTimestamp, + ); + + const summed = (data?.summary ?? []).reduce((acc, task) => { + Object.entries(task.progress).forEach(([k, count]) => { + const key = k as keyof TaskProgress; + acc[key] = (acc[key] ?? 0) + count; + }); + return acc; + }, {} as TaskProgress); + + const driverExists = !jobId ? false : true; + return { + progress: summed, + totalTasks: data?.totalTasks, + isLoading, + msg, + error, + driverExists, + latestFetchTimestamp, + }; +}; + +/** + * Hook for fetching a job's task progress grouped by task name. + * Refetches every 4 seconds unless refresh switch is toggled off. + * + * If jobId is not provided, will fetch the task progress across all jobs. + * @param jobId The id of the job whose task progress to fetch or undefined + * to fetch all progress for all jobs + */ +export const useJobProgressByTaskName = (jobId: string) => { + const [page, setPage] = useState(1); + const [msg, setMsg] = useState("Loading progress..."); + const [error, setError] = useState(false); + const [isRefreshing, setRefresh] = useState(true); + const onSwitchChange = (event: React.ChangeEvent) => { + setRefresh(event.target.checked); + }; + + const { data, isLoading } = useFetchStateApiProgressByTaskName( + jobId, + isRefreshing, + setMsg, + setError, + setRefresh, + false, + ); + + const formattedTasks = (data?.summary ?? []).map((task) => { + const { + numFailed = 0, + numPendingArgsAvail = 0, + numPendingNodeAssignment = 0, + numRunning = 0, + numSubmittedToWorker = 0, + numFinished = 0, + } = task.progress; + + const numActive = + numPendingArgsAvail + + numPendingNodeAssignment + + numRunning + + numSubmittedToWorker; + + return { ...task, numFailed, numActive, numFinished }; + }); + const sortedTasks = _.orderBy( + formattedTasks, + ["numFailed", "numActive", "numFinished"], + ["desc", "desc", "desc"], + ); + const paginatedTasks = sliceToPage(sortedTasks, page).items; + + return { + progress: paginatedTasks, + page: { pageNo: page, pageSize: 10 }, + total: formattedTasks.length, + totalTasks: data?.totalTasks, + isLoading, + setPage, + msg, + error, + onSwitchChange, + }; +}; + +const formatStateCountsToProgress = (stateCounts: { + [stateName: string]: number; +}) => { + const formattedProgress: TaskProgress = {}; + Object.entries(stateCounts).forEach(([state, count]) => { + const taskStatus: TaskStatus = + TASK_STATE_NAME_TO_PROGRESS_KEY[state as TypeTaskStatus]; + + const key: keyof TaskProgress = + TaskStatusToTaskProgressMapping[taskStatus] ?? "numUnknown"; + + formattedProgress[key] = (formattedProgress[key] ?? 0) + count; + }); + + return formattedProgress; +}; + +export const formatSummaryToTaskProgress = ( + summary: StateApiJobProgressByTaskName, +) => { + const tasks = summary.node_id_to_summary.cluster.summary; + const formattedTasks = Object.entries(tasks).map(([name, task]) => { + const formattedProgress = formatStateCountsToProgress(task.state_counts); + return { name, progress: formattedProgress }; + }); + + return formattedTasks; +}; + +const formatToJobProgressGroup = ( + nestedJobProgress: NestedJobProgress, + showFinishedTasks = true, +): JobProgressGroup | undefined => { + const formattedProgress = formatStateCountsToProgress( + nestedJobProgress.state_counts, + ); + + const total = Object.values(formattedProgress).reduce( + (acc, count) => acc + count, + 0, + ); + if ( + !showFinishedTasks && + total - (formattedProgress.numFinished ?? 0) === 0 + ) { + return undefined; + } + + return { + name: nestedJobProgress.name, + key: nestedJobProgress.key, + progress: formattedProgress, + children: nestedJobProgress.children + .map((child) => formatToJobProgressGroup(child, showFinishedTasks)) + .filter((child): child is JobProgressGroup => child !== undefined), + type: nestedJobProgress.type, + link: nestedJobProgress.link, + }; +}; + +export const formatNestedJobProgressToJobProgressGroup = ( + summary: StateApiNestedJobProgress, + showFinishedTasks = true, +) => { + const tasks = summary.node_id_to_summary.cluster.summary; + const progressGroups = tasks + .map((task) => formatToJobProgressGroup(task, showFinishedTasks)) + .filter((group): group is JobProgressGroup => group !== undefined); + + const total = tasks.reduce((acc, group) => { + const formattedProgress = formatStateCountsToProgress(group.state_counts); + Object.entries(formattedProgress).forEach(([key, count]) => { + const progressKey = key as keyof TaskProgress; + acc[progressKey] = (acc[progressKey] ?? 0) + count; + }); + return acc; + }, {}); + + return { progressGroups, total }; +}; + +/** + * Hook for fetching a job's task progress grouped by lineage. This is + * used for the Advanced progress bar. + * Refetches every 4 seconds. + * + * @param jobId The id of the job whose task progress to fetch or undefined + * to fetch all progress for all jobs + * If null, we will avoid fetching. + */ +export const useJobProgressByLineage = ( + jobId: string | undefined, + disableRefresh = false, + showFinishedTasks = true, +) => { + const [msg, setMsg] = useState("Loading progress..."); + const [error, setError] = useState(false); + const [isRefreshing, setRefresh] = useState(true); + const [latestFetchTimestamp, setLatestFetchTimestamp] = useState(0); + + const { data, isLoading } = useSWR( + jobId ? ["useJobProgressByLineageAndName", jobId, showFinishedTasks] : null, + async ([_, jobId, showFinishedTasks]) => { + const rsp = await getStateApiJobProgressByLineage(jobId); + setMsg(rsp.data.msg); + + if (rsp.data.result) { + setLatestFetchTimestamp(new Date().getTime()); + const summary = formatNestedJobProgressToJobProgressGroup( + rsp.data.data.result.result, + showFinishedTasks, + ); + return { summary, totalTasks: rsp.data.data.result.num_filtered }; + } else { + setError(true); + setRefresh(false); + } + }, + { + refreshInterval: + isRefreshing && !disableRefresh ? API_REFRESH_INTERVAL_MS : 0, + revalidateOnFocus: false, + }, + ); + + return { + progressGroups: data?.summary?.progressGroups, + total: data?.summary?.total, + totalTasks: data?.totalTasks, + isLoading, + msg, + error, + latestFetchTimestamp, + }; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/job/hook/useJobProgress.unit.test.ts b/historyserver/dashboard/ray/client/src/pages/job/hook/useJobProgress.unit.test.ts new file mode 100644 index 00000000000..90fc95abe94 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/hook/useJobProgress.unit.test.ts @@ -0,0 +1,382 @@ +import { + JobProgressGroup, + StateApiJobProgressByTaskName, + StateApiNestedJobProgress, + TaskProgress, +} from "../../../type/job"; +import { TypeTaskStatus, TypeTaskType } from "../../../type/task"; +import { + formatNestedJobProgressToJobProgressGroup, + formatSummaryToTaskProgress, +} from "./useJobProgress"; + +describe("formatSummaryToTaskProgress", () => { + it("formats correctly", () => { + const summary: StateApiJobProgressByTaskName = { + node_id_to_summary: { + cluster: { + summary: { + task_1: { + func_or_class_name: "task_1", + state_counts: { + [TypeTaskStatus.FINISHED]: 1, + [TypeTaskStatus.FAILED]: 2, + [TypeTaskStatus.RUNNING]: 3, + [TypeTaskStatus.RUNNING_IN_RAY_GET]: 4, + [TypeTaskStatus.PENDING_ARGS_AVAIL]: 5, + }, + }, + task_2: { + func_or_class_name: "task_2", + state_counts: { + [TypeTaskStatus.FINISHED]: 100, + [TypeTaskStatus.NIL]: 5, + }, + }, + task_3: { + func_or_class_name: "task_3", + state_counts: { + [TypeTaskStatus.RUNNING]: 1, + someNewState: 1, + }, + }, + }, + }, + }, + }; + + const expected: { name: string; progress: TaskProgress }[] = [ + { + name: "task_1", + progress: { + numFinished: 1, + numFailed: 2, + numRunning: 7, + numPendingArgsAvail: 5, + }, + }, + { + name: "task_2", + progress: { + numFinished: 100, + numUnknown: 5, + }, + }, + { + name: "task_3", + progress: { + numRunning: 1, + numUnknown: 1, + }, + }, + ]; + + expect(formatSummaryToTaskProgress(summary)).toEqual(expected); + }); +}); + +describe("formatNestedJobProgressToJobProgressGroup", () => { + it("formats correctly without", () => { + // First without hiding progress + const summary: StateApiNestedJobProgress = { + node_id_to_summary: { + cluster: { + summary: [ + { + name: "failed_tasks", + key: "failed_tasks_group", + state_counts: { + [TypeTaskStatus.FAILED]: 3, + }, + type: "GROUP", + children: [ + { + name: "failed_tasks", + key: "failed_tasks_1", + state_counts: { + [TypeTaskStatus.FAILED]: 1, + }, + type: TypeTaskType.NORMAL_TASK, + children: [], + }, + { + name: "failed_tasks", + key: "failed_tasks_2", + state_counts: { + [TypeTaskStatus.FAILED]: 1, + }, + type: TypeTaskType.NORMAL_TASK, + children: [], + }, + { + name: "failed_tasks", + key: "failed_tasks_3", + state_counts: { + [TypeTaskStatus.FAILED]: 1, + }, + type: TypeTaskType.NORMAL_TASK, + children: [], + }, + ], + }, + { + name: "succeeded_tasks", + key: "succeeded_tasks_group", + state_counts: { + [TypeTaskStatus.FINISHED]: 2, + }, + type: "GROUP", + children: [ + { + name: "succeeded_tasks", + key: "succeeded_tasks_1", + state_counts: { + [TypeTaskStatus.FINISHED]: 1, + }, + type: TypeTaskType.NORMAL_TASK, + children: [], + }, + { + name: "succeeded_tasks", + key: "succeeded_tasks_2", + state_counts: { + [TypeTaskStatus.FINISHED]: 1, + }, + type: TypeTaskType.NORMAL_TASK, + children: [], + }, + ], + }, + { + name: "father_task", + key: "father_task", + state_counts: { + [TypeTaskStatus.FINISHED]: 1, + [TypeTaskStatus.FAILED]: 1, + }, + type: TypeTaskType.NORMAL_TASK, + children: [ + { + name: "suceeded_child", + key: "succeeded_child_1", + state_counts: { + [TypeTaskStatus.FINISHED]: 1, + }, + type: TypeTaskType.NORMAL_TASK, + children: [], + }, + { + name: "failed_child", + key: "failed_child_1", + state_counts: { + [TypeTaskStatus.FAILED]: 1, + }, + type: TypeTaskType.NORMAL_TASK, + children: [], + }, + ], + }, + ], + }, + }, + }; + + const expectedWithFinishedTasks: { + total: TaskProgress; + progressGroups: JobProgressGroup[]; + } = { + total: { + numFinished: 3, + numFailed: 4, + }, + progressGroups: [ + { + name: "failed_tasks", + key: "failed_tasks_group", + progress: { + numFailed: 3, + }, + link: undefined, + type: "GROUP", + children: [ + { + name: "failed_tasks", + key: "failed_tasks_1", + progress: { + numFailed: 1, + }, + link: undefined, + type: TypeTaskType.NORMAL_TASK, + children: [], + }, + { + name: "failed_tasks", + key: "failed_tasks_2", + progress: { + numFailed: 1, + }, + link: undefined, + type: TypeTaskType.NORMAL_TASK, + children: [], + }, + { + name: "failed_tasks", + key: "failed_tasks_3", + progress: { + numFailed: 1, + }, + link: undefined, + type: TypeTaskType.NORMAL_TASK, + children: [], + }, + ], + }, + { + name: "succeeded_tasks", + key: "succeeded_tasks_group", + progress: { + numFinished: 2, + }, + link: undefined, + type: "GROUP", + children: [ + { + name: "succeeded_tasks", + key: "succeeded_tasks_1", + progress: { + numFinished: 1, + }, + link: undefined, + type: TypeTaskType.NORMAL_TASK, + children: [], + }, + { + name: "succeeded_tasks", + key: "succeeded_tasks_2", + progress: { + numFinished: 1, + }, + link: undefined, + type: TypeTaskType.NORMAL_TASK, + children: [], + }, + ], + }, + { + name: "father_task", + key: "father_task", + progress: { + numFinished: 1, + numFailed: 1, + }, + link: undefined, + type: TypeTaskType.NORMAL_TASK, + children: [ + { + name: "suceeded_child", + key: "succeeded_child_1", + progress: { + numFinished: 1, + }, + link: undefined, + type: TypeTaskType.NORMAL_TASK, + children: [], + }, + { + name: "failed_child", + key: "failed_child_1", + progress: { + numFailed: 1, + }, + link: undefined, + type: TypeTaskType.NORMAL_TASK, + children: [], + }, + ], + }, + ], + }; + + expect(formatNestedJobProgressToJobProgressGroup(summary, true)).toEqual( + expectedWithFinishedTasks, + ); + + const expectedWithoutFinishedTasks: { + total: TaskProgress; + progressGroups: JobProgressGroup[]; + } = { + total: { + numFinished: 3, + numFailed: 4, + }, + progressGroups: [ + { + name: "failed_tasks", + key: "failed_tasks_group", + type: "GROUP", + progress: { + numFailed: 3, + }, + children: [ + { + key: "failed_tasks_1", + name: "failed_tasks", + link: undefined, + type: TypeTaskType.NORMAL_TASK, + progress: { + numFailed: 1, + }, + children: [], + }, + { + key: "failed_tasks_2", + name: "failed_tasks", + link: undefined, + type: TypeTaskType.NORMAL_TASK, + progress: { + numFailed: 1, + }, + children: [], + }, + { + key: "failed_tasks_3", + name: "failed_tasks", + link: undefined, + type: TypeTaskType.NORMAL_TASK, + progress: { + numFailed: 1, + }, + children: [], + }, + ], + }, + { + name: "father_task", + key: "father_task", + link: undefined, + progress: { + numFinished: 1, + numFailed: 1, + }, + type: TypeTaskType.NORMAL_TASK, + children: [ + { + name: "failed_child", + key: "failed_child_1", + link: undefined, + progress: { + numFailed: 1, + }, + type: TypeTaskType.NORMAL_TASK, + children: [], + }, + ], + }, + ], + }; + + expect(formatNestedJobProgressToJobProgressGroup(summary, false)).toEqual( + expectedWithoutFinishedTasks, + ); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/job/index.tsx b/historyserver/dashboard/ray/client/src/pages/job/index.tsx new file mode 100644 index 00000000000..8e4202835f6 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/job/index.tsx @@ -0,0 +1,181 @@ +import { + Box, + InputAdornment, + Switch, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + TextField, + Typography, +} from "@mui/material"; +import Autocomplete from "@mui/material/Autocomplete"; +import Pagination from "@mui/material/Pagination"; +import React from "react"; +import { Outlet } from "react-router-dom"; +import { sliceToPage } from "../../common/util"; +import Loading from "../../components/Loading"; +import { SearchInput } from "../../components/SearchComponent"; +import TitleCard from "../../components/TitleCard"; +import { HelpInfo } from "../../components/Tooltip"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import { useJobList } from "./hook/useJobList"; +import { JobRow } from "./JobRow"; + +const columns = [ + { label: "Job ID" }, + { label: "Submission ID" }, + { label: "Entrypoint" }, + { label: "Status" }, + { label: "Status message" }, + { label: "Duration" }, + { + label: "Tasks", + helpInfo: ( + + The progress of the all submitted tasks per job. Tasks that are not yet + submitted do not show up in the progress bar. + + ), + }, + { + label: "Actions", + }, + { label: "StartTime" }, + { label: "EndTime" }, + { label: "Driver Pid" }, +]; + +const JobList = () => { + const { + msg, + isLoading, + isRefreshing, + onSwitchChange, + jobList, + changeFilter, + page, + setPage, + } = useJobList(); + + const { + items: list, + constrainedPage, + maxPage, + } = sliceToPage(jobList, page.pageNo, page.pageSize); + + return ( + + + + Auto Refresh: + { + onSwitchChange(event); + }} + name="refresh" + inputProps={{ "aria-label": "secondary checkbox" }} + /> +
+ Request Status: {msg} +
+ + + + changeFilter("job_id", value)} + /> + { + setPage("pageSize", Math.min(Number(value), 500) || 10); + }, + endAdornment: ( + Per Page + ), + }} + /> + + changeFilter("status", value.trim()) + } + renderInput={(params) => } + /> + +
+ setPage("pageNo", pageNo)} + /> +
+ + + + {columns.map(({ label, helpInfo }) => ( + + + {label} + {helpInfo && ( + {helpInfo} + )} + + + ))} + + + + {list.map((job, index) => { + const { job_id, submission_id } = job; + return ( + + ); + })} + +
+
+
+
+ ); +}; + +/** + * Jobs page for the new information hierarchy + */ +export const JobsLayout = () => { + return ( + + + + + ); +}; + +export default JobList; diff --git a/historyserver/dashboard/ray/client/src/pages/layout/MainNavLayout.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/layout/MainNavLayout.component.test.tsx new file mode 100644 index 00000000000..997ef4229d9 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/layout/MainNavLayout.component.test.tsx @@ -0,0 +1,147 @@ +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import React from "react"; +import { Link, MemoryRouter, Outlet, Route, Routes } from "react-router-dom"; +import { STYLE_WRAPPER } from "../../util/test-utils"; +import { MainNavPageInfo } from "./mainNavContext"; +import { MainNavLayout } from "./MainNavLayout"; + +const TestPageA = () => { + return ( +
+ + Page A1 + go-a2 + +
+ ); +}; +const TestChildPageA = () => { + return ( +
+ + Page A2 + go-a3 + +
+ ); +}; +const TestGrandChildPageA = () => { + return ( +
+ + Page A3 + go-b2 +
+ ); +}; +const TestPageB = () => { + return ( +
+ + Page B1 + +
+ ); +}; +const TestChildNonMainNavPageB = () => { + return ( +
+ {/* Not a Main Nav page */} + Page B2 + go-b3 + +
+ ); +}; +const TestGrandChildPageB = () => { + return ( +
+ + Page B3 + go-c +
+ ); +}; +const TestPageC = () => { + return ( +
+ + Page C +
+ ); +}; + +const TestApp = ({ location = "/" }: { location?: string }) => { + return ( + + + + }> + } path="a1"> + } path="a2"> + } path="a3" /> + + + } path="b1"> + } path="b2"> + } path="b3" /> + + + } path="c" /> + + + + + ); +}; + +describe("MainNavLayout", () => { + it("navigates and renders breadcrumbs correctly", async () => { + const user = userEvent.setup(); + + render(); + await screen.findByText(/Page A1/); + // No breadcrumbs when there is only 1 page + expect(screen.queryByText(/breadcrumb-a1/)).not.toBeInTheDocument(); + + await user.click(screen.getByText(/go-a2/)); + await screen.findByText(/Page A2/); + expect(screen.getByText(/breadcrumb-a1/)).toBeInTheDocument(); + expect(screen.getByText(/breadcrumb-a2/)).toBeInTheDocument(); + + await user.click(screen.getByText(/go-a3/)); + await screen.findByText(/Page A3/); + expect(screen.getByText(/breadcrumb-a1/)).toBeInTheDocument(); + expect(screen.getByText(/breadcrumb-a2/)).toBeInTheDocument(); + expect(screen.getByText(/breadcrumb-a3/)).toBeInTheDocument(); + + await user.click(screen.getByText(/go-b2/)); + await screen.findByText(/Page B2/); + // No breadcrumbs because only one of the pages is a main nav page + expect(screen.queryByText(/breadcrumb-b1/)).not.toBeInTheDocument(); + expect(screen.queryByText(/breadcrumb-b3/)).not.toBeInTheDocument(); + + await user.click(screen.getByText(/go-b3/)); + await screen.findByText(/Page B3/); + expect(screen.getByText(/breadcrumb-b1/)).toBeInTheDocument(); + expect(screen.getByText(/breadcrumb-b3/)).toBeInTheDocument(); + + // Test that single non-parent pages work as well + await user.click(screen.getByText(/go-c/)); + await screen.findByText(/Page C/); + expect(screen.queryByText(/breadcrumb-c/)).not.toBeInTheDocument(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/layout/MainNavLayout.tsx b/historyserver/dashboard/ray/client/src/pages/layout/MainNavLayout.tsx new file mode 100644 index 00000000000..1abb231e432 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/layout/MainNavLayout.tsx @@ -0,0 +1,294 @@ +import {Box, IconButton, Link, Tooltip, Typography} from "@mui/material"; +import Cookies from 'js-cookie' +import React, {useContext, useEffect, useMemo} from "react"; +import {RiBookMarkLine, RiFeedbackLine} from "react-icons/ri/"; +import {Link as RouterLink, Outlet, useParams} from "react-router-dom"; +import {GlobalContext} from "../../App"; +import Logo from "../../logo.svg"; +import {MainNavContext, useMainNavState} from "./mainNavContext"; + +export const MAIN_NAV_HEIGHT = 56; +export const BREADCRUMBS_HEIGHT = 36; + +/** + * This is the main navigation stack of the entire application. + * Only certain pages belong to the main navigation stack. + * + * This layout is always shown at the top with at least one row and up to two rows. + * - The first row shows all the top level pages of the main navigation stack and + * highlights the top level page that the user is currently on. + * - The second row show breadcrumbs of the main navigation stack. + * If we are at a top level page (i.e. the breadcrumbs is of length 1), + * we do not show the breadcrumbs. + * + * To use this layout, simply create use react-router-6 nested routes to produce the + * correct hierarchy. Then for the routes which should be considered part of the main + * navigation stack, render the component at the top of the route. + */ +export const MainNavLayout = () => { + const mainNavContextState = useMainNavState(); + + const { clusterName, sessionName } = useParams(); + useEffect(function () { + if (clusterName) { + const safeSessionName = sessionName ? sessionName : ""; + Cookies.set('cluster_name', clusterName); + Cookies.set('session_name', safeSessionName); + } + }, [clusterName, sessionName]) + + return ( + + + + + +
+ + ); +}; + +const Main = () => { + const { mainNavPageHierarchy } = useContext(MainNavContext); + + const tallNav = mainNavPageHierarchy.length > 1; + + return ( + + + + ); +}; + +const MainNavBar = () => { + const { clusterName, sessionName } = useParams(); + const { mainNavPageHierarchy } = useContext(MainNavContext); + const rootRouteId = mainNavPageHierarchy[0]?.id; + const { metricsContextLoaded, grafanaHost } = useContext(GlobalContext); + + let navItems = useMemo(() => + [ + { + title: "Overview", + path: `/clusters/${clusterName}/${sessionName}/overview`, + id: "overview", + }, + { + title: "Jobs", + path: `/clusters/${clusterName}/${sessionName}/jobs`, + id: "jobs", + }, + { + title: "Serve", + path: `/clusters/${clusterName}/${sessionName}/serve`, + id: "serve", + }, + { + title: "Cluster", + path: `/clusters/${clusterName}/${sessionName}/cluster`, + id: "cluster", + }, + { + title: "Actors", + path: `/clusters/${clusterName}/${sessionName}/actors`, + id: "actors", + }, + { + title: "Metrics", + path: `/clusters/${clusterName}/${sessionName}/metrics`, + id: "metrics", + }, + { + title: "Logs", + path: `/clusters/${clusterName}/${sessionName}/logs`, + id: "logs", + } + ], [clusterName, sessionName]); + + if (!metricsContextLoaded || grafanaHost === "DISABLED") { + navItems = navItems.filter(({ id }) => id !== "metrics"); + } + + return ( + + + Ray + + {navItems.map(({ title, path, id }) => ( + + + {title} + + + ))} + + + + + + + + + + + + + + + ); +}; + +const MainNavBreadcrumbs = () => { + const { mainNavPageHierarchy } = useContext(MainNavContext); + + if (mainNavPageHierarchy.length <= 1) { + // Only render breadcrumbs if we have at least 2 items + return null; + } + + let currentPath = ""; + + return ( + + {mainNavPageHierarchy.map(({ title, id, path }, index) => { + if (path) { + if (path.startsWith("/")) { + currentPath = path; + } else { + currentPath = `${currentPath}/${path}`; + } + } + const linkOrText = path ? ( + + {title} + + ) : ( + title + ); + if (index === 0) { + return ( + + {linkOrText} + + ); + } else { + return ( + + + {"/"} + + + {linkOrText} + + + ); + } + })} + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/layout/SideTabLayout.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/layout/SideTabLayout.component.test.tsx new file mode 100644 index 00000000000..35f32044a68 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/layout/SideTabLayout.component.test.tsx @@ -0,0 +1,83 @@ +import { cleanup, render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import React from "react"; +import { MemoryRouter, Route, Routes } from "react-router-dom"; + +import { STYLE_WRAPPER } from "../../util/test-utils"; +import { SideTabLayout, SideTabPage, SideTabRouteLink } from "./SideTabLayout"; + +const TestApp = ({ location = "/" }: { location?: string }) => { + return ( + + + + + + + + } + > + +
Page Contents A
+ + } + path="tab-a" + /> + +
Page Contents B
+ + } + path="tab-b" + /> + Not a tabbed page} path="page-c" /> + +
+
+
+ ); +}; + +describe("SideTabLayout", () => { + it("navigates and renders correctly", async () => { + const user = userEvent.setup(); + + render(); + await screen.findByText(/Page Contents A/); + expect(screen.queryByText(/Page Contents B/)).toBeNull(); + expect(screen.getByRole("tab", { selected: true })).toHaveTextContent( + "tab-a", + ); + + // Go to tab b + await user.click(screen.getByText(/tab-b/)); + await screen.findByText(/Page Contents B/); + expect(screen.queryByText(/Page Contents A/)).toBeNull(); + expect(screen.getByRole("tab", { selected: true })).toHaveTextContent( + "tab-b", + ); + + cleanup(); + + // Go to non tab page and make sure nothing is broken + render(); + await screen.findByText(/Not a tabbed page/); + expect(screen.queryByText(/Page Contents A/)).toBeNull(); + expect(screen.queryByText(/Page Contents B/)).toBeNull(); + expect(screen.queryByRole("tab", { selected: true })).toBeNull(); + + // Go to tab a + await user.click(screen.getByText(/tab-a/)); + await screen.findByText(/Page Contents A/); + expect(screen.queryByText(/Not a tabbed page/)).toBeNull(); + expect(screen.queryByText(/Page Contents B/)).toBeNull(); + expect(screen.getByRole("tab", { selected: true })).toHaveTextContent( + "tab-a", + ); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/layout/SideTabLayout.tsx b/historyserver/dashboard/ray/client/src/pages/layout/SideTabLayout.tsx new file mode 100644 index 00000000000..2e4b56ba7c4 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/layout/SideTabLayout.tsx @@ -0,0 +1,130 @@ +import { Box } from "@mui/material"; +import React, { PropsWithChildren, useContext } from "react"; +import { IconType } from "react-icons/lib"; +import { Link, Outlet } from "react-router-dom"; +import { StyledTooltip } from "../../components/Tooltip"; +import { + SideTabContext, + useSideTabPage, + useSideTabState, +} from "./sideTabContext"; + +/** + * A layout which has tabs on the left and content on the right. + * Render components as children to display tabs. + * + * The standard way to use this layout is to use nested routes. + * A parent route should render the SideTabLayout with SideTabs + * and children routes should render render a SideTabPage along + * with the contents of the page. + * + * See "TestApp" in SideTabLayout.component.test.tsx for an example. + */ +export const SideTabLayout = ({ children }: PropsWithChildren<{}>) => { + const sideTabState = useSideTabState(); + return ( + + + + {children} + + + + + + + ); +}; + +export type SideTabProps = { + /** + * Required unique id to identify which tab should be highlighted when on that tab's page. + */ + tabId: string; + /** + * The title is shown as a tooltip when hovering over the tab. + */ + title: string; + Icon?: IconType; +}; + +/** + * A single tab to show in the tab bar + */ +export const SideTab = ({ tabId, title, Icon }: SideTabProps) => { + const { selectedTab } = useContext(SideTabContext); + const isSelected = selectedTab === tabId; + return ( + + + {Icon ? : tabId} + + + ); +}; + +export type SideTabRouteLinkProps = SideTabProps & { + /** + * Path to link to. If not provided, we default to tabId. + */ + to?: string; +}; + +/** + * A that also links to a route. In most cases, the SideTabLayout will + * be used closely with routing so we want the tabs to link to different page. + */ +export const SideTabRouteLink = ({ to, ...props }: SideTabRouteLinkProps) => { + const { tabId } = props; + return ( + + + + ); +}; + +export type SideTabPageProps = { + tabId: string; + children: JSX.Element | null; +}; + +/** + * A page that represents the content of a tab. Render this when we are on the + * tab's page and it will make sure the tab bar has the correct icon highlighted. + */ +export const SideTabPage = ({ tabId, children }: SideTabPageProps) => { + useSideTabPage(tabId); + return children; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/layout/mainNavContext.ts b/historyserver/dashboard/ray/client/src/pages/layout/mainNavContext.ts new file mode 100644 index 00000000000..ee24ff850d8 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/layout/mainNavContext.ts @@ -0,0 +1,158 @@ +import React, { useCallback, useContext, useEffect, useState } from "react"; + +export type MainNavPage = { + /** + * This gets shown in the breadcrumbs. + */ + title: string; + /** + * This gets shown as the HTML document page title. If this is not set, the title field will be used automatically. + */ + pageTitle?: string; + /** + * This helps identifies the current page a user is on and highlights the nav bar correctly. + * This should be unique per page within an hiearchy. i.e. you should NOT put two pages with the same ID + * as parents or children of each other. + * DO NOT change the pageId of a page. The behavior of the main nav and + * breadcrumbs is undefined in that case. + */ + id: string; + /** + * URL to link to access this route. + * If this begins with a `/`, it is treated as an absolute path. + * If not, this is treated as a relative path and the path is appended to the parent breadcrumb's path. + */ + path?: string; + + +}; + +export type MainNavContextType = { + mainNavPageHierarchy: MainNavPage[]; + addPage: (pageId: string) => void; + updatePage: ( + title: string, + id: string, + path?: string, + pageTitle?: string, + ) => void; + removePage: (pageId: string) => void; +}; + +export const DEFAULT_VALUE: MainNavContextType = { + mainNavPageHierarchy: [], + addPage: () => { + /* purposefully empty */ + }, + updatePage: () => { + /* purposefully empty */ + }, + removePage: () => { + /* purposefully empty */ + }, +}; + +export const MainNavContext = + React.createContext(DEFAULT_VALUE); + +export const useMainNavState = (): MainNavContextType => { + const [pageHierarchy, setPageHierarchy] = useState([]); + + const addPage = useCallback((pageId: string) => { + setPageHierarchy((hierarchy) => [ + ...hierarchy, + // Use dummy values for title and pageTitle to start. This gets filled by the next callback. + { title: pageId, pageTitle: pageId, id: pageId }, + ]); + }, []); + + const updatePage = useCallback( + ( + title: string, + id: string, + path: string | undefined, + pageTitle: string | undefined, + ) => { + setPageHierarchy((hierarchy) => { + const pageIndex = hierarchy.findIndex((page) => page.id === id); + return [ + ...hierarchy.slice(0, pageIndex), + { title, pageTitle, id, path }, + ...hierarchy.slice(pageIndex + 1), + ]; + }); + }, + [], + ); + + const removePage = useCallback((pageId: string) => { + setPageHierarchy((hierarchy) => { + console.assert( + hierarchy.length > 0, + "Trying to remove when nav hierarchy length is 0", + ); + const pageIndex = hierarchy.findIndex((page) => page.id === pageId); + console.assert( + pageIndex !== -1, + "Trying to remove page that is not in the hiearchy...", + ); + if (pageIndex === -1) { + return hierarchy; + } + return [ + ...hierarchy.slice(0, pageIndex), + ...hierarchy.slice(pageIndex + 1), + ]; + }); + }, []); + + return { + mainNavPageHierarchy: pageHierarchy, + addPage, + updatePage, + removePage, + }; +}; + +const useMainNavPage = (pageInfo: MainNavPage) => { + const { addPage, updatePage, removePage } = useContext(MainNavContext); + + // First effect to add and remove the page into the right spot of the hierarchy + useEffect(() => { + addPage(pageInfo.id); + + return () => { + removePage(pageInfo.id); + }; + }, [pageInfo.id, addPage, removePage]); + + // Second effect to allow for the title of a page to change. + useEffect(() => { + updatePage(pageInfo.title, pageInfo.id, pageInfo.path, pageInfo.pageTitle); + document.title = `${pageInfo.pageTitle ?? pageInfo.title} | Ray Dashboard`; + return () => { + document.title = "Ray Dashboard"; + }; + }, [ + pageInfo.title, + pageInfo.id, + pageInfo.path, + pageInfo.pageTitle, + updatePage, + ]); +}; + +type MainNavPageProps = { + pageInfo: MainNavPage; +}; + +/** + * Render this component at the top of your page if your page should belong in the Main Nav hierarchy + * Users cannot call the hook directly because useEffect hooks are called from child -> parent on first render + * However, children are always rendered in order so we can use a child component to force the parent + * effect to run before the children effect. + */ +export const MainNavPageInfo = ({ pageInfo }: MainNavPageProps) => { + useMainNavPage(pageInfo); + return null; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/layout/sideTabContext.ts b/historyserver/dashboard/ray/client/src/pages/layout/sideTabContext.ts new file mode 100644 index 00000000000..4cef6590dad --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/layout/sideTabContext.ts @@ -0,0 +1,36 @@ +import React, { useContext, useEffect, useState } from "react"; + +export type SideTabContextType = { + selectedTab?: string; + setSelectedTab: (value?: string) => void; +}; + +export const DEFAULT_VALUE: SideTabContextType = { + setSelectedTab: () => { + /* purposefully empty */ + }, +}; + +export const SideTabContext = + React.createContext(DEFAULT_VALUE); + +export const useSideTabState = (): SideTabContextType => { + const [selectedTab, setSelectedTab] = useState(); + + return { selectedTab, setSelectedTab }; +}; + +/** + * Call this hook at the start of the component that represents the tab contents. + */ +export const useSideTabPage = (tabId: string) => { + const { setSelectedTab } = useContext(SideTabContext); + + useEffect(() => { + setSelectedTab(tabId); + + return () => { + setSelectedTab(undefined); + }; + }, [tabId, setSelectedTab]); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/log/LogViewer.tsx b/historyserver/dashboard/ray/client/src/pages/log/LogViewer.tsx new file mode 100644 index 00000000000..dd47b3acd6c --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/log/LogViewer.tsx @@ -0,0 +1,161 @@ +import { SearchOutlined } from "@mui/icons-material"; +import { + Box, + Button, + InputAdornment, + LinearProgress, + Switch, + TextField, +} from "@mui/material"; +import React, { memo, useState } from "react"; +import LogVirtualView from "../../components/LogView/LogVirtualView"; + +const useLogViewer = () => { + const [search, setSearch] = + useState<{ + keywords?: string; + lineNumber?: string; + fontSize?: number; + revert?: boolean; + }>(); + const [startTime, setStart] = useState(); + const [endTime, setEnd] = useState(); + + return { + search, + setSearch, + startTime, + setStart, + endTime, + setEnd, + }; +}; + +type LogViewerProps = { + path?: string; + log: string; + downloadUrl?: string; + onRefreshClick?: () => void; + height?: number; +}; + +/** + * Memoized component because React-window does not work well with re-renders. + * If text is selected, it will get unselected if the component re-renders. + */ +export const LogViewer = memo( + ({ + path, + log, + downloadUrl, + onRefreshClick, + height = 600, + }: LogViewerProps) => { + const { search, setSearch, startTime, setStart, endTime, setEnd } = + useLogViewer(); + + return ( + + {log !== "Loading..." && ( +
+
+ { + setSearch({ ...search, keywords: value }); + }, + type: "", + endAdornment: ( + + + + ), + }} + /> + { + setStart(val.target.value); + }} + InputLabelProps={{ + shrink: true, + }} + /> + { + setEnd(val.target.value); + }} + InputLabelProps={{ + shrink: true, + }} + /> + + Reverse:{" "} + setSearch({ ...search, revert: v })} + /> + {onRefreshClick && ( + + )} + + {downloadUrl && path && ( + + )} + +
+ +
+ )} + {log === "Loading..." && ( +
+
+ +
+ )} +
+ ); + }, +); diff --git a/historyserver/dashboard/ray/client/src/pages/log/Logs.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/log/Logs.component.test.tsx new file mode 100644 index 00000000000..06c5b0eb84b --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/log/Logs.component.test.tsx @@ -0,0 +1,233 @@ +import { render, screen } from "@testing-library/react"; +import React from "react"; +import { MemoryRouter } from "react-router-dom"; +import { SWRConfig } from "swr"; +import { listStateApiLogs } from "../../service/log"; +import { getNodeList } from "../../service/node"; +import { STYLE_WRAPPER } from "../../util/test-utils"; +import { useStateApiLogs } from "./hooks"; +import { StateApiLogsListPage, StateApiLogViewerPage } from "./Logs"; + +jest.mock("../../service/node"); +jest.mock("../../service/log"); +jest.mock("./hooks"); + +const mockGetNodeList = jest.mocked(getNodeList); +const mockListStateApiLogs = jest.mocked(listStateApiLogs); +const mockUseStateApiLogs = jest.mocked(useStateApiLogs); + +describe("LogsPage", () => { + it("renders a nodes view", async () => { + expect.assertions(5); + + mockGetNodeList.mockResolvedValueOnce({ + data: { + data: { + summary: [ + { + ip: "127.0.0.1", + raylet: { + nodeId: "node-id-1", + state: "ALIVE", + }, + }, + { + ip: "127.0.0.2", + raylet: { + nodeId: "node-id-2", + state: "ALIVE", + }, + }, + { + ip: "127.0.0.3", + raylet: { + nodeId: "node-id-3", + state: "DEAD", + }, + }, + ], + }, + }, + } as any); + + render( + + + , + { wrapper: STYLE_WRAPPER }, + ); + await screen.findByText("Select a node to view logs"); + + expect( + screen.getByText("Node ID: node-id-1 (IP: 127.0.0.1)"), + ).toBeVisible(); + expect( + screen.getByRole("link", { name: /Node ID: node-id-1/ }), + ).toHaveAttribute("href", "/?nodeId=node-id-1"); + expect( + screen.getByText("Node ID: node-id-2 (IP: 127.0.0.2)"), + ).toBeVisible(); + expect( + screen.getByRole("link", { name: /Node ID: node-id-2/ }), + ).toHaveAttribute("href", "/?nodeId=node-id-2"); + expect( + screen.queryByText("Node ID: node-id-3 (IP: 127.0.0.3)"), + ).not.toBeInTheDocument(); + }); + + it("renders a list view of files", async () => { + expect.assertions(6); + + mockListStateApiLogs.mockResolvedValueOnce({ + data: { + data: { + result: { + dashboard: ["dashboard.log", "dashboard.err", "dashboard.out"], + internal: ["events/", "monitor.out"], + }, + }, + }, + } as any); + + render( + + + , + { wrapper: STYLE_WRAPPER }, + ); + await screen.findByText(`Node: node-id-1`); + + expect(screen.getByRole("link", { name: "Back To ../" })).toHaveAttribute( + "href", + "/logs/", + ); + + expect(screen.getByRole("link", { name: "dashboard.err" })).toHaveAttribute( + "href", + "/viewer?nodeId=node-id-1&fileName=dashboard.err", + ); + expect(screen.getByRole("link", { name: "dashboard.out" })).toHaveAttribute( + "href", + "/viewer?nodeId=node-id-1&fileName=dashboard.out", + ); + expect(screen.getByRole("link", { name: "dashboard.log" })).toHaveAttribute( + "href", + "/viewer?nodeId=node-id-1&fileName=dashboard.log", + ); + expect(screen.getByRole("link", { name: "monitor.out" })).toHaveAttribute( + "href", + "/viewer?nodeId=node-id-1&fileName=monitor.out", + ); + expect(screen.getByRole("link", { name: "events/" })).toHaveAttribute( + "href", + "/?nodeId=node-id-1&folder=events", + ); + }); + + it("renders a list view of files in a folder", async () => { + expect.assertions(4); + + mockListStateApiLogs.mockResolvedValueOnce({ + data: { + data: { + result: { + internal: [ + "events/events_RAYLET.log", + "events/events_AUTOSCALER.log", + "events/secondFolder/", + ], + }, + }, + }, + } as any); + + render( + + new Map() }}> + + + , + { wrapper: STYLE_WRAPPER }, + ); + await screen.findByText(`Node: node-id-1`); + + expect(screen.getByRole("link", { name: "Back To ../" })).toHaveAttribute( + "href", + "/logs/?nodeId=node-id-1&folder=", + ); + + expect( + screen.getByRole("link", { name: "events_RAYLET.log" }), + ).toHaveAttribute( + "href", + "/viewer?nodeId=node-id-1&fileName=events%2Fevents_RAYLET.log", + ); + expect( + screen.getByRole("link", { name: "events_AUTOSCALER.log" }), + ).toHaveAttribute( + "href", + "/viewer?nodeId=node-id-1&fileName=events%2Fevents_AUTOSCALER.log", + ); + expect(screen.getByRole("link", { name: "secondFolder/" })).toHaveAttribute( + "href", + "/?nodeId=node-id-1&folder=events%2FsecondFolder", + ); + }); + + it("renders a log viewer", async () => { + expect.assertions(4); + + mockUseStateApiLogs.mockReturnValue({ + downloadUrl: "www.download.com", + log: "SOME LOGS", + path: "some/path", + refresh: (() => { + /* empty */ + }) as any, + }); + + render( + + + , + { wrapper: STYLE_WRAPPER }, + ); + await screen.findByText(`Node: node-id-1`); + expect(screen.getByText("File: dashboard.log")).toBeVisible(); + + expect(screen.getByRole("link", { name: "Back To ../" })).toHaveAttribute( + "href", + "/logs/?nodeId=node-id-1&folder=", + ); + + await screen.findByText("SOME"); + expect(screen.getByText("SOME")).toBeVisible(); + expect(screen.getByText("LOGS")).toBeVisible(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/log/Logs.tsx b/historyserver/dashboard/ray/client/src/pages/log/Logs.tsx new file mode 100644 index 00000000000..57e5864fde7 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/log/Logs.tsx @@ -0,0 +1,304 @@ +import { + Box, + Button, + IconButton, + Link, + List, + ListItem, + Paper, + Typography, +} from "@mui/material"; +import { grey } from "@mui/material/colors"; +import React, { useMemo, useState } from "react"; +import { RiDownload2Line } from "react-icons/ri"; +import { Outlet, Link as RouterLink, useSearchParams } from "react-router-dom"; +import useSWR from "swr"; +import { StateApiLogViewer } from "../../common/MultiTabLogViewer"; +import { SearchInput } from "../../components/SearchComponent"; +import TitleCard from "../../components/TitleCard"; +import { getStateApiDownloadLogUrl, listStateApiLogs } from "../../service/log"; +import { getNodeList } from "../../service/node"; +import { MainNavPageInfo } from "../layout/mainNavContext"; + +export const StateApiLogsListPage = () => { + const [searchParams] = useSearchParams(); + const nodeId = searchParams.get("nodeId"); + const folder = searchParams.get("folder"); + const fileNameParam = searchParams.get("fileName"); + const [fileName, setFileName] = useState(fileNameParam || ""); + + const backFolder = folder + ? [...folder.split("/").slice(0, -1)].join("/") + : undefined; + const backHref = + // backGlob is undefined when glob is empty + // backGlob is empty string when glob is 1 level deep. + backFolder !== undefined && nodeId + ? `/logs/?nodeId=${encodeURIComponent( + nodeId, + )}&folder=${encodeURIComponent(backFolder)}` + : `/logs/`; + + return ( + + + + {!nodeId &&

Select a node to view logs

} + {nodeId && ( + +

Node: {nodeId}

+

{decodeURIComponent(folder || "")}

+
+ )} + {nodeId && ( + + + { + setFileName(val); + }} + /> + + )} +
+ + {nodeId ? ( + + ) : ( + + )} + +
+
+ ); +}; + +export const StateApiLogsNodesList = () => { + const { data: nodes, error } = useSWR(["/api/v0/nodes"], async () => { + const resp = await getNodeList(); + const nodes = resp.data.data.summary; + return nodes.filter((node) => node.raylet.state === "ALIVE"); + }); + + const isLoading = nodes === undefined && error === undefined; + + return ( + + {isLoading ? ( + Loading... + ) : error ? ( + {error} + ) : ( + + {nodes?.map(({ raylet: { nodeId }, ip }) => ( + + + Node ID: {nodeId} (IP: {ip}) + + + ))} + + )} + + ); +}; + +type StateApiLogsFilesListProps = { + nodeId: string; + folder: string | null; + fileName: string; +}; + +export const StateApiLogsFilesList = ({ + nodeId, + folder, + fileName, +}: StateApiLogsFilesListProps) => { + // We want to do a partial search for file name. + const fileNameGlob = fileName ? `*${fileName}*` : undefined; + const glob = fileNameGlob + ? folder + ? `${folder}/${fileNameGlob}` + : `${fileNameGlob}` + : folder + ? `${folder}/*` + : undefined; + + const { data: fileGroups, error } = useSWR( + nodeId ? ["/api/v0/logs", nodeId, glob] : null, + async ([_, nodeId, glob]) => { + const resp = await listStateApiLogs({ nodeId, glob }); + return resp.data.data.result; + }, + ); + + const isLoading = fileGroups === undefined && error === undefined; + + const files = useMemo( + () => + (fileGroups !== undefined + ? Object.values(fileGroups) + .flatMap((e) => e) + .sort() + : [] + ).map((fileName) => { + const isDir = fileName.endsWith("/"); + const fileNameWithoutEndingSlash = fileName.substring( + 0, + fileName.length - 1, + ); + const parentFolder = folder ? `${folder}/` : ""; + const fileNameWithoutParent = fileName.startsWith(parentFolder) + ? fileName.substring(parentFolder.length) + : fileName; + + const linkPath = isDir + ? `?nodeId=${encodeURIComponent(nodeId)}&folder=${encodeURIComponent( + fileNameWithoutEndingSlash, + )}` + : `viewer?nodeId=${encodeURIComponent( + nodeId, + )}&fileName=${encodeURIComponent(fileName)}`; + + const downloadUrl = isDir + ? undefined + : getStateApiDownloadLogUrl({ + nodeId, + filename: fileName, + maxLines: -1, + }); + + return { + fileName, + name: fileNameWithoutParent, + linkPath, + isDir, + downloadUrl, + }; + }), + [fileGroups, folder, nodeId], + ); + + return ( + + {isLoading ? ( +

Loading...

+ ) : ( + files.length === 0 &&

No files found.

+ )} + {files && ( + + {files.map(({ fileName, name, downloadUrl, linkPath }) => { + return ( + + + {name} + + {downloadUrl && ( + + + + + + )} + + ); + })} + + )} +
+ ); +}; + +export const StateApiLogViewerPage = () => { + const [searchParams] = useSearchParams(); + const nodeId = searchParams.get("nodeId"); + const fileName = searchParams.get("fileName"); + + const backFolder = fileName + ? [...fileName.split("/").slice(0, -1)].join("/") + : undefined; + const backHref = + // backGlob is undefined when glob is empty + // backGlob is empty string when glob is 1 level deep. + backFolder !== undefined + ? `/logs/?nodeId=${nodeId}&folder=${backFolder}` + : `/logs/?nodeId=${nodeId}`; + + return ( + + + + {!nodeId &&

Select a node to view logs

} + {nodeId && ( + +

Node: {nodeId}

+

File: {decodeURIComponent(fileName || "")}

+
+ )} + {nodeId && ( + + + + )} +
+ + {nodeId && fileName ? ( + + ) : ( + Invalid url parameters + )} + +
+
+ ); +}; + +/** + * Logs page for the new information architecture + */ +export const LogsLayout = () => { + return ( + + + + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/log/hooks.ts b/historyserver/dashboard/ray/client/src/pages/log/hooks.ts new file mode 100644 index 00000000000..be0f3a95d50 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/log/hooks.ts @@ -0,0 +1,31 @@ +import useSWR from "swr"; +import { + getStateApiDownloadLogUrl, + getStateApiLog, + StateApiLogInput, +} from "../../service/log"; + +export const useStateApiLogs = ( + props: StateApiLogInput, + path: string | undefined, +) => { + const downloadUrl = getStateApiDownloadLogUrl({ ...props, maxLines: -1 }); + + const { + data: log, + isLoading, + mutate, + } = useSWR( + downloadUrl ? ["useDriverLogs", downloadUrl] : null, + async ([_]) => { + return getStateApiLog(props); + }, + ); + + return { + log: isLoading ? "Loading..." : log, + downloadUrl, + refresh: mutate, + path, + }; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/metrics/Metrics.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/metrics/Metrics.component.test.tsx new file mode 100644 index 00000000000..a24206310f6 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/metrics/Metrics.component.test.tsx @@ -0,0 +1,95 @@ +import { render, screen } from "@testing-library/react"; +import React, { PropsWithChildren } from "react"; +import { GlobalContext } from "../../App"; +import { STYLE_WRAPPER } from "../../util/test-utils"; +import { Metrics } from "./Metrics"; + +const Wrapper = ({ children }: PropsWithChildren<{}>) => { + return ( + + {children} + + ); +}; + +const MetricsDisabledWrapper = ({ children }: PropsWithChildren<{}>) => { + return ( + + {children} + + ); +}; + +describe("Metrics", () => { + it("renders", async () => { + expect.assertions(5); + + render(, { wrapper: Wrapper }); + await screen.findByText(/View in Grafana/); + expect(screen.getByText(/5 minutes/)).toBeVisible(); + expect(screen.getByText(/Tasks and Actors/)).toBeVisible(); + expect(screen.getByText(/Ray Resource Usage/)).toBeVisible(); + expect(screen.getByText(/Hardware Utilization/)).toBeVisible(); + expect( + screen.queryByText( + /Set up Prometheus and Grafana for better Ray Dashboard experience/, + ), + ).toBeNull(); + }); + + it("renders warning when ", async () => { + expect.assertions(5); + + render(, { wrapper: MetricsDisabledWrapper }); + await screen.findByText( + /Set up Prometheus and Grafana for better Ray Dashboard experience/, + ); + expect(screen.queryByText(/View in Grafana/)).toBeNull(); + expect(screen.queryByText(/5 minutes/)).toBeNull(); + expect(screen.queryByText(/Tasks and Actors/)).toBeNull(); + expect(screen.queryByText(/Ray Resource Usage/)).toBeNull(); + expect(screen.queryByText(/Hardware Utilization/)).toBeNull(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/metrics/Metrics.tsx b/historyserver/dashboard/ray/client/src/pages/metrics/Metrics.tsx new file mode 100644 index 00000000000..dfa936fd1d7 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/metrics/Metrics.tsx @@ -0,0 +1,663 @@ +import { + Alert, + AlertProps, + Box, + Button, + InputAdornment, + Link, + Menu, + MenuItem, + Paper, + SxProps, + TextField, + Theme, + Tooltip, +} from "@mui/material"; +import React, { useContext, useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; +import { BiRefresh, BiTime } from "react-icons/bi"; +import { RiExternalLinkLine } from "react-icons/ri"; + +import { GlobalContext } from "../../App"; +import { CollapsibleSection } from "../../common/CollapsibleSection"; +import { ClassNameProps } from "../../common/props"; +import { HelpInfo } from "../../components/Tooltip"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import { MAIN_NAV_HEIGHT } from "../layout/MainNavLayout"; +import axios from 'axios'; + +export enum RefreshOptions { + OFF = "off", + FIVE_SECONDS = "5s", + TEN_SECONDS = "10s", + THIRTY_SECONDS = "30s", + ONE_MIN = "1m", + FIVE_MINS = "5m", + FIFTEEN_MINS = "15m", + THIRTY_MINS = "30m", + ONE_HOUR = "1h", + TWO_HOURS = "2h", + ONE_DAY = "1d", +} + +export enum TimeRangeOptions { + FIVE_MINS = "Last 5 minutes", + THIRTY_MINS = "Last 30 minutes", + ONE_HOUR = "Last 1 hour", + THREE_HOURS = "Last 3 hours", + SIX_HOURS = "Last 6 hours", + TWELVE_HOURS = "Last 12 hours", + ONE_DAY = "Last 1 day", + TWO_DAYS = "Last 2 days", + SEVEN_DAYS = "Last 7 days", +} + +export const REFRESH_VALUE: Record = { + [RefreshOptions.OFF]: "", + [RefreshOptions.FIVE_SECONDS]: "5s", + [RefreshOptions.TEN_SECONDS]: "10s", + [RefreshOptions.THIRTY_SECONDS]: "30s", + [RefreshOptions.ONE_MIN]: "1m", + [RefreshOptions.FIVE_MINS]: "5m", + [RefreshOptions.FIFTEEN_MINS]: "15m", + [RefreshOptions.THIRTY_MINS]: "30m", + [RefreshOptions.ONE_HOUR]: "1h", + [RefreshOptions.TWO_HOURS]: "2h", + [RefreshOptions.ONE_DAY]: "1d", +}; + +export const TIME_RANGE_TO_FROM_VALUE: Record = { + [TimeRangeOptions.FIVE_MINS]: "now-5m", + [TimeRangeOptions.THIRTY_MINS]: "now-30m", + [TimeRangeOptions.ONE_HOUR]: "now-1h", + [TimeRangeOptions.THREE_HOURS]: "now-3h", + [TimeRangeOptions.SIX_HOURS]: "now-6h", + [TimeRangeOptions.TWELVE_HOURS]: "now-12h", + [TimeRangeOptions.ONE_DAY]: "now-1d", + [TimeRangeOptions.TWO_DAYS]: "now-2d", + [TimeRangeOptions.SEVEN_DAYS]: "now-7d", +}; + +export type MetricConfig = { + title: string; + pathParams: string; +}; + +export type MetricsSectionConfig = { + title: string; + contents: MetricConfig[]; +}; + +// NOTE: please keep the titles here in sync with dashboard/modules/metrics/dashboards/default_dashboard_panels.py +const METRICS_CONFIG: MetricsSectionConfig[] = [ + { + title: "Tasks and Actors", + contents: [ + { + title: "Scheduler Task State", + pathParams: "theme=light&panelId=26", + }, + { + title: "Active Tasks by Name", + pathParams: "theme=light&panelId=35", + }, + { + title: "Scheduler Actor State", + pathParams: "theme=light&panelId=33", + }, + { + title: "Active Actors by Name", + pathParams: "theme=light&panelId=36", + }, + { + title: "Out of Memory Failures by Name", + pathParams: "theme=light&panelId=44", + }, + ], + }, + { + title: "Ray Resource Usage", + contents: [ + { + title: "Scheduler CPUs (logical slots)", + pathParams: "theme=light&panelId=27", + }, + { + title: "Scheduler GPUs (logical slots)", + pathParams: "theme=light&panelId=28", + }, + { + title: "Object Store Memory", + pathParams: "theme=light&panelId=29", + }, + { + title: "Placement Groups", + pathParams: "theme=light&panelId=40", + }, + ], + }, + { + title: "Hardware Utilization", + contents: [ + { + title: "Node Count", + pathParams: "theme=light&panelId=24", + }, + { + title: "Node CPU (hardware utilization)", + pathParams: "theme=light&panelId=2", + }, + { + title: "Node Memory (heap + object store)", + pathParams: "theme=light&panelId=4", + }, + { + title: "Node GPU (hardware utilization)", + pathParams: "theme=light&panelId=8", + }, + { + title: "Node GPU Memory (GRAM)", + pathParams: "theme=light&panelId=18", + }, + { + title: "Node Disk", + pathParams: "theme=light&panelId=6", + }, + { + title: "Node Disk IO Speed", + pathParams: "theme=light&panelId=32", + }, + { + title: "Node Network", + pathParams: "theme=light&panelId=20", + }, + { + title: "Node CPU by Component", + pathParams: "theme=light&panelId=37", + }, + { + title: "Node Memory by Component", + pathParams: "theme=light&panelId=34", + }, + ], + }, +]; + +const DATA_METRICS_CONFIG: MetricsSectionConfig[] = [ + { + title: "Ray Data Metrics (Overview)", + contents: [ + { + title: "Bytes Spilled", + pathParams: "theme=light&panelId=1", + }, + { + title: "Bytes Allocated", + pathParams: "theme=light&panelId=2", + }, + { + title: "Bytes Freed", + pathParams: "theme=light&panelId=3", + }, + { + title: "Object Store Memory", + pathParams: "theme=light&panelId=4", + }, + { + title: "CPUs (logical slots)", + pathParams: "theme=light&panelId=5", + }, + { + title: "GPUs (logical slots)", + pathParams: "theme=light&panelId=6", + }, + { + title: "Bytes Outputted", + pathParams: "theme=light&panelId=7", + }, + { + title: "Rows Outputted", + pathParams: "theme=light&panelId=11", + }, + ], + }, + { + title: "Ray Data Metrics (Inputs)", + contents: [ + { + title: "Input Blocks Received by Operator", + pathParams: "theme=light&panelId=17", + }, + { + title: "Input Blocks Processed by Tasks", + pathParams: "theme=light&panelId=19", + }, + { + title: "Input Bytes Processed by Tasks", + pathParams: "theme=light&panelId=20", + }, + { + title: "Input Bytes Submitted to Tasks", + pathParams: "theme=light&panelId=21", + }, + ], + }, + { + title: "Ray Data Metrics (Outputs)", + contents: [ + { + title: "Blocks Generated by Tasks", + pathParams: "theme=light&panelId=22", + }, + { + title: "Bytes Generated by Tasks", + pathParams: "theme=light&panelId=23", + }, + { + title: "Rows Generated by Tasks", + pathParams: "theme=light&panelId=24", + }, + { + title: "Output Blocks Taken by Downstream Operators", + pathParams: "theme=light&panelId=25", + }, + { + title: "Output Bytes Taken by Downstream Operators", + pathParams: "theme=light&panelId=26", + }, + ], + }, + { + title: "Ray Data Metrics (Tasks)", + contents: [ + { + title: "Submitted Tasks", + pathParams: "theme=light&panelId=29", + }, + { + title: "Running Tasks", + pathParams: "theme=light&panelId=30", + }, + { + title: "Tasks with output blocks", + pathParams: "theme=light&panelId=31", + }, + { + title: "Finished Tasks", + pathParams: "theme=light&panelId=32", + }, + { + title: "Failed Tasks", + pathParams: "theme=light&panelId=33", + }, + { + title: "Block Generation Time", + pathParams: "theme=light&panelId=8", + }, + { + title: "Task Submission Backpressure Time", + pathParams: "theme=light&panelId=37", + }, + ], + }, + { + title: "Ray Data Metrics (Object Store Memory)", + contents: [ + { + title: "Operator Internal Inqueue Size (Blocks)", + pathParams: "theme=light&panelId=13", + }, + { + title: "Operator Internal Inqueue Size (Bytes)", + pathParams: "theme=light&panelId=14", + }, + { + title: "Operator Internal Outqueue Size (Blocks)", + pathParams: "theme=light&panelId=15", + }, + { + title: "Operator Internal Outqueue Size (Bytes)", + pathParams: "theme=light&panelId=16", + }, + { + title: "Size of Blocks used in Pending Tasks (Bytes)", + pathParams: "theme=light&panelId=34", + }, + { + title: "Freed Memory in Object Store (Bytes)", + pathParams: "theme=light&panelId=35", + }, + { + title: "Spilled Memory in Object Store (Bytes)", + pathParams: "theme=light&panelId=36", + }, + ], + }, + { + title: "Ray Data Metrics (Iteration)", + contents: [ + { + title: "Iteration Initialization Time", + pathParams: "theme=light&panelId=12", + }, + { + title: "Iteration Blocked Time", + pathParams: "theme=light&panelId=9", + }, + { + title: "Iteration User Time", + pathParams: "theme=light&panelId=10", + }, + ], + }, + // Add metrics with `metrics_group: "misc"` here. + // { + // title: "Ray Data Metrics (Miscellaneous)", + // contents: [], + // }, +]; + +export const Metrics = () => { + const { grafanaHost, prometheusHealth, dashboardUids, dashboardDatasource } = + useContext(GlobalContext); + + const grafanaDefaultDashboardUid = + dashboardUids?.default ?? "rayDefaultDashboard"; + + + const grafanaDefaultDashboardUidParams = + dashboardUids?.default_params ?? "orgId=1"; + + const grafanaDefaultDatasource = dashboardDatasource ?? "Prometheus"; + + const [refreshOption, setRefreshOption] = useState( + RefreshOptions.FIVE_SECONDS, + ); + + const [timeRangeOption, setTimeRangeOption] = useState( + TimeRangeOptions.FIVE_MINS, + ); + + const [refresh, setRefresh] = useState(null); + + const [[from, to], setTimeRange] = useState<[string | null, string | null]>([ + null, + null, + ]); + + useEffect(() => { + setRefresh(REFRESH_VALUE[refreshOption]); + }, [refreshOption]); + + useEffect(() => { + const from = TIME_RANGE_TO_FROM_VALUE[timeRangeOption]; + setTimeRange([from, "now"]); + }, [timeRangeOption]); + + const [viewInGrafanaMenuRef, setViewInGrafanaMenuRef] = + useState(null); + + const fromParam = from !== null ? `&from=${from}` : ""; + const toParam = to !== null ? `&to=${to}` : ""; + const timeRangeParams = `${fromParam}${toParam}`; + + const refreshParams = refresh ? `&refresh=${refresh}` : ""; + + return ( +
+ + {grafanaHost === undefined || !prometheusHealth ? ( + + ) : ( +
+ + + {viewInGrafanaMenuRef && ( + { + setViewInGrafanaMenuRef(null); + }} + > + + Core Dashboard + + {dashboardUids?.["data"] && ( + + + Ray Data Dashboard + + + )} + + )} + { + setRefreshOption(value as RefreshOptions); + }} + variant="standard" + InputProps={{ + startAdornment: ( + + + + ), + }} + > + {Object.entries(RefreshOptions).map(([key, value]) => ( + + {value} + + ))} + + Auto-refresh interval + { + setTimeRangeOption(value as TimeRangeOptions); + }} + variant="standard" + InputProps={{ + startAdornment: ( + + + + ), + }} + > + {Object.entries(TimeRangeOptions).map(([key, value]) => ( + + {value} + + ))} + + Time range picker + + + Tip: You can click on the legend to focus on a specific line in the + time-series graph. You can use control/cmd + click to filter out a + line in the time-series graph. + + + {METRICS_CONFIG.map((config) => ( + + ))} + {dashboardUids?.["data"] && + DATA_METRICS_CONFIG.map((config) => ( + + ))} + +
+ )} +
+ ); +}; + +type MetricsSectionProps = { + metricConfig: MetricsSectionConfig; + refreshParams: string; + timeRangeParams: string; + dashboardUid: string; + dashboardDatasource: string; + dashboardParams: string; +}; + +const MetricsSection = ({ + metricConfig: { title, contents }, + refreshParams, + timeRangeParams, + dashboardUid, + dashboardDatasource, + dashboardParams, +}: MetricsSectionProps) => { + const { grafanaHost } = useContext(GlobalContext); + const { clusterName, sessionName } = useParams(); + + return ( + + + {contents.map(({ title, pathParams }) => { + const path = + `/d-solo/${dashboardUid}?${dashboardParams}&${pathParams}&${refreshParams}${timeRangeParams}&var-SessionName=${sessionName}`; + // const path = + // `/d-solo/${dashboardUid}?${pathParams}` + + // `&${refreshParams}${timeRangeParams}&var-SessionName=${sessionName}&var-datasource=${dashboardDatasource}`; + return ( + ({ + width: "100%", + height: 400, + overflow: "hidden", + [theme.breakpoints.up("md")]: { + // Calculate max width based on 1/3 of the total width minus padding between cards + width: `calc((100% - ${theme.spacing(3)} * 2) / 3)`, + }, + })} + variant="outlined" + elevation={0} + > + + + ); + })} + + + ); +}; + +export type GrafanaNotRunningAlertProps = { + severity?: AlertProps["severity"]; + sx?: SxProps; +} & ClassNameProps; + +export const GrafanaNotRunningAlert = ({ + className, + severity = "warning", + sx, +}: GrafanaNotRunningAlertProps) => { + const { grafanaHost, prometheusHealth } = useContext(GlobalContext); + return grafanaHost === undefined || !prometheusHealth ? ( + + + Set up Prometheus and Grafana for better Ray Dashboard experience + +
+
+ Time-series charts are hidden because either Prometheus or Grafana server + is not detected. Follow{" "} + + these instructions + {" "} + to set them up and refresh this page. +
+ ) : null; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/metrics/index.ts b/historyserver/dashboard/ray/client/src/pages/metrics/index.ts new file mode 100644 index 00000000000..83c363aa7c4 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/metrics/index.ts @@ -0,0 +1 @@ +export * from "./Metrics"; diff --git a/historyserver/dashboard/ray/client/src/pages/metrics/utils.ts b/historyserver/dashboard/ray/client/src/pages/metrics/utils.ts new file mode 100644 index 00000000000..b5f31b9850c --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/metrics/utils.ts @@ -0,0 +1,75 @@ +import { get } from "../../service/requestHandlers"; + +const GRAFANA_HEALTHCHECK_URL = "/api/grafana_health"; +const PROMETHEUS_HEALTHCHECK_URL = "/api/prometheus_health"; + +export type DashboardUids = { + default: string; + serve: string; + serveDeployment: string; + data: string; + default_params: string; + serve_params: string; + serveDeployment_params: string; + data_params: string; +}; + +type GrafanaHealthcheckRsp = { + result: boolean; + msg: string; + data: { + grafanaHost: string; + sessionName: string; + dashboardUids: DashboardUids; + dashboardDatasource: string; + }; +}; + +type PrometheusHealthcheckRsp = { + result: boolean; + msg: string; +}; + +const fetchGrafanaHealthcheck = async () => { + return await get(GRAFANA_HEALTHCHECK_URL); +}; + +const fetchPrometheusHealthcheck = async () => { + return await get(PROMETHEUS_HEALTHCHECK_URL); +}; + +type MetricsInfo = { + grafanaHost?: string; + sessionName?: string; + prometheusHealth?: boolean; + dashboardUids?: DashboardUids; + dashboardDatasource?: string; +}; + +export const getMetricsInfo = async () => { + const info: MetricsInfo = { + grafanaHost: undefined, + sessionName: undefined, + prometheusHealth: undefined, + dashboardUids: undefined, + dashboardDatasource: undefined, + }; + try { + const resp = await fetchGrafanaHealthcheck(); + if (resp.data.result) { + info.grafanaHost = `http://${window.location.hostname}:3000`; + // info.grafanaHost = resp.data.data.grafanaHost; + info.sessionName = resp.data.data.sessionName; + info.dashboardUids = resp.data.data.dashboardUids; + info.dashboardDatasource = resp.data.data.dashboardDatasource; + } + } catch (e) {} + try { + const resp = await fetchPrometheusHealthcheck(); + if (resp.data.result) { + info.prometheusHealth = resp.data.result; + } + } catch (e) {} + + return info; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/node/ClusterDetailInfoPage.tsx b/historyserver/dashboard/ray/client/src/pages/node/ClusterDetailInfoPage.tsx new file mode 100644 index 00000000000..f3a7ec076dd --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/node/ClusterDetailInfoPage.tsx @@ -0,0 +1,98 @@ +import { Box } from "@mui/material"; +import React from "react"; +import Loading from "../../components/Loading"; +import { MetadataSection } from "../../components/MetadataSection"; +import { StatusChip } from "../../components/StatusChip"; +import TitleCard from "../../components/TitleCard"; +import { MainNavPageInfo } from "../layout/mainNavContext"; + +import { useClusterDetail } from "./hook/useClusterDetail"; + +export const ClusterDetailInfoPage = () => { + // TODO(aguo): Add more content to this page! + + const { clusterDetail, msg, isLoading } = useClusterDetail(); + + if (!clusterDetail) { + return ( + + + + + +
+ Request Status: {msg}
+
+
+ ); + } + + return ( + + + + + + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/node/ClusterLayout.tsx b/historyserver/dashboard/ray/client/src/pages/node/ClusterLayout.tsx new file mode 100644 index 00000000000..16a02d05eb9 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/node/ClusterLayout.tsx @@ -0,0 +1,12 @@ +import React from "react"; +import { RiInformationLine, RiTableLine } from "react-icons/ri"; +import { SideTabLayout, SideTabRouteLink } from "../layout/SideTabLayout"; + +export const ClusterLayout = () => { + return ( + + + + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/node/GPUColumn.tsx b/historyserver/dashboard/ray/client/src/pages/node/GPUColumn.tsx new file mode 100644 index 00000000000..dc84c7c9641 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/node/GPUColumn.tsx @@ -0,0 +1,94 @@ +import { Box, Tooltip, Typography } from "@mui/material"; +import React from "react"; +import { RightPaddedTypography } from "../../common/CustomTypography"; +import UsageBar from "../../common/UsageBar"; +import { GPUStats, NodeDetail } from "../../type/node"; + +export type NodeGPUEntryProps = { + slot: number; + gpu: GPUStats; +}; + +export const NodeGPUEntry: React.FC = ({ gpu, slot }) => { + return ( + + + [{slot}]: + {gpu.utilizationGpu !== undefined ? ( + + ) : ( + + N/A + + )} + + + ); +}; + +export const NodeGPUView = ({ node }: { node: NodeDetail }) => { + return ( + + {node.gpus !== undefined && node.gpus.length !== 0 ? ( + node.gpus.map((gpu, i) => ( + + )) + ) : ( + + N/A + + )} + + ); +}; + +export const WorkerGpuRow = ({ + workerPID, + gpus, +}: { + workerPID: number | null; + gpus?: GPUStats[]; +}) => { + const workerGPUEntries = (gpus ?? []) + .map((gpu, i) => { + const process = gpu.processesPids?.find( + (process) => process.pid === workerPID, + ); + if (!process) { + return undefined; + } + return ; + }) + .filter((entry) => entry !== undefined); + + return workerGPUEntries.length === 0 ? ( + + N/A + + ) : ( + {workerGPUEntries} + ); +}; + +export const getSumGpuUtilization = ( + workerPID: number | null, + gpus?: GPUStats[], +) => { + // Get sum of all GPU utilization values for this worker PID. This is an + // aggregate of the WorkerGpuRow and follows the same logic. + const workerGPUUtilizationEntries = (gpus ?? []) + .map((gpu, i) => { + const process = gpu.processesPids?.find( + (process) => process.pid === workerPID, + ); + if (!process) { + return 0; + } + return gpu.utilizationGpu || 0; + }) + .filter((entry) => entry !== undefined); + return workerGPUUtilizationEntries.reduce((a, b) => a + b, 0); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/node/GRAMColumn.tsx b/historyserver/dashboard/ray/client/src/pages/node/GRAMColumn.tsx new file mode 100644 index 00000000000..c1830725c50 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/node/GRAMColumn.tsx @@ -0,0 +1,119 @@ +import { Box, Tooltip, Typography } from "@mui/material"; +import React from "react"; +import { RightPaddedTypography } from "../../common/CustomTypography"; +import PercentageBar from "../../components/PercentageBar"; +import { GPUStats, NodeDetail } from "../../type/node"; + +const GRAM_COL_WIDTH = 120; + +export const NodeGRAM = ({ node }: { node: NodeDetail }) => { + const nodeGRAMEntries = (node.gpus ?? []).map((gpu, i) => { + const props = { + key: gpu.uuid, + gpuName: gpu.name, + utilization: gpu.memoryUsed, + total: gpu.memoryTotal, + slot: gpu.index, + }; + return ; + }); + return ( +
+ {nodeGRAMEntries.length === 0 ? ( + + N/A + + ) : ( +
{nodeGRAMEntries}
+ )} +
+ ); +}; + +export const WorkerGRAM = ({ + workerPID, + gpus, +}: { + workerPID: number | null; + gpus?: GPUStats[]; +}) => { + const workerGRAMEntries = (gpus ?? []) + .map((gpu, i) => { + const process = gpu.processesPids?.find( + (process) => workerPID && process.pid === workerPID, + ); + if (!process) { + return undefined; + } + const props = { + key: gpu.uuid, + gpuName: gpu.name, + total: gpu.memoryTotal, + utilization: process.gpuMemoryUsage, + slot: gpu.index, + }; + return ; + }) + .filter((entry) => entry !== undefined); + + return workerGRAMEntries.length === 0 ? ( + + N/A + + ) : ( +
{workerGRAMEntries}
+ ); +}; + +export const getSumGRAMUsage = ( + workerPID: number | null, + gpus?: GPUStats[], +) => { + // Get sum of all GRAM usage values for this worker PID. This is an + // aggregate of WorkerGRAM and follows the same logic. + const workerGRAMEntries = (gpus ?? []) + .map((gpu, i) => { + const process = gpu.processesPids?.find( + (process) => workerPID && process.pid === workerPID, + ); + if (!process) { + return 0; + } + return process.gpuMemoryUsage; + }) + .filter((entry) => entry !== undefined); + return workerGRAMEntries.reduce((a, b) => a + b, 0); +}; + +const getMiBRatioNoPercent = (used: number, total: number) => + `${used}MiB/${total}MiB`; + +type GRAMEntryProps = { + gpuName: string; + slot: number; + utilization: number; + total: number; +}; + +const GRAMEntry: React.FC = ({ + gpuName, + slot, + utilization, + total, +}) => { + const ratioStr = getMiBRatioNoPercent(utilization, total); + return ( + + + + + [{slot}]:{" "} + + + {ratioStr} + + + + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/node/NodeDetail.tsx b/historyserver/dashboard/ray/client/src/pages/node/NodeDetail.tsx new file mode 100644 index 00000000000..55d21fe2dad --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/node/NodeDetail.tsx @@ -0,0 +1,245 @@ +import { Box, Grid, Switch, Tab, TableContainer, Tabs } from "@mui/material"; +import React from "react"; +import { Link } from "react-router-dom"; +import { formatDateFromTimeMs } from "../../common/formatUtils"; +import ActorTable from "../../components/ActorTable"; +import Loading from "../../components/Loading"; +import PercentageBar from "../../components/PercentageBar"; +import { StatusChip } from "../../components/StatusChip"; +import TitleCard from "../../components/TitleCard"; +import RayletWorkerTable from "../../components/WorkerTable"; +import { memoryConverter } from "../../util/converter"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import { useNodeDetail } from "./hook/useNodeDetail"; + +const NodeDetailPage = () => { + const { + params, + selectedTab, + nodeDetail, + msg, + isLoading, + isRefreshing, + onRefreshChange, + raylet, + handleChange, + } = useNodeDetail(); + + return ( + + + + + +
+ Auto Refresh: + +
+ Request Status: {msg} +
+ + + + + + + + {nodeDetail && selectedTab === "info" && ( + + + + Hostname{" "} + {nodeDetail.hostname} + + + IP {nodeDetail.ip} + + + + + {nodeDetail.cpus && ( + + CPU (Logic/Physic){" "} + {nodeDetail.cpus[0]}/ {nodeDetail.cpus[1]} + + )} + + + Load (1/5/15min){" "} + {nodeDetail?.loadAvg[0] && + nodeDetail.loadAvg[0] + .map((e) => Number(e).toFixed(2)) + .join("/")} + + + + + Load per CPU (1/5/15min){" "} + {nodeDetail?.loadAvg[1] && + nodeDetail.loadAvg[1] + .map((e) => Number(e).toFixed(2)) + .join("/")} + + + Boot Time{" "} + {formatDateFromTimeMs(nodeDetail.bootTime * 1000)} + + + + + Sent Tps{" "} + {memoryConverter(nodeDetail?.networkSpeed[0])}/s + + + Recieved Tps{" "} + {memoryConverter(nodeDetail?.networkSpeed[1])}/s + + + + + Memory{" "} + {nodeDetail?.mem && ( + + {memoryConverter(nodeDetail?.mem[0] - nodeDetail?.mem[1])}/ + {memoryConverter(nodeDetail?.mem[0])}({nodeDetail?.mem[2]}%) + + )} + + + CPU{" "} + + {nodeDetail.cpu}% + + + + + {nodeDetail?.disk && + Object.entries(nodeDetail?.disk).map(([path, obj]) => ( + + Disk ({path}){" "} + {obj && ( + + {memoryConverter(obj.used)}/{memoryConverter(obj.total)} + ({obj.percent}%, {memoryConverter(obj.free)} free) + + )} + + ))} + + + + Logs{" "} + + log + + + + + )} + {raylet && Object.keys(raylet).length > 0 && selectedTab === "raylet" && ( + + + + + Command +
+
+ {nodeDetail?.cmdline.join(" ")} +
+
+
+ + + Pid {raylet?.pid} + + + Workers Num{" "} + {raylet?.numWorkers} + + + Node Manager Port{" "} + {raylet?.nodeManagerPort} + + +
+
+ )} + {nodeDetail?.workers && selectedTab === "worker" && ( + + + + + + )} + {nodeDetail?.actors && selectedTab === "actor" && ( + + + + + + )} +
+
+ ); +}; + +export default NodeDetailPage; diff --git a/historyserver/dashboard/ray/client/src/pages/node/NodeRow.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/node/NodeRow.component.test.tsx new file mode 100644 index 00000000000..b6746aa02e8 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/node/NodeRow.component.test.tsx @@ -0,0 +1,122 @@ +import { render, screen } from "@testing-library/react"; +import { noop } from "lodash"; +import React from "react"; +import { NodeDetail } from "../../type/node"; +import { CoreWorkerStats, Worker } from "../../type/worker"; +import { TEST_APP_WRAPPER } from "../../util/test-utils"; +import { NodeRow, WorkerRow } from "./NodeRow"; + +const NODE: NodeDetail = { + hostname: "test-hostname", + ip: "192.168.0.1", + cpu: 15, + mem: [100, 95, 5], + state: "ALIVE", + disk: { + "/": { + used: 20000000, + total: 200000000, + free: 180000000, + percent: 10, + }, + "/tmp": { + used: 0, + total: 200, + free: 200, + percent: 0, + }, + }, + networkSpeed: [5, 10], + raylet: { + state: "ALIVE", + nodeId: "1234567890ab", + isHeadNode: true, + numWorkers: 0, + pid: 2345, + startTime: 100, + terminateTime: -1, + brpcPort: 3456, + nodeManagerPort: 5890, + objectStoreAvailableMemory: 40, + objectStoreUsedMemory: 10, + }, +} as NodeDetail; + +const WORKER: Worker = { + cmdline: ["echo hi"], + pid: 3456, + cpuPercent: 14, + memoryInfo: { + rss: 75, + vms: 0, + pageins: 0, + pfaults: 0, + }, + coreWorkerStats: [ + { + workerId: "worker-12345", + } as CoreWorkerStats, + ], +} as Worker; + +const DEAD_NODE = { ...NODE, state: "DEAD" }; + +describe("NodeRow", () => { + it("renders", async () => { + render( + { + /* purposefully empty */ + }} + />, + { wrapper: TEST_APP_WRAPPER }, + ); + + await screen.findByText("test-hostname"); + expect(screen.getByText(/ALIVE/)).toBeVisible(); + expect(screen.getByText(/1234567890ab/)).toBeVisible(); + expect(screen.getByText(/192\.168\.0\.1.*\(Head\)/)).toBeVisible(); + // CPU Usage + expect(screen.getByText(/15%/)).toBeVisible(); + // Memory Usage + expect(screen.getByText(/5\.0000B\/100\.0000B\(5\.0%\)/)).toBeVisible(); + // Disk Usage + expect(screen.getByText(/19\.07MB\/190\.73MB\(10\.0%\)/)).toBeVisible(); + // Object store memory + expect(screen.getByText(/10\.0000B\/50\.0000B\(20\.0%\)/)).toBeVisible(); + // Network usage + expect(screen.getByText(/5.0000B\/s/)).toBeVisible(); + expect(screen.getByText(/10.0000B\/s/)).toBeVisible(); + }); + + it("Disable actions for Dead node", async () => { + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + await screen.findByText("test-hostname"); + // Could not access logs for Dead nodes(the log is hidden) + expect(screen.queryByLabelText(/Log/)).not.toBeInTheDocument(); + + expect(screen.getByText(/3456/)).toBeVisible(); + }); +}); + +describe("WorkerRow", () => { + it("renders", async () => { + render(, { + wrapper: TEST_APP_WRAPPER, + }); + + await screen.findByText("echo hi"); + expect(screen.getByText(/ALIVE/)).toBeVisible(); + expect(screen.getByText(/worker-12345/)).toBeVisible(); + expect(screen.getByText(/3456/)).toBeVisible(); + // CPU Usage + expect(screen.getByText(/14%/)).toBeVisible(); + // Memory Usage + expect(screen.getByText(/75\.0000B\/100\.0000B\(75\.0%\)/)).toBeVisible(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/node/NodeRow.tsx b/historyserver/dashboard/ray/client/src/pages/node/NodeRow.tsx new file mode 100644 index 00000000000..d8a13551050 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/node/NodeRow.tsx @@ -0,0 +1,382 @@ +import { + Box, + IconButton, + Link, + TableCell, + TableRow, + Tooltip, +} from "@mui/material"; +import { sortBy } from "lodash"; +import React, { useState } from "react"; +import { RiArrowDownSLine, RiArrowRightSLine } from "react-icons/ri"; +import { Link as RouterLink } from "react-router-dom"; +import useSWR from "swr"; +import { CodeDialogButtonWithPreview } from "../../common/CodeDialogButton"; +import { API_REFRESH_INTERVAL_MS } from "../../common/constants"; +import { NodeLink } from "../../common/links"; +import { + CpuProfilingLink, + CpuStackTraceLink, + MemoryProfilingButton, +} from "../../common/ProfilingLink"; +import PercentageBar from "../../components/PercentageBar"; +import { StatusChip } from "../../components/StatusChip"; +import { getNodeDetail } from "../../service/node"; +import { NodeDetail } from "../../type/node"; +import { Worker } from "../../type/worker"; +import { memoryConverter } from "../../util/converter"; +import { NodeGPUView, WorkerGpuRow } from "./GPUColumn"; +import { NodeGRAM, WorkerGRAM } from "./GRAMColumn"; + +const TEXT_COL_MIN_WIDTH = 100; + +type NodeRowProps = Pick & { + /** + * Whether the node has been expanded to show workers + */ + expanded: boolean; + /** + * Click handler for when one clicks on the expand/unexpand button in this row. + */ + onExpandButtonClick: () => void; +}; + +/** + * A single row that represents the node information only. + * Does not show any data about the node's workers. + */ +export const NodeRow = ({ + node, + expanded, + onExpandButtonClick, +}: NodeRowProps) => { + const { + hostname = "", + ip = "", + cpu = 0, + mem, + disk, + networkSpeed = [0, 0], + raylet, + logicalResources, + } = node; + + const objectStoreTotalMemory = + raylet.objectStoreAvailableMemory + raylet.objectStoreUsedMemory; + + /** + * Why do we use raylet.state instead of node.state in the following code? + * Because in ray, raylet == node + */ + + return ( + + + + {!expanded ? ( + theme.palette.text.secondary, + fontSize: "1.5em", + verticalAlign: "middle", + }} + /> + ) : ( + theme.palette.text.secondary, + fontSize: "1.5em", + verticalAlign: "middle", + }} + /> + )} + + + + {hostname} + + + + + + {raylet.stateMessage ? ( + + ) : ( + "-" + )} + + + +
+ +
+
+
+ + + {ip} {raylet.isHeadNode && "(Head)"} + + + + {raylet.state !== "DEAD" && ( + + Log + + )} + + + + {cpu}% + + + + {mem && ( + + {memoryConverter(mem[0] - mem[1])}/{memoryConverter(mem[0])}( + {mem[2].toFixed(1)} + %) + + )} + + + + + + + + + {raylet && objectStoreTotalMemory && ( + + {memoryConverter(raylet.objectStoreUsedMemory)}/ + {memoryConverter(objectStoreTotalMemory)}( + {( + (raylet.objectStoreUsedMemory / objectStoreTotalMemory) * + 100 + ).toFixed(1)} + %) + + )} + + + {disk && disk["/"] && ( + + {memoryConverter(disk["/"].used)}/{memoryConverter(disk["/"].total)} + ({disk["/"].percent.toFixed(1)}%) + + )} + + {memoryConverter(networkSpeed[0])}/s + {memoryConverter(networkSpeed[1])}/s + + {logicalResources ? ( + + ) : ( + "-" + )} + + + + +
+ ); +}; + +type WorkerRowProps = { + /** + * Details of the worker + */ + worker: Worker; + /** + * Detail of the node the worker is inside. + */ + node: NodeDetail; +}; + +/** + * A single row that represents the data of a Worker + */ +export const WorkerRow = ({ node, worker }: WorkerRowProps) => { + const { + ip, + mem, + raylet: { nodeId }, + } = node; + const { + pid, + cpuPercent: cpu = 0, + memoryInfo, + coreWorkerStats, + cmdline, + } = worker; + + const coreWorker = coreWorkerStats.length ? coreWorkerStats[0] : undefined; + const workerLogUrl = + `/logs/?nodeId=${encodeURIComponent(nodeId)}` + + (coreWorker ? `&fileName=${coreWorker.workerId}` : ""); + + return ( + + + {/* Empty because workers do not have an expand / unexpand button. */} + + {cmdline[0]} + + + + N/A + + {coreWorker && ( + + + {coreWorker.workerId} + + + )} + + {pid} + + + Log + +
+ +
+ +
+ +
+ + + {cpu}% + + + + {mem && ( + + {memoryConverter(memoryInfo.rss)}/{memoryConverter(mem[0])}( + {((memoryInfo.rss / mem[0]) * 100).toFixed(1)} + %) + + )} + + + + + + + + N/A + N/A + N/A + N/A + N/A + N/A +
+ ); +}; + +type NodeRowsProps = { + /** + * Details of the node + */ + node: NodeDetail; + /** + * Whether the node row should refresh data about its workers. + */ + isRefreshing: boolean; + /** + * Whether the row should start expanded. By default, this is false. + */ + startExpanded?: boolean; +}; + +/** + * The rows related to a node and its workers. Expandable to show information about workers. + */ +export const NodeRows = ({ + node, + isRefreshing, + startExpanded = false, +}: NodeRowsProps) => { + const [isExpanded, setExpanded] = useState(startExpanded); + + const { data } = useSWR( + ["getNodeDetail", node.raylet.nodeId], + async ([_, nodeId]) => { + const { data } = await getNodeDetail(nodeId); + const { data: rspData, result } = data; + + if (result === false) { + console.error("Node Query Error Please Check Node Name"); + } + + if (rspData?.detail) { + const sortedWorkers = sortBy( + rspData.detail.workers, + (worker) => worker.pid, + ); + return sortedWorkers; + } + }, + { refreshInterval: isRefreshing ? API_REFRESH_INTERVAL_MS : 0 }, + ); + + const workers = data ?? []; + + const handleExpandButtonClick = () => { + setExpanded(!isExpanded); + }; + + return ( + + + {isExpanded && + workers.map((worker) => ( + + ))} + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/node/hook/useClusterDetail.ts b/historyserver/dashboard/ray/client/src/pages/node/hook/useClusterDetail.ts new file mode 100644 index 00000000000..8bfe35c4408 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/node/hook/useClusterDetail.ts @@ -0,0 +1,28 @@ +import { useState } from "react"; +import useSWR from "swr"; +import { API_REFRESH_INTERVAL_MS } from "../../../common/constants"; +import { getClusterMetadata } from "../../../service/global"; + +export const useClusterDetail = () => { + const [msg, setMsg] = useState("Loading the job detail"); + const [refreshing, setRefresh] = useState(true); + const { data: clusterDetail, isLoading } = useSWR( + "useClusterDetail", + async () => { + try { + const rsp = await getClusterMetadata(); + return rsp.data; + } catch (e) { + setMsg("Cluster Detail Query Error."); + setRefresh(false); + } + }, + { refreshInterval: refreshing ? API_REFRESH_INTERVAL_MS : 0 }, + ); + + return { + clusterDetail, + msg, + isLoading, + }; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/node/hook/useNodeDetail.ts b/historyserver/dashboard/ray/client/src/pages/node/hook/useNodeDetail.ts new file mode 100644 index 00000000000..5d06fba2544 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/node/hook/useNodeDetail.ts @@ -0,0 +1,57 @@ +import { useContext, useState } from "react"; +import { useParams } from "react-router-dom"; +import useSWR from "swr"; +import { GlobalContext } from "../../../App"; +import { API_REFRESH_INTERVAL_MS } from "../../../common/constants"; +import { getNodeDetail } from "../../../service/node"; + +export const useNodeDetail = () => { + const params = useParams() as { id: string }; + const [selectedTab, setTab] = useState("info"); + const [msg, setMsg] = useState("Loading the node infos..."); + const { namespaceMap } = useContext(GlobalContext); + const [isRefreshing, setRefresh] = useState(true); + const onRefreshChange = (event: React.ChangeEvent) => { + setRefresh(event.target.checked); + }; + + const { data: nodeDetail, isLoading } = useSWR( + ["useNodeDetail", params.id], + async ([_, nodeId]) => { + const { data } = await getNodeDetail(nodeId); + const { data: rspData, msg, result } = data; + + if (msg) { + setMsg(msg); + } + + if (result === false) { + setMsg("Node Query Error Please Check Node Name"); + setRefresh(false); + } + + if (rspData?.detail) { + return rspData.detail; + } + }, + { refreshInterval: isRefreshing ? API_REFRESH_INTERVAL_MS : 0 }, + ); + + const raylet = nodeDetail?.raylet; + const handleChange = (event: React.ChangeEvent<{}>, newValue: string) => { + setTab(newValue); + }; + + return { + params, + selectedTab, + nodeDetail, + msg, + isLoading, + isRefreshing, + onRefreshChange, + raylet, + handleChange, + namespaceMap, + }; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/node/hook/useNodeList.ts b/historyserver/dashboard/ray/client/src/pages/node/hook/useNodeList.ts new file mode 100644 index 00000000000..e5eadf68fb2 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/node/hook/useNodeList.ts @@ -0,0 +1,94 @@ +import _ from "lodash"; +import { useState } from "react"; +import useSWR from "swr"; +import { API_REFRESH_INTERVAL_MS } from "../../../common/constants"; +import { getNodeList } from "../../../service/node"; +import { useSorter } from "../../../util/hook"; + +export const useNodeList = () => { + const [msg, setMsg] = useState("Loading the nodes infos..."); + const [isRefreshing, setRefresh] = useState(true); + const [mode, setMode] = useState("table"); + const [filter, setFilter] = useState< + { key: "hostname" | "ip" | "state" | "nodeId"; val: string }[] + >([]); + const [page, setPage] = useState({ pageSize: 10, pageNo: 1 }); + const { sorterFunc, setOrderDesc, setSortKey, sorterKey } = useSorter(""); + const changeFilter = ( + key: "hostname" | "ip" | "state" | "nodeId", + val: string, + ) => { + const f = filter.find((e) => e.key === key); + if (f) { + f.val = val; + } else { + filter.push({ key, val }); + } + setFilter([...filter]); + }; + const onSwitchChange = (event: React.ChangeEvent) => { + setRefresh(event.target.checked); + }; + const { data, isLoading } = useSWR( + "useNodeList", + async () => { + const { data } = await getNodeList(); + const { data: rspData, msg } = data; + if (msg) { + setMsg(msg); + } else { + setMsg(""); + } + return rspData; + }, + { refreshInterval: isRefreshing ? API_REFRESH_INTERVAL_MS : 0 }, + ); + + const nodeList = data?.summary ?? []; + const nodeLogicalResources = data?.nodeLogicalResources ?? {}; + + const nodeListWithAdditionalInfo = nodeList.map((e) => ({ + ...e, + state: e.raylet.state, + logicalResources: nodeLogicalResources[e.raylet.nodeId], + })); + + const sortedList = _.sortBy(nodeListWithAdditionalInfo, (node) => { + // After sorting by user specified field, stable sort by + // 1) Alive nodes first then alphabetically for other states + // 2) Head node + // 3) Alphabetical by node id + const nodeStateOrder = + node.raylet.state === "ALIVE" ? "0" : node.raylet.state; + const isHeadNodeOrder = node.raylet.isHeadNode ? "0" : "1"; + const nodeIdOrder = node.raylet.nodeId; + return [nodeStateOrder, isHeadNodeOrder, nodeIdOrder]; + }).sort(sorterFunc); + + const filteredList = sortedList.filter((node) => { + const nodeId = node.raylet.nodeId; + return filter.every((f) => { + if (f.key === "nodeId") { + return nodeId && nodeId.includes(f.val); + } else { + return node[f.key] && node[f.key].includes(f.val); + } + }); + }); + return { + nodeList: filteredList, + msg, + isLoading, + isRefreshing, + onSwitchChange, + changeFilter, + page, + originalNodes: nodeList, + setPage: (key: string, val: number) => setPage({ ...page, [key]: val }), + sorterKey, + setSortKey, + setOrderDesc, + mode, + setMode, + }; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/node/index.tsx b/historyserver/dashboard/ray/client/src/pages/node/index.tsx new file mode 100644 index 00000000000..babc8e00e7d --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/node/index.tsx @@ -0,0 +1,416 @@ +import { + Box, + Button, + ButtonGroup, + Grid, + Link, + Paper, + Switch, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Typography, +} from "@mui/material"; +import Pagination from "@mui/material/Pagination"; +import React from "react"; +import { Outlet, Link as RouterLink } from "react-router-dom"; +import { sliceToPage } from "../../common/util"; +import Loading from "../../components/Loading"; +import PercentageBar from "../../components/PercentageBar"; +import { SearchInput, SearchSelect } from "../../components/SearchComponent"; +import StateCounter from "../../components/StatesCounter"; +import { StatusChip } from "../../components/StatusChip"; +import TitleCard from "../../components/TitleCard"; +import { HelpInfo } from "../../components/Tooltip"; +import { NodeDetail } from "../../type/node"; +import { memoryConverter } from "../../util/converter"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import { useNodeList } from "./hook/useNodeList"; +import { NodeRows } from "./NodeRow"; + +const codeTextStyle = { + fontFamily: "Roboto Mono, monospace", +}; +const columns = [ + { label: "" }, // Expand button + { label: "Host / Worker Process name" }, + { label: "State" }, + { label: "State Message" }, + { label: "ID" }, + { label: "IP / PID" }, + { label: "Actions" }, + { + label: "CPU", + helpInfo: ( + + Hardware CPU usage of a Node or a Worker Process. +
+
+ Node’s CPU usage is calculated against all CPU cores. Worker Process’s + CPU usage is calculated against 1 CPU core. As a result, the sum of CPU + usage from all Worker Processes is not equal to the Node’s CPU usage. +
+ ), + }, + { + label: "Memory", + helpInfo: ( + + A Node or a Worker Process's RAM usage.
+
+ For a Node, Object Store holds up to 30% of RAM by default or a custom + value configured by users. +
+
+ RAM is not pre-allocated for Object Store. Once memory is used by and + allocated to Object Store, it will hold and not release it until the Ray + Cluster is terminated. +
+ ), + }, + { + label: "GPU", + helpInfo: ( + + Usage of each GPU device. If no GPU usage is detected, here are the + potential root causes: +
+ 1. non-GPU Ray image is used on this node. Switch to a GPU Ray image and + try again.
+ 2. Non Nvidia GPUs are being used. Non Nvidia GPUs' utilizations are not + currently supported. +
+ 3. pynvml module raises an exception. +
+ ), + }, + { label: "GRAM" }, + { label: "Object Store Memory" }, + { + label: "Disk(root)", + helpInfo: + "For Ray Clusters on Kubernetes, multiple Ray Nodes/Pods may share the same Kubernetes Node's disk, resulting in multiple nodes having the same disk usage.", + }, + { label: "Sent" }, + { label: "Received" }, + { + label: "Logical Resources", + helpInfo: ( + + + Logical resources usage + {" "} + (e.g., CPU, memory) for a node. Alternatively, you can run the CLI + command

ray status -v

+ to obtain a similar result. +
+ ), + }, + { label: "Labels" }, +]; + +export const brpcLinkChanger = (href: string) => { + const { location } = window; + const { pathname } = location; + const pathArr = pathname.split("/"); + if (pathArr.some((e) => e.split(".").length > 1)) { + const index = pathArr.findIndex((e) => e.includes(".")); + const resultArr = pathArr.slice(0, index); + resultArr.push(href); + return `${location.protocol}//${location.host}${resultArr.join("/")}`; + } + + return `http://${href}`; +}; + +export const NodeCard = (props: { node: NodeDetail }) => { + const { node } = props; + + if (!node) { + return null; + } + + const { raylet, hostname, ip, cpu, mem, networkSpeed, disk } = node; + const { nodeId, state, objectStoreUsedMemory, objectStoreAvailableMemory } = + raylet; + + const objectStoreTotalMemory = + objectStoreUsedMemory + objectStoreAvailableMemory; + + return ( + +

+ + {nodeId} + {" "} +

+

+ + + + + + {hostname}({ip}) + + {networkSpeed && networkSpeed[0] >= 0 && ( + + Sent{" "} + {memoryConverter(networkSpeed[0])}/s{" "} + Received{" "} + {memoryConverter(networkSpeed[1])}/s + + )} + +

+ + {cpu >= 0 && ( + + CPU + + {cpu}% + + + )} + {mem && ( + + Memory + + {memoryConverter(mem[0] - mem[1])}/{memoryConverter(mem[0])}( + {mem[2]}%) + + + )} + {raylet && ( + + Object Store Memory + + {memoryConverter(objectStoreUsedMemory)}/ + {memoryConverter(objectStoreTotalMemory)} + + + )} + {disk && disk["/"] && ( + + Disk('/') + + {memoryConverter(disk["/"].used)}/ + {memoryConverter(disk["/"].total)}({disk["/"].percent}%) + + + )} + + + + + + +
+ ); +}; + +const Nodes = () => { + const { + msg, + isLoading, + isRefreshing, + onSwitchChange, + nodeList, + changeFilter, + page, + setPage, + setSortKey, + setOrderDesc, + mode, + setMode, + } = useNodeList(); + + const { + items: list, + constrainedPage, + maxPage, + } = sliceToPage(nodeList, page.pageNo, page.pageSize); + + return ( + + + + Auto Refresh: + +
+ Request Status: {msg} +
+ + + + + + + changeFilter("hostname", value.trim())} + /> + + + changeFilter("ip", value.trim())} + /> + + + changeFilter("nodeId", value.trim())} + /> + + + changeFilter("state", value.trim())} + options={["ALIVE", "DEAD"]} + showAllOption={true} + /> + + + + setPage("pageSize", Math.min(Number(value), 500) || 10) + } + /> + + + setSortKey(val)} + showAllOption={true} + /> + + + + Reverse: + setOrderDesc(checked)} /> + + + + + + + + + +
+ setPage("pageNo", pageNo)} + /> +
+ {mode === "table" && ( + + + + + {columns.map(({ label, helpInfo }) => ( + + + {label} + {helpInfo && ( + {helpInfo} + )} + + + ))} + + + + {list.map((node) => ( + + ))} + +
+
+ )} + {mode === "card" && ( + + {list.map((e) => ( + + + + ))} + + )} +
+
+ ); +}; + +/** + * Cluster page for the new IA + */ +export const ClusterMainPageLayout = () => { + return ( + + + + + ); +}; + +export default Nodes; diff --git a/historyserver/dashboard/ray/client/src/pages/node/useNodeList.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/node/useNodeList.component.test.tsx new file mode 100644 index 00000000000..facddd48fe2 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/node/useNodeList.component.test.tsx @@ -0,0 +1,137 @@ +import { render, screen } from "@testing-library/react"; +import React from "react"; +import { MemoryRouter } from "react-router-dom"; +import useSWR from "swr"; +import { NodeDetail } from "../../type/node"; +import { useNodeList } from "./hook/useNodeList"; + +jest.mock("swr"); +const useSWRMocked = jest.mocked(useSWR); + +const NODE: NodeDetail = { + hostname: "test-hostname", + ip: "192.168.0.1", + cpu: 15, + mem: [100, 95, 5], + state: "ALIVE", + disk: { + "/": { + used: 20000000, + total: 200000000, + free: 180000000, + percent: 10, + }, + "/tmp": { + used: 0, + total: 200, + free: 200, + percent: 0, + }, + }, + networkSpeed: [5, 10], + raylet: { + state: "ALIVE", + nodeId: "1234567890ab", + isHeadNode: true, + numWorkers: 0, + pid: 2345, + startTime: 100, + terminateTime: -1, + brpcPort: 3456, + nodeManagerPort: 5890, + objectStoreAvailableMemory: 40, + objectStoreUsedMemory: 10, + }, +} as NodeDetail; + +const aliveHeadNode = { ...NODE, hostname: "test-hostname-alive-head-node" }; +const deadHeadNode = { + ...NODE, + hostname: "test-hostname-dead-head-node", + state: "DEAD", + raylet: { + state: "DEAD", + nodeId: "1234567890ab", + isHeadNode: false, + numWorkers: 0, + pid: 2345, + startTime: 100, + terminateTime: -1, + brpcPort: 3456, + nodeManagerPort: 5890, + objectStoreAvailableMemory: 40, + objectStoreUsedMemory: 10, + }, +}; +const aliveWorkerNode1 = { + ...NODE, + hostname: "test-hostname-worker1", + raylet: { + state: "ALIVE", + nodeId: "1234567890ab", + isHeadNode: false, + numWorkers: 0, + pid: 2345, + startTime: 100, + terminateTime: -1, + brpcPort: 3456, + nodeManagerPort: 5890, + objectStoreAvailableMemory: 40, + objectStoreUsedMemory: 10, + }, +}; +const aliveWorkerNode2 = { + ...NODE, + hostname: "test-hostname-worker2", + raylet: { + state: "ALIVE", + nodeId: "1234567890ac", + isHeadNode: false, + numWorkers: 0, + pid: 2345, + startTime: 100, + terminateTime: -1, + brpcPort: 3456, + nodeManagerPort: 5890, + objectStoreAvailableMemory: 40, + objectStoreUsedMemory: 10, + }, +}; + +describe("useNodeList", () => { + it("verify default sort order of useNodeList", () => { + useSWRMocked.mockReturnValue({ + data: { + summary: [ + deadHeadNode, + aliveWorkerNode2, + aliveHeadNode, + aliveWorkerNode1, + ], + nodeLogicalResources: undefined, + }, + isLoading: false, + } as any); + + const TestComponent = () => { + const { nodeList } = useNodeList(); + const nodeHostNames = nodeList.map((e) => e.hostname); + return
{nodeHostNames}
; + }; + + render( + + + , + ); + + const nodeHostNames = screen.getByTestId("nodeHostNames"); + const expectedOrderNodeList = [ + aliveHeadNode.hostname, + aliveWorkerNode1.hostname, + aliveWorkerNode2.hostname, + deadHeadNode.hostname, + ]; + expect(nodeHostNames.textContent).toEqual(expectedOrderNodeList.join("")); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/overview/OverviewPage.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/overview/OverviewPage.component.test.tsx new file mode 100644 index 00000000000..7f2d16a2d54 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/overview/OverviewPage.component.test.tsx @@ -0,0 +1,98 @@ +import { render, screen, waitFor } from "@testing-library/react"; +import React, { PropsWithChildren } from "react"; +import { MemoryRouter } from "react-router-dom"; +import { GlobalContext } from "../../App"; +import { STYLE_WRAPPER } from "../../util/test-utils"; +import { useJobList } from "../job/hook/useJobList"; +import { OverviewPage } from "./OverviewPage"; + +jest.mock("../job/hook/useJobList"); + +describe("OverviewPage", () => { + it("renders", async () => { + expect.assertions(3); + + const mockedUseJobList = jest.mocked(useJobList); + + mockedUseJobList.mockReturnValue({ + jobList: [ + { + job_id: "01000000", + submission_id: "raysubmit_12345", + status: "SUCCEEDED", + }, + ], + } as any); + + render(, { wrapper: Wrapper(false) }); + await screen.findByText(/Events/); + expect(screen.getByText(/Events/)).toBeVisible(); + expect(screen.getByTitle("Cluster Utilization")).toBeInTheDocument(); + expect(screen.getByTitle("Node Count")).toBeInTheDocument(); + // Wait because for some reason events is trying to log something after test is finished + await waitFor(() => new Promise((resolve) => setTimeout(resolve, 10))); + }); + + it("does not render metrics cards if grafana is disabled", async () => { + expect.assertions(5); + + const mockedUseJobList = jest.mocked(useJobList); + + mockedUseJobList.mockReturnValue({ + jobList: [ + { + job_id: "01000000", + submission_id: "raysubmit_12345", + status: "SUCCEEDED", + }, + ], + } as any); + + render(, { wrapper: Wrapper(true) }); + await screen.findByText(/Events/); + expect(screen.getByText(/Events/)).toBeVisible(); + expect(screen.queryByText("Cluster utilization")).toBeNull(); + expect(screen.queryByTitle("Cluster Utilization")).toBeNull(); + expect(screen.queryByText("Node count")).toBeNull(); + expect(screen.queryByTitle("Node Count")).toBeNull(); + // Wait because for some reason events is trying to log something after test is finished + await waitFor(() => new Promise((resolve) => setTimeout(resolve, 10))); + }); +}); + +const Wrapper = + (grafanaHostDisabled: boolean) => + ({ children }: PropsWithChildren<{}>) => { + return ( + + + + {children} + + + + ); + }; diff --git a/historyserver/dashboard/ray/client/src/pages/overview/OverviewPage.tsx b/historyserver/dashboard/ray/client/src/pages/overview/OverviewPage.tsx new file mode 100644 index 00000000000..c465f65c5f1 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/overview/OverviewPage.tsx @@ -0,0 +1,94 @@ +import { Box, Theme } from "@mui/material"; +import React from "react"; +import {useParams} from "react-router-dom"; +import { CollapsibleSection } from "../../common/CollapsibleSection"; +import { + NodeStatusCard, + ResourceStatusCard, +} from "../../components/AutoscalerStatusCards"; +import EventTable from "../../components/EventTable"; +import { useRayStatus } from "../job/hook/useClusterStatus"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import { ClusterUtilizationCard } from "./cards/ClusterUtilizationCard"; +import { NodeCountCard } from "./cards/NodeCountCard"; +import { OverviewCard } from "./cards/OverviewCard"; +import { RecentJobsCard } from "./cards/RecentJobsCard"; +import { RecentServeCard } from "./cards/RecentServeCard"; + +const styles = { + overviewCard: (theme: Theme) => ({ + flex: "1 0 448px", + maxWidth: "100%", + [theme.breakpoints.up("md")]: { + // Calculate max width based on 1/3 of the total width minus padding between cards + maxWidth: `calc((100% - ${theme.spacing(3)} * 2) / 3)`, + }, + }), + autoscalerCard: { + backgroundColor: "white", + paddingX: 3, + paddingY: 2, + }, +}; + +export const OverviewPage = () => { + //return
hello world
+ const { clusterStatus } = useRayStatus(); + + return ( + + + ({ + display: "flex", + flexDirection: "row", + flexWrap: "wrap", + marginBottom: 4, + gap: 3, + [theme.breakpoints.up("md")]: { + flexWrap: "nowrap", + }, + })} + > + + + + + + + { + ({ + display: "flex", + flexDirection: "row", + flexWrap: "wrap", + marginBottom: 4, + gap: 3, + [theme.breakpoints.up("md")]: { + flexWrap: "nowrap", + }, + })} + > + + + + + + + + + } + + + + + + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/overview/cards/ClusterUtilizationCard.tsx b/historyserver/dashboard/ray/client/src/pages/overview/cards/ClusterUtilizationCard.tsx new file mode 100644 index 00000000000..e80343e11c5 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/overview/cards/ClusterUtilizationCard.tsx @@ -0,0 +1,76 @@ +import { Box, SxProps, Theme, Typography } from "@mui/material"; +import { useParams } from "react-router-dom"; +import React, { useContext } from "react"; +import { GlobalContext } from "../../../App"; +import { GrafanaNotRunningAlert } from "../../metrics"; +import { LinkWithArrow, OverviewCard } from "./OverviewCard"; + +type ClusterUtilizationCardProps = { + className?: string; + sx?: SxProps; +}; + +export const ClusterUtilizationCard = ({ + className, + sx, +}: ClusterUtilizationCardProps) => { + const { + metricsContextLoaded, + grafanaHost, + prometheusHealth, + dashboardUids, + dashboardDatasource, + } = useContext(GlobalContext); + const grafanaDefaultDashboardUid = + dashboardUids?.default ?? "rayDefaultDashboard"; + const grafanaDefaultDashboardUidParams = + dashboardUids?.default_params ?? "orgId=1"; + const path = `/d-solo/${grafanaDefaultDashboardUid}?${grafanaDefaultDashboardUidParams}&theme=light&panelId=41`; + const timeRangeParams = "&from=now-30m&to=now"; + const { clusterName, sessionName } = useParams(); + + if (!metricsContextLoaded || grafanaHost === "DISABLED") { + return null; + } + + return ( + + {/* TODO (aguo): Switch this to overall utilization graph */} + {/* TODO (aguo): Handle grafana not running */} + {grafanaHost === undefined || !prometheusHealth ? ( + + Cluster utilization + + + ) : ( + + + + + + + )} + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/overview/cards/NodeCountCard.tsx b/historyserver/dashboard/ray/client/src/pages/overview/cards/NodeCountCard.tsx new file mode 100644 index 00000000000..47566bdf89a --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/overview/cards/NodeCountCard.tsx @@ -0,0 +1,69 @@ +import { Box, SxProps, Theme, Typography } from "@mui/material"; +import React, { useContext } from "react"; +import { GlobalContext } from "../../../App"; +import { GrafanaNotRunningAlert } from "../../metrics"; +import { LinkWithArrow, OverviewCard } from "./OverviewCard"; +import { useParams } from "react-router-dom"; + +type NodeCountCardProps = { + className?: string; + sx?: SxProps; +}; +{/*change by bingyu*/} +export const NodeCountCard = ({ className, sx }: NodeCountCardProps) => { + const {clusterName, sessionName}= useParams(); + const { + metricsContextLoaded, + grafanaHost, + prometheusHealth, + dashboardUids, + dashboardDatasource, + } = useContext(GlobalContext); + const grafanaDefaultDashboardUid = + dashboardUids?.default ?? "rayDefaultDashboard"; + const grafanaDefaultDashboardUidParams = + dashboardUids?.default_params ?? "orgId=1"; + const path = `/d-solo/${grafanaDefaultDashboardUid}?${grafanaDefaultDashboardUidParams}&theme=light&panelId=24`; + const timeRangeParams = "&from=now-30m&to=now"; + + if (!metricsContextLoaded || grafanaHost === "DISABLED") { + return null; + } + + return ( + + {grafanaHost === undefined || !prometheusHealth ? ( + + Node count + + + ) : ( + + )} + + + + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/overview/cards/OverviewCard.tsx b/historyserver/dashboard/ray/client/src/pages/overview/cards/OverviewCard.tsx new file mode 100644 index 00000000000..d8b5b24058a --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/overview/cards/OverviewCard.tsx @@ -0,0 +1,60 @@ +import { Box, Link, Paper, SxProps, Theme, Typography } from "@mui/material"; +import React, { PropsWithChildren } from "react"; +import { RiArrowRightLine } from "react-icons/ri"; +import { Link as RouterLink } from "react-router-dom"; + +type OverviewCardProps = PropsWithChildren<{ + className?: string; + sx?: SxProps; +}>; + +export const OverviewCard = ({ + children, + className, + sx, +}: OverviewCardProps) => { + return ( + + {children} + + ); +}; + +type LinkWithArrowProps = { + text: string; + to: string; +}; + +export const LinkWithArrow = ({ text, to }: LinkWithArrowProps) => { + return ( + + {text} + + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/overview/cards/RecentJobsCard.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/overview/cards/RecentJobsCard.component.test.tsx new file mode 100644 index 00000000000..cb6ae3b37dd --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/overview/cards/RecentJobsCard.component.test.tsx @@ -0,0 +1,84 @@ +import { render, screen } from "@testing-library/react"; +import React from "react"; +import { TEST_APP_WRAPPER } from "../../../util/test-utils"; +import { useJobList } from "../../job/hook/useJobList"; +import { RecentJobsCard } from "./RecentJobsCard"; + +const JOB_LIST = [ + { + job_id: "01000000", + submission_id: "raysubmit_12345", + status: "SUCCEEDED", + }, + { + job_id: "02000000", + submission_id: null, + status: "FAILED", + }, + { + job_id: null, + submission_id: "raysubmit_23456", + status: "STOPPED", + }, + { + job_id: "04000000", + submission_id: "raysubmit_34567", + status: "SUCCEEDED", + }, + { + job_id: "05000000", + submission_id: "raysubmit_45678", + status: "RUNNING", + }, + { + job_id: "06000000", + submission_id: "raysubmit_56789", + status: "RUNNING", + }, + { + job_id: "07000000", + submission_id: "raysubmit_67890", + status: "RUNNING", + }, +]; +const mockedUseJobList = jest.mocked(useJobList); + +jest.mock("../../job/hook/useJobList"); +describe("RecentJobsCard", () => { + beforeEach(() => { + mockedUseJobList.mockReturnValue({ + jobList: JOB_LIST, + } as any); + }); + + it("renders", async () => { + render(, { wrapper: TEST_APP_WRAPPER }); + + await screen.findByText("raysubmit_12345 (01000000)"); + expect(screen.getByText("02000000")).toBeVisible(); + expect(screen.getByText("raysubmit_23456")).toBeVisible(); + expect(screen.getByText("raysubmit_34567 (04000000)")).toBeVisible(); + expect(screen.getByText("raysubmit_45678 (05000000)")).toBeVisible(); + expect(screen.getByText("raysubmit_56789 (06000000)")).toBeVisible(); + expect(screen.queryByText(/raysubmit_67890/)).toBeNull(); + }); + + it("the link is active when job_id is not null", async () => { + render(, { wrapper: TEST_APP_WRAPPER }); + + await screen.findByText(/raysubmit_12345/); + + const link = screen.getByRole("link", { name: /raysubmit_45678/ }); + expect(link).toHaveAttribute("href"); + }); + + it("link is active for driverless job(only have submission_id)", async () => { + render(, { wrapper: TEST_APP_WRAPPER }); + + await screen.findByText(/raysubmit_12345/); + + expect( + screen.queryByRole("link", { name: /raysubmit_23456/ }), + ).toBeVisible(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/overview/cards/RecentJobsCard.tsx b/historyserver/dashboard/ray/client/src/pages/overview/cards/RecentJobsCard.tsx new file mode 100644 index 00000000000..03aa806702c --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/overview/cards/RecentJobsCard.tsx @@ -0,0 +1,58 @@ +import { SxProps, Theme } from "@mui/material"; +import _ from "lodash"; +import React from "react"; +import { JobStatusIcon } from "../../../common/JobStatus"; +import { ListItemCard } from "../../../components/ListItemCard"; +import { UnifiedJob } from "../../../type/job"; +import { useJobList } from "../../job/hook/useJobList"; +import { useParams } from "react-router-dom"; + +type RecentJobsCardProps = { + className?: string; + sx?: SxProps; +}; + +{/*add by bingyu*/} +const getLink = (clusterName: string | undefined, sessionName: string | undefined, job: UnifiedJob) => { + if (job.job_id !== null && job.job_id !== "") { + return `/clusters/${clusterName}/${sessionName}/jobs/${job.job_id}`; + } else if (job.submission_id !== null && job.submission_id !== "") { + return `/clusters/${clusterName}/${sessionName}/jobs/${job.submission_id}`; + } + return undefined; +}; + +export const RecentJobsCard = ({ className, sx }: RecentJobsCardProps) => { + const { jobList } = useJobList(); + const {clusterName, sessionName}= useParams(); + const sortedJobs = _.orderBy(jobList, ["startTime"], ["desc"]).slice(0, 6); + + const sortedJobToRender = sortedJobs.map((job) => { + let title: string | undefined; + if (job.submission_id && job.job_id) { + title = `${job.submission_id} (${job.job_id})`; + } else { + title = job.submission_id ?? job.job_id ?? undefined; + } + return { + title, + subtitle: job.entrypoint, + link: getLink(clusterName, sessionName, job), + className: className, + icon: , + }; + }); + + {/*add by bingyu*/} + return ( + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/overview/cards/RecentServeCard.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/overview/cards/RecentServeCard.component.test.tsx new file mode 100644 index 00000000000..fec3c043688 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/overview/cards/RecentServeCard.component.test.tsx @@ -0,0 +1,92 @@ +import { render, screen } from "@testing-library/react"; +import React from "react"; +import { getServeApplications } from "../../../service/serve"; +import { + ServeApplicationStatus, + ServeProxyLocation, +} from "../../../type/serve"; +import { TEST_APP_WRAPPER } from "../../../util/test-utils"; +import { RecentServeCard } from "./RecentServeCard"; + +jest.mock("../../../service/serve"); + +const mockGetServeApplications = jest.mocked(getServeApplications); + +describe("RecentServeCard", () => { + beforeEach(() => { + mockGetServeApplications.mockResolvedValue({ + data: { + http_options: { host: "1.2.3.4", port: 8000 }, + proxy_location: ServeProxyLocation.EveryNode, + applications: { + home: { + name: "home", + route_prefix: "/", + message: null, + status: ServeApplicationStatus.RUNNING, + deployed_app_config: { + import_path: "home:graph", + }, + last_deployed_time_s: new Date().getTime() / 1000, + deployments: { + FirstDeployment: { + name: "FirstDeployment", + }, + }, + }, + "second-app": { + name: "second-app", + route_prefix: "/second-app", + message: null, + status: ServeApplicationStatus.DEPLOYING, + deployed_app_config: null, + last_deployed_time_s: new Date().getTime() / 1000, + deployments: { + SecondDeployment: { + name: "SecondDeployment", + }, + }, + }, + }, + }, + } as any); + }); + + it("should display serve deployments with deployed_app_config", async () => { + render(, { + wrapper: TEST_APP_WRAPPER, + }); + + await screen.findByText("View all deployments"); + + expect.assertions(3); + expect(screen.getByText("FirstDeployment")).toBeInTheDocument(); + expect(screen.getByText("home:graph")).toBeInTheDocument(); + expect(screen.getByText("Serve Deployments")).toBeInTheDocument(); + }); + + it("should display serve deployments without deployed_app_config", async () => { + render(, { + wrapper: TEST_APP_WRAPPER, + }); + + await screen.findByText("View all deployments"); + + expect.assertions(3); + expect(screen.getByText("SecondDeployment")).toBeInTheDocument(); + expect(screen.getByText("second-app")).toBeInTheDocument(); // default value for no deployed_app_config + expect(screen.getByText("Serve Deployments")).toBeInTheDocument(); + }); + + it("should navigate to the applications page when the 'View all deployments' link is clicked", async () => { + render(, { + wrapper: TEST_APP_WRAPPER, + }); + + await screen.findByText("View all deployments"); + const link = screen.getByRole("link", { + name: /view all deployments/i, + }); + expect(link).toHaveAttribute("href", "/serve"); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/overview/cards/RecentServeCard.tsx b/historyserver/dashboard/ray/client/src/pages/overview/cards/RecentServeCard.tsx new file mode 100644 index 00000000000..ce4a641d943 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/overview/cards/RecentServeCard.tsx @@ -0,0 +1,59 @@ +import { SxProps, Theme } from "@mui/material"; +import _ from "lodash"; +import React from "react"; +import { ServeStatusIcon } from "../../../common/ServeStatus"; +import { ListItemCard } from "../../../components/ListItemCard"; +import { useServeDeployments } from "../../serve/hook/useServeApplications"; +import { useParams } from "react-router-dom"; + +type RecentServeCardProps = { + className?: string; + sx?: SxProps; +}; + +{/* change by bingyu*/} +export const RecentServeCard = ({ className, sx }: RecentServeCardProps) => { + const { serveDeployments: deployments } = useServeDeployments(); + const {clusterName}= useParams(); + const sortedDeployments = _.orderBy( + deployments, + ["application.last_deployed_time_s", "name"], + ["desc", "asc"], + ).slice(0, 6); + + const sortedDeploymentsToRender = sortedDeployments.map((deployment) => { + return { + title: deployment.name, + subtitle: + deployment.application.deployed_app_config?.import_path || + deployment.application.name || + deployment.application.route_prefix, + link: + deployment.application.name && deployment.name + ? `/clusters/${clusterName}/serve/applications/${encodeURIComponent( + deployment.application.name, + )}/${encodeURIComponent(deployment.name)}` + : undefined, + className: className, + icon: ( + + ), + }; + }); + + return ( + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeApplicationDetailPage.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeApplicationDetailPage.component.test.tsx new file mode 100644 index 00000000000..aee0f787297 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeApplicationDetailPage.component.test.tsx @@ -0,0 +1,149 @@ +import { render, screen, within } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import React from "react"; +import { useParams } from "react-router-dom"; +import { getServeApplications } from "../../service/serve"; +import { + ServeApplicationStatus, + ServeDeploymentStatus, + ServeReplicaState, +} from "../../type/serve"; +import { TEST_APP_WRAPPER } from "../../util/test-utils"; +import { ServeApplicationDetailPage } from "./ServeApplicationDetailPage"; + +jest.mock("react-router-dom", () => ({ + ...jest.requireActual("react-router-dom"), + useParams: jest.fn(), +})); +jest.mock("../../service/serve"); + +const mockUseParams = jest.mocked(useParams); +const mockGetServeApplications = jest.mocked(getServeApplications); + +describe("ServeApplicationDetailPage", () => { + it("renders page with deployments and replicas", async () => { + expect.assertions(13); + + mockUseParams.mockReturnValue({ + applicationName: "home", + }); + mockGetServeApplications.mockResolvedValue({ + data: { + applications: { + home: { + name: "home", + route_prefix: "/home", + message: null, + status: ServeApplicationStatus.RUNNING, + deployed_app_config: { + import_path: "home:graph", + }, + last_deployed_time_s: new Date().getTime() / 1000, + deployments: { + FirstDeployment: { + name: "FirstDeployment", + deployment_config: { + "test-config": 1, + autoscaling_config: { + "autoscaling-value": 2, + }, + }, + status: ServeDeploymentStatus.HEALTHY, + message: "deployment is healthy", + replicas: [ + { + actor_id: "test-actor-id", + actor_name: "FirstDeployment", + node_id: "test-node-id", + node_ip: "123.456.789.123", + pid: "12345", + replica_id: "test-replica-1", + start_time_s: new Date().getTime() / 1000, + state: ServeReplicaState.STARTING, + }, + { + actor_id: "test-actor-id-2", + actor_name: "FirstDeployment", + node_id: "test-node-id", + node_ip: "123.456.789.123", + pid: "12346", + replica_id: "test-replica-2", + start_time_s: new Date().getTime() / 1000, + state: ServeReplicaState.RUNNING, + }, + ], + }, + SecondDeployment: { + name: "SecondDeployment", + deployment_config: {}, + status: ServeDeploymentStatus.UPDATING, + message: "deployment is updating", + replicas: [ + { + actor_id: "test-actor-id-3", + actor_name: "SecondDeployment", + node_id: "test-node-id", + node_ip: "123.456.789.123", + pid: "12347", + replica_id: "test-replica-3", + start_time_s: new Date().getTime() / 1000, + state: ServeReplicaState.STARTING, + }, + ], + }, + }, + }, + "second-app": { + // Decoy second app + }, + "third-app": { + // Decoy third app + }, + }, + }, + } as any); + + render(, { wrapper: TEST_APP_WRAPPER }); + + const user = userEvent.setup(); + + await screen.findAllByText("home"); + expect(screen.getByTestId("metadata-content-for-Name")).toHaveTextContent( + "home", + ); + expect( + screen.getByTestId("metadata-content-for-Route prefix"), + ).toHaveTextContent("/home"); + expect(screen.getByTestId("metadata-content-for-Status")).toHaveTextContent( + "RUNNING", + ); + expect( + screen.getByTestId("metadata-content-for-Replicas"), + ).toHaveTextContent("3"); + + // First deployment + expect(screen.getByText("FirstDeployment")).toBeVisible(); + expect(screen.getByText("deployment is healthy")).toBeVisible(); + expect(screen.getByText("HEALTHY")).toBeVisible(); + + // Second deployment + expect(screen.getByText("SecondDeployment")).toBeVisible(); + expect(screen.getByText("deployment is updating")).toBeVisible(); + expect(screen.getByText("UPDATING")).toBeVisible(); + + // Config dialog for application + await user.click( + within( + screen.getByTestId("metadata-content-for-Application config"), + ).getByText("View"), + ); + await screen.findByText(/import_path: home:graph/); + expect(screen.getByText(/import_path: home:graph/)).toBeVisible(); + + // Config dialog for first deployment + await user.click(screen.getAllByText("View config")[0]); + await screen.findByText(/test-config: 1/); + expect(screen.getByText(/test-config: 1/)).toBeVisible(); + expect(screen.getByText(/autoscaling-value: 2/)).toBeVisible(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeApplicationDetailPage.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeApplicationDetailPage.tsx new file mode 100644 index 00000000000..6cc78e75d07 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeApplicationDetailPage.tsx @@ -0,0 +1,269 @@ +import { + Autocomplete, + Box, + Pagination, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + TextField, + TextFieldProps, + Typography, +} from "@mui/material"; +import React, { ReactElement } from "react"; +import { Outlet, useParams } from "react-router-dom"; +import { CodeDialogButton } from "../../common/CodeDialogButton"; +import { CollapsibleSection } from "../../common/CollapsibleSection"; +import { DurationText } from "../../common/DurationText"; +import { formatDateFromTimeMs } from "../../common/formatUtils"; +import { sliceToPage } from "../../common/util"; +import Loading from "../../components/Loading"; +import { MetadataSection } from "../../components/MetadataSection"; +import { StatusChip } from "../../components/StatusChip"; +import { HelpInfo } from "../../components/Tooltip"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import { useServeApplicationDetails } from "./hook/useServeApplications"; +import { ServeDeploymentRow } from "./ServeDeploymentRow"; + +const columns: { label: string; helpInfo?: ReactElement; width?: string }[] = [ + { label: "Deployment name" }, + { label: "Status" }, + { label: "Status message", width: "30%" }, + { label: "Num replicas" }, + { label: "Actions" }, + { label: "Route prefix" }, + { label: "Last deployed at" }, + { label: "Duration (since last deploy)" }, +]; + +export const ServeApplicationDetailPage = () => { + const { applicationName } = useParams(); + + const { + application, + filteredDeployments, + page, + setPage, + changeFilter, + allDeployments, + } = useServeApplicationDetails(applicationName); + + if (!application) { + return ( + + Application with name "{applicationName}" not found. + + ); + } + + const appName = application.name ? application.name : "-"; + + const { + items: list, + constrainedPage, + maxPage, + } = sliceToPage(filteredDeployments, page.pageNo, page.pageSize); + + return ( + + + {" "} + {application.message && ( + + )} + + ), + }, + { + label: "Deployments", + content: { + value: `${Object.keys(application.deployments).length}`, + }, + }, + { + label: "Replicas", + content: { + value: Object.values(application.deployments) + .map(({ replicas }) => replicas.length) + .reduce((acc, curr) => acc + curr, 0) + .toString(), + }, + }, + { + label: "Application config", + content: application.deployed_app_config ? ( + + ) : ( + - + ), + }, + { + label: "Last deployed at", + content: { + value: formatDateFromTimeMs( + application.last_deployed_time_s * 1000, + ), + }, + }, + { + label: "Duration (since last deploy)", + content: ( + + ), + }, + { + label: "Import path", + content: { + value: application?.deployed_app_config?.import_path || "-", + }, + }, + ]} + /> + + +
+ e.name)))} + onInputChange={(_: any, value: string) => { + changeFilter("name", value.trim() !== "-" ? value.trim() : ""); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + e.status)))} + onInputChange={(_: any, value: string) => { + changeFilter("status", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + { + setPage("pageSize", Math.min(Number(value), 500) || 10); + }, + }} + /> +
+
+ setPage("pageNo", pageNo)} + /> +
+ + + + {columns.map(({ label, helpInfo, width }) => ( + + + {label} + {helpInfo && ( + {helpInfo} + )} + + + ))} + + + + {list.map((deployment) => ( + + ))} + +
+
+
+
+ ); +}; + +export const ServeApplicationDetailLayout = () => { + const { applicationName } = useParams(); + + const { loading, application } = useServeApplicationDetails(applicationName); + + if (loading) { + return ; + } else if (!application) { + return ( + + Application with name "{applicationName}" not found. + + ); + } + + const appName = application.name ? application.name : "-"; + + return ( + + + + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeApplicationRow.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeApplicationRow.tsx new file mode 100644 index 00000000000..392915eb252 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeApplicationRow.tsx @@ -0,0 +1,126 @@ +import { Box, IconButton, Link, TableCell, TableRow } from "@mui/material"; +import React, { useState } from "react"; +import { RiArrowDownSLine, RiArrowRightSLine } from "react-icons/ri"; +import { Link as RouterLink } from "react-router-dom"; +import { + CodeDialogButton, + CodeDialogButtonWithPreview, +} from "../../common/CodeDialogButton"; +import { DurationText } from "../../common/DurationText"; +import { formatDateFromTimeMs } from "../../common/formatUtils"; +import { StatusChip } from "../../components/StatusChip"; +import { ServeApplication } from "../../type/serve"; +import { ServeDeploymentRow } from "./ServeDeploymentRow"; + +export type ServeApplicationRowsProps = { + application: ServeApplication; + startExpanded?: boolean; +}; + +export const ServeApplicationRows = ({ + application, + startExpanded = true, +}: ServeApplicationRowsProps) => { + const [isExpanded, setExpanded] = useState(startExpanded); + + const { + name, + message, + status, + route_prefix, + last_deployed_time_s, + deployments, + deployed_app_config, + } = application; + + const deploymentsList = Object.values(deployments); + + const onExpandButtonClick = () => { + setExpanded(!isExpanded); + }; + + // TODO(aguo): Add duration and end time once available in the API + return ( + + + + + {!isExpanded ? ( + theme.palette.text.secondary, + fontSize: "1.5em", + verticalAlign: "middle", + }} + /> + ) : ( + theme.palette.text.secondary, + fontSize: "1.5em", + verticalAlign: "middle", + }} + /> + )} + + + + + {name ? name : "-"} + + + + + + + {message ? ( + + ) : ( + "-" + )} + + + {/* placeholder for num_replicas, which does not apply to an application */} + - + + + {deployed_app_config ? ( + + ) : ( + "-" + )} + + {route_prefix} + + {formatDateFromTimeMs(last_deployed_time_s * 1000)} + + + + + + {isExpanded && + deploymentsList.map((deployment) => ( + + ))} + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentDetailPage.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentDetailPage.component.test.tsx new file mode 100644 index 00000000000..effdbf7f3ed --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentDetailPage.component.test.tsx @@ -0,0 +1,142 @@ +import { render, screen, within } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import React from "react"; +import { useParams } from "react-router-dom"; +import { getServeApplications } from "../../service/serve"; +import { + ServeApplicationStatus, + ServeDeploymentStatus, + ServeReplicaState, +} from "../../type/serve"; +import { TEST_APP_WRAPPER } from "../../util/test-utils"; +import { ServeDeploymentDetailPage } from "./ServeDeploymentDetailPage"; + +jest.mock("react-router-dom", () => ({ + ...jest.requireActual("react-router-dom"), + useParams: jest.fn(), +})); +jest.mock("../../service/serve"); + +const mockUseParams = jest.mocked(useParams); +const mockGetServeApplications = jest.mocked(getServeApplications); + +describe("ServeDeploymentDetailPage", () => { + it("renders page with deployment details", async () => { + expect.assertions(9); + + mockUseParams.mockReturnValue({ + applicationName: "home", + deploymentName: "FirstDeployment", + }); + mockGetServeApplications.mockResolvedValue({ + data: { + applications: { + home: { + name: "home", + route_prefix: "/home", + message: null, + status: ServeApplicationStatus.RUNNING, + deployed_app_config: { + import_path: "home:graph", + }, + last_deployed_time_s: new Date().getTime() / 1000, + deployments: { + FirstDeployment: { + name: "FirstDeployment", + deployment_config: { + "test-config": 1, + autoscaling_config: { + "autoscaling-value": 2, + }, + }, + status: ServeDeploymentStatus.HEALTHY, + message: "deployment is healthy", + replicas: [ + { + actor_id: "test-actor-id", + actor_name: "FirstDeployment", + node_id: "test-node-id", + node_ip: "123.456.789.123", + pid: "12345", + replica_id: "test-replica-1", + start_time_s: new Date().getTime() / 1000, + state: ServeReplicaState.STARTING, + }, + { + actor_id: "test-actor-id-2", + actor_name: "FirstDeployment", + node_id: "test-node-id", + node_ip: "123.456.789.123", + pid: "12346", + replica_id: "test-replica-2", + start_time_s: new Date().getTime() / 1000, + state: ServeReplicaState.RUNNING, + }, + ], + }, + SecondDeployment: { + name: "SecondDeployment", + deployment_config: {}, + status: ServeDeploymentStatus.UPDATING, + message: "deployment is updating", + replicas: [ + { + actor_id: "test-actor-id-3", + actor_name: "SecondDeployment", + node_id: "test-node-id", + node_ip: "123.456.789.123", + pid: "12347", + replica_id: "test-replica-3", + start_time_s: new Date().getTime() / 1000, + state: ServeReplicaState.STARTING, + }, + ], + }, + }, + }, + "second-app": { + // Decoy second app + }, + "third-app": { + // Decoy third app + }, + }, + }, + } as any); + + render(, { wrapper: TEST_APP_WRAPPER }); + + const user = userEvent.setup(); + + await screen.findByText("FirstDeployment"); + expect(screen.getByTestId("metadata-content-for-Name")).toHaveTextContent( + "FirstDeployment", + ); + expect(screen.getByTestId("metadata-content-for-Status")).toHaveTextContent( + "HEALTHY", + ); + expect( + screen.getByTestId("metadata-content-for-Replicas"), + ).toHaveTextContent("2"); + + // First replica + // First instance of text is the Replica row + // Second instance of text is the Replica selection in the dropdown + expect(screen.getAllByText("test-replica-1")[0]).toBeVisible(); + expect(screen.getByText("STARTING")).toBeVisible(); + + // Second replica + expect(screen.getByText("test-replica-2")).toBeVisible(); + expect(screen.getByText("RUNNING")).toBeVisible(); + + // Config dialog for deployment + await user.click( + within( + screen.getByTestId("metadata-content-for-Deployment config"), + ).getByText("View"), + ); + await screen.findByText(/test-config: 1/); + expect(screen.getByText(/test-config: 1/)).toBeVisible(); + expect(screen.getByText(/autoscaling-value: 2/)).toBeVisible(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentDetailPage.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentDetailPage.tsx new file mode 100644 index 00000000000..a0f8ceae9db --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentDetailPage.tsx @@ -0,0 +1,277 @@ +import { + Autocomplete, + Box, + Pagination, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + TextField, + TextFieldProps, + Typography, +} from "@mui/material"; +import React, { ReactElement } from "react"; +import { Outlet, useParams } from "react-router-dom"; +import { CodeDialogButton } from "../../common/CodeDialogButton"; +import { CollapsibleSection } from "../../common/CollapsibleSection"; +import { DurationText } from "../../common/DurationText"; +import { formatDateFromTimeMs } from "../../common/formatUtils"; +import { sliceToPage } from "../../common/util"; +import Loading from "../../components/Loading"; +import { MetadataSection } from "../../components/MetadataSection"; +import { StatusChip } from "../../components/StatusChip"; +import { HelpInfo } from "../../components/Tooltip"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import { useServeDeploymentDetails } from "./hook/useServeApplications"; +import { ServeReplicaRow } from "./ServeDeploymentRow"; +import { ServeEntityLogViewer } from "./ServeEntityLogViewer"; + +const columns: { label: string; helpInfo?: ReactElement; width?: string }[] = [ + { label: "Replica ID" }, + { label: "Status" }, + { label: "Actions" }, + { label: "Started at" }, + { label: "Duration" }, +]; + +export const ServeDeploymentDetailPage = () => { + const { applicationName, deploymentName } = useParams(); + + const { + application, + deployment, + filteredReplicas, + page, + setPage, + changeFilter, + } = useServeDeploymentDetails(applicationName, deploymentName); + + if (!application) { + return ( + + Application with name "{applicationName}" not found. + + ); + } + + if (!deployment) { + return ( + + Deployment with name "{deploymentName}" not found. + + ); + } + + const { + items: list, + constrainedPage, + maxPage, + } = sliceToPage(filteredReplicas, page.pageNo, page.pageSize); + + return ( + + + {" "} + {deployment.message && ( + + )} + + ), + }, + { + label: "Name", + content: { + value: deployment.name, + }, + }, + { + label: "Replicas", + content: { + value: `${Object.keys(deployment.replicas).length}`, + }, + }, + { + label: "Deployment config", + content: deployment.deployment_config ? ( + + ) : ( + - + ), + }, + { + label: "Last deployed at", + content: { + value: formatDateFromTimeMs( + application.last_deployed_time_s * 1000, + ), + }, + }, + { + label: "Duration (since last deploy)", + content: ( + + ), + }, + ]} + /> + + +
+ e.replica_id)), + )} + onInputChange={(_: any, value: string) => { + changeFilter( + "replica_id", + value.trim() !== "-" ? value.trim() : "", + ); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + e.state)), + )} + onInputChange={(_: any, value: string) => { + changeFilter("state", value.trim()); + }} + renderInput={(params: TextFieldProps) => ( + + )} + /> + { + setPage("pageSize", Math.min(Number(value), 500) || 10); + }, + }} + /> +
+
+ setPage("pageNo", pageNo)} + /> +
+ + + + {columns.map(({ label, helpInfo, width }) => ( + + + {label} + {helpInfo && ( + {helpInfo} + )} + + + ))} + + + + {list.map((replica) => ( + + ))} + +
+
+
+ + + +
+ ); +}; + +export const ServeDeploymentDetailLayout = () => { + const { applicationName, deploymentName } = useParams(); + + const { application, deployment, loading, error } = useServeDeploymentDetails( + applicationName, + deploymentName, + ); + + if (loading) { + return ; + } + + if (error) { + return {error.message}; + } + + if (!application) { + return ( + + Application with name "{applicationName}" not found. + + ); + } + + if (!deployment) { + return ( + + Deployment with name "{deploymentName}" not found. + + ); + } + + const appName = application.name ? application.name : "-"; + + return ( + + + + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentMetricsSection.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentMetricsSection.component.test.tsx new file mode 100644 index 00000000000..50d55882abd --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentMetricsSection.component.test.tsx @@ -0,0 +1,102 @@ +import { render, screen, waitFor } from "@testing-library/react"; +import React, { PropsWithChildren } from "react"; +import { GlobalContext } from "../../App"; +import { STYLE_WRAPPER } from "../../util/test-utils"; +import { ServeReplicaMetricsSection } from "./ServeDeploymentMetricsSection"; + +const Wrapper = ({ children }: PropsWithChildren<{}>) => { + return ( + + {children} + + ); +}; + +const MetricsDisabledWrapper = ({ children }: PropsWithChildren<{}>) => { + return ( + + {children} + + ); +}; + +describe("ServeReplicaMetricsSection", () => { + it("renders", async () => { + expect.assertions(4); + + render( + , + { wrapper: Wrapper }, + ); + await screen.findByText(/View in Grafana/); + expect(screen.getByText(/5 minutes/)).toBeVisible(); + expect(screen.getByTitle("QPS per replica")).toBeInTheDocument(); + expect(screen.getByTitle("Error QPS per replica")).toBeInTheDocument(); + expect(screen.getByTitle("P90 latency per replica")).toBeInTheDocument(); + }); + + it("renders nothing when grafana is not available", async () => { + expect.assertions(5); + + render( + , + { wrapper: MetricsDisabledWrapper }, + ); + // Wait .1 seconds for render to finish + await waitFor(() => new Promise((r) => setTimeout(r, 100))); + + expect(screen.queryByText(/View in Grafana/)).toBeNull(); + expect(screen.queryByText(/5 minutes/)).toBeNull(); + expect(screen.queryByTitle("QPS per replica")).toBeNull(); + expect(screen.queryByTitle("Error QPS per replica")).toBeNull(); + expect(screen.queryByTitle("P90 latency per replica")).toBeNull(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentMetricsSection.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentMetricsSection.tsx new file mode 100644 index 00000000000..59ba14dd6aa --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentMetricsSection.tsx @@ -0,0 +1,236 @@ +import { + Box, + Button, + InputAdornment, + MenuItem, + Paper, + SxProps, + TextField, + Theme, +} from "@mui/material"; +import React, { useContext, useEffect, useState } from "react"; +import { BiRefresh, BiTime } from "react-icons/bi"; +import { RiExternalLinkLine } from "react-icons/ri"; +import { GlobalContext } from "../../App"; +import { CollapsibleSection } from "../../common/CollapsibleSection"; +import { ClassNameProps } from "../../common/props"; +import { HelpInfo } from "../../components/Tooltip"; +import { + MetricConfig, + REFRESH_VALUE, + RefreshOptions, + TIME_RANGE_TO_FROM_VALUE, + TimeRangeOptions, +} from "../metrics"; + +// NOTE: please keep the titles here in sync with dashboard/modules/metrics/dashboards/serve_deployment_dashboard_panels.py +const METRICS_CONFIG: MetricConfig[] = [ + { + title: "QPS per replica", + pathParams: "orgId=1&theme=light&panelId=2", + }, + { + title: "Error QPS per replica", + pathParams: "orgId=1&theme=light&panelId=3", + }, + { + title: "P90 latency per replica", + pathParams: "orgId=1&theme=light&panelId=5", + }, +]; + +type ServeDeploymentMetricsSectionProps = { + deploymentName: string; + replicaId: string; + sx?: SxProps; +} & ClassNameProps; + +export const ServeReplicaMetricsSection = ({ + deploymentName, + replicaId, + className, + sx, +}: ServeDeploymentMetricsSectionProps) => { + const { grafanaHost, prometheusHealth, dashboardUids, dashboardDatasource } = + useContext(GlobalContext); + const grafanaServeDashboardUid = + dashboardUids?.serveDeployment ?? "rayServeDashboard"; + + const [refreshOption, setRefreshOption] = useState( + RefreshOptions.FIVE_SECONDS, + ); + + const [timeRangeOption, setTimeRangeOption] = useState( + TimeRangeOptions.FIVE_MINS, + ); + + const [refresh, setRefresh] = useState(null); + + const [[from, to], setTimeRange] = useState<[string | null, string | null]>([ + null, + null, + ]); + useEffect(() => { + setRefresh(REFRESH_VALUE[refreshOption]); + }, [refreshOption]); + useEffect(() => { + const from = TIME_RANGE_TO_FROM_VALUE[timeRangeOption]; + setTimeRange([from, "now"]); + }, [timeRangeOption]); + + const fromParam = from !== null ? `&from=${from}` : ""; + const toParam = to !== null ? `&to=${to}` : ""; + const timeRangeParams = `${fromParam}${toParam}`; + const refreshParams = refresh ? `&refresh=${refresh}` : ""; + + const replicaButtonUrl = useViewServeDeploymentMetricsButtonUrl( + deploymentName, + replicaId, + ); + + return grafanaHost === undefined || + !prometheusHealth || + !replicaButtonUrl ? null : ( + +
+ + + { + setRefreshOption(value as RefreshOptions); + }} + variant="standard" + InputProps={{ + startAdornment: ( + + + + ), + }} + > + {Object.entries(RefreshOptions).map(([key, value]) => ( + + {value} + + ))} + + Auto-refresh interval + { + setTimeRangeOption(value as TimeRangeOptions); + }} + variant="standard" + InputProps={{ + startAdornment: ( + + + + ), + }} + > + {Object.entries(TimeRangeOptions).map(([key, value]) => ( + + {value} + + ))} + + Time range picker + + + {METRICS_CONFIG.map(({ title, pathParams }) => { + const path = + `/d-solo/${grafanaServeDashboardUid}?${pathParams}` + + `${refreshParams}${timeRangeParams}&var-Deployment=${encodeURIComponent( + deploymentName, + )}&var-Replica=${encodeURIComponent( + replicaId, + )}`; + return ( + ({ + width: "100%", + height: 400, + overflow: "hidden", + [theme.breakpoints.up("md")]: { + // Calculate max width based on 1/3 of the total width minus gap between cards + width: `calc((100% - ${theme.spacing(3)} * 2) / 3)`, + }, + })} + variant="outlined" + > + + + ); + })} + +
+
+ ); +}; + +export const useViewServeDeploymentMetricsButtonUrl = ( + deploymentName: string, + replicaId?: string, +) => { + const { grafanaHost, prometheusHealth, dashboardUids, dashboardDatasource } = + useContext(GlobalContext); + const grafanaServeDashboardUid = + dashboardUids?.serveDeployment ?? "rayServeDashboard"; + + const replicaStr = replicaId + ? `&var-Replica=${encodeURIComponent(replicaId)}` + : ""; + + return grafanaHost === undefined || !prometheusHealth + ? null + : `${grafanaHost}/d/${grafanaServeDashboardUid}?var-Deployment=${encodeURIComponent( + deploymentName, + )}${replicaStr}`; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentRow.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentRow.tsx new file mode 100644 index 00000000000..f7f6730f9c9 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentRow.tsx @@ -0,0 +1,164 @@ +import { Link, TableCell, TableRow } from "@mui/material"; +import React from "react"; +import { Link as RouterLink } from "react-router-dom"; +import { + CodeDialogButton, + CodeDialogButtonWithPreview, +} from "../../common/CodeDialogButton"; +import { DurationText } from "../../common/DurationText"; +import { formatDateFromTimeMs } from "../../common/formatUtils"; +import { StatusChip } from "../../components/StatusChip"; +import { + ServeApplication, + ServeDeployment, + ServeReplica, +} from "../../type/serve"; +import { useViewServeDeploymentMetricsButtonUrl } from "./ServeDeploymentMetricsSection"; + +export type ServeDeploymentRowProps = { + deployment: ServeDeployment; + application: ServeApplication; + // Optional prop to control the visibility of the first column. + // This is used to display an expand/collapse button on the applications page, but not the deployment page. + showExpandColumn?: boolean; +}; + +export const ServeDeploymentRow = ({ + deployment, + application: { last_deployed_time_s, name: applicationName }, + showExpandColumn = false, +}: ServeDeploymentRowProps) => { + const { name, status, message, deployment_config, replicas } = deployment; + + const metricsUrl = useViewServeDeploymentMetricsButtonUrl(name); + + return ( + + + {showExpandColumn && ( + + {/* Empty column for expand/unexpand button in the row of the parent Serve application. */} + + )} + + + {name} + + + + + + + {message ? ( + + ) : ( + "-" + )} + + + {" "} + + {replicas.length} + + + + +
+ + Logs + + {metricsUrl && ( + +
+ + Metrics + +
+ )} +
+ + {/* placeholder for route_prefix, which does not apply to a deployment */} + - + + + {formatDateFromTimeMs(last_deployed_time_s * 1000)} + + + + +
+
+ ); +}; + +export type ServeReplicaRowProps = { + replica: ServeReplica; + deployment: ServeDeployment; +}; + +export const ServeReplicaRow = ({ + replica, + deployment, +}: ServeReplicaRowProps) => { + const { replica_id, state, start_time_s } = replica; + const { name } = deployment; + const metricsUrl = useViewServeDeploymentMetricsButtonUrl(name, replica_id); + + return ( + + + + {replica_id} + + + + + + + + Log + + {metricsUrl && ( + +
+ + Metrics + +
+ )} +
+ + {formatDateFromTimeMs(start_time_s * 1000)} + + + + +
+ ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentsListPage.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentsListPage.component.test.tsx new file mode 100644 index 00000000000..23f528dac91 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentsListPage.component.test.tsx @@ -0,0 +1,103 @@ +import { render, screen } from "@testing-library/react"; +import React from "react"; +import { getActor } from "../../service/actor"; +import { getServeApplications } from "../../service/serve"; +import { + ServeApplicationStatus, + ServeProxyLocation, + ServeSystemActorStatus, +} from "../../type/serve"; +import { TEST_APP_WRAPPER } from "../../util/test-utils"; +import { ServeDeploymentsListPage } from "./ServeDeploymentsListPage"; + +jest.mock("../../service/actor"); +jest.mock("../../service/serve"); + +const mockGetServeApplications = jest.mocked(getServeApplications); +const mockGetActor = jest.mocked(getActor); + +describe("ServeDeploymentsListPage", () => { + it("renders list", async () => { + expect.assertions(4); + + // Mock ServeController actor fetch + mockGetActor.mockResolvedValue({ + data: { + data: { + detail: { + state: "ALIVE", + }, + }, + }, + } as any); + + mockGetServeApplications.mockResolvedValue({ + data: { + http_options: { host: "1.2.3.4", port: 8000 }, + proxies: { + foo: { + node_id: "node:12345", + status: ServeSystemActorStatus.STARTING, + actor_id: "actor:12345", + }, + }, + controller_info: { + node_id: "node:12345", + actor_id: "actor:12345", + }, + proxy_location: ServeProxyLocation.EveryNode, + applications: { + home: { + name: "home", + route_prefix: "/", + message: null, + status: ServeApplicationStatus.RUNNING, + deployed_app_config: { + import_path: "home:graph", + }, + last_deployed_time_s: new Date().getTime() / 1000, + deployments: { + FirstDeployment: { + name: "FirstDeployment", + replicas: [], + }, + SecondDeployment: { + name: "SecondDeployment", + replicas: [], + }, + }, + }, + "second-app": { + name: "second-app", + route_prefix: "/second-app", + message: null, + status: ServeApplicationStatus.DEPLOYING, + deployed_app_config: { + import_path: "second_app:graph", + }, + last_deployed_time_s: new Date().getTime() / 1000, + deployments: { + ThirdDeployment: { + name: "ThirdDeployment", + replicas: [], + }, + }, + }, + }, + }, + } as any); + + render(, { wrapper: TEST_APP_WRAPPER }); + await screen.findByText("Application status"); + + // First row + expect(screen.getByText("FirstDeployment")).toBeVisible(); + + // Second row + expect(screen.getByText("SecondDeployment")).toBeVisible(); + + // Third row + expect(screen.getByText("ThirdDeployment")).toBeVisible(); + expect(screen.getByText("/second-app")).toBeVisible(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentsListPage.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentsListPage.tsx new file mode 100644 index 00000000000..025b4dc5409 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeDeploymentsListPage.tsx @@ -0,0 +1,158 @@ +import { + Alert, + Box, + InputAdornment, + Pagination, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + TextField, + Typography, +} from "@mui/material"; +import React, { ReactElement } from "react"; +import { CollapsibleSection } from "../../common/CollapsibleSection"; +import { sliceToPage } from "../../common/util"; +import Loading from "../../components/Loading"; +import { HelpInfo } from "../../components/Tooltip"; +import { useServeDeployments } from "./hook/useServeApplications"; +import { ServeApplicationRows } from "./ServeApplicationRow"; +import { ServeEntityLogViewer } from "./ServeEntityLogViewer"; +import { + APPS_METRICS_CONFIG, + ServeMetricsSection, +} from "./ServeMetricsSection"; +import { ServeSystemPreview } from "./ServeSystemDetails"; + +const columns: { label: string; helpInfo?: ReactElement; width?: string }[] = [ + { label: "" }, // Empty space for expand button + { label: "Name" }, + { label: "Status" }, + { label: "Status message", width: "30%" }, + { label: "Replicas" }, + { label: "Actions" }, + { label: "Route prefix" }, + { label: "Last deployed at" }, + { label: "Duration (since last deploy)" }, +]; + +export const ServeDeploymentsListPage = () => { + const { + serveDetails, + error, + page, + setPage, + proxies, + serveApplications, + serveDeployments, + } = useServeDeployments(); + + if (error) { + return {error.toString()}; + } + + if (serveDetails === undefined) { + return ; + } + + const { + items: list, + constrainedPage, + maxPage, + } = sliceToPage(serveApplications, page.pageNo, page.pageSize); + + return ( + + {serveDetails.http_options === undefined ? ( + + Serve not started. Please deploy a serve application first. + + ) : ( + + + + + { + setPage("pageSize", Math.min(Number(value), 500) || 10); + }, + endAdornment: ( + Per Page + ), + }} + /> + setPage("pageNo", pageNo)} + /> + + + + {columns.map(({ label, helpInfo, width }) => ( + + + {label} + {helpInfo && ( + + {helpInfo} + + )} + + + ))} + + + + {list.map((application) => ( + + ))} + +
+
+
+ + + +
+ )} + +
+ ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeEntityLogViewer.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeEntityLogViewer.component.test.tsx new file mode 100644 index 00000000000..3acd8d1eaff --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeEntityLogViewer.component.test.tsx @@ -0,0 +1,294 @@ +import { render, screen, within } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import React from "react"; +import { + MultiTabLogViewer, + MultiTabLogViewerTabDetails, +} from "../../common/MultiTabLogViewer"; +import { TEST_APP_WRAPPER } from "../../util/test-utils"; +import { ServeEntityLogViewer } from "./ServeEntityLogViewer"; + +jest.mock("../../common/MultiTabLogViewer"); + +const MockMultiTabLogViewer = jest.mocked(MultiTabLogViewer); + +describe("ServeEntityLogViewer", () => { + beforeEach(() => { + MockMultiTabLogViewer.mockImplementation( + ({ tabs }: { tabs: MultiTabLogViewerTabDetails[] }) => { + return ( +
+ {tabs.map((tab) => ( +
+ {Object.entries(tab).map(([key, value]) => ( + + {key}: {value} + + ))} +
+ ))} +
+ ); + }, + ); + }); + + it("renders with multiple entity groups", async () => { + expect.assertions(43); + + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + + await screen.findByText("View logs from"); + + const user = userEvent.setup(); + + // Verify dropdowns are rendered + expect(screen.getByText("View logs from")).toBeVisible(); + expect(screen.getByTestId("entity-group-select")).toBeVisible(); + expect(screen.queryByText("HTTP Proxy")).not.toBeInTheDocument(); + expect(screen.queryByText("Deployment replicas")).not.toBeInTheDocument(); + + // Verify Controller logs are rendered + expect(screen.getByText("title: Controller logs")).toBeVisible(); + expect( + screen.getByText("nodeId: test-node-id-for-controller"), + ).toBeVisible(); + expect( + screen.getByText("filename: test-log-file-path-for-controller"), + ).toBeVisible(); + expect( + screen.queryByText("title: HTTP Proxy logs"), + ).not.toBeInTheDocument(); + + // Verify HTTP Proxy logs are rendered + await user.click( + within(screen.getByTestId("entity-group-select")).getByRole("combobox"), + ); + await screen.findByText(/Proxies/); + await user.click(screen.getByRole("option", { name: /Proxies/ })); + await screen.findByText("HTTP Proxy"); + + expect(screen.getByTestId("proxies-select")).toBeVisible(); + + expect(screen.getByText("title: HTTP Proxy logs")).toBeVisible(); + expect(screen.getByText("nodeId: test-node-id-for-proxy-1")).toBeVisible(); + expect( + screen.getByText("filename: test-log-file-path-for-proxy-1"), + ).toBeVisible(); + + // Switch to proxy 2 + await user.click( + within(screen.getByTestId("proxies-select")).getByRole("combobox"), + ); + await screen.findByText("HTTPProxyActor:test-actor-id-for-proxy-2"); + await user.click( + screen.getByRole("option", { + name: "HTTPProxyActor:test-actor-id-for-proxy-2", + }), + ); + await screen.findByText("nodeId: test-node-id-for-proxy-2"); + + expect(screen.getByText("title: HTTP Proxy logs")).toBeVisible(); + expect(screen.getByText("nodeId: test-node-id-for-proxy-2")).toBeVisible(); + expect( + screen.getByText("filename: test-log-file-path-for-proxy-2"), + ).toBeVisible(); + + // Verify Deployment logs are rendered + await user.click( + within(screen.getByTestId("entity-group-select")).getByRole("combobox"), + ); + await screen.findByText(/Deployments/); + await user.click(screen.getByRole("option", { name: /Deployments/ })); + await screen.findByText("Deployment replica"); + + expect( + within(screen.getByTestId("replicas-select")).getByRole("combobox"), + ).toBeVisible(); + + expect(screen.getByText("title: Serve logger")).toBeVisible(); + expect( + screen.getByText("nodeId: test-node-id-for-deployment-1"), + ).toBeVisible(); + expect( + screen.getByText("filename: test-log-file-path-for-deployment-1"), + ).toBeVisible(); + expect(screen.getByText("title: stderr")).toBeVisible(); + expect( + screen.getAllByText("actorId: test-actor-id-for-deployment-1")[0], + ).toBeVisible(); + expect(screen.getByText("suffix: err")).toBeVisible(); + expect(screen.getByText("title: stderr")).toBeVisible(); + expect( + screen.getAllByText("actorId: test-actor-id-for-deployment-1")[1], + ).toBeVisible(); + expect(screen.getByText("suffix: out")).toBeVisible(); + + // Switch to replica 2 + await user.click( + within(screen.getByTestId("replicas-select")).getByRole("combobox"), + ); + await screen.findByText("test-replica-id-2-for-deployment-1"); + await user.click( + screen.getByRole("option", { + name: "test-replica-id-2-for-deployment-1", + }), + ); + await screen.findByText("nodeId: test-node-id-2-for-deployment-1"); + + expect(screen.getByText("title: Serve logger")).toBeVisible(); + expect( + screen.getByText("nodeId: test-node-id-2-for-deployment-1"), + ).toBeVisible(); + expect( + screen.getByText("filename: test-log-file-path-2-for-deployment-1"), + ).toBeVisible(); + expect(screen.getByText("title: stderr")).toBeVisible(); + expect( + screen.getAllByText("actorId: test-actor-id-2-for-deployment-1")[0], + ).toBeVisible(); + expect(screen.getByText("suffix: err")).toBeVisible(); + expect(screen.getByText("title: stderr")).toBeVisible(); + expect( + screen.getAllByText("actorId: test-actor-id-2-for-deployment-1")[1], + ).toBeVisible(); + expect(screen.getByText("suffix: out")).toBeVisible(); + + // Switch to replica 3 + await user.click( + within(screen.getByTestId("replicas-select")).getByRole("combobox"), + ); + await screen.findByText("test-replica-id-for-deployment-2"); + await user.click( + screen.getByRole("option", { + name: "test-replica-id-for-deployment-2", + }), + ); + await screen.findByText("nodeId: test-node-id-for-deployment-2"); + + expect(screen.getByText("title: Serve logger")).toBeVisible(); + expect( + screen.getByText("nodeId: test-node-id-for-deployment-2"), + ).toBeVisible(); + expect( + screen.getByText("filename: test-log-file-path-for-deployment-2"), + ).toBeVisible(); + expect(screen.getByText("title: stderr")).toBeVisible(); + expect( + screen.getAllByText("actorId: test-actor-id-for-deployment-2")[0], + ).toBeVisible(); + expect(screen.getByText("suffix: err")).toBeVisible(); + expect(screen.getByText("title: stderr")).toBeVisible(); + expect( + screen.getAllByText("actorId: test-actor-id-for-deployment-2")[1], + ).toBeVisible(); + expect(screen.getByText("suffix: out")).toBeVisible(); + }); + + it("renders only deployments when controller and proxies are not passed in", async () => { + expect.assertions(5); + + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + + await screen.findByText("Deployment replica"); + + // Verify dropdowns are rendered + expect(screen.queryByText("View logs from")).not.toBeInTheDocument(); + expect(screen.queryByText("Controller")).not.toBeInTheDocument(); + expect(screen.queryByText("HTTP Proxy")).not.toBeInTheDocument(); + expect(screen.getByText("Deployment replica")).toBeVisible(); + expect(screen.getByTestId("replicas-select")).toBeVisible(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeEntityLogViewer.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeEntityLogViewer.tsx new file mode 100644 index 00000000000..f90311ee91e --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeEntityLogViewer.tsx @@ -0,0 +1,312 @@ +import { Box, MenuItem, TextField, Typography } from "@mui/material"; +import _ from "lodash"; +import React, { useEffect } from "react"; +import { useSearchParams } from "react-router-dom"; +import { + MultiTabLogViewer, + MultiTabLogViewerTabDetails, +} from "../../common/MultiTabLogViewer"; +import { Section } from "../../common/Section"; +import { ServeDeployment, ServeSystemActor } from "../../type/serve"; +import { LOG_CONTEXT_KEY_SERVE_DEPLOYMENTS } from "./ServeReplicaDetailPage"; +import { + LOG_CONTEXT_KEY_SERVE_CONTROLLER, + LOG_CONTEXT_KEY_SERVE_PROXY, +} from "./ServeSystemActorDetailPage"; + +type ServeEntityLogsProps = { + controller?: ServeSystemActor; + proxies?: ServeSystemActor[]; + deployments: ServeDeployment[]; + showDeploymentName?: boolean; +}; + +/** + * A component that displays a log viewer for all types of Serve logs. + * A user uses dropdown menus to select the entity they wish to view logs of. + */ +export const ServeEntityLogViewer = ({ + controller, + proxies, + deployments, + showDeploymentName = false, +}: ServeEntityLogsProps) => { + const [params, setParams] = useSearchParams(); + + const showEntityGroups = controller !== undefined || proxies !== undefined; + const defaultEntityGroupName = showEntityGroups + ? controller + ? "controller" + : "proxies" + : "deployments"; + + const selectedEntityGroupName = + params.get("entityGroup") || defaultEntityGroupName; + + const selectedProxyId = + params.get("proxyId") || proxies?.[0]?.actor_id || undefined; + + const selectedProxy = proxies?.find( + ({ actor_id }) => actor_id === selectedProxyId, + ); + + const allReplicas = deployments.flatMap( + ({ name: deploymentName, replicas }) => + replicas.map((replica) => ({ + ...replica, + name: showDeploymentName + ? `${deploymentName}#${replica.replica_id}` + : replica.replica_id, + })), + ); + + const selectedReplicaId = + params.get("replicaId") || allReplicas[0]?.replica_id || undefined; + + // Effect to update URL params to initial values if they are not set + useEffect(() => { + let paramsModified = false; + if (!params.get("entityGroup") && showEntityGroups) { + params.set("entityGroup", defaultEntityGroupName); + paramsModified = true; + } + if (!params.get("proxyId") && selectedProxyId) { + params.set("proxyId", selectedProxyId); + paramsModified = true; + } + if (!params.get("replicaId") && selectedReplicaId) { + params.set("replicaId", selectedReplicaId); + paramsModified = true; + } + if (paramsModified) { + setParams(params, { replace: true }); + } + }, [ + params, + setParams, + showEntityGroups, + defaultEntityGroupName, + selectedProxyId, + selectedReplicaId, + ]); + + const selectedReplica = allReplicas.find( + ({ replica_id }) => replica_id === selectedReplicaId, + ); + + // Detect if replicaId or http proxy does not exist. If not, reset the selected log. + useEffect(() => { + let paramsModified = false; + if (selectedProxyId && !selectedProxy) { + params.delete("proxyId"); + paramsModified = true; + } + if (selectedReplicaId && !selectedReplica) { + params.delete("replicaId"); + paramsModified = true; + } + if (paramsModified) { + setParams(params, { replace: true }); + } + }, [ + params, + setParams, + selectedProxy, + selectedProxyId, + selectedReplica, + selectedReplicaId, + ]); + + const tabs: MultiTabLogViewerTabDetails[] = + selectedEntityGroupName === "controller" && controller + ? [ + { + title: "Controller logs", + nodeId: controller.node_id, + filename: + (controller.log_file_path?.startsWith("/") + ? controller.log_file_path.substring(1) + : controller.log_file_path) || undefined, + }, + ] + : selectedEntityGroupName === "proxies" && selectedProxy + ? [ + { + title: "HTTP Proxy logs", + nodeId: selectedProxy.node_id, + filename: + (selectedProxy.log_file_path?.startsWith("/") + ? selectedProxy.log_file_path.substring(1) + : selectedProxy.log_file_path) || undefined, + }, + ] + : selectedEntityGroupName === "deployments" && selectedReplica + ? [ + { + title: "Serve logger", + nodeId: selectedReplica.node_id, + filename: + (selectedReplica.log_file_path?.startsWith("/") + ? selectedReplica.log_file_path.substring(1) + : selectedReplica.log_file_path) || undefined, + }, + { + title: "stderr", + actorId: selectedReplica.actor_id, + suffix: "err", + }, + { + title: "stdout", + actorId: selectedReplica.actor_id, + suffix: "out", + }, + ] + : []; + + const contextKey = + selectedEntityGroupName === "controller" + ? LOG_CONTEXT_KEY_SERVE_CONTROLLER + : selectedEntityGroupName === "proxies" + ? LOG_CONTEXT_KEY_SERVE_PROXY + : LOG_CONTEXT_KEY_SERVE_DEPLOYMENTS; + + return ( +
+ + {showEntityGroups && ( + + View logs from + _.capitalize(value as string), + }} + onChange={({ target: { value } }) => { + setParams( + (params) => { + params.set("entityGroup", value); + return params; + }, + { + replace: true, + }, + ); + }} + > + + + Controller + theme.palette.grey[600] }} + > + Logs for app initialization, dependency installation, and + autoscaling. + + + + + + Proxies + theme.palette.grey[600] }} + > + Logs for proxy initialization and HTTP handling. + + + + + + Deployments + theme.palette.grey[600] }} + > + Application output and logs. + + + + + + )} + {selectedEntityGroupName === "proxies" && proxies?.length && ( + + HTTP Proxy + { + setParams( + (params) => { + params.set("proxyId", value); + return params; + }, + { + replace: true, + }, + ); + }} + > + {proxies.map(({ actor_id }) => ( + + HTTPProxyActor:{actor_id} + + ))} + + + )} + {selectedEntityGroupName === "deployments" && deployments.length && ( + + Deployment replica + { + setParams( + (params) => { + params.set("replicaId", value); + return params; + }, + { + replace: true, + }, + ); + }} + > + {allReplicas.map(({ replica_id, name }) => ( + + {name} + + ))} + + + )} + + +
+ +
+
+
+ ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeLayout.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeLayout.tsx new file mode 100644 index 00000000000..b2cdc76e5c9 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeLayout.tsx @@ -0,0 +1,39 @@ +import { Box } from "@mui/material"; +import React from "react"; +import { RiInformationLine, RiTableLine } from "react-icons/ri"; +import { Outlet } from "react-router-dom"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import { SideTabLayout, SideTabRouteLink } from "../layout/SideTabLayout"; + +export const ServeLayout = () => { + return ( + + + + + ); +}; + +export const ServeSideTabLayout = () => { + return ( + + + + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeMetricsSection.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeMetricsSection.component.test.tsx new file mode 100644 index 00000000000..27977191002 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeMetricsSection.component.test.tsx @@ -0,0 +1,122 @@ +import { render, screen, waitFor } from "@testing-library/react"; +import React, { PropsWithChildren } from "react"; +import { GlobalContext } from "../../App"; +import { STYLE_WRAPPER } from "../../util/test-utils"; +import { + APPS_METRICS_CONFIG, + SERVE_SYSTEM_METRICS_CONFIG, + ServeMetricsSection, +} from "./ServeMetricsSection"; + +const Wrapper = ({ children }: PropsWithChildren<{}>) => { + return ( + + {children} + + ); +}; + +const MetricsDisabledWrapper = ({ children }: PropsWithChildren<{}>) => { + return ( + + {children} + + ); +}; + +describe("ServeMetricsSection", () => { + it("renders app metrics", async () => { + expect.assertions(4); + + render(, { + wrapper: Wrapper, + }); + await screen.findByText(/View in Grafana/); + expect(screen.getByText(/5 minutes/)).toBeVisible(); + expect(screen.getByTitle("QPS per application")).toBeInTheDocument(); + expect(screen.getByTitle("Error QPS per application")).toBeInTheDocument(); + expect( + screen.getByTitle("P90 latency per application"), + ).toBeInTheDocument(); + }); + + it("renders serve system metrics", async () => { + expect.assertions(6); + + render( + , + { + wrapper: Wrapper, + }, + ); + await screen.findByText(/View in Grafana/); + expect(screen.getByTitle("Ongoing HTTP Requests")).toBeInTheDocument(); + expect(screen.getByTitle("Ongoing gRPC Requests")).toBeInTheDocument(); + expect(screen.getByTitle("Scheduling Tasks")).toBeInTheDocument(); + expect( + screen.getByTitle("Scheduling Tasks in Backoff"), + ).toBeInTheDocument(); + expect( + screen.getByTitle("Controller Control Loop Duration"), + ).toBeInTheDocument(); + expect(screen.getByTitle("Number of Control Loops")).toBeInTheDocument(); + }); + + it("renders nothing when grafana is not available", async () => { + expect.assertions(5); + + render(, { + wrapper: MetricsDisabledWrapper, + }); + // Wait .1 seconds for render to finish + await waitFor(() => new Promise((r) => setTimeout(r, 100))); + + expect(screen.queryByText(/View in Grafana/)).toBeNull(); + expect(screen.queryByText(/5 minutes/)).toBeNull(); + expect(screen.queryByTitle("QPS per application")).toBeNull(); + expect(screen.queryByTitle("Error QPS per application")).toBeNull(); + expect(screen.queryByTitle("P90 latency per application")).toBeNull(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeMetricsSection.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeMetricsSection.tsx new file mode 100644 index 00000000000..515164c2f17 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeMetricsSection.tsx @@ -0,0 +1,230 @@ +import { + Box, + Button, + InputAdornment, + MenuItem, + Paper, + SxProps, + TextField, + Theme, +} from "@mui/material"; +import React, { useContext, useEffect, useState } from "react"; +import { BiRefresh, BiTime } from "react-icons/bi"; +import { RiExternalLinkLine } from "react-icons/ri"; +import { GlobalContext } from "../../App"; +import { CollapsibleSection } from "../../common/CollapsibleSection"; +import { ClassNameProps } from "../../common/props"; +import { HelpInfo } from "../../components/Tooltip"; +import { + MetricConfig, + REFRESH_VALUE, + RefreshOptions, + TIME_RANGE_TO_FROM_VALUE, + TimeRangeOptions, +} from "../metrics"; + +// NOTE: please keep the titles here in sync with dashboard/modules/metrics/dashboards/serve_dashboard_panels.py +export const APPS_METRICS_CONFIG: MetricConfig[] = [ + { + title: "QPS per application", + pathParams: "orgId=1&theme=light&panelId=7", + }, + { + title: "Error QPS per application", + pathParams: "orgId=1&theme=light&panelId=8", + }, + { + title: "P90 latency per application", + pathParams: "orgId=1&theme=light&panelId=15", + }, +]; + +// NOTE: please keep the titles here in sync with dashboard/modules/metrics/dashboards/serve_dashboard_panels.py +export const SERVE_SYSTEM_METRICS_CONFIG: MetricConfig[] = [ + { + title: "Ongoing HTTP Requests", + pathParams: "orgId=1&theme=light&panelId=20", + }, + { + title: "Ongoing gRPC Requests", + pathParams: "orgId=1&theme=light&panelId=21", + }, + { + title: "Scheduling Tasks", + pathParams: "orgId=1&theme=light&panelId=22", + }, + { + title: "Scheduling Tasks in Backoff", + pathParams: "orgId=1&theme=light&panelId=23", + }, + { + title: "Controller Control Loop Duration", + pathParams: "orgId=1&theme=light&panelId=24", + }, + { + title: "Number of Control Loops", + pathParams: "orgId=1&theme=light&panelId=25", + }, +]; + +type ServeMetricsSectionProps = ClassNameProps & { + metricsConfig: MetricConfig[]; + sx?: SxProps; +}; + +export const ServeMetricsSection = ({ + className, + metricsConfig, + sx, +}: ServeMetricsSectionProps) => { + const { grafanaHost, prometheusHealth, dashboardUids, dashboardDatasource } = + useContext(GlobalContext); + const grafanaServeDashboardUid = dashboardUids?.serve ?? "rayServeDashboard"; + const [refreshOption, setRefreshOption] = useState( + RefreshOptions.FIVE_SECONDS, + ); + const [timeRangeOption, setTimeRangeOption] = useState( + TimeRangeOptions.FIVE_MINS, + ); + const [refresh, setRefresh] = useState(null); + const [[from, to], setTimeRange] = useState<[string | null, string | null]>([ + null, + null, + ]); + useEffect(() => { + setRefresh(REFRESH_VALUE[refreshOption]); + }, [refreshOption]); + useEffect(() => { + const from = TIME_RANGE_TO_FROM_VALUE[timeRangeOption]; + setTimeRange([from, "now"]); + }, [timeRangeOption]); + + const fromParam = from !== null ? `&from=${from}` : ""; + const toParam = to !== null ? `&to=${to}` : ""; + const timeRangeParams = `${fromParam}${toParam}`; + const refreshParams = refresh ? `&refresh=${refresh}` : ""; + + return grafanaHost === undefined || !prometheusHealth ? null : ( + +
+ + + { + setRefreshOption(value as RefreshOptions); + }} + variant="standard" + InputProps={{ + startAdornment: ( + + + + ), + }} + > + {Object.entries(RefreshOptions).map(([key, value]) => ( + + {value} + + ))} + + Auto-refresh interval + { + setTimeRangeOption(value as TimeRangeOptions); + }} + variant="standard" + InputProps={{ + startAdornment: ( + + + + ), + }} + > + {Object.entries(TimeRangeOptions).map(([key, value]) => ( + + {value} + + ))} + + Time range picker + + + {metricsConfig.map(({ title, pathParams }) => { + const path = + `/d-solo/${grafanaServeDashboardUid}?${pathParams}` + + `${refreshParams}${timeRangeParams}`; + return ( + ({ + width: "100%", + height: 400, + overflow: "hidden", + [theme.breakpoints.up("md")]: { + // Calculate max width based on 1/3 of the total width minus padding between cards + width: `calc((100% - ${theme.spacing(3)} * 2) / 3)`, + }, + })} + variant="outlined" + elevation={0} + > + + + ); + })} + +
+
+ ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeReplicaDetailLayout.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeReplicaDetailLayout.tsx new file mode 100644 index 00000000000..c1a389d72aa --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeReplicaDetailLayout.tsx @@ -0,0 +1,47 @@ +import { Typography } from "@mui/material"; +import React from "react"; +import { Outlet, useParams } from "react-router-dom"; +import Loading from "../../components/Loading"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import { useServeReplicaDetails } from "./hook/useServeApplications"; + +export const ServeReplicaDetailLayout = () => { + const { applicationName, deploymentName, replicaId } = useParams(); + const { loading, application, deployment, replica, error } = + useServeReplicaDetails(applicationName, deploymentName, replicaId); + + if (error) { + return {error.toString()}; + } + + if (loading) { + return ; + } else if (!replica || !deployment || !application) { + return ( + + {applicationName} / {deploymentName} / {replicaId} not found. + + ); + } + + const appName = application.name ? application.name : "-"; + const { replica_id } = replica; + + return ( +
+ + +
+ ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeReplicaDetailPage.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeReplicaDetailPage.component.test.tsx new file mode 100644 index 00000000000..e61563d7f8e --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeReplicaDetailPage.component.test.tsx @@ -0,0 +1,106 @@ +import { render, screen } from "@testing-library/react"; +import React from "react"; +import { useParams } from "react-router-dom"; +import { getServeApplications } from "../../service/serve"; +import { ServeReplicaState } from "../../type/serve"; +import { TEST_APP_WRAPPER } from "../../util/test-utils"; +import { ServeReplicaDetailPage } from "./ServeReplicaDetailPage"; + +jest.mock("react-router-dom", () => ({ + ...jest.requireActual("react-router-dom"), + useParams: jest.fn(), +})); +jest.mock("../../service/serve"); + +const mockUseParams = jest.mocked(useParams); +const mockGetServeApplications = jest.mocked(getServeApplications); + +describe("ServeReplicaDetailPage", () => { + it("renders", async () => { + expect.assertions(9); + + mockUseParams.mockReturnValue({ + applicationName: "home", + deploymentName: "FirstDeployment", + replicaId: "test-replica-1", + }); + mockGetServeApplications.mockResolvedValue({ + data: { + applications: { + home: { + name: "home", + route_prefix: "/home", + deployments: { + FirstDeployment: { + name: "FirstDeployment", + deployment_config: { + "test-config": 1, + autoscaling_config: { + "autoscaling-value": 2, + }, + }, + replicas: [ + { + actor_id: "test-actor-id", + actor_name: "FirstDeployment", + node_id: "test-node-id", + node_ip: "123.456.789.123", + pid: "12345", + replica_id: "test-replica-1", + start_time_s: new Date().getTime() / 1000, + state: ServeReplicaState.STARTING, + }, + { + // Decoy second replica + }, + ], + }, + SecondDeployment: { + name: "SecondDeployment", + deployment_config: {}, + replicas: [ + { + // Decoy third replica + }, + ], + }, + }, + }, + "second-app": { + // Decoy second app + }, + "third-app": { + // Decoy third app + }, + }, + }, + } as any); + + render(, { wrapper: TEST_APP_WRAPPER }); + + await screen.findByTestId("metadata-content-for-ID"); + expect(screen.getByTestId("metadata-content-for-ID")).toHaveTextContent( + "test-replica-1", + ); + expect(screen.getByTestId("metadata-content-for-State")).toHaveTextContent( + "STARTING", + ); + expect( + screen.getByTestId("metadata-content-for-Actor ID"), + ).toHaveTextContent("test-actor-id"); + expect( + screen.getByTestId("metadata-content-for-Actor name"), + ).toHaveTextContent("FirstDeployment"); + expect( + screen.getByTestId("metadata-content-for-Node ID"), + ).toHaveTextContent("test-node-id"); + expect( + screen.getByTestId("metadata-content-for-Node IP"), + ).toHaveTextContent("123.456.789.123"); + expect(screen.getByTestId("metadata-content-for-PID")).toHaveTextContent( + "12345", + ); + expect(screen.getByText("Tasks History")).toBeVisible(); + expect(screen.getByText("Metrics")).toBeVisible(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeReplicaDetailPage.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeReplicaDetailPage.tsx new file mode 100644 index 00000000000..5ae60124f08 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeReplicaDetailPage.tsx @@ -0,0 +1,180 @@ +import { Box, Typography } from "@mui/material"; +import React from "react"; +import { useParams } from "react-router-dom"; +import { CodeDialogButton } from "../../common/CodeDialogButton"; +import { CollapsibleSection } from "../../common/CollapsibleSection"; +import { DurationText } from "../../common/DurationText"; +import { formatDateFromTimeMs } from "../../common/formatUtils"; +import { generateActorLink, generateNodeLink } from "../../common/links"; +import { + MultiTabLogViewer, + MultiTabLogViewerTabDetails, +} from "../../common/MultiTabLogViewer"; +import { Section } from "../../common/Section"; +import { MetadataSection } from "../../components/MetadataSection"; +import { StatusChip } from "../../components/StatusChip"; +import { ServeReplica } from "../../type/serve"; +import TaskList from "../state/task"; +import { useServeReplicaDetails } from "./hook/useServeApplications"; +import { ServeReplicaMetricsSection } from "./ServeDeploymentMetricsSection"; + +export const LOG_CONTEXT_KEY_SERVE_DEPLOYMENTS = "serve-entity-deployments"; + +export const ServeReplicaDetailPage = () => { + const { applicationName, deploymentName, replicaId } = useParams(); + + const { application, deployment, replica } = useServeReplicaDetails( + applicationName, + deploymentName, + replicaId, + ); + + if (!replica || !deployment || !application) { + return ( + + {applicationName} / {deploymentName} / {replicaId} not found. + + ); + } + + const { + replica_id, + state, + actor_id, + actor_name, + node_id, + node_ip, + pid, + start_time_s, + } = replica; + return ( + + , + }, + { + label: "Actor ID", + content: { + value: actor_id ? actor_id : "-", + copyableValue: actor_id ? actor_id : undefined, + link: actor_id ? generateActorLink(actor_id) : undefined, + }, + }, + { + label: "Actor name", + content: { + value: actor_name, + copyableValue: actor_name, + }, + }, + { + label: "Node ID", + content: { + value: node_id ? node_id : "-", + copyableValue: node_id ? node_id : undefined, + link: node_id ? generateNodeLink(node_id) : undefined, + }, + }, + { + label: "Node IP", + content: { + value: node_ip ? node_ip : "-", + copyableValue: node_ip ? node_ip : undefined, + }, + }, + { + label: "PID", + content: { + value: pid ? pid : "-", + copyableValue: pid ? pid : undefined, + }, + }, + { + label: "Deployment config", + content: ( + + ), + }, + { + label: "Started at", + content: { + value: formatDateFromTimeMs(start_time_s * 1000), + }, + }, + { + label: "Duration", + content: , + }, + ]} + /> + +
+ +
+
+ + + + +
+ ); +}; + +type ServeReplicaLogsProps = { + replica: Pick; +}; + +const ServeReplicaLogs = ({ + replica: { log_file_path, node_id, actor_id }, +}: ServeReplicaLogsProps) => { + const tabs: MultiTabLogViewerTabDetails[] = [ + ...(log_file_path + ? [ + { + title: "Serve logger", + nodeId: node_id, + filename: log_file_path.startsWith("/") + ? log_file_path.substring(1) + : log_file_path, + }, + ] + : []), + { + title: "stderr", + actorId: actor_id, + suffix: "err", + }, + { + title: "stdout", + actorId: actor_id, + suffix: "out", + }, + ]; + return ( + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemActorDetailPage.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemActorDetailPage.tsx new file mode 100644 index 00000000000..c326e2c86cd --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemActorDetailPage.tsx @@ -0,0 +1,258 @@ +import { Box, Typography } from "@mui/material"; +import React from "react"; +import { useParams } from "react-router-dom"; +import { CollapsibleSection } from "../../common/CollapsibleSection"; +import { generateActorLink, generateNodeLink } from "../../common/links"; +import { + MultiTabLogViewer, + MultiTabLogViewerTabDetails, +} from "../../common/MultiTabLogViewer"; +import { Section } from "../../common/Section"; +import Loading from "../../components/Loading"; +import { MetadataSection } from "../../components/MetadataSection"; +import { StatusChip } from "../../components/StatusChip"; +import { ActorDetail, ActorEnum } from "../../type/actor"; +import { + ServeProxy, + ServeSystemActor, + ServeSystemActorStatus, +} from "../../type/serve"; +import { useFetchActor } from "../actor/hook/useActorDetail"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import { + useServeControllerDetails, + useServeProxyDetails, +} from "./hook/useServeApplications"; + +export const ServeProxyDetailPage = () => { + const { proxyId } = useParams(); + + const { proxy, loading } = useServeProxyDetails(proxyId); + + if (loading) { + return ; + } + + if (!proxy) { + return ( + + ProxyActor with id "{proxyId}" not found. + + ); + } + + return ( + + + + + ); +}; + +export const ServeControllerDetailPage = () => { + const { controller, loading } = useServeControllerDetails(); + + if (loading) { + return ; + } + + if (!controller) { + return Serve controller not found.; + } + + return ( + + + + + ); +}; + +type ActorInfo = + | { + type: "proxy"; + detail: ServeProxy; + } + | { + type: "controller"; + detail: ServeSystemActor; + }; + +type ServeSystemActorDetailProps = { + actor: ActorInfo; +}; + +export const convertActorStateForServeController = ( + actorState: ActorEnum | string, +) => { + if (actorState === ActorEnum.ALIVE) { + return ServeSystemActorStatus.HEALTHY; + } else if (actorState === ActorEnum.DEAD) { + return ServeSystemActorStatus.UNHEALTHY; + } else { + return ServeSystemActorStatus.STARTING; + } +}; + +export const ServeSystemActorDetail = ({ + actor, +}: ServeSystemActorDetailProps) => { + const name = + actor.type === "proxy" + ? `ProxyActor:${actor.detail.actor_id}` + : "Serve Controller"; + + const { data: fetchedActor } = useFetchActor(actor.detail.actor_id); + + return ( +
+ + ) : fetchedActor ? ( + + ) : ( + { + value: "-", + } + ), + }, + { + label: "Actor ID", + content: actor.detail.actor_id + ? { + value: actor.detail.actor_id, + copyableValue: actor.detail.actor_id, + link: actor.detail.actor_id + ? generateActorLink(actor.detail.actor_id) + : undefined, + } + : { + value: "-", + }, + }, + { + label: "Actor name", + content: { + value: actor.detail.actor_name ? actor.detail.actor_name : "-", + }, + }, + { + label: "Worker ID", + content: actor.detail.worker_id + ? { + value: actor.detail.worker_id, + copyableValue: actor.detail.worker_id, + } + : { + value: "-", + }, + }, + { + label: "Node ID", + content: actor.detail.node_id + ? { + value: actor.detail.node_id, + copyableValue: actor.detail.node_id, + link: actor.detail.node_id + ? generateNodeLink(actor.detail.node_id) + : undefined, + } + : { + value: "-", + }, + }, + { + label: "Node IP", + content: { + value: actor.detail.node_ip ? actor.detail.node_ip : "-", + }, + }, + ]} + /> + {fetchedActor && actor.detail.log_file_path && ( + +
+ +
+
+ )} +
+ ); +}; + +export const LOG_CONTEXT_KEY_SERVE_CONTROLLER = "serve-entity-controllers"; +export const LOG_CONTEXT_KEY_SERVE_PROXY = "serve-entity-proxies"; + +type ServeSystemActorLogsProps = { + type: "controller" | "proxy"; + actor: Pick; + systemLogFilePath: string; +}; + +const ServeSystemActorLogs = ({ + type, + actor: { + actorId, + pid, + address: { workerId, rayletId }, + }, + systemLogFilePath, +}: ServeSystemActorLogsProps) => { + const tabs: MultiTabLogViewerTabDetails[] = [ + { + title: type === "controller" ? "Controller logs" : "proxy logs", + nodeId: rayletId, + filename: systemLogFilePath.startsWith("/") + ? systemLogFilePath.substring(1) + : systemLogFilePath, + }, + ]; + const contextKey = + type === "controller" + ? LOG_CONTEXT_KEY_SERVE_CONTROLLER + : LOG_CONTEXT_KEY_SERVE_PROXY; + return ; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemDetailPage.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemDetailPage.component.test.tsx new file mode 100644 index 00000000000..c3ef9360adc --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemDetailPage.component.test.tsx @@ -0,0 +1,97 @@ +import { render, screen } from "@testing-library/react"; +import React from "react"; +import { getActor } from "../../service/actor"; +import { getServeApplications } from "../../service/serve"; +import { + ServeApplicationStatus, + ServeProxyLocation, + ServeSystemActorStatus, +} from "../../type/serve"; +import { TEST_APP_WRAPPER } from "../../util/test-utils"; +import { ServeSystemDetailPage } from "./ServeSystemDetailPage"; + +jest.mock("../../service/actor"); +jest.mock("../../service/serve"); + +const mockGetServeApplications = jest.mocked(getServeApplications); +const mockGetActor = jest.mocked(getActor); + +describe("ServeSystemDetailPage", () => { + it("renders list", async () => { + expect.assertions(7); + + // Mock ServeController actor fetch + mockGetActor.mockResolvedValue({ + data: { + data: { + detail: { + state: "ALIVE", + }, + }, + }, + } as any); + + mockGetServeApplications.mockResolvedValue({ + data: { + http_options: { host: "1.2.3.4", port: 8000 }, + grpc_options: { port: 9000 }, + proxies: { + foo: { + node_id: "node:12345", + status: ServeSystemActorStatus.STARTING, + actor_id: "actor:12345", + }, + }, + controller_info: { + node_id: "node:12345", + actor_id: "actor:12345", + }, + proxy_location: ServeProxyLocation.EveryNode, + applications: { + home: { + name: "home", + route_prefix: "/", + message: null, + status: ServeApplicationStatus.RUNNING, + deployed_app_config: { + import_path: "home:graph", + }, + last_deployed_time_s: new Date().getTime() / 1000, + deployments: { + FirstDeployment: {}, + SecondDeployment: {}, + }, + }, + "second-app": { + name: "second-app", + route_prefix: "/second-app", + message: null, + status: ServeApplicationStatus.DEPLOYING, + deployed_app_config: { + import_path: "second_app:graph", + }, + last_deployed_time_s: new Date().getTime() / 1000, + deployments: { + ThirdDeployment: {}, + }, + }, + }, + }, + } as any); + + render(, { wrapper: TEST_APP_WRAPPER }); + + await screen.findByText("System"); + expect(screen.getByText("System")).toBeVisible(); + expect(screen.getByText("1.2.3.4")).toBeVisible(); + expect(screen.getByText("8000")).toBeVisible(); + + // Proxy row + expect(screen.getByText("HTTPProxyActor:node:12345")).toBeVisible(); + expect(screen.getByText("STARTING")).toBeVisible(); + + // Serve Controller row + expect(screen.getByText("Serve Controller")).toBeVisible(); + expect(screen.getByText("HEALTHY")).toBeVisible(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemDetailPage.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemDetailPage.tsx new file mode 100644 index 00000000000..64d6e664cc4 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemDetailPage.tsx @@ -0,0 +1,65 @@ +import { Alert, Box, Typography } from "@mui/material"; +import React from "react"; +import { Outlet } from "react-router-dom"; +import Loading from "../../components/Loading"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import { useServeDeployments } from "./hook/useServeApplications"; +import { + SERVE_SYSTEM_METRICS_CONFIG, + ServeMetricsSection, +} from "./ServeMetricsSection"; +import { ServeSystemDetails } from "./ServeSystemDetails"; + +export const ServeSystemDetailPage = () => { + const { serveDetails, proxies, proxiesPage, setProxiesPage, error } = + useServeDeployments(); + + if (error) { + return {error.toString()}; + } + + if (serveDetails === undefined) { + return ; + } + + return ( + + + {serveDetails.http_options === undefined ? ( + + Serve not started. Please deploy a serve application first. + + ) : ( + + )} + + + ); +}; + +export const ServeSystemDetailLayout = () => ( + + + + +); diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemDetailRows.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemDetailRows.tsx new file mode 100644 index 00000000000..37a347e9b2d --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemDetailRows.tsx @@ -0,0 +1,136 @@ +import { Link, TableCell, TableRow, Tooltip } from "@mui/material"; +import React from "react"; +import { Link as RouterLink } from "react-router-dom"; +import { StatusChip } from "../../components/StatusChip"; +import { ServeProxy, ServeSystemActor } from "../../type/serve"; +import { useFetchActor } from "../actor/hook/useActorDetail"; +import { convertActorStateForServeController } from "./ServeSystemActorDetailPage"; + +export type ServeProxyRowProps = { + proxy: ServeProxy; +}; + +export const ServeProxyRow = ({ proxy }: ServeProxyRowProps) => { + const { status } = proxy; + + return ( + } + /> + ); +}; + +export type ServeControllerRowProps = { + controller: ServeSystemActor; +}; + +export const ServeControllerRow = ({ controller }: ServeControllerRowProps) => { + const { data: actor } = useFetchActor(controller.actor_id); + + const status = actor?.state; + + return ( + + ) : ( + "-" + ) + } + /> + ); +}; + +type ServeSystemActorRowProps = { + actor: ServeSystemActor; + type: "controller" | "proxy"; + status: React.ReactNode; +}; + +const ServeSystemActorRow = ({ + actor, + type, + status, +}: ServeSystemActorRowProps) => { + const { node_id, actor_id } = actor; + + return ( + + + {type === "proxy" ? ( + + HTTPProxyActor:{node_id} + + ) : ( + + Serve Controller + + )} + + {status} + + {type === "proxy" ? ( + + Log + + ) : ( + + Log + + )} + + + {node_id ? ( + + + {node_id} + + + ) : ( + "-" + )} + + + {actor_id ? ( + + + {actor_id} + + + ) : ( + "-" + )} + + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemDetails.component.test.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemDetails.component.test.tsx new file mode 100644 index 00000000000..778f1f3312a --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemDetails.component.test.tsx @@ -0,0 +1,88 @@ +import { render, screen } from "@testing-library/react"; +import React from "react"; +import { ActorEnum } from "../../type/actor"; +import { + ServeApplicationStatus, + ServeDeploymentStatus, + ServeSystemActorStatus, +} from "../../type/serve"; +import { TEST_APP_WRAPPER } from "../../util/test-utils"; +import { useFetchActor } from "../actor/hook/useActorDetail"; +import { ServeSystemPreview } from "./ServeSystemDetails"; + +jest.mock("../actor/hook/useActorDetail"); +const mockedUseFetchActor = jest.mocked(useFetchActor); + +describe("ServeSystemDetails", () => { + it("renders", async () => { + expect.assertions(7); + + mockedUseFetchActor.mockReturnValue({ + data: { + state: ActorEnum.ALIVE, + }, + } as any); + + render( + , + { wrapper: TEST_APP_WRAPPER }, + ); + await screen.findByText("STARTING"); + // Controller, Proxy, and Deployment + expect(screen.getAllByText("HEALTHY")).toHaveLength(2); + expect(screen.getByText("STARTING")).toBeInTheDocument(); + // Applications + expect(screen.getByText("UNHEALTHY")).toBeInTheDocument(); + expect(screen.getByText("RUNNING")).toBeInTheDocument(); + expect(screen.getByText("DEPLOYING")).toBeInTheDocument(); + expect( + screen.getByText(/View system status and configuration/), + ).toBeInTheDocument(); + + expect(mockedUseFetchActor).toBeCalledWith("actor_id"); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemDetails.tsx b/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemDetails.tsx new file mode 100644 index 00000000000..e965b686b2d --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/ServeSystemDetails.tsx @@ -0,0 +1,243 @@ +import { + Box, + Pagination, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Typography, +} from "@mui/material"; +import _ from "lodash"; +import React, { ReactElement } from "react"; +import { sliceToPage } from "../../common/util"; +import Loading from "../../components/Loading"; +import { MetadataSection } from "../../components/MetadataSection"; +import { StatusChip, StatusChipProps } from "../../components/StatusChip"; +import { HelpInfo } from "../../components/Tooltip"; +import { + ServeApplication, + ServeApplicationsRsp, + ServeDeployment, + ServeProxy, +} from "../../type/serve"; +import { useFetchActor } from "../actor/hook/useActorDetail"; +import { LinkWithArrow } from "../overview/cards/OverviewCard"; +import { convertActorStateForServeController } from "./ServeSystemActorDetailPage"; +import { ServeControllerRow, ServeProxyRow } from "./ServeSystemDetailRows"; + +export type ServeDetails = Pick< + ServeApplicationsRsp, + "http_options" | "grpc_options" | "proxy_location" | "controller_info" +>; + +type ServeSystemDetailsProps = { + serveDetails: ServeDetails; + proxies: ServeProxy[]; + page: { pageSize: number; pageNo: number }; + setPage: (key: string, value: number) => void; +}; + +const columns: { label: string; helpInfo?: ReactElement; width?: string }[] = [ + { label: "Name" }, + { label: "Status" }, + { label: "Actions" }, + { label: "Node ID" }, + { label: "Actor ID" }, +]; + +export const ServeSystemDetails = ({ + serveDetails, + proxies, + page, + setPage, +}: ServeSystemDetailsProps) => { + const { + items: list, + constrainedPage, + maxPage, + } = sliceToPage(proxies, page.pageNo, page.pageSize); + + return ( +
+ + System + + {serveDetails.http_options && ( + + )} + +
+ setPage("pageNo", pageNo)} + /> +
+ + + + {columns.map(({ label, helpInfo, width }) => ( + + + {label} + {helpInfo && ( + {helpInfo} + )} + + + ))} + + + + + {list.map((proxy) => ( + + ))} + +
+
+
+ ); +}; + +type ServeSystemPreviewProps = { + serveDetails: ServeDetails; + proxies: ServeProxy[]; + allDeployments: ServeDeployment[]; + allApplications: ServeApplication[]; +}; + +export const ServeSystemPreview = ({ + serveDetails, + proxies, + allDeployments, + allApplications, +}: ServeSystemPreviewProps) => { + const { data: controllerActor } = useFetchActor( + serveDetails.controller_info.actor_id, + ); + + if (!controllerActor) { + return ; + } + + return ( +
+ + ), + }, + { + label: "Proxy status", + content: ( + + ), + }, + { + label: "Application status", + content: ( + + ), + }, + ]} + footer={ + + } + /> +
+ ); +}; + +type StatusCountChipsProps = { + elements: T[]; + statusKey: keyof T; + type: StatusChipProps["type"]; +}; + +const StatusCountChips = ({ + elements, + statusKey, + type, +}: StatusCountChipsProps) => { + const statusCounts = _.mapValues( + _.groupBy(elements, statusKey), + (group) => group.length, + ); + + return ( + + {_.orderBy( + Object.entries(statusCounts), + ([, count]) => count, + "desc", + ).map(([status, count]) => ( +  {`x ${count}`}} + /> + ))} + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/hook/useServeApplications.ts b/historyserver/dashboard/ray/client/src/pages/serve/hook/useServeApplications.ts new file mode 100644 index 00000000000..ca36700052a --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/hook/useServeApplications.ts @@ -0,0 +1,290 @@ +import { useState } from "react"; +import useSWR from "swr"; +import { API_REFRESH_INTERVAL_MS } from "../../../common/constants"; +import { getServeApplications } from "../../../service/serve"; +import { ServeSystemActorStatus } from "../../../type/serve"; +import { ServeDetails } from "../ServeSystemDetails"; + +const SERVE_PROXY_STATUS_SORT_ORDER: Record = { + [ServeSystemActorStatus.UNHEALTHY]: 0, + [ServeSystemActorStatus.STARTING]: 1, + [ServeSystemActorStatus.HEALTHY]: 2, + [ServeSystemActorStatus.DRAINING]: 3, +}; + +export const useServeDeployments = () => { + const [page, setPage] = useState({ pageSize: 10, pageNo: 1 }); + + const [proxiesPage, setProxiesPage] = useState({ + pageSize: 10, + pageNo: 1, + }); + + const { data, error } = useSWR( + "useServeDeployments", + async () => { + const rsp = await getServeApplications(); + + if (rsp) { + const serveApplicationsList = rsp.data + ? Object.values(rsp.data.applications).sort( + (a, b) => + (b.last_deployed_time_s ?? 0) - (a.last_deployed_time_s ?? 0), + ) + : []; + + const serveDeploymentsList = serveApplicationsList.flatMap((app) => + Object.values(app.deployments).map((d) => ({ + ...d, + applicationName: app.name, + application: app, + })), + ); + return { ...rsp.data, serveApplicationsList, serveDeploymentsList }; + } + }, + { refreshInterval: API_REFRESH_INTERVAL_MS }, + ); + + const serveDetails: ServeDetails | undefined = data + ? { + http_options: data.http_options, + grpc_options: data.grpc_options, + proxy_location: data.proxy_location, + controller_info: data.controller_info, + } + : undefined; + + const proxies = + data && data.proxies + ? Object.values(data.proxies).sort( + (a, b) => + SERVE_PROXY_STATUS_SORT_ORDER[b.status] - + SERVE_PROXY_STATUS_SORT_ORDER[a.status], + ) + : []; + + const serveDeploymentsList = data?.serveDeploymentsList ?? []; + const serveApplicationsList = data?.serveApplicationsList ?? []; + + return { + serveDetails, + serveDeployments: serveDeploymentsList, + proxies, + error, + page, + setPage: (key: string, val: number) => setPage({ ...page, [key]: val }), + proxiesPage, + setProxiesPage: (key: string, val: number) => + setProxiesPage({ ...proxiesPage, [key]: val }), + serveApplications: serveApplicationsList, + }; +}; + +export const useServeApplicationDetails = ( + applicationName: string | undefined, +) => { + const [page, setPage] = useState({ pageSize: 10, pageNo: 1 }); + const [filter, setFilter] = useState< + { + key: "name" | "status"; + val: string; + }[] + >([]); + const changeFilter = (key: "name" | "status", val: string) => { + const f = filter.find((e) => e.key === key); + if (f) { + f.val = val; + } else { + filter.push({ key, val }); + } + setFilter([...filter]); + }; + + // TODO(aguo): Use a fetch by applicationName endpoint? + const { data, error } = useSWR( + "useServeApplications", + async () => { + const rsp = await getServeApplications(); + + if (rsp) { + return rsp.data; + } + }, + { refreshInterval: API_REFRESH_INTERVAL_MS }, + ); + + const application = applicationName + ? data?.applications?.[applicationName !== "-" ? applicationName : ""] + : undefined; + const deployments = application + ? Object.values(application.deployments).sort((a, b) => + a.name.localeCompare(b.name), + ) + : []; + + // Need to expose loading because it's not clear if undefined values + // for application means loading or missing data. + return { + loading: !data && !error, + application, + filteredDeployments: deployments.filter((deployment) => + filter.every((f) => + f.val + ? deployment[f.key] && (deployment[f.key] ?? "").includes(f.val) + : true, + ), + ), + error, + changeFilter, + page, + setPage: (key: string, val: number) => setPage({ ...page, [key]: val }), + allDeployments: deployments, + }; +}; + +export const useServeDeploymentDetails = ( + applicationName: string | undefined, + deploymentName: string | undefined, +) => { + const [page, setPage] = useState({ pageSize: 10, pageNo: 1 }); + const [filter, setFilter] = useState< + { + key: "replica_id" | "state"; + val: string; + }[] + >([]); + const changeFilter = (key: "replica_id" | "state", val: string) => { + const f = filter.find((e) => e.key === key); + if (f) { + f.val = val; + } else { + filter.push({ key, val }); + } + setFilter([...filter]); + }; + + // TODO(aguo): Use a fetch by deploymentId endpoint? + const { data, error } = useSWR( + "useServeApplications", + async () => { + const rsp = await getServeApplications(); + + if (rsp) { + return rsp.data; + } + }, + { refreshInterval: API_REFRESH_INTERVAL_MS }, + ); + + const application = applicationName + ? data?.applications?.[applicationName !== "-" ? applicationName : ""] + : undefined; + const deployment = deploymentName + ? application?.deployments[deploymentName] + : undefined; + + const replicas = deployment?.replicas ?? []; + + // Need to expose loading because it's not clear if undefined values + // for application, deployment, or replica means loading or missing data. + return { + loading: !data && !error, + application, + deployment, + filteredReplicas: replicas.filter((replica) => + filter.every((f) => + f.val ? replica[f.key] && (replica[f.key] ?? "").includes(f.val) : true, + ), + ), + changeFilter, + page, + setPage: (key: string, val: number) => setPage({ ...page, [key]: val }), + error, + }; +}; + +export const useServeReplicaDetails = ( + applicationName: string | undefined, + deploymentName: string | undefined, + replicaId: string | undefined, +) => { + // TODO(aguo): Use a fetch by replicaId endpoint? + const { data, error } = useSWR( + "useServeApplications", + async () => { + const rsp = await getServeApplications(); + + if (rsp) { + return rsp.data; + } + }, + { refreshInterval: API_REFRESH_INTERVAL_MS }, + ); + + const application = applicationName + ? data?.applications?.[applicationName !== "-" ? applicationName : ""] + : undefined; + const deployment = deploymentName + ? application?.deployments[deploymentName] + : undefined; + const replica = deployment?.replicas.find( + ({ replica_id }) => replica_id === replicaId, + ); + + // Need to expose loading because it's not clear if undefined values + // for application, deployment, or replica means loading or missing data. + return { + loading: !data && !error, + application, + deployment, + replica, + error, + }; +}; + +export const useServeProxyDetails = (proxyId: string | undefined) => { + const { data, error, isLoading } = useSWR( + "useServeApplications", + async () => { + const rsp = await getServeApplications(); + + if (rsp) { + return rsp.data; + } + }, + { refreshInterval: API_REFRESH_INTERVAL_MS }, + ); + + const proxy = proxyId ? data?.proxies?.[proxyId] : undefined; + + // Need to expose loading because it's not clear if undefined values + // for proxies means loading or missing data. + return { + loading: isLoading, + proxy, + error, + }; +}; + +export const useServeControllerDetails = () => { + const { data, error, isLoading } = useSWR( + "useServeApplications", + async () => { + const rsp = await getServeApplications(); + + if (rsp) { + return rsp.data; + } + }, + { refreshInterval: API_REFRESH_INTERVAL_MS }, + ); + + // Need to expose loading because it's not clear if undefined values + // for serve controller means loading or missing data. + return { + loading: isLoading, + controller: data?.controller_info, + error, + }; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/serve/mockServeApplication.ts b/historyserver/dashboard/ray/client/src/pages/serve/mockServeApplication.ts new file mode 100644 index 00000000000..5ed996d2829 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/serve/mockServeApplication.ts @@ -0,0 +1,63 @@ +import { ServeApplicationStatus } from "../../type/serve"; + +export const mockServeApplications = { + applications: { + app1: { + name: "app1", + route_prefix: "/app1", + message: null, + status: ServeApplicationStatus.RUNNING, + deployed_app_config: { + import_path: "app1:graph", + }, + last_deployed_time_s: new Date().getTime() / 1000, + }, + app2: { + name: "app2", + route_prefix: "/app2", + message: null, + status: ServeApplicationStatus.RUNNING, + deployed_app_config: null, + last_deployed_time_s: new Date().getTime() / 1000, + deployments: {}, + }, + app3: { + name: "app3", + route_prefix: "/app3", + message: null, + status: ServeApplicationStatus.DEPLOYING, + deployed_app_config: null, + last_deployed_time_s: new Date().getTime() / 1000, + deployments: {}, + }, + app4: { + name: "app4", + route_prefix: "/app4", + message: null, + status: ServeApplicationStatus.RUNNING, + deployed_app_config: { + import_path: "app4:graph", + }, + last_deployed_time_s: new Date().getTime() / 1000, + }, + app5: { + name: "app5", + route_prefix: "/app5", + message: null, + status: ServeApplicationStatus.DEPLOY_FAILED, + deployed_app_config: { + import_path: "app5:graph", + }, + last_deployed_time_s: new Date().getTime() / 1000, + }, + app6: { + name: "app6", + route_prefix: "/app6", + message: null, + status: ServeApplicationStatus.DELETING, + deployed_app_config: null, + last_deployed_time_s: new Date().getTime() / 1000, + deployments: {}, + }, + }, +}; diff --git a/historyserver/dashboard/ray/client/src/pages/state/PlacementGroup.tsx b/historyserver/dashboard/ray/client/src/pages/state/PlacementGroup.tsx new file mode 100644 index 00000000000..7c712aaedf1 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/state/PlacementGroup.tsx @@ -0,0 +1,32 @@ +import { Grid } from "@mui/material"; +import dayjs from "dayjs"; +import React, { useState } from "react"; +import PlacementGroupTable from "../../components/PlacementGroupTable"; +import { getPlacementGroup } from "../../service/placementGroup"; +import { PlacementGroup } from "../../type/placementGroup"; +import { useStateApiList } from "./hook/useStateApi"; + +/** + * Represent the embedable actors page. + */ +const PlacementGroupList = ({ jobId = null }: { jobId?: string | null }) => { + const [timeStamp] = useState(dayjs()); + const data: PlacementGroup[] | undefined = useStateApiList( + "usePlacementGroup", + getPlacementGroup, + ); + const placementGroups = data ? data : []; + + return ( +
+ + + Last updated: {timeStamp.format("YYYY-MM-DD HH:mm:ss")} + + + +
+ ); +}; + +export default PlacementGroupList; diff --git a/historyserver/dashboard/ray/client/src/pages/state/hook/mockedPlacementGroup.ts b/historyserver/dashboard/ray/client/src/pages/state/hook/mockedPlacementGroup.ts new file mode 100644 index 00000000000..68723a80690 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/state/hook/mockedPlacementGroup.ts @@ -0,0 +1,61 @@ +export const bundles = [ + { + bundle_id: "bundle-1", + node_id: "node-1", + unit_resources: { + cpu: 4, + memory: 8192, + }, + }, + { + bundle_id: "bundle-2", + node_id: null, + unit_resources: { + cpu: 2, + memory: 4096, + }, + }, + { + bundle_id: "bundle-3", + node_id: "node-2", + unit_resources: { + cpu: 8, + memory: 16384, + }, + }, +]; + +export const mockData = [ + { + placement_group_id: "pg-123456789", + name: "MyPlacementGroup", + creator_job_id: "job-987654321", + state: "CREATED", + stats: null, + bundles, + }, + { + placement_group_id: "pg-123456789", + name: "MyPlacementGroup", + creator_job_id: "job-987654321", + state: "REMOVED", + stats: null, + bundles, + }, + { + placement_group_id: "pg-123456789", + name: "MyPlacementGroup", + creator_job_id: "job-987654321", + state: "RESCHEDULING", + stats: null, + bundles, + }, + { + placement_group_id: "pg-123456789", + name: "MyPlacementGroup", + creator_job_id: "job-987654321", + state: "PENDING", + stats: null, + bundles, + }, +]; diff --git a/historyserver/dashboard/ray/client/src/pages/state/hook/useStateApi.ts b/historyserver/dashboard/ray/client/src/pages/state/hook/useStateApi.ts new file mode 100644 index 00000000000..3ee375e4785 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/state/hook/useStateApi.ts @@ -0,0 +1,52 @@ +import { AxiosResponse } from "axios"; +import useSWR, { Key } from "swr"; +import { PER_JOB_PAGE_REFRESH_INTERVAL_MS } from "../../../common/constants"; +import { getTask } from "../../../service/task"; +import { + AsyncFunction, + StateApiResponse, + StateApiTypes, +} from "../../../type/stateApi"; + +export const useStateApiList = ( + key: Key, + getFunc: AsyncFunction>>, +) => { + /** + * getFunc is a method defined within ../service. + */ + const { data } = useSWR( + key, + async () => { + const rsp = await getFunc(); + if (rsp?.data?.data?.result?.result) { + return rsp.data.data.result.result; + } else { + return []; + } + }, + { refreshInterval: PER_JOB_PAGE_REFRESH_INTERVAL_MS }, + ); + + return data; +}; + +export const useStateApiTask = (taskId: string | undefined) => { + const { data, isLoading } = useSWR( + taskId ? ["useStateApiTask", taskId] : null, + async ([_, taskId]) => { + const rsp = await getTask(taskId); + if (rsp?.data?.data?.result?.result) { + return rsp.data.data.result.result[0]; + } else { + return undefined; + } + }, + { refreshInterval: PER_JOB_PAGE_REFRESH_INTERVAL_MS }, + ); + + return { + task: data, + isLoading, + }; +}; diff --git a/historyserver/dashboard/ray/client/src/pages/state/task.tsx b/historyserver/dashboard/ray/client/src/pages/state/task.tsx new file mode 100644 index 00000000000..fb788c48df8 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/state/task.tsx @@ -0,0 +1,43 @@ +import { Grid } from "@mui/material"; +import dayjs from "dayjs"; +import React, { useState } from "react"; +import TaskTable, { TaskTableProps } from "../../components/TaskTable"; +import { getTasks } from "../../service/task"; +import { Task } from "../../type/task"; +import { useStateApiList } from "./hook/useStateApi"; + +/** + * Represent the embedable tasks page. + */ +const TaskList = ({ + jobId, + actorId, + ...taskTableProps +}: { + jobId?: string; + actorId?: string; +} & Pick) => { + const [timeStamp] = useState(dayjs()); + const data: Task[] | undefined = useStateApiList(["useTasks", jobId], () => + getTasks(jobId), + ); + const tasks = data ? data : []; + + return ( +
+ + + Last updated: {timeStamp.format("YYYY-MM-DD HH:mm:ss")} + + + +
+ ); +}; + +export default TaskList; diff --git a/historyserver/dashboard/ray/client/src/pages/task/TaskPage.tsx b/historyserver/dashboard/ray/client/src/pages/task/TaskPage.tsx new file mode 100644 index 00000000000..de99214fe6e --- /dev/null +++ b/historyserver/dashboard/ray/client/src/pages/task/TaskPage.tsx @@ -0,0 +1,325 @@ +import { Box, Typography } from "@mui/material"; +import React from "react"; +import { useParams } from "react-router-dom"; +import { CodeDialogButtonWithPreview } from "../../common/CodeDialogButton"; +import { CollapsibleSection } from "../../common/CollapsibleSection"; +import { DurationText } from "../../common/DurationText"; +import { formatDateFromTimeMs } from "../../common/formatUtils"; +import { generateActorLink, generateNodeLink } from "../../common/links"; +import { + MultiTabLogViewer, + MultiTabLogViewerTabDetails, +} from "../../common/MultiTabLogViewer"; +import { + TaskCpuProfilingLink, + TaskCpuStackTraceLink, + TaskMemoryProfilingButton, +} from "../../common/ProfilingLink"; +import { Section } from "../../common/Section"; +import Loading from "../../components/Loading"; +import { MetadataSection } from "../../components/MetadataSection"; +import { StatusChip } from "../../components/StatusChip"; +import { Task } from "../../type/task"; +import { MainNavPageInfo } from "../layout/mainNavContext"; +import { useStateApiTask } from "../state/hook/useStateApi"; + +export const TaskPage = () => { + const { taskId } = useParams(); + const { task, isLoading } = useStateApiTask(taskId); + + return ( + + + + + ); +}; + +type TaskPageContentsProps = { + taskId?: string; + task?: Task; + isLoading: boolean; +}; + +const TaskPageContents = ({ + taskId, + task, + isLoading, +}: TaskPageContentsProps) => { + if (isLoading) { + return ; + } + + if (!task) { + return ( + Task with ID "{taskId}" not found. + ); + } + + const { + attempt_number, + task_id, + actor_id, + end_time_ms, + start_time_ms, + node_id, + placement_group_id, + required_resources, + state, + type, + worker_id, + job_id, + func_or_class_name, + name, + } = task; + const isTaskActive = task.state === "RUNNING" && task.worker_id; + + return ( +
+ , + }, + { + label: "Job ID", + content: { + value: job_id, + copyableValue: job_id, + }, + }, + { + label: "Function or class name", + content: { + value: func_or_class_name, + }, + }, + { + label: "Actor ID", + content: actor_id + ? { + value: actor_id, + copyableValue: actor_id, + link: generateActorLink(actor_id), + } + : { + value: "-", + }, + }, + { + label: "Node ID", + content: node_id + ? { + value: node_id, + copyableValue: node_id, + link: generateNodeLink(node_id), + } + : { + value: "-", + }, + }, + { + label: "Worker ID", + content: worker_id + ? { + value: worker_id, + copyableValue: worker_id, + } + : { + value: "-", + }, + }, + { + label: "Type", + content: { + value: type, + }, + }, + { + label: "Placement group ID", + content: placement_group_id + ? { + value: placement_group_id, + copyableValue: placement_group_id, + } + : { + value: "-", + }, + }, + { + label: "Required resources", + content: + Object.entries(required_resources).length > 0 ? ( + + + + ) : ( + { + value: "{}", + } + ), + }, + { + label: "Started at", + content: { + value: start_time_ms ? formatDateFromTimeMs(start_time_ms) : "-", + }, + }, + { + label: "Ended at", + content: { + value: end_time_ms ? formatDateFromTimeMs(end_time_ms) : "-", + }, + }, + { + label: "Duration", + content: start_time_ms ? ( + + ) : ( + { + value: "-", + } + ), + }, + isTaskActive + ? { + label: "Actions", + content: ( + + +
+ +
+ +
+ ), + } + : { + label: "", + content: undefined, + }, + ]} + /> + +
+ +
+
+
+ ); +}; + +type TaskLogsProps = { + task: Task; +}; + +const TaskLogs = ({ + task: { + task_id, + error_message, + error_type, + worker_id, + task_log_info, + actor_id, + }, +}: TaskLogsProps) => { + const errorDetails = + error_type !== null && error_message !== null + ? `Error Type: ${error_type}\n\n${error_message}` + : undefined; + + const otherLogsLink = + task_log_info === null && actor_id !== null + ? `/actors/${actor_id}` + : undefined; + + const tabs: MultiTabLogViewerTabDetails[] = [ + ...(worker_id !== null && task_log_info !== null + ? ([ + { + title: "stderr", + taskId: task_id, + suffix: "err", + }, + { + title: "stdout", + taskId: task_id, + suffix: "out", + }, + ] as const) + : []), + ...(task_log_info === null + ? [ + { + title: "Logs", + contents: + "Logs of actor tasks are only available " + + "as part of the actor logs by default due to performance reason. " + + 'Please click "Other logs" link above to access the actor logs. \n' + + "To record actor task log by default, you could set the runtime env of the actor or start the cluster with RAY_ENABLE_RECORD_ACTOR_TASK_LOGGING=1 ", + }, + ] + : []), + // TODO(aguo): uncomment once PID is available in the API. + // { + // title: "system", + // nodeId: node_id, + // // TODO(aguo): Have API return the log file name. + // filename: `python-core-worker-${worker_id}_${pid}.log`, + // }, + ...(errorDetails + ? [{ title: "Error stack trace", contents: errorDetails }] + : []), + ]; + return ( + + ); +}; diff --git a/historyserver/dashboard/ray/client/src/react-app-env.d.ts b/historyserver/dashboard/ray/client/src/react-app-env.d.ts new file mode 100644 index 00000000000..6431bc5fc6b --- /dev/null +++ b/historyserver/dashboard/ray/client/src/react-app-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/historyserver/dashboard/ray/client/src/service/actor.ts b/historyserver/dashboard/ray/client/src/service/actor.ts new file mode 100644 index 00000000000..843d12e74ae --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/actor.ts @@ -0,0 +1,26 @@ +import { ActorDetail } from "../type/actor"; +import { get } from "./requestHandlers"; + +export const getActors = () => { + return get<{ + result: boolean; + message: string; + data: { + actors: { + [actorId: string]: ActorDetail; + }; + }; + }>("logical/actors"); +}; + +export type ActorResp = { + result: boolean; + msg: string; + data: { + detail: ActorDetail; + }; +}; + +export const getActor = (actorId: string) => { + return get(`logical/actors/${actorId}`); +}; diff --git a/historyserver/dashboard/ray/client/src/service/cluster.ts b/historyserver/dashboard/ray/client/src/service/cluster.ts new file mode 100644 index 00000000000..67116e065d3 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/cluster.ts @@ -0,0 +1,6 @@ +import { RayConfigRsp } from "../type/config"; +import { get } from "./requestHandlers"; + +export const getRayConfig = () => { + return get("api/ray_config"); +}; diff --git a/historyserver/dashboard/ray/client/src/service/clusters.ts b/historyserver/dashboard/ray/client/src/service/clusters.ts new file mode 100644 index 00000000000..e872c88ff1f --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/clusters.ts @@ -0,0 +1,10 @@ +import { ClusterListRsp, ClusterDetail} from "../type/clusters"; +import { get } from "./requestHandlers"; + +export const getClusterList = async () => { + return await get("clusters"); +}; + +export const getClusterDetail = async (id: string, session: string) => { + return await get(`clusters/${id}/${session}`); +}; diff --git a/historyserver/dashboard/ray/client/src/service/data.ts b/historyserver/dashboard/ray/client/src/service/data.ts new file mode 100644 index 00000000000..dfb7be1db9c --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/data.ts @@ -0,0 +1,6 @@ +import { DatasetResponse } from "../type/data"; +import { get } from "./requestHandlers"; + +export const getDataDatasets = (jobId: string) => { + return get(`api/data/datasets/${jobId}`); +}; diff --git a/historyserver/dashboard/ray/client/src/service/event.ts b/historyserver/dashboard/ray/client/src/service/event.ts new file mode 100644 index 00000000000..dcd153ed454 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/event.ts @@ -0,0 +1,18 @@ +import axios from "axios"; +import { EventGlobalRsp, EventRsp } from "../type/event"; + +export const getEvents = (jobId: string) => { + if (jobId) { + return axios.get(`events?job_id=${jobId}`); + } +}; + +export const getPipelineEvents = (jobId: string) => { + if (jobId) { + return axios.get(`events?job_id=${jobId}&view=pipeline`); + } +}; + +export const getGlobalEvents = () => { + return axios.get("events"); +}; diff --git a/historyserver/dashboard/ray/client/src/service/global.ts b/historyserver/dashboard/ray/client/src/service/global.ts new file mode 100644 index 00000000000..43d17dec0ec --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/global.ts @@ -0,0 +1,24 @@ +import { get } from "./requestHandlers"; + +export type UsageStatsEnabledResponse = { + usageStatsEnabled: boolean; + usageStatsPromptEnabled: boolean; +}; + +export type ClusterMetadataResponse = { + result: boolean; + message: string; + data: { + rayVersion: string; + pythonVersion: string; + sessionId: string; + gitCommit: string; + os: string; + }; +}; + +export const getUsageStatsEnabled = () => + get("/usage_stats_enabled"); + +export const getClusterMetadata = () => + get("/api/v0/cluster_metadata"); diff --git a/historyserver/dashboard/ray/client/src/service/job.ts b/historyserver/dashboard/ray/client/src/service/job.ts new file mode 100644 index 00000000000..41e80cbfc28 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/job.ts @@ -0,0 +1,27 @@ +import { + JobListRsp, + StateApiJobProgressByTaskNameRsp, + StateApiNestedJobProgressRsp, + UnifiedJob, +} from "../type/job"; +import { get } from "./requestHandlers"; + +export const getJobList = () => { + return get("api/jobs/"); +}; + +export const getJobDetail = (id: string) => { + return get(`api/jobs/${id}`); +}; + +export const getStateApiJobProgressByTaskName = (jobId: string) => { + return get( + `api/v0/tasks/summarize?filter_keys=job_id&filter_predicates=%3D&filter_values=${jobId}`, + ); +}; + +export const getStateApiJobProgressByLineage = (jobId: string) => { + return get( + `api/v0/tasks/summarize?filter_keys=job_id&filter_predicates=%3D&filter_values=${jobId}&summary_by=lineage`, + ); +}; diff --git a/historyserver/dashboard/ray/client/src/service/log.ts b/historyserver/dashboard/ray/client/src/service/log.ts new file mode 100644 index 00000000000..271f8706809 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/log.ts @@ -0,0 +1,113 @@ +import { get } from "./requestHandlers"; + +export const MAX_LINES_FOR_LOGS = 50_000; + +export type StateApiLogInput = { + nodeId?: string | null; + /** + * If actorId is provided, nodeId is not necessary + */ + actorId?: string | null; + /** + * If taskId is provided, nodeId is not necessary + */ + taskId?: string | null; + suffix?: string; + /** + * If filename is provided, suffix is not necessary + */ + filename?: string | null; + /** + * -1 for all lines. + */ + maxLines?: number; + /** + * Use "text" for orignal log, "leading_1" for an error bit for each chunk. + */ + format?: "text" | "leading_1"; +}; + +export const getStateApiDownloadLogUrl = ({ + nodeId, + filename, + taskId, + actorId, + suffix, + format = "text", + maxLines = MAX_LINES_FOR_LOGS, +}: StateApiLogInput) => { + if ( + nodeId === null || + actorId === null || + taskId === null || + filename === null + ) { + // Null means data is not ready yet. + return null; + } + const variables = [ + ...(nodeId !== undefined ? [`node_id=${encodeURIComponent(nodeId)}`] : []), + ...(filename !== undefined + ? [`filename=${encodeURIComponent(filename)}`] + : []), + ...(taskId !== undefined ? [`task_id=${encodeURIComponent(taskId)}`] : []), + ...(actorId !== undefined + ? [`actor_id=${encodeURIComponent(actorId)}`] + : []), + ...(suffix !== undefined ? [`suffix=${encodeURIComponent(suffix)}`] : []), + `lines=${maxLines}`, + `format=${format}`, + ]; + + return `api/v0/logs/file?${variables.join("&")}`; +}; + +export const getStateApiLog = async (props: StateApiLogInput) => { + const url = getStateApiDownloadLogUrl({ ...props, format: "leading_1" }); + if (url === null) { + return undefined; + } + const resp = await get(url); + // Handle case where log file is empty. + if (resp.status === 200 && resp.data.length === 0) { + return ""; + } + // TODO(aguo): get rid of this first byte check once we support state-api logs without this streaming byte. + if (resp.data[0] !== "1") { + throw new Error(resp.data.substring(1)); + } + return resp.data.substring(1); +}; + +type ListStateApiLogsResponse = { + data: { + result: { + // The response is a list of file names. File names with "/" at the end are directories. + [logGroup: string]: string[]; + }; + }; +}; + +export const listStateApiLogs = ({ + glob, + ...props +}: ( + | { + nodeId: string; + } + | { + nodeIp: string; + } +) & { glob?: string }) => { + const nodeId = "nodeId" in props ? props.nodeId : undefined; + const nodeIp = "nodeIp" in props ? props.nodeIp : undefined; + + const variables = [ + ...(nodeId !== undefined ? [`node_id=${encodeURIComponent(nodeId)}`] : []), + ...(nodeIp !== undefined ? [`node_ip=${encodeURIComponent(nodeIp)}`] : []), + ...(glob !== undefined ? [`glob=${encodeURIComponent(glob)}`] : []), + ]; + + const url = `api/v0/logs?${variables.join("&")}`; + return get(url); +}; diff --git a/historyserver/dashboard/ray/client/src/service/log.unit.test.ts b/historyserver/dashboard/ray/client/src/service/log.unit.test.ts new file mode 100644 index 00000000000..4e3e28f8123 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/log.unit.test.ts @@ -0,0 +1,81 @@ +import { getStateApiDownloadLogUrl, MAX_LINES_FOR_LOGS } from "./log"; + +describe("getStateApiDownloadLogUrl", () => { + it("only uses parameters provided but doesn't fetch when parameters are null", () => { + expect.assertions(9); + + expect( + getStateApiDownloadLogUrl({ + nodeId: "node-id", + filename: "file.log", + }), + ).toStrictEqual( + `api/v0/logs/file?node_id=node-id&filename=file.log&lines=${MAX_LINES_FOR_LOGS}&format=text`, + ); + + expect( + getStateApiDownloadLogUrl({ + nodeId: "node-id", + filename: "file.log", + format: "leading_1", + }), + ).toStrictEqual( + `api/v0/logs/file?node_id=node-id&filename=file.log&lines=${MAX_LINES_FOR_LOGS}&format=leading_1`, + ); + + expect( + getStateApiDownloadLogUrl({ + taskId: "task-id", + suffix: "err", + }), + ).toStrictEqual( + `api/v0/logs/file?task_id=task-id&suffix=err&lines=${MAX_LINES_FOR_LOGS}&format=text`, + ); + + expect( + getStateApiDownloadLogUrl({ + taskId: "task-id", + suffix: "out", + }), + ).toStrictEqual( + `api/v0/logs/file?task_id=task-id&suffix=out&lines=${MAX_LINES_FOR_LOGS}&format=text`, + ); + + expect( + getStateApiDownloadLogUrl({ + actorId: "actor-id", + suffix: "err", + }), + ).toStrictEqual( + `api/v0/logs/file?actor_id=actor-id&suffix=err&lines=${MAX_LINES_FOR_LOGS}&format=text`, + ); + + expect( + getStateApiDownloadLogUrl({ + nodeId: null, + filename: "file.log", + }), + ).toBeNull(); + + expect( + getStateApiDownloadLogUrl({ + nodeId: null, + filename: null, + }), + ).toBeNull(); + + expect( + getStateApiDownloadLogUrl({ + taskId: null, + suffix: "err", + }), + ).toBeNull(); + + expect( + getStateApiDownloadLogUrl({ + actorId: null, + suffix: "err", + }), + ).toBeNull(); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/service/node.ts b/historyserver/dashboard/ray/client/src/service/node.ts new file mode 100644 index 00000000000..147a7a0cbb9 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/node.ts @@ -0,0 +1,10 @@ +import { NodeDetailRsp, NodeListRsp } from "../type/node"; +import { get } from "./requestHandlers"; + +export const getNodeList = async () => { + return await get("nodes?view=summary"); +}; + +export const getNodeDetail = async (id: string) => { + return await get(`nodes/${id}`); +}; diff --git a/historyserver/dashboard/ray/client/src/service/placementGroup.ts b/historyserver/dashboard/ray/client/src/service/placementGroup.ts new file mode 100644 index 00000000000..11eee66c955 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/placementGroup.ts @@ -0,0 +1,9 @@ +import { PlacementGroup } from "../type/placementGroup"; +import { StateApiResponse } from "../type/stateApi"; +import { get } from "./requestHandlers"; + +export const getPlacementGroup = () => { + return get>( + "api/v0/placement_groups?detail=1&limit=10000", + ); +}; diff --git a/historyserver/dashboard/ray/client/src/service/requestHandlers.ts b/historyserver/dashboard/ray/client/src/service/requestHandlers.ts new file mode 100644 index 00000000000..9da2ff6fc8a --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/requestHandlers.ts @@ -0,0 +1,34 @@ +/** + * This utility file formats and sends HTTP requests such that + * they fullfill the requirements expected by users of the dashboard. + * + * All HTTP requests should be sent using the helpers in this file. + * + * More HTTP Methods helpers should be added to this file when the need + * arises. + */ + +import axios, { AxiosRequestConfig, AxiosResponse } from "axios"; + +/** + * This function formats URLs such that the user's browser + * sets the HTTP request's Request URL relative to the path at + * which the dashboard is served. + * This works behind a reverse proxy. + * + * @param {String} url The URL to be hit + * @return {String} The reverse proxy compatible URL + */ +export const formatUrl = (url: string): string => { + if (url.startsWith("/")) { + return url.slice(1); + } + return url; +}; + +export const get = >( + url: string, + config?: AxiosRequestConfig, +): Promise => { + return axios.get(formatUrl(url), config); +}; diff --git a/historyserver/dashboard/ray/client/src/service/serve.ts b/historyserver/dashboard/ray/client/src/service/serve.ts new file mode 100644 index 00000000000..642a002181f --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/serve.ts @@ -0,0 +1,6 @@ +import { ServeApplicationsRsp } from "../type/serve"; +import { get } from "./requestHandlers"; + +export const getServeApplications = () => { + return get("api/serve/applications/"); +}; diff --git a/historyserver/dashboard/ray/client/src/service/status.ts b/historyserver/dashboard/ray/client/src/service/status.ts new file mode 100644 index 00000000000..31dd5944712 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/status.ts @@ -0,0 +1,13 @@ +import { get } from "./requestHandlers"; + +export type RayStatusResp = { + result: boolean; + message: string; + data: { + clusterStatus: string; + }; +}; + +export const getRayStatus = () => { + return get("api/cluster_status?format=1"); +}; diff --git a/historyserver/dashboard/ray/client/src/service/task.ts b/historyserver/dashboard/ray/client/src/service/task.ts new file mode 100644 index 00000000000..5009c1d5495 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/task.ts @@ -0,0 +1,26 @@ +import { StateApiResponse } from "../type/stateApi"; +import { Task } from "../type/task"; +import { get } from "./requestHandlers"; + +export const getTasks = (jobId: string | undefined) => { + let url = "api/v0/tasks?detail=1&limit=10000"; + if (jobId) { + url += `&filter_keys=job_id&filter_predicates=%3D&filter_values=${jobId}`; + } + return get>(url); +}; + +export const getTask = (taskId: string) => { + const url = `api/v0/tasks?detail=1&limit=1&filter_keys=task_id&filter_predicates=%3D&filter_values=${encodeURIComponent( + taskId, + )}`; + return get>(url); +}; + +export const downloadTaskTimelineHref = (jobId: string | undefined) => { + let url = "api/v0/tasks/timeline?download=1"; + if (jobId) { + url += `&job_id=${jobId}`; + } + return url; +}; diff --git a/historyserver/dashboard/ray/client/src/service/util.ts b/historyserver/dashboard/ray/client/src/service/util.ts new file mode 100644 index 00000000000..966c82db291 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/service/util.ts @@ -0,0 +1,52 @@ +import axios from "axios"; + +type CMDRsp = { + result: boolean; + msg: string; + data: { + output: string; + }; +}; + +export const getJstack = (ip: string, pid: string) => { + return axios.get("utils/jstack", { + params: { + ip, + pid, + }, + }); +}; + +export const getJmap = (ip: string, pid: string) => { + return axios.get("utils/jmap", { + params: { + ip, + pid, + }, + }); +}; + +export const getJstat = (ip: string, pid: string, options: string) => { + return axios.get("utils/jstat", { + params: { + ip, + pid, + options, + }, + }); +}; + +type NamespacesRsp = { + result: boolean; + msg: string; + data: { + namespaces: { + namespaceId: string; + hostNameList: string[]; + }[]; + }; +}; + +export const getNamespaces = () => { + return axios.get("namespaces"); +}; diff --git a/historyserver/dashboard/ray/client/src/setupTests.js b/historyserver/dashboard/ray/client/src/setupTests.js new file mode 100644 index 00000000000..965ad020f99 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/setupTests.js @@ -0,0 +1,5 @@ +import "@testing-library/jest-dom"; +import dayjs from "dayjs"; +import duration from "dayjs/plugin/duration"; + +dayjs.extend(duration); diff --git a/historyserver/dashboard/ray/client/src/theme.ts b/historyserver/dashboard/ray/client/src/theme.ts new file mode 100644 index 00000000000..9b4809949e9 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/theme.ts @@ -0,0 +1,146 @@ +import { blueGrey, grey, lightBlue } from "@mui/material/colors"; +import { createTheme, ThemeOptions } from "@mui/material/styles"; + +const basicTheme: ThemeOptions = { + typography: { + fontSize: 12, + fontFamily: [ + "Roboto", + "-apple-system", + "BlinkMacSystemFont", + '"Segoe UI"', + '"Helvetica Neue"', + "Arial", + "sans-serif", + '"Apple Color Emoji"', + '"Segoe UI Emoji"', + '"Segoe UI Symbol"', + ].join(","), + h1: { + fontSize: "1.5rem", + fontWeight: 500, + }, + h2: { + fontSize: "1.25rem", + fontWeight: 500, + }, + h3: { + fontSize: "1rem", + fontWeight: 500, + }, + h4: { + fontSize: "1rem", + }, + body1: { + fontSize: "0.75rem", + }, + body2: { + fontSize: "14px", + lineHeight: "20px", + }, + caption: { + fontSize: "0.75rem", + lineHeight: "16px", + }, + }, + components: { + MuiAutocomplete: { + defaultProps: { + size: "small", + }, + }, + MuiButton: { + defaultProps: { + size: "small", + }, + }, + MuiCssBaseline: { + styleOverrides: { + "@global": { + a: { + color: "#036DCF", + }, + }, + }, + }, + MuiTextField: { + defaultProps: { + size: "small", + }, + }, + MuiTooltip: { + styleOverrides: { + tooltip: { + fontSize: "0.75rem", + fontWeight: 400, + boxShadow: "0px 3px 14px 2px rgba(3, 28, 74, 0.12)", + padding: 8, + }, + tooltipPlacementRight: { + margin: "0 8px", + "@media (min-width: 600px)": { + margin: "0 8px", + }, + }, + }, + }, + MuiPaper: { + styleOverrides: { + outlined: { + borderColor: "#D2DCE6", + borderRadius: 8, + }, + }, + }, + }, +}; + +export const lightTheme = createTheme(basicTheme, { + palette: { + primary: { + main: "#036DCF", + }, + secondary: lightBlue, + success: { + main: "#43A047", + }, + error: { + main: "#D32F2F", + }, + text: { + primary: grey[900], + secondary: grey[800], + disabled: grey[400], + hint: grey[300], + }, + background: { + paper: "#fff", + default: blueGrey[50], + }, + }, +}); + +export const darkTheme = createTheme(basicTheme, { + palette: { + primary: { + main: "#538DF9", + }, + secondary: lightBlue, + success: { + main: "#43A047", + }, + error: { + main: "#D32F2F", + }, + text: { + primary: blueGrey[50], + secondary: blueGrey[100], + disabled: blueGrey[200], + hint: blueGrey[300], + }, + background: { + paper: grey[800], + default: grey[900], + }, + }, +}); diff --git a/historyserver/dashboard/ray/client/src/type/actor.ts b/historyserver/dashboard/ray/client/src/type/actor.ts new file mode 100644 index 00000000000..3b40909f45a --- /dev/null +++ b/historyserver/dashboard/ray/client/src/type/actor.ts @@ -0,0 +1,67 @@ +import { GPUStats } from "./node"; + +export enum ActorEnum { + DEPENDENCIES_UNREADY = "DEPENDENCIES_UNREADY", + PENDING_CREATION = "PENDING_CREATION", + ALIVE = "ALIVE", + RESTARTING = "RESTARTING", + DEAD = "DEAD", +} + +export type Address = { + rayletId: string; + ipAddress: string; + port: number; + workerId: string; +}; + +export type Actor = { + actorId: string; + jobId: string; + placementGroupId: string | null; + state: ActorEnum | string; // PENDING, ALIVE, RECONSTRUCTING, DEAD + pid: number | null; + address: Address; + name: string; + numRestarts: string; + actorClass: string; + startTime: number | null; + endTime: number | null; + requiredResources: { + [key: string]: number; + }; + exitDetail: string; + reprName: string; +}; + +export type ActorDetail = { + workerId: string; + numPendingTasks: number; + taskQueueLength: number; + numExecutedTasks: number; + numInPlasma: number; + numLocalObjects: number; + numObjectRefsInScope: number; + gpus?: GPUStats[]; // GPU stats fetched from node, 1 entry per GPU + processStats: { + cmdline: string[]; + cpuPercent: number; + cpuTimes: { + user: number; + system: number; + childrenUser: number; + childrenUystem: number; + iowait?: number; + }; + createTime: number; + memoryInfo: { + rss: number; // aka “Resident Set Size”, this is the non-swapped physical memory a process has used. On UNIX it matches “top“‘s RES column). On Windows this is an alias for wset field and it matches “Mem Usage” column of taskmgr.exe. + vms: number; // aka “Virtual Memory Size”, this is the total amount of virtual memory used by the process. On UNIX it matches “top“‘s VIRT column. On Windows this is an alias for pagefile field and it matches “Mem Usage” “VM Size” column of taskmgr.exe. + pfaults: number; // number of page faults. + pageins: number; // number of actual pageins. + [key: string]: number; + }; + pid: number | null; + }; + mem?: number[]; // total memory, free memory, memory used ratio +} & Actor; diff --git a/historyserver/dashboard/ray/client/src/type/clusters.ts b/historyserver/dashboard/ray/client/src/type/clusters.ts new file mode 100644 index 00000000000..f48d8ed2f0f --- /dev/null +++ b/historyserver/dashboard/ray/client/src/type/clusters.ts @@ -0,0 +1,12 @@ +import { Actor } from "./actor"; +import { Raylet } from "./raylet"; +import { Worker } from "./worker"; + +export type ClusterDetail = { + name: string; + createTime: string; + sessionName: string; +}; + +export type ClusterListRsp = ClusterDetail[] + diff --git a/historyserver/dashboard/ray/client/src/type/config.d.ts b/historyserver/dashboard/ray/client/src/type/config.d.ts new file mode 100644 index 00000000000..40a34a25fcd --- /dev/null +++ b/historyserver/dashboard/ray/client/src/type/config.d.ts @@ -0,0 +1,22 @@ +export type RayConfig = { + userName: string; + workNodeNumber: number; + headNodeNumber: number; + containerVcores: number; + containerMemory: number; + clusterName: string; + supremeFo: boolean; + jobManagerPort: number; + externalRedisAddresses: string; + envParams: string; + sourceCodeLink: string; + imageUrl: string; +}; + +export type RayConfigRsp = { + result: boolean; + msg: string; + data: { + config: RayConfig; + }; +}; diff --git a/historyserver/dashboard/ray/client/src/type/data.ts b/historyserver/dashboard/ray/client/src/type/data.ts new file mode 100644 index 00000000000..dbbfc588923 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/type/data.ts @@ -0,0 +1,39 @@ +export type DatasetResponse = { + datasets: DatasetMetrics[]; +}; + +export type DatasetMetrics = DataMetrics & { + dataset: string; + job_id: string; + operators: OperatorMetrics[]; + start_time: number; + end_time: number | undefined; +}; + +export type OperatorMetrics = DataMetrics & { + operator: string; +}; + +export type DataMetrics = { + state: string; + ray_data_current_bytes: { + value: number; + max: number; + }; + ray_data_output_rows: { + max: number; + }; + ray_data_spilled_bytes: { + max: number; + }; + ray_data_cpu_usage_cores: { + value: number; + max: number; + }; + ray_data_gpu_usage_cores: { + value: number; + max: number; + }; + progress: number; + total: number; +}; diff --git a/historyserver/dashboard/ray/client/src/type/event.d.ts b/historyserver/dashboard/ray/client/src/type/event.d.ts new file mode 100644 index 00000000000..2a85b4818f0 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/type/event.d.ts @@ -0,0 +1,38 @@ +export type Event = { + eventId: string; + jobId: string; + nodeId: string; + sourceType: string; + sourceHostname: string; + hostName: string; + sourcePid: number; + pid: number; + label: string; + message: string; + timestamp: number; + timeStamp: number; + jobName: string; + severity: string; + customFields: { + [key: string]: any; + }; +}; + +export type EventRsp = { + result: boolean; + msg: string; + data: { + jobId: string; + events: Event[]; + }; +}; + +export type EventGlobalRsp = { + result: boolean; + msg: string; + data: { + events: { + global: Event[]; + }; + }; +}; diff --git a/historyserver/dashboard/ray/client/src/type/job.ts b/historyserver/dashboard/ray/client/src/type/job.ts new file mode 100644 index 00000000000..cccb7978046 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/type/job.ts @@ -0,0 +1,194 @@ +import { Actor } from "./actor"; +import { TypeTaskType } from "./task"; +import { Worker } from "./worker"; + +export type Job = { + jobId: string; + name: string; + owner: string; + language: string; + driverEntry: string; + state: string; + timestamp: number; + startTime: number; + endTime: number; + namespaceId: string; + driverPid: number; + driverIpAddress: string; + isDead: boolean; +}; + +export type PythonDependenciey = string; + +export type JavaDependency = { + name: string; + version: string; + md5: string; + url: string; +}; + +export type JobInfo = { + url: string; + driverArgs: string; + customConfig: { + [k: string]: string; + }; + jvmOptions: string; + dependencies: { + python: PythonDependenciey[]; + java: JavaDependency[]; + }; + driverStarted: boolean; + submitTime: string; + startTime: null | string | number; + endTime: null | string | number; + driverIpAddress: string; + driverHostname: string; + driverPid: number; + eventUrl: string; + failErrorMessage: string; + driverCmdline: string; +} & Job; + +export type JobDetail = { + jobInfo: JobInfo; + jobActors: { [id: string]: Actor }; + jobWorkers: Worker[]; +}; + +export type JobListRsp = UnifiedJob[]; + +export enum JobStatus { + PENDING = "PENDING", + RUNNING = "RUNNING", + STOPPED = "STOPPED", + SUCCEEDED = "SUCCEEDED", + FAILED = "FAILED", +} + +export type UnifiedJob = { + job_id: string | null; + submission_id: string | null; + type: string; + status: JobStatus; + entrypoint: string; + message: string | null; + error_type: string | null; + start_time: number | null; + end_time: number | null; + metadata: { [key: string]: string } | null; + runtime_env: { [key: string]: string } | null; + driver_info: DriverInfo | null; + driver_agent_http_address: string | null; + driver_node_id: string | null; +}; + +export type DriverInfo = { + id: string; + node_ip_address: string; + node_id: string; + pid: string; +}; + +export type TaskProgress = { + numFinished?: number; + numPendingArgsAvail?: number; + numSubmittedToWorker?: number; + numRunning?: number; + numPendingNodeAssignment?: number; + numFailed?: number; + numCancelled?: number; + numUnknown?: number; +}; + +export type JobProgressRsp = { + data: { + detail: TaskProgress; + }; + msg: string; + result: boolean; +}; + +export type JobProgressByTaskName = { + tasks: { name: string; progress: TaskProgress }[]; +}; + +export type JobProgressByTaskNameRsp = { + data: { + detail: JobProgressByTaskName; + }; + msg: string; + result: boolean; +}; + +export type StateApiJobProgressByTaskName = { + node_id_to_summary: { + cluster: { + summary: { + [taskName: string]: { + func_or_class_name: string; + state_counts: { + [stateName: string]: number; + }; + }; + }; + }; + }; +}; + +export type StateApiJobProgressByTaskNameRsp = { + data: { + result: { + result: StateApiJobProgressByTaskName; + num_filtered: number; + total: number; + }; + }; + msg: string; + result: boolean; +}; + +export type NestedJobProgressLink = { + type: "actor" | "task"; + id: string; +}; + +export type NestedJobProgress = { + name: string; + key: string; + state_counts: { + [stateName: string]: number; + }; + children: NestedJobProgress[]; + type: TypeTaskType | "GROUP" | "ACTOR"; + link?: NestedJobProgressLink; +}; + +export type JobProgressGroup = { + name: string; + key: string; + progress: TaskProgress; + children: JobProgressGroup[]; + type: TypeTaskType | "GROUP" | "ACTOR"; + link?: NestedJobProgressLink; +}; + +export type StateApiNestedJobProgress = { + node_id_to_summary: { + cluster: { + summary: NestedJobProgress[]; + }; + }; +}; + +export type StateApiNestedJobProgressRsp = { + data: { + result: { + result: StateApiNestedJobProgress; + num_filtered: number; + total: number; + }; + }; + msg: string; + result: boolean; +}; diff --git a/historyserver/dashboard/ray/client/src/type/node.d.ts b/historyserver/dashboard/ray/client/src/type/node.d.ts new file mode 100644 index 00000000000..653bd362229 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/type/node.d.ts @@ -0,0 +1,87 @@ +import { Actor } from "./actor"; +import { Raylet } from "./raylet"; +import { Worker } from "./worker"; + +export type NodeDetail = { + now: number; + hostname: string; + ip: string; + cpu: number; // cpu usage + cpus?: number[]; // Logic CPU Count, Physical CPU Count + mem?: number[]; // total memory, free memory, memory used ratio + gpus?: GPUStats[]; // GPU stats fetched from node, 1 entry per GPU + bootTime: number; // start time + loadAvg: number[][]; // recent 1,5,15 minitues system load,load per cpu http://man7.org/linux/man-pages/man3/getloadavg.3.html + disk: { + // disk used on root + "/": { + total: number; + used: number; + free: number; + percent: number; + }; + // disk used on tmp + "/tmp": { + total: number; + used: number; + free: number; + percent: number; + }; + }; + networkSpeed: number[]; // sent tps, received tps + raylet: Raylet; + logCounts: number; + errorCounts: number; + actors: { [id: string]: Actor }; + cmdline: string[]; + state: string; + logicalResources?: str; +}; + +// Example: +// "27fcdbcd36f9227b88bf07d48769efb4471cb204adbfb4b077cd2bc7": "0.0/8.0 CPU\n 0B/25.75GiB memory\n 0B/12.88GiB object_store_memory" +type NodeLogicalResourcesMap = { + [nodeId: string]: str; +}; + +export type NodeListRsp = { + data: { + summary: NodeDetail[]; + nodeLogicalResources: NodeLogicalResourcesMap; + }; + result: boolean; + msg: string; +}; + +export type ProcessGPUUsage = { + // This gpu usage stats from a process + pid: number; + gpuMemoryUsage: number; +}; + +export type GPUStats = { + // This represents stats fetched from a node about a single GPU + uuid: string; + index: number; + name: string; + utilizationGpu?: number; + memoryUsed: number; + memoryTotal: number; + processesPids?: ProcessGPUUsage[]; +}; + +export type NodeDetailExtend = { + workers: Worker[]; + raylet: Raylet; + actors: { + [actorId: string]: ActorDetail; + }; +} & NodeDetail; + +export type NodeDetailRsp = { + data: { + detail: NodeDetailExtend; + }; + msg: string; + result: boolean; +}; diff --git a/historyserver/dashboard/ray/client/src/type/placementGroup.ts b/historyserver/dashboard/ray/client/src/type/placementGroup.ts new file mode 100644 index 00000000000..42e71162abd --- /dev/null +++ b/historyserver/dashboard/ray/client/src/type/placementGroup.ts @@ -0,0 +1,26 @@ +export enum PlacementGroupState { + // Must be in sync with gcs.proto PlacementGroupState + PENDING = "PENDING", + CREATED = "CREATED", + REMOVED = "REMOVED", + RESCHEDULING = "RESCHEDULING", +} + +export type Bundle = { + bundle_id: string; + node_id: string | null; + unit_resources: { + [key: string]: number; + }; +}; + +export type PlacementGroup = { + placement_group_id: string; + name: string; + creator_job_id: string; + state: PlacementGroupState | string; + stats?: { + [key: string]: number | string; + } | null; + bundles: Bundle[]; +}; diff --git a/historyserver/dashboard/ray/client/src/type/raylet.d.ts b/historyserver/dashboard/ray/client/src/type/raylet.d.ts new file mode 100644 index 00000000000..b44c3b263f9 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/type/raylet.d.ts @@ -0,0 +1,31 @@ +export type ViewMeasures = { + tags: string; + int_value?: number; + double_value?: number; + distribution_min?: number; + distribution_mean?: number; + distribution_max?: number; + distribution_count?: number; + distribution_bucket_boundaries?: number[]; + distribution_bucket_counts?: number[]; +}; + +type LabelMap = { + [key: string]: string; +}; + +export type Raylet = { + numWorkers: number; + pid: number; + nodeId: string; + nodeManagerPort: number; + brpcPort: pid; + state: string; + stateMessage: string; + startTime: number; + terminateTime: number; + objectStoreAvailableMemory: number; + objectStoreUsedMemory: number; + isHeadNode: boolean; + labels: LabelMap; +}; diff --git a/historyserver/dashboard/ray/client/src/type/serve.ts b/historyserver/dashboard/ray/client/src/type/serve.ts new file mode 100644 index 00000000000..e079f41b9ff --- /dev/null +++ b/historyserver/dashboard/ray/client/src/type/serve.ts @@ -0,0 +1,129 @@ +export enum ServeApplicationStatus { + // Keep in sync with ApplicationStatus in python/ray/serve/_private/common.py + NOT_STARTED = "NOT_STARTED", + DEPLOYING = "DEPLOYING", + RUNNING = "RUNNING", + DEPLOY_FAILED = "DEPLOY_FAILED", + DELETING = "DELETING", + UNHEALTHY = "UNHEALTHY", +} + +export type ServeApplication = { + name: string; + route_prefix: string; + docs_path: string | null; + status: ServeApplicationStatus; + message: string; + last_deployed_time_s: number; + deployed_app_config: Record | null; // It could be null if user did not provide deployed_app_config + deployments: { + [name: string]: ServeDeployment; + }; +}; + +export enum ServeDeploymentStatus { + // Keep in sync with DeploymentStatus in python/ray/serve/_private/common.py + UPDATING = "UPDATING", + HEALTHY = "HEALTHY", + UNHEALTHY = "UNHEALTHY", +} + +export type ServeDeployment = { + name: string; + status: ServeDeploymentStatus; + message: string; + deployment_config: ServeDeploymentConfig; + replicas: ServeReplica[]; +}; + +export type ServeDeploymentConfig = { + name: string; + num_replicas: number; + max_ongoing_requests: number; + user_config: Record | null; + autoscaling_config: ServeAutoscalingConfig | null; + graceful_shutdown_wait_loop_s: number; + graceful_shutdown_timeout_s: number; + health_check_period_s: number; + health_check_timeout_s: number; + ray_actor_options: Record; + is_driver_deployment: boolean; +}; + +export type ServeAutoscalingConfig = { + min_replicas: number; + initial_replicas: number | null; + max_replicas: number; + target_ongoing_requests: number; +}; + +export enum ServeReplicaState { + // Keep in sync with ReplicaState in python/ray/serve/_private/common.py + STARTING = "STARTING", + UPDATING = "UPDATING", + RECOVERING = "RECOVERING", + RUNNING = "RUNNING", + STOPPING = "STOPPING", +} + +export type ServeReplica = { + replica_id: string; + state: ServeReplicaState; + pid: string | null; + actor_name: string; + actor_id: string | null; + node_id: string | null; + node_ip: string | null; + start_time_s: number; + log_file_path: string | null; +}; + +// Keep in sync with ProxyLocation in python/ray/serve/config.py +export enum ServeProxyLocation { + Disabled = "Disabled", + NoServer = "NoServer", + HeadOnly = "HeadOnly", + EveryNode = "EveryNode", + FixedNumber = "FixedNumber", +} + +// Keep in sync with ProxyStatus in python/ray/serve/_private/common.py +export enum ServeSystemActorStatus { + STARTING = "STARTING", + HEALTHY = "HEALTHY", + UNHEALTHY = "UNHEALTHY", + DRAINING = "DRAINING", +} + +export type ServeSystemActor = { + node_id: string | null; + node_ip: string | null; + actor_id: string | null; + actor_name: string | null; + worker_id: string | null; + log_file_path: string | null; +}; + +export type ServeProxy = { + status: ServeSystemActorStatus; +} & ServeSystemActor; + +export type ServeApplicationsRsp = { + http_options: + | { + host: string; + port: number; + } + | undefined; + grpc_options: { + port: number; + }; + proxy_location: ServeProxyLocation; + controller_info: ServeSystemActor; + proxies: { + [name: string]: ServeProxy; + } | null; + applications: { + [name: string]: ServeApplication; + }; +}; diff --git a/historyserver/dashboard/ray/client/src/type/stateApi.d.ts b/historyserver/dashboard/ray/client/src/type/stateApi.d.ts new file mode 100644 index 00000000000..dc23e26380b --- /dev/null +++ b/historyserver/dashboard/ray/client/src/type/stateApi.d.ts @@ -0,0 +1,14 @@ +import { Task } from "./task"; + +export type StateApiResponse = { + result: boolean; + message: string; + data: { + [result: string]: { + [result: string]: T[]; + }; + }; +}; + +export type AsyncFunction = () => Promise; +export type StateApiTypes = Task | PlacementGroup; diff --git a/historyserver/dashboard/ray/client/src/type/task.ts b/historyserver/dashboard/ray/client/src/type/task.ts new file mode 100644 index 00000000000..add80e4c216 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/type/task.ts @@ -0,0 +1,57 @@ +export enum TypeTaskStatus { + // Must be in sync with custom_types.py::TaskStatus + NIL = "NIL", + PENDING_ARGS_AVAIL = "PENDING_ARGS_AVAIL", + PENDING_NODE_ASSIGNMENT = "PENDING_NODE_ASSIGNMENT", + PENDING_OBJ_STORE_MEM_AVAIL = "PENDING_OBJ_STORE_MEM_AVAIL", + PENDING_ARGS_FETCH = "PENDING_ARGS_FETCH", + SUBMITTED_TO_WORKER = "SUBMITTED_TO_WORKER", + RUNNING = "RUNNING", + RUNNING_IN_RAY_GET = "RUNNING_IN_RAY_GET", + RUNNING_IN_RAY_WAIT = "RUNNING_IN_RAY_WAIT", + FINISHED = "FINISHED", + FAILED = "FAILED", +} + +export enum TypeTaskType { + // Must be in sync with custom_types.py::TaskType + NORMAL_TASK = "NORMAL_TASK", + ACTOR_CREATION_TASK = "ACTOR_CREATION_TASK", + ACTOR_TASK = "ACTOR_TASK", + DRIVER_TASK = "DRIVER_TASK", +} + +export type Task = { + task_id: string; + name: string; + attempt_number: number; + state: TypeTaskStatus; + job_id: string; + node_id: string; + actor_id: string | null; + placement_group_id: string | null; + type: TypeTaskType; + func_or_class_name: string; + language: string; + required_resources: { [key: string]: number }; + runtime_env_info: string; + events: { [key: string]: string }[]; + start_time_ms: number | null; + end_time_ms: number | null; + worker_id: string | null; + profiling_data: ProfilingData; + error_type: string | null; + error_message: string | null; + task_log_info: { [key: string]: string | null | number }; +}; + +export type ProfilingData = { + node_ip_address?: string; + events: { + event_name: string; + extra_data?: { + type?: string; + traceback?: string; + }; + }[]; +}; diff --git a/historyserver/dashboard/ray/client/src/type/worker.d.ts b/historyserver/dashboard/ray/client/src/type/worker.d.ts new file mode 100644 index 00000000000..8f4d89e685e --- /dev/null +++ b/historyserver/dashboard/ray/client/src/type/worker.d.ts @@ -0,0 +1,49 @@ +export type ResourceSlot = { + slot: number; + allocation: number; +}; + +export type ResourceAllocations = { + resourceSlots: ResourceSlot[]; +}; + +export type CoreWorkerStats = { + ipAddress: string; + port: string; + actorId: string; + usedResources: { [key: string]: ResourceAllocations }; + numExecutedTasks: number; + numPendingTasks: number; + workerId: string; + actorTitle: string; + jobId: string; + numObjectRefsInScope: number; + numInPlasma: number; + numLocalObjects: number; + usedObjectStoreMemory: string; +}; + +export type Worker = { + createTime: number; + cpuPercent: number; + cmdline: string[]; + memoryInfo: { + rss: number; // aka “Resident Set Size”, this is the non-swapped physical memory a process has used. On UNIX it matches “top“‘s RES column). On Windows this is an alias for wset field and it matches “Mem Usage” column of taskmgr.exe. + vms: number; // aka “Virtual Memory Size”, this is the total amount of virtual memory used by the process. On UNIX it matches “top“‘s VIRT column. On Windows this is an alias for pagefile field and it matches “Mem Usage” “VM Size” column of taskmgr.exe. + pfaults: number; // number of page faults. + pageins: number; // number of actual pageins. + [key: string]: number; + }; + cpuTimes: { + user: number; + system: number; + childrenUser: number; + childrenUystem: number; + iowait?: number; + }; + pid: number; + coreWorkerStats: CoreWorkerStats[]; + language: string; + hostname: string; + ip: hostname; +}; diff --git a/historyserver/dashboard/ray/client/src/util/converter.ts b/historyserver/dashboard/ray/client/src/util/converter.ts new file mode 100644 index 00000000000..0bfd52736de --- /dev/null +++ b/historyserver/dashboard/ray/client/src/util/converter.ts @@ -0,0 +1,27 @@ +export const memoryConverter = (bytes: number) => { + if (bytes < 1024) { + return `${bytes.toFixed(4)}B`; + } + + if (bytes < 1024 ** 2) { + return `${(bytes / 1024 ** 1).toFixed(2)}KB`; + } + + if (bytes < 1024 ** 3) { + return `${(bytes / 1024 ** 2).toFixed(2)}MB`; + } + + if (bytes < 1024 ** 4) { + return `${(bytes / 1024 ** 3).toFixed(2)}GB`; + } + + if (bytes < 1024 ** 5) { + return `${(bytes / 1024 ** 4).toFixed(2)}TB`; + } + + if (bytes < 1024 ** 6) { + return `${(bytes / 1024 ** 5).toFixed(2)}PB`; + } + + return ""; +}; diff --git a/historyserver/dashboard/ray/client/src/util/converter.unit.test.ts b/historyserver/dashboard/ray/client/src/util/converter.unit.test.ts new file mode 100644 index 00000000000..a3d544c78d6 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/util/converter.unit.test.ts @@ -0,0 +1,40 @@ +import { memoryConverter } from "./converter"; + +describe("memoryConverter", () => { + const table: { name: string; input: number; expected: string }[] = [ + { + name: "convert to Bytes", + input: 4, + expected: "4.0000B", + }, + { + name: "convert to KB", + input: 5 * 1024 ** 1, + expected: "5.00KB", + }, + { + name: "convert to MB", + input: 6 * 1024 ** 2, + expected: "6.00MB", + }, + { + name: "convert to GB", + input: 7 * 1024 ** 3, + expected: "7.00GB", + }, + { + name: "convert to TB", + input: 8 * 1024 ** 4, + expected: "8.00TB", + }, + { + name: "convert to PB", + input: 9 * 1024 ** 5, + expected: "9.00PB", + }, + ]; + + test.each(table)("$name", ({ input, expected }) => { + expect(memoryConverter(input)).toEqual(expected); + }); +}); diff --git a/historyserver/dashboard/ray/client/src/util/func.tsx b/historyserver/dashboard/ray/client/src/util/func.tsx new file mode 100644 index 00000000000..846cdbb18f1 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/util/func.tsx @@ -0,0 +1,28 @@ +import { Tooltip } from "@mui/material"; +import React, { CSSProperties } from "react"; + +export const longTextCut = (text = "", len = 28) => ( + + {text.length > len ? text.slice(0, len) + "..." : text} + +); + +export const jsonFormat = (str: string | object) => { + const preStyle = { + textAlign: "left", + wordBreak: "break-all", + whiteSpace: "pre-wrap", + } as CSSProperties; + if (typeof str === "object") { + return
{JSON.stringify(str, null, 2)}
; + } + try { + const j = JSON.parse(str); + if (typeof j !== "object") { + return JSON.stringify(j); + } + return
{JSON.stringify(j, null, 2)}
; + } catch (e) { + return str; + } +}; diff --git a/historyserver/dashboard/ray/client/src/util/hook.ts b/historyserver/dashboard/ray/client/src/util/hook.ts new file mode 100644 index 00000000000..73e2b00ca6b --- /dev/null +++ b/historyserver/dashboard/ray/client/src/util/hook.ts @@ -0,0 +1,78 @@ +import { get } from "lodash"; +import { useState } from "react"; + +export const useFilter = ({ + overrideFilters, + onFilterChange, +}: + | { + overrideFilters?: { key: KeyType; val: string }[]; + onFilterChange?: () => void; + } + | undefined = {}) => { + const [filters, setFilters] = useState<{ key: KeyType; val: string }[]>([]); + const finalFilters = + overrideFilters !== undefined ? overrideFilters : filters; + const changeFilter = (key: KeyType, val: string) => { + const f = filters.find((e) => e.key === key); + if (f) { + f.val = val; + } else { + filters.push({ key, val }); + } + setFilters([...filters]); + onFilterChange?.(); + }; + const filterFunc = (instance: { [key: string]: any }) => { + return finalFilters.every((f) => { + const instance_val = get(instance, f.key, ""); + return ( + !f.val || (instance_val && instance_val.toString().includes(f.val)) + ); + }); + }; + + return { + changeFilter, + filterFunc, + }; +}; + +export const useSorter = (initialSortKey?: string) => { + const [sorter, setSorter] = useState({ + key: initialSortKey || "", + desc: false, + }); + + const sorterFunc = ( + instanceA: { [key: string]: any }, + instanceB: { [key: string]: any }, + ) => { + if (!sorter.key) { + return 0; + } + + let [b, a] = [instanceA, instanceB]; + if (sorter.desc) { + [a, b] = [instanceA, instanceB]; + } + + if (!get(a, sorter.key)) { + return -1; + } + + if (!get(b, sorter.key)) { + return 1; + } + + return get(a, sorter.key) > get(b, sorter.key) ? 1 : -1; + }; + + return { + sorterFunc, + setSortKey: (key: string) => setSorter({ ...sorter, key }), + setOrderDesc: (desc: boolean) => setSorter({ ...sorter, desc }), + sorterKey: sorter.key, + descVal: sorter.desc, + }; +}; diff --git a/historyserver/dashboard/ray/client/src/util/test-utils.tsx b/historyserver/dashboard/ray/client/src/util/test-utils.tsx new file mode 100644 index 00000000000..f6b9e4788e2 --- /dev/null +++ b/historyserver/dashboard/ray/client/src/util/test-utils.tsx @@ -0,0 +1,50 @@ +import { StyledEngineProvider, ThemeProvider } from "@mui/material/styles"; +import React, { PropsWithChildren } from "react"; +import { MemoryRouter } from "react-router-dom"; +import { SWRConfig } from "swr"; +import { GlobalContext, GlobalContextType } from "../App"; +import { lightTheme } from "../theme"; + +export const TEST_APP_WRAPPER = ({ children }: PropsWithChildren<{}>) => { + const context: GlobalContextType = { + nodeMap: {}, + nodeMapByIp: {}, + namespaceMap: {}, + metricsContextLoaded: true, + grafanaHost: "localhost:3000", + dashboardUids: { + default: "rayDefaultDashboard", + serve: "rayServeDashboard", + serveDeployment: "rayServeDeploymentDashboard", + data: "rayDataDashboard", + default_params: "rayDefaultParams", + serve_params: "rayServeParams", + serveDeployment_params: "rayServeDeploymentParams", + data_params: "rayDataParams", + }, + prometheusHealth: true, + sessionName: "session-name", + dashboardDatasource: "Prometheus", + }; + + return ( + + {/* + Clear SWR cache between tests so that tests do impact each other. + */} + new Map() }}> + + {children} + + + + ); +}; + +export const STYLE_WRAPPER = ({ children }: PropsWithChildren<{}>) => { + return ( + + {children} + + ); +}; diff --git a/historyserver/dashboard/ray/client/tsconfig.json b/historyserver/dashboard/ray/client/tsconfig.json new file mode 100644 index 00000000000..fbce9be2349 --- /dev/null +++ b/historyserver/dashboard/ray/client/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react", + "noFallthroughCasesInSwitch": true + }, + "include": [ + "src" + ] +} diff --git a/historyserver/go.mod b/historyserver/go.mod new file mode 100644 index 00000000000..3dedf019bd5 --- /dev/null +++ b/historyserver/go.mod @@ -0,0 +1,27 @@ +module github.com/ray-project/kuberay/historyserver + +go 1.25.1 + +require ( + github.com/alibabacloud-go/tea v1.3.11 + github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible + github.com/aliyun/credentials-go v1.4.7 + github.com/emicklei/go-restful/v3 v3.13.0 + github.com/fsnotify/fsnotify v1.9.0 + github.com/hpcloud/tail v1.0.0 + github.com/sirupsen/logrus v1.9.3 + k8s.io/apimachinery v0.34.0 +) + +require ( + github.com/alibabacloud-go/debug v1.0.1 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/time v0.9.0 // indirect + gopkg.in/fsnotify.v1 v1.4.7 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect +) diff --git a/historyserver/go.sum b/historyserver/go.sum new file mode 100644 index 00000000000..04bf91b12f5 --- /dev/null +++ b/historyserver/go.sum @@ -0,0 +1,138 @@ +github.com/alibabacloud-go/debug v1.0.0/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc= +github.com/alibabacloud-go/debug v1.0.1 h1:MsW9SmUtbb1Fnt3ieC6NNZi6aEwrXfDksD4QA6GSbPg= +github.com/alibabacloud-go/debug v1.0.1/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc= +github.com/alibabacloud-go/tea v1.2.2/go.mod h1:CF3vOzEMAG+bR4WOql8gc2G9H3EkH3ZLAQdpmpXMgwk= +github.com/alibabacloud-go/tea v1.3.11 h1:F7s2HRszY0J+tFckhy5FCpnBEENTijgFcYR68Brg9/Y= +github.com/alibabacloud-go/tea v1.3.11/go.mod h1:A560v/JTQ1n5zklt2BEpurJzZTI8TUT+Psg2drWlxRg= +github.com/alibabacloud-go/tea-utils/v2 v2.0.7/go.mod h1:qxn986l+q33J5VkialKMqT/TTs3E+U9MJpd001iWQ9I= +github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g= +github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/aliyun/credentials-go v1.4.7 h1:T17dLqEtPUFvjDRRb5giVvLh6dFT8IcNFJJb7MeyCxw= +github.com/aliyun/credentials-go v1.4.7/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U= +github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/apimachinery v0.34.0 h1:eR1WO5fo0HyoQZt1wdISpFDffnWOvFLOOeJ7MgIv4z0= +k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= diff --git a/historyserver/utils/types.go b/historyserver/utils/types.go new file mode 100644 index 00000000000..dbeb4361cd8 --- /dev/null +++ b/historyserver/utils/types.go @@ -0,0 +1,30 @@ +// Package utils is +/* +Copyright 2024 by the zhangjie bingyu.zj@alibaba-inc.com Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package utils + +type ClusterInfo struct { + Name string `json:"name"` + SessionName string `json:"sessionName"` + CreateTime string `json:"createTime"` + CreateTimeStamp int64 `json:"createTimeStamp"` +} + +type ClusterInfoList []ClusterInfo + +func (a ClusterInfoList) Len() int { return len(a) } +func (a ClusterInfoList) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a ClusterInfoList) Less(i, j int) bool { return a[i].CreateTimeStamp > a[j].CreateTimeStamp } // 降序排序 diff --git a/historyserver/utils/utils.go b/historyserver/utils/utils.go new file mode 100644 index 00000000000..0933956799b --- /dev/null +++ b/historyserver/utils/utils.go @@ -0,0 +1,241 @@ +// Package utils is +/* +Copyright 2024 by the zhangjie bingyu.zj@alibaba-inc.com Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package utils + +import ( + "bytes" + "fmt" + "os" + "path" + "strings" + "time" + + "github.com/aliyun/aliyun-oss-go-sdk/oss" + "github.com/sirupsen/logrus" +) + +const ( + RAY_SESSIONDIR_LOGDIR_NAME = "logs" + RAY_SESSIONDIR_METADIR_NAME = "meta" +) + +const ( + OssMetaFile_BasicInfo = "ack__basicinfo" + + OssMetaFile_NodeSummaryKey = "restful__nodes_view_summary" + OssMetaFile_Node_Prefix = "restful__nodes_" + OssMetaFile_JOBTASK_DETAIL_Prefix = "restful__api__v0__tasks_detail_job_id_" + OssMetaFile_JOBTASK_SUMMARIZE_BY_FUNC_NAME_Prefix = "restful__api__v0__tasks_summarize_by_func_name_job_id_" + OssMetaFile_JOBTASK_SUMMARIZE_BY_LINEAGE_Prefix = "restful__api__v0__tasks_summarize_by_lineage_job_id_" + OssMetaFile_JOBDATASETS_Prefix = "restful__api__data__datasets_job_id_" + OssMetaFile_NodeLogs_Prefix = "restful__api__v0__logs_node_id_" + OssMetaFile_ClusterStatus = "restful__api__cluster_status" + OssMetaFile_LOGICAL_ACTORS = "restful__logical__actors" + OssMetaFile_ALLTASKS_DETAIL = "restful__api__v0__tasks_detail" + OssMetaFile_Events = "restful__events" + OssMetaFile_PlacementGroups = "restful__api__v0__placement_groups_detail" + + OssMetaFile_ClusterSessionName = "static__api__cluster_session_name" + + OssMetaFile_Jobs = "restful__api__jobs" + OssMetaFile_Applications = "restful__api__serve__applications" +) + +const RAY_HISTORY_SERVER_LOGNAME = "historyserver-ray.log" + +func RecreateObjectDir(bucket *oss.Bucket, dir string, options ...oss.Option) error { + objectDir := fmt.Sprintf("%s/", path.Clean(dir)) + + isExist, err := bucket.IsObjectExist(objectDir) + if err != nil { + logrus.Errorf("Failed to check object dir %s exists: %v", objectDir, err) + return err + } + + if isExist { + logrus.Infof("ObjectDir %s has exist, begin to delete ...", objectDir) + err = bucket.DeleteObject(objectDir) + if err != nil { + logrus.Errorf("Failed to delete objectdir %s: %v", objectDir, err) + return err + } + logrus.Infof("ObjectDir %s has delete success...", objectDir) + + // 列举所有包含指定前缀的文件并删除。 + marker := oss.Marker("") + // 如果您仅需要删除src目录及目录下的所有文件,则prefix设置为src/。 + prefix := oss.Prefix(objectDir) + var totalDeleted int + + for { + lor, err := bucket.ListObjects(marker, prefix) + if err != nil { + logrus.Errorf("Failed to list objectsdir %s error %v", objectDir, err) + return err + } + + objects := make([]string, len(lor.Objects)) + for i, object := range lor.Objects { + objects[i] = object.Key + } + + // 删除对象 + delRes, err := bucket.DeleteObjects(objects, oss.DeleteObjectsQuiet(true)) + if err != nil { + logrus.Errorf("Failed to delete allobjects in dir %s : %v", objectDir, err) + return err + } + + if len(delRes.DeletedObjects) > 0 { + logrus.Errorf("Some dir %s objects failed to delete: %v", objectDir, delRes.DeletedObjects) + return fmt.Errorf("Some dir %s objects failed to delete: %v", objectDir, delRes.DeletedObjects) + } + + totalDeleted += len(objects) + + // 更新marker + marker = oss.Marker(lor.NextMarker) + if !lor.IsTruncated { + break + } + } + + } + + logrus.Infof("Begin to create oss object dir %s ...", objectDir) + err = bucket.PutObject(objectDir, bytes.NewReader([]byte("")), options...) + if err != nil { + logrus.Errorf("Failed to create oss object dir %s: %v", objectDir, err) + return err + } + return nil +} + +func CreateObjectIfNotExist(bucket *oss.Bucket, obj string, options ...oss.Option) error { + isExist, err := bucket.IsObjectExist(obj) + if err != nil { + logrus.Errorf("Failed to check if object %s exists: %v", obj, err) + return err + } + if !isExist { + logrus.Infof("Begin to create oss object %s ...", obj) + err = bucket.PutObject(obj, bytes.NewReader([]byte("")), options...) + if err != nil { + logrus.Errorf("Failed to create directory '%s': %v", obj, err) + return err + } + logrus.Infof("Create oss object %s success", obj) + } + return nil +} + +func CreateObjectDirIfNotExist(bucket *oss.Bucket, dir string, options ...oss.Option) error { + objectDir := fmt.Sprintf("%s/", path.Clean(dir)) + + isExist, err := bucket.IsObjectExist(objectDir) + if err != nil { + logrus.Errorf("Failed to check if dirObject %s exists: %v", objectDir, err) + return err + } + if !isExist { + logrus.Infof("Begin to create oss dir %s ...", objectDir) + err = bucket.PutObject(objectDir, bytes.NewReader([]byte("")), options...) + if err != nil { + logrus.Errorf("Failed to create directory '%s': %v", objectDir, err) + return err + } + logrus.Infof("Create oss dir %s success", objectDir) + } + return nil +} + +func DeleteObject(bucket *oss.Bucket, objectName string) error { + isExist, err := bucket.IsObjectExist(objectName) + if err != nil { + logrus.Errorf("Failed to check if object %s exists: %v", objectName, err) + return err + } + + if isExist { + // 删除单个文件。 + err = bucket.DeleteObject(objectName) + if err != nil { + logrus.Warnf("Failed to delete object '%s': %v", objectName, err) + return err + } + } + return nil +} + +func GetMetaDir(ossHistorySeverDir, rayClusterName, rayClusterID string) string { + return fmt.Sprintf("%s/", path.Clean(path.Join(ossHistorySeverDir, AppendRayClusterNameID(rayClusterName, rayClusterID), RAY_SESSIONDIR_METADIR_NAME))) +} +func GetMetaDirByNameID(ossHistorySeverDir, rayClusterNameID string) string { + return fmt.Sprintf("%s/", path.Clean(path.Join(ossHistorySeverDir, rayClusterNameID, RAY_SESSIONDIR_METADIR_NAME))) +} + +func GetLogDirByNameID(ossHistorySeverDir, rayClusterNameID, rayNodeID string) string { + return fmt.Sprintf("%s/", path.Clean(path.Join(ossHistorySeverDir, rayClusterNameID, RAY_SESSIONDIR_LOGDIR_NAME, rayNodeID))) +} + +func GetLogDir(ossHistorySeverDir, rayClusterName, rayClusterID, rayNodeID string) string { + return fmt.Sprintf("%s/", path.Clean(path.Join(ossHistorySeverDir, AppendRayClusterNameID(rayClusterName, rayClusterID), RAY_SESSIONDIR_LOGDIR_NAME, rayNodeID))) +} + +const ( + // do not change + connector = "_" +) + +func AppendRayClusterNameID(rayClusterName, rayClusterID string) string { + return fmt.Sprintf("%s%s%s", rayClusterName, connector, rayClusterID) +} + +func GetRarClusterNameAndID(rayClusterNameID string) (string, string) { + nameID := strings.Split(rayClusterNameID, connector) + if len(nameID) < 2 { + logrus.Fatalf("rayClusterNameID %s must match name%sid pattern", rayClusterNameID, connector) + } + return strings.Join(nameID[:len(nameID)-1], "_"), nameID[len(nameID)-1] +} + +func GetSessionDir() (string, error) { + session_latest_path := "/tmp/ray/session_latest" + for i := 0; i < 12; i++ { + rp, err := os.Readlink(session_latest_path) + if err != nil { + logrus.Errorf("read session_latest file error %v", err) + time.Sleep(time.Second * 5) + continue + } + return rp, nil + } + return "", fmt.Errorf("timeout log_monitor --session-dir not found") +} + +func GetRayNodeID() (string, error) { + for i := 0; i < 12; i++ { + nodeidBytes, err := os.ReadFile("/tmp/ray/raylet_node_id") + if err != nil { + logrus.Errorf("read nodeid file error %v", err) + time.Sleep(time.Second * 5) + continue + } + return strings.Trim(string(nodeidBytes), "\n"), nil + } + return "", fmt.Errorf("timeout --node_id= not found") +} diff --git a/historyserver/utils/utils_test.go b/historyserver/utils/utils_test.go new file mode 100644 index 00000000000..d9df6f52c02 --- /dev/null +++ b/historyserver/utils/utils_test.go @@ -0,0 +1,37 @@ +// Package utils is +/* +Copyright 2024 by the zhangjie bingyu.zj@alibaba-inc.com Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package utils + +import ( + "strings" + "testing" +) + +func TestSlice(t *testing.T) { + strs := []string{"1", "2", "3", "4", "5"} + t.Logf("laster %s", strs[len(strs)-1]) + t.Logf("not laster all %s", strings.Join(strs[:len(strs)-1], "")) + clusterNameId := "a_s_sdf_sdfsdfsdfisfdf1_2safd-0sdf-sdf-000" + strs = strings.Split(clusterNameId, "_") + t.Logf("laster %s", strs[len(strs)-1]) + t.Logf("not laster all %s", strings.Join(strs[:len(strs)-1], "_")) + + clusterNameId = "a-s-sdf-sdfsdfsdfisfdf1A_B2safd-0sdf-sdf-000" + strs = strings.Split(clusterNameId, "_") + t.Logf("laster %s", strs[len(strs)-1]) + t.Logf("not laster all %s", strings.Join(strs[:len(strs)-1], "_")) +}