diff options
226 files changed, 9990 insertions, 17106 deletions
@@ -3,3 +3,7 @@ assets/ .idea .bin/soko +__debug* + +*_templ.go +*_templ.txt diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 611b35c..af22518 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,6 +6,9 @@ stages: build: stage: build + image: + name: gcr.io/kaniko-project/executor:v1.9.1-debug + entrypoint: [""] except: - tags variables: @@ -13,21 +16,24 @@ build: UPDATER_IMAGE_TAG: $CI_REGISTRY_IMAGE/updater-$CI_COMMIT_BRANCH:$CI_COMMIT_SHA LATEST_IMAGE_TAG: $CI_REGISTRY_IMAGE/$CI_COMMIT_BRANCH:latest LATEST_UPDATER_IMAGE_TAG: $CI_REGISTRY_IMAGE/updater-$CI_COMMIT_BRANCH:latest - script: + before_script: - echo $IMAGE_TAG - echo $UPDATER_IMAGE_TAG - echo $LATEST_IMAGE_TAG - echo $LATEST_UPDATER_IMAGE_TAG - - docker info - - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" "$CI_REGISTRY" --password-stdin - - docker pull gentoo/portage:latest - - docker pull gentoo/stage3-amd64 - - docker build --no-cache -t $IMAGE_TAG -t $LATEST_IMAGE_TAG . - - docker build --no-cache -t $UPDATER_IMAGE_TAG -t $LATEST_UPDATER_IMAGE_TAG -f Dockerfile.updater . - - docker push $LATEST_IMAGE_TAG - - docker push $IMAGE_TAG - - docker push $UPDATER_IMAGE_TAG - - docker push $LATEST_UPDATER_IMAGE_TAG + script: + - /kaniko/executor + --cache=true + --context "${CI_PROJECT_DIR}" + --dockerfile "${CI_PROJECT_DIR}/Dockerfile" + --destination "${IMAGE_TAG}" + --destination "${LATEST_IMAGE_TAG}" + - /kaniko/executor + --cache=true + --context "${CI_PROJECT_DIR}" + --dockerfile "${CI_PROJECT_DIR}/Dockerfile.updater" + --destination "${UPDATER_IMAGE_TAG}" + --destination "${LATEST_UPDATER_IMAGE_TAG}" build-tag: stage: build @@ -36,32 +42,23 @@ build-tag: variables: IMAGE_TAG: $CI_REGISTRY_IMAGE/web:$CI_COMMIT_TAG UPDATER_IMAGE_TAG: $CI_REGISTRY_IMAGE/updater:$CI_COMMIT_TAG - script: + before_script: - echo $IMAGE_TAG - echo $UPDATER_IMAGE_TAG - - docker info - - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" "$CI_REGISTRY" --password-stdin - - docker pull gentoo/portage:latest - - docker pull gentoo/stage3-amd64 - - docker build -t $IMAGE_TAG . - - docker build -t $UPDATER_IMAGE_TAG -f Dockerfile.updater . - - docker push $IMAGE_TAG - - docker push $UPDATER_IMAGE_TAG + script: + - /kaniko/executor + --cache=true + --context "${CI_PROJECT_DIR}" + --dockerfile "${CI_PROJECT_DIR}/Dockerfile" + --destination "${IMAGE_TAG}" + - /kaniko/executor + --cache=true + --context "${CI_PROJECT_DIR}" + --dockerfile "${CI_PROJECT_DIR}/Dockerfile.updater" + --destination "${UPDATER_IMAGE_TAG}" go-test: stage: go-test - image: golang:1.14.0 + image: golang:1.22.2 script: - go test -v ./pkg/models/... - -include: - - template: Dependency-Scanning.gitlab-ci.yml - - template: Container-Scanning.gitlab-ci.yml - - template: SAST.gitlab-ci.yml - - template: DAST.gitlab-ci.yml - -variables: - DS_DISABLE_DIND: "true" - SAST_DISABLE_DIND: "true" - DAST_WEBSITE: https://packagestest.gentoo.org -# DAST_FULL_SCAN_ENABLED: "true" @@ -1,15 +1,13 @@ -FROM golang:1.14.0 AS builder +FROM golang:1.22.2 AS builder +RUN go install github.com/a-h/templ/cmd/templ@v0.2.663 WORKDIR /go/src/soko COPY . /go/src/soko -RUN go get github.com/go-pg/pg/v9 -RUN go get github.com/mcuadros/go-version -RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o bin . +RUN templ generate && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o bin . -FROM node:13 AS assetsbuilder +FROM node:21 AS assetsbuilder WORKDIR /go/src/soko COPY . /go/src/soko -RUN npm install && cd node_modules/@gentoo/tyrian && npm install && npm run dist && cd /go/src/soko -RUN npx webpack +RUN npm install && npx webpack FROM scratch WORKDIR /go/src/soko diff --git a/Dockerfile.dev b/Dockerfile.dev index 1d8dad7..b90726f 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -1,4 +1,4 @@ -FROM golang:1.14.0 +FROM golang:1.22.2 RUN apt update && apt install -y ca-certificates ntp ntpdate WORKDIR /go/src/soko COPY . /go/src/soko diff --git a/Dockerfile.updater b/Dockerfile.updater index 4129dad..5255acc 100644 --- a/Dockerfile.updater +++ b/Dockerfile.updater @@ -1,25 +1,12 @@ -FROM golang:1.14.0 AS builder +FROM golang:1.22.2 AS builder +RUN go install github.com/a-h/templ/cmd/templ@v0.2.663 WORKDIR /go/src/soko COPY . /go/src/soko -RUN go get github.com/go-pg/pg/v9 -RUN go get github.com/mcuadros/go-version -RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o bin . +RUN templ generate && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o bin . -FROM gentoo/stage3-amd64 as gentoobuilder -# Need a portage tree to build, use last nights. -COPY --from=gentoo/portage:latest /var/db/repos/gentoo /var/db/repos/gentoo -# Sandbox doesn't work well in docker. -ENV FEATURES="-userpriv -usersandbox -sandbox" -ENV USE="-bindist" -RUN emerge -C openssh -RUN emerge --quiet-build dev-vcs/git -RUN echo 'FEATURES="-userpriv -usersandbox -sandbox"' >> /etc/portage/make.conf -RUN rm -rf /var/db/repos/gentoo +FROM ghcr.io/pkgcore/pkgcheck:latest - -FROM scratch -COPY --from=gentoobuilder / / COPY --from=builder /go/src/soko/assets /go/src/soko/assets COPY --from=builder /go/src/soko/bin /go/src/soko/bin COPY --from=builder /go/src/soko/pkg /go/src/soko/pkg diff --git a/Dockerfile.updater.dev b/Dockerfile.updater.dev index c6327a3..ea4a482 100644 --- a/Dockerfile.updater.dev +++ b/Dockerfile.updater.dev @@ -1,4 +1,4 @@ -FROM golang:1.14.0 +FROM golang:1.22.2 RUN apt update && apt install -y ca-certificates ntp ntpdate git WORKDIR /go/src/soko COPY . /go/src/soko @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. @@ -3,7 +3,7 @@ <p align="center"> <a href="https://gitlab.com/gentoo/soko/-/pipelines"> <img src="https://gitlab.com/gentoo/soko/badges/master/pipeline.svg"></a> -<a href="https://blog.golang.org/go1.14" ><img src="https://img.shields.io/badge/Go-v1.14-blue"></a> +<a href="https://blog.golang.org/go1.22" ><img src="https://img.shields.io/badge/Go-v1.22-blue"></a> <a href="#contributing"> <img src="https://img.shields.io/badge/contributions-welcome-orange.svg"></a> <a href="https://packagestest.gentoo.org"><img src="https://img.shields.io/badge/staging%20environment-develop-blue" /></a> <a href="https://opensource.org/licenses/TBD"><img src="https://img.shields.io/badge/license-TBD-blue.svg"></a> @@ -14,7 +14,7 @@ This the code that powers [packages.gentoo.org](https://packages.gentoo.org/), internally codenamed soko which is Korean for package (who would have thought!) -## Table Of Contents +## Table Of Contents - [Usage](#usage) - [Contributing](#contributing) @@ -23,7 +23,7 @@ This the code that powers [packages.gentoo.org](https://packages.gentoo.org/), i ## Usage -To get started quickly you can use docker-compose: +To get started quickly you can use docker-compose: ``` $ docker-compose up ``` @@ -48,9 +48,10 @@ Some of the rewrites were complete flops, and never went public. * Golang * PostgreSQL backend. * Authors: - * [Max Magorsch](mailto:arzano@gentoo.org) + * [Max Magorsch (arzano)](mailto:arzano@gentoo.org) * Contributors: * [Alec Warner (antarus)](mailto:antarus@gentoo.org) + * [Arthur Zamarin (arthurzam)](mailto:arthurzam@gentoo.org) ### 2016-2019: 'kkuleomi' * https://gitweb.gentoo.org/sites/packages.git/ @@ -108,4 +109,4 @@ Some of the rewrites were complete flops, and never went public. * [Albert Hopkins (marduk)](mailto:marduk@gentoo.org) * Contributors: (unknown) -## License
\ No newline at end of file +## License diff --git a/assets/pgo5.png b/assets/pgo5.png Binary files differdeleted file mode 100644 index 933d2aa..0000000 --- a/assets/pgo5.png +++ /dev/null diff --git a/assets/pgo6.png b/assets/pgo6.png Binary files differdeleted file mode 100644 index a889239..0000000 --- a/assets/pgo6.png +++ /dev/null diff --git a/bin/fullupdate.sh b/bin/fullupdate.sh index a4627a3..c4d5be3 100755 --- a/bin/fullupdate.sh +++ b/bin/fullupdate.sh @@ -27,15 +27,8 @@ update_repository(){ update_md5cache(){ mkdir -p /var/cache/pgo-egencache - cd /mnt/packages-tree/gentoo/ || exit 1 - - #echo 'FEATURES="-userpriv -usersandbox -sandbox"' >> /etc/portage/make.conf - - egencache -j "${JOBS}" --cache-dir /var/cache/pgo-egencache --repo gentoo --repositories-configuration '[gentoo] - location = /mnt/packages-tree/gentoo' --update - egencache -j "${JOBS}" --cache-dir /var/cache/pgo-egencache --repo gentoo --repositories-configuration '[gentoo] - location = /mnt/packages-tree/gentoo' --update-use-local-desc + pmaint regen --threads "${JOBS}" --use-local-desc --pkg-desc-index /mnt/packages-tree/gentoo/ } fullupdate_database(){ diff --git a/bin/soko b/bin/soko Binary files differdeleted file mode 100755 index 99ef2d6..0000000 --- a/bin/soko +++ /dev/null diff --git a/bin/update.sh b/bin/update.sh index 1774e34..77ac70e 100755 --- a/bin/update.sh +++ b/bin/update.sh @@ -27,15 +27,8 @@ update_repository(){ update_md5cache(){ mkdir -p /var/cache/pgo-egencache - cd /mnt/packages-tree/gentoo/ || exit 1 - - #echo 'FEATURES="-userpriv -usersandbox -sandbox"' >> /etc/portage/make.conf - - egencache -j "${JOBS}" --cache-dir /var/cache/pgo-egencache --repo gentoo --repositories-configuration '[gentoo] - location = /mnt/packages-tree/gentoo' --update - egencache -j "${JOBS}" --cache-dir /var/cache/pgo-egencache --repo gentoo --repositories-configuration '[gentoo] - location = /mnt/packages-tree/gentoo' --update-use-local-desc + pmaint regen --threads "${JOBS}" --use-local-desc --pkg-desc-index /mnt/packages-tree/gentoo/ } update_database(){ diff --git a/docker-compose.yml b/docker-compose.yml index def3280..90444fe 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -69,6 +69,11 @@ services: image: containrrr/watchtower:0.3.10 restart: always volumes: - - /var/run/docker.sock:/var/run/docker.sock + # docker has an issue, that if it mounts a socket directly, upon daemon restart, + # the socket is recreated and the new one isn't mounted. Mounting the whole /var/run + # directory is scatchy, so add another socket position for the daemon to create, and + # bind mount it. Add to docker daemon those args: + # --host=unix:///var/run/docker.sock --host=unix:///var/run/docker-watchtower/docker.sock + - /var/run/docker-watchtower:/var/run/docker-watchtower - /root/.docker/config.json:/config.json - command: --label-enable + command: --label-enable --host unix:///var/run/docker-watchtower/docker.sock @@ -1,15 +1,66 @@ module soko -go 1.13 +go 1.22 require ( - github.com/99designs/gqlgen v0.11.3 - github.com/go-git/go-git/v5 v5.2.0 - github.com/go-pg/pg v8.0.6+incompatible - github.com/go-pg/pg/v9 v9.1.3 - github.com/gorilla/feeds v1.1.1 + github.com/99designs/gqlgen v0.17.45 + github.com/a-h/templ v0.2.663 + github.com/go-git/go-git/v5 v5.12.0 + github.com/go-pg/pg v8.0.7+incompatible + github.com/go-pg/pg/v10 v10.12.0 + github.com/gorilla/feeds v1.1.2 github.com/jasonlvhit/gocron v0.0.1 - github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 - github.com/prometheus/client_golang v1.8.0 - github.com/vektah/gqlparser/v2 v2.0.1 + github.com/lmittmann/tint v1.0.4 + github.com/prometheus/client_golang v1.19.0 + github.com/samber/slog-multi v1.0.2 + github.com/ulikunitz/xz v0.5.12 + github.com/vektah/gqlparser/v2 v2.5.11 + golang.org/x/time v0.5.0 +) + +require ( + dario.cat/mergo v1.0.0 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/ProtonMail/go-crypto v1.0.0 // indirect + github.com/agnivade/levenshtein v1.1.1 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-pg/zerochecker v0.2.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.1 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.52.3 // indirect + github.com/prometheus/procfs v0.13.0 // indirect + github.com/samber/lo v1.39.0 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/skeema/knownhosts v1.2.2 // indirect + github.com/sosodev/duration v1.2.0 // indirect + github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect + github.com/vmihailenco/bufpool v0.1.11 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect + github.com/vmihailenco/tagparser v0.1.2 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + golang.org/x/crypto v0.22.0 // indirect + golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/tools v0.20.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + mellium.im/sasl v0.3.1 // indirect ) @@ -1,555 +1,245 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/99designs/gqlgen v0.11.3 h1:oFSxl1DFS9X///uHV3y6CEfpcXWrDUxVblR4Xib2bs4= -github.com/99designs/gqlgen v0.11.3/go.mod h1:RgX5GRRdDWNkh4pBrdzNpNPFVsdoUFY2+adM6nb1N+4= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= -github.com/agnivade/levenshtein v1.0.3 h1:M5ZnqLOoZR8ygVq0FfkXsNOKzMCk0xRiow0R5+5VkQ0= -github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/99designs/gqlgen v0.17.45 h1:bH0AH67vIJo8JKNKPJP+pOPpQhZeuVRQLf53dKIpDik= +github.com/99designs/gqlgen v0.17.45/go.mod h1:Bas0XQ+Jiu/Xm5E33jC8sES3G+iC2esHBMXcq0fUPs0= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/a-h/templ v0.2.663 h1:aa0WMm27InkYHGjimcM7us6hJ6BLhg98ZbfaiDPyjHE= +github.com/a-h/templ v0.2.663/go.mod h1:SA7mtYwVEajbIXFRh3vKdYm/4FYyLQAtPH1+KxzGPA8= +github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= +github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +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/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/codemodus/kace v0.5.1 h1:4OCsBlE2c/rSJo375ggfnucv9eRzge/U5LrrOZd47HA= -github.com/codemodus/kace v0.5.1/go.mod h1:coddaHoX1ku1YFSe4Ip0mL9kQjJvKkzb9CfIdG1YR04= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= 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/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= -github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= -github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= -github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git v1.0.0 h1:YcN9iDGDoXuIw0vHls6rINwV416HYa0EB2X+RBsyYp4= -github.com/go-git/go-git v4.7.0+incompatible h1:+W9rgGY4DOKKdX2x6HxSR7HNeTxqiKrOvKnuittYVdA= -github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= -github.com/go-git/go-git/v5 v5.2.0 h1:YPBLG/3UK1we1ohRkncLjaXWLW+HKp5QNM/jTli2JgI= -github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-pg/pg v8.0.6+incompatible h1:Hi7yUJ2zwmHFq1Mar5XqhCe3NJ7j9r+BaiNmd+vqf+A= -github.com/go-pg/pg v8.0.6+incompatible/go.mod h1:a2oXow+aFOrvwcKs3eIA0lNFmMilrxK2sOkB5NWe0vA= -github.com/go-pg/pg/v9 v9.0.0-beta.14/go.mod h1:T2Sr6bpTCOr2lUqOUMiXLMJqZHSUBKk1LdgSqjwhZfA= -github.com/go-pg/pg/v9 v9.0.3/go.mod h1:Tm/Q3Vt6gdQOH6TTN1H/xLlIXc+Qrka7TZ6uREtu/eA= -github.com/go-pg/pg/v9 v9.1.3 h1:gmE7k5ib45+NcRJBGUDPD/keJGCMqhH7TPqbd9xbdz4= -github.com/go-pg/pg/v9 v9.1.3/go.mod h1:QM13HBLkdml4zcKOfUfGLymM6hb72aKTJLrmaH8rsFg= -github.com/go-pg/urlstruct v0.1.0/go.mod h1:2Nag+BIny6G/KYCkdt++ZnqU/VinzimGapKfs4kwlN0= -github.com/go-pg/urlstruct v0.2.6/go.mod h1:dxENwVISWSOX+k87hDt0ueEJadD+gZWv3tHzwfmZPu8= -github.com/go-pg/urlstruct v0.3.0 h1:ORiTb205uT7v7lvq4VUOQ4ddJ5TjFRlVRWqWsMBgek4= -github.com/go-pg/urlstruct v0.3.0/go.mod h1:/XKyiUOUUS3onjF+LJxbfmSywYAdl6qMfVbX33Q8rgg= -github.com/go-pg/zerochecker v0.1.1 h1:av77Qe7Gs+1oYGGh51k0sbZ0bUaxJEdeP0r8YE64Dco= -github.com/go-pg/zerochecker v0.1.1/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= +github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +github.com/go-pg/pg v8.0.7+incompatible h1:ty/sXL1OZLo+47KK9N8llRcmbA9tZasqbQ/OO4ld53g= +github.com/go-pg/pg v8.0.7+incompatible/go.mod h1:a2oXow+aFOrvwcKs3eIA0lNFmMilrxK2sOkB5NWe0vA= +github.com/go-pg/pg/v10 v10.12.0 h1:rBmfDDHTN7FQW0OemYmcn5UuBy6wkYWgh/Oqt1OBEB8= +github.com/go-pg/pg/v10 v10.12.0/go.mod h1:USA08CdIasAn0F6wC1nBf5nQhMHewVQodWoH89RPXaI= +github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU= +github.com/go-pg/zerochecker v0.2.0/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo= github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/feeds v1.1.1 h1:HwKXxqzcRNg9to+BbvJog4+f3s/xzvtZXICcQGutYfY= -github.com/gorilla/feeds v1.1.1/go.mod h1:Nk0jZrvPFZX1OBe5NPiddPw7CfwF6Q9eqzaBbaightA= -github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ= -github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/feeds v1.1.2 h1:pxzZ5PD3RJdhFH2FsJJ4x6PqMqbgFk1+Vez4XWBW8Iw= +github.com/gorilla/feeds v1.1.2/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= -github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jasonlvhit/gocron v0.0.1 h1:qTt5qF3b3srDjeOIR4Le1LfeyvoYzJlYpqvG7tJX5YU= github.com/jasonlvhit/gocron v0.0.1/go.mod h1:k9a3TV8VcU73XZxfVHCHWMWF9SOqgoku0/QlY2yvlA4= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= -github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007 h1:reVOUXwnhsYv/8UqjvhrMOu5CNT9UapHFLbQ2JcXsmg= -github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 h1:YocNLcTBdEdvY3iDK6jfWXvEaM5OCKkjxPKoJRdB3Gg= -github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047 h1:zCoDWFD5nrJJVjbXiDZcVhOBSzKn3o9LgRLLMRNuru8= -github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc= +github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= +github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M= +github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.8.0 h1:zvJNkoCFAnYFNC24FV8nW4JdRJ3GIFcLbg65lL/JDcw= -github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.14.0 h1:RHRyE8UocrbjU+6UvRzwi6HjiDfxrrBU91TtbKzkGp4= -github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4= -github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/segmentio/encoding v0.1.10 h1:0b8dva47cSuNQR5ZcU3d0pfi9EnPpSK6q7y5ZGEW36Q= -github.com/segmentio/encoding v0.1.10/go.mod h1:RWhr02uzMB9gQC1x+MfYxedtmBibb9cZ6Vv9VxRSSbw= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA= +github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= +github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= +github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/samber/slog-multi v1.0.2 h1:6BVH9uHGAsiGkbbtQgAOQJMpKgV8unMrHhhJaw+X1EQ= +github.com/samber/slog-multi v1.0.2/go.mod h1:uLAvHpGqbYgX4FSL0p1ZwoLuveIAJvBECtE07XmYvFo= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/sosodev/duration v1.2.0 h1:pqK/FLSjsAADWY74SyWDCjOcd5l7H8GSnnOGEB9A1Us= +github.com/sosodev/duration v1.2.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k= -github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= -github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e h1:+w0Zm/9gaWpEAyDlU1eKOuk5twTjAjuevXqcJJw8hrg= -github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U= -github.com/vektah/gqlparser/v2 v2.0.1 h1:xgl5abVnsd4hkN9rk65OJID9bfcLSMuTaTcZj777q1o= -github.com/vektah/gqlparser/v2 v2.0.1/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms= -github.com/vmihailenco/bufpool v0.1.5 h1:mEO/biwhAgiY97yPMmAdH4PvaIu63C6uGBdfSdoMo/I= -github.com/vmihailenco/bufpool v0.1.5/go.mod h1:fL9i/PRTuS7AELqAHwSU1Zf1c70xhkhGe/cD5ud9pJk= -github.com/vmihailenco/msgpack/v4 v4.3.5/go.mod h1:DuaveEe48abshDmz5UBKyZ+yDugvaeFk5ayfrewUOaw= -github.com/vmihailenco/msgpack/v4 v4.3.7 h1:Aj4eMY2qXTRfWRwHKJ2n/CWKVy15pCYN327QMJ/OUVs= -github.com/vmihailenco/msgpack/v4 v4.3.7/go.mod h1:Ii+PksJlvFT5ZRcB/4YLAInMIp6a0WOCm0L3BU0aNG4= -github.com/vmihailenco/tagparser v0.1.0/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= -github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= -github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= +github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= +github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8= +github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= +github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94= +github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= +github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= +github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +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-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -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= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -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/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= +golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +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.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222033325-078779b8f2d8 h1:4l6HGmcZuPkox4Zl1b7SZQfYo8KIKvPe+5VG6ibuUEg= -golang.org/x/net v0.0.0-20200222033325-078779b8f2d8/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +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.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY= -golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 h1:9UQO31fZ+0aKQOFldThf7BKPMJTiBfWycGh/u3UoO88= -golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/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.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/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.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.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-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589 h1:rjUrONFu4kLchcZTfp3/96bR8bW8dIa8uz3cR5n0cgM= -golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +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.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 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-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= 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/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -mellium.im/sasl v0.2.1 h1:nspKSRg7/SyO0cRGY71OkfHab8tf9kCts6a6oTDut0w= -mellium.im/sasl v0.2.1/go.mod h1:ROaEDLQNuf9vjKqE1SrAfnsobm2YKXT1gnN1uDp1PjQ= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20180110180208-2cc67fd64755/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= -sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo= +mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw= diff --git a/package-lock.json b/package-lock.json index 50437ba..c6a313c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8416 +1,2808 @@ { + "name": "soko", + "lockfileVersion": 3, "requires": true, - "lockfileVersion": 1, - "dependencies": { - "@csstools/convert-colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz", - "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==" - }, - "@csstools/sass-import-resolve": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/sass-import-resolve/-/sass-import-resolve-1.0.0.tgz", - "integrity": "sha512-pH4KCsbtBLLe7eqUrw8brcuFO8IZlN36JjdKlOublibVdAIPHCzEnpBWOVUXK5sCf+DpBi8ZtuWtjF0srybdeA==" - }, - "@gentoo/tyrian": { - "version": "git+https://anongit.gentoo.org/git/sites/tyrian-theme.git#5b6b8e70fb7067b54fa4f2fac3966ae74fcb713c", - "from": "git+https://anongit.gentoo.org/git/sites/tyrian-theme.git", - "requires": { - "autoprefixer": "^7.2.4", - "bootstrap": "4.3.1", - "font-awesome": "4.7.0", - "jquery": "^3.3.1", - "popper.js": "1.14.7" + "packages": { + "": { + "dependencies": { + "@gentoo/tyrian": "git+https://anongit.gentoo.org/git/sites/tyrian-theme.git#v2.0.2", + "core-js": "^3.36.0", + "d3": "3.5.17", + "jquery": "^3.6.4", + "jquery-typeahead": "^2.11.1", + "jquery-ujs": "^1.2.3", + "regenerator-runtime": "^0.14.1", + "turbolinks": "^5.2.0" + }, + "devDependencies": { + "css-loader": "^6.10.0", + "mini-css-extract-plugin": "^2.8.0", + "resolve-url-loader": "^5.0.0", + "sass": "^1.71.1", + "sass-loader": "^14.1.1", + "webpack": "^5.90.3", + "webpack-cli": "^5.1.4" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "peer": true, + "dependencies": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", + "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", + "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", + "peer": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.3", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.3", + "@babel/types": "^7.23.3", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" }, - "dependencies": { - "autoprefixer": { - "version": "7.2.6", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.6.tgz", - "integrity": "sha512-Iq8TRIB+/9eQ8rbGhcP7ct5cYb/3qjNYAR2SnzLCEcwF6rvVOax8+9+fccgXk4bEhQGjOZd5TLhsksmAdsbGqQ==", - "requires": { - "browserslist": "^2.11.3", - "caniuse-lite": "^1.0.30000805", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^6.0.17", - "postcss-value-parser": "^3.2.3" - } - }, - "browserslist": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", - "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", - "requires": { - "caniuse-lite": "^1.0.30000792", - "electron-to-chromium": "^1.3.30" - } - }, - "popper.js": { - "version": "1.14.7", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.7.tgz", - "integrity": "sha512-4q1hNvoUre/8srWsH7hnoSJ5xVmIL4qgz+s4qf2TnJIMyZFUFMGH+9vE7mXynAlHSZ/NdTmmow86muD0myUkVQ==" - } + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" + "node_modules/@babel/generator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.3.tgz", + "integrity": "sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==", + "peer": true, + "dependencies": { + "@babel/types": "^7.23.3", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "peer": true, + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } }, - "@types/node": { - "version": "13.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.1.tgz", - "integrity": "sha512-E6M6N0blf/jiZx8Q3nb0vNaswQeEyn0XlupO+xN6DtJ6r6IT4nXrTry7zhIfYvFCl3/8Cu6WIysmUBKiqV0bqQ==", - "dev": true + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } }, - "@webassemblyjs/ast": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", - "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", - "requires": { - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", - "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", - "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", - "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==" - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", - "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", - "requires": { - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", - "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==" - }, - "@webassemblyjs/helper-module-context": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", - "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "mamacro": "^0.0.3" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", - "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", - "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", - "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", - "requires": { - "@xtuc/ieee754": "^1.2.0" + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "peer": true, + "engines": { + "node": ">=6.9.0" } }, - "@webassemblyjs/leb128": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", - "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", - "requires": { - "@xtuc/long": "4.2.2" + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "peer": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@webassemblyjs/utf8": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", - "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", - "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/helper-wasm-section": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-opt": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", - "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", - "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", - "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", - "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/floating-point-hex-parser": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-code-frame": "1.8.5", - "@webassemblyjs/helper-fsm": "1.8.5", - "@xtuc/long": "4.2.2" + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "peer": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "@webassemblyjs/wast-printer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", - "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5", - "@xtuc/long": "4.2.2" + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "peer": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" } }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "peer": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } }, - "@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==" + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "peer": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "peer": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "peer": true, + "engines": { + "node": ">=6.9.0" } }, - "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" + "node_modules/@babel/helper-validator-option": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } }, - "adjust-sourcemap-loader": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-2.0.0.tgz", - "integrity": "sha512-4hFsTsn58+YjrU9qKzML2JSSDqKvN8mUGQ0nNIrfPi8hmIONT4L3uUaT6MKdMsZ9AjsU6D2xDkZxCkbQPxChrA==", - "requires": { - "assert": "1.4.1", - "camelcase": "5.0.0", - "loader-utils": "1.2.3", - "object-path": "0.11.4", - "regex-parser": "2.2.10" + "node_modules/@babel/helpers": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", + "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", + "peer": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.2", + "@babel/types": "^7.23.0" }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "peer": true, "dependencies": { - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "requires": { - "util": "0.10.3" - } - }, - "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==" - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "requires": { - "inherits": "2.0.1" - } - } + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "ajv": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", - "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", - "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" + "node_modules/@babel/parser": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz", + "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==", + "peer": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" } }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" + "node_modules/@babel/register": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.22.15.tgz", + "integrity": "sha512-V3Q3EqoQdn65RCgTLwauZaTfd1ShhwPmbBv+1dkZV/HpCGMKVyn6oFcRlI7RaKqiDQjX2Qd3AuoEguBgdjIKlg==", + "dependencies": { + "clone-deep": "^4.0.1", + "find-cache-dir": "^2.0.0", + "make-dir": "^2.1.0", + "pirates": "^4.0.5", + "source-map-support": "^0.5.16" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.3.tgz", + "integrity": "sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.3", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.3", + "@babel/types": "^7.23.3", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==" + "node_modules/@babel/types": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.3.tgz", + "integrity": "sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==", + "peer": true, + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } }, - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true + "node_modules/@gentoo/tyrian": { + "version": "2.0.0", + "resolved": "git+https://anongit.gentoo.org/git/sites/tyrian-theme.git#7a60004f46a8d48e9b9369ddc180f35f17e26a90", + "dependencies": { + "autoprefixer": "^10.4.14", + "bootstrap": "4.6.2", + "font-awesome": "4.7.0", + "jquery": "^3.6.4", + "popper.js": "^1.16.0" + } }, - "ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", - "dev": true + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "engines": { + "node": ">=6.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" + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" } }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "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" + "node_modules/@types/eslint": { + "version": "8.44.7", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.7.tgz", + "integrity": "sha512-f5ORu2hcBbKei97U73mf+l9t4zTGl74IqZ0GQk4oVea/VS8tQZYkUveSYojk+frraAVYId0V2WC9O4PTNru2FQ==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" } }, - "arity-n": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", - "integrity": "sha1-2edrEXM+CFacCEeuezmyhgswt0U=" + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + "node_modules/@types/node": { + "version": "20.11.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz", + "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } }, - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, - "requires": { - "array-uniq": "^1.0.1" + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" } }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" } }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" } }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "requires": { - "inherits": "2.0.1" - } - } + "@xtuc/long": "4.2.2" } }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, - "requires": { - "lodash": "^4.17.14" + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" } }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" - }, - "async-foreach": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", - "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=" + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" - }, - "autoprefixer": { - "version": "9.7.4", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.4.tgz", - "integrity": "sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g==", - "requires": { - "browserslist": "^4.8.3", - "caniuse-lite": "^1.0.30001020", - "chalk": "^2.4.2", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.26", - "postcss-value-parser": "^4.0.2" - }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dev": true, "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "postcss-value-parser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz", - "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" } }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } }, - "aws4": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "engines": { + "node": ">=14.15.0" }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true } } }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "node_modules/@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==", "dev": true }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" } }, - "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": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "requires": { - "inherits": "~2.0.0" - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "node_modules/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==", "dev": true, - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - } + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" } }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, - "requires": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - } - }, - "bootstrap": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz", - "integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag==" - }, - "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": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true } } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" } }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "node_modules/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==", + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "requires": { - "pako": "~1.0.5" - } - }, - "browserslist": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.1.tgz", - "integrity": "sha512-Q0DnKq20End3raFulq6Vfp1ecB9fh8yUNV55s8sekaDDeqBaCtWlRHCUdaWyUeSSBJM7IbM6HcsyaeYqgeDhnw==", - "requires": { - "caniuse-lite": "^1.0.30001030", - "electron-to-chromium": "^1.3.363", - "node-releases": "^1.1.50" - } - }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "cacache": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", - "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" + "node_modules/autoprefixer": { + "version": "10.4.16", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", + "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.21.10", + "caniuse-lite": "^1.0.30001538", + "fraction.js": "^4.3.6", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "requires": { - "callsites": "^2.0.0" + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" } }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "requires": { - "caller-callsite": "^2.0.0" + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" } }, - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + "node_modules/bootstrap": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz", + "integrity": "sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "peerDependencies": { + "jquery": "1.9.1 - 3", + "popper.js": "^1.16.1" + } }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "caniuse-lite": { - "version": "1.0.30001035", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001035.tgz", - "integrity": "sha512-C1ZxgkuA4/bUEdMbU5WrGY4+UhMFFiXrgNAfxiMIqWgFTWfv/xsZCS2xEHT2LMq7xAZfuAnu6mcqyDl0ZR6wLQ==" + "node_modules/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==" }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "node_modules/caniuse-lite": { + "version": "1.0.30001563", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001563.tgz", + "integrity": "sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] }, - "chalk": { + "node_modules/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": { + "peer": true, + "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" }, - "dependencies": { - "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" - } - } + "engines": { + "node": ">=4" } }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.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" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" } }, - "clone-deep": { + "node_modules/clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "requires": { + "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "coffeescript": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.5.1.tgz", - "integrity": "sha512-J2jRPX0eeFh5VKyVnoLrfVFgLZtnnmp96WQSLAS8OrLm2wtQLcnikYKe1gViJKDH7vucjuhHvBKKBP3rKcD1tQ==" - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { + "node_modules/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": { + "peer": true, + "dependencies": { "color-name": "1.1.3" } }, - "color-name": { + "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "peer": true }, - "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" - } + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true }, - "commander": { + "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true }, - "commondir": { + "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "compose-function": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", - "integrity": "sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8=", - "requires": { - "arity-n": "^1.0.4" - } + "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==", - "dev": true, - "requires": { - "mime-db": ">= 1.43.0 < 2" - } + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "peer": true }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "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" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "node_modules/core-js": { + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.0.tgz", + "integrity": "sha512-mt7+TUBbTFg5+GngsAxeKBTl5/VS0guFeJacYge9OmHb+m058UwwIm41SE9T4Den7ClatV57B6TYTuJ0CX1MAw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, - "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "dev": true - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "requires": { - "safe-buffer": "5.1.2" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" - }, - "core-js": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", - "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, "dependencies": { - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - } - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "css": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", - "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "requires": { - "inherits": "^2.0.3", - "source-map": "^0.6.1", - "source-map-resolve": "^0.5.2", - "urix": "^0.1.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "engines": { + "node": ">= 8" } }, - "css-blank-pseudo": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz", - "integrity": "sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==", - "requires": { - "postcss": "^7.0.5" - }, + "node_modules/css-loader": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.10.0.tgz", + "integrity": "sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==", + "dev": true, "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "css-has-pseudo": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz", - "integrity": "sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==", - "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^5.0.0-rc.4" + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.4", + "postcss-modules-scope": "^3.1.1", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" }, - "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "css-loader": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.4.2.tgz", - "integrity": "sha512-jYq4zdZT0oS0Iykt+fqnzVLRIeiPWhka+7BqPn+oSIpWJAHak5tmB/WZrJ2a21JhCeFyNnnlroSl8c+MtVndzA==", - "requires": { - "camelcase": "^5.3.1", - "cssesc": "^3.0.0", - "icss-utils": "^4.1.1", - "loader-utils": "^1.2.3", - "normalize-path": "^3.0.0", - "postcss": "^7.0.23", - "postcss-modules-extract-imports": "^2.0.0", - "postcss-modules-local-by-default": "^3.0.2", - "postcss-modules-scope": "^2.1.1", - "postcss-modules-values": "^3.0.0", - "postcss-value-parser": "^4.0.2", - "schema-utils": "^2.6.0" + "engines": { + "node": ">= 12.13.0" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "postcss-value-parser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz", - "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==" - }, - "schema-utils": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", - "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", - "requires": { - "ajv": "^6.12.0", - "ajv-keywords": "^3.4.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "css-prefers-color-scheme": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz", - "integrity": "sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==", - "requires": { - "postcss": "^7.0.5" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "webpack": { + "optional": true } } }, - "cssdb": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz", - "integrity": "sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==" - }, - "cssesc": { + "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "requires": { - "array-find-index": "^1.0.1" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=" - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "d3": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.6.tgz", - "integrity": "sha1-lFHGUcpzP7lnLIH7fyZVFkpzpC0=" - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "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" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" } }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } + "node_modules/d3": { + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz", + "integrity": "sha512-yFk/2idb8OHPKkbAL8QaOaqENNoMhIaSHZerk3oQsECwkObkCpJyjYwCe+OHiq6UEdhe1m8ZGARRRO3ljFjlKg==" }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "peer": true, "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true } } }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + "node_modules/electron-to-chromium": { + "version": "1.4.587", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.587.tgz", + "integrity": "sha512-RyJX0q/zOkAoefZhB9XHghGeATVP0Q3mwA253XD/zj2OeXc+JZB9pCaEv6R578JUYaWM9PRhye0kXvd/V1cQ3Q==" }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" - }, - "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true - }, - "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "dev": true, - "requires": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" + "engines": { + "node": ">= 4" } }, - "dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dev": true, - "requires": { - "buffer-indexof": "^1.0.0" - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.376", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.376.tgz", - "integrity": "sha512-cv/PYVz5szeMz192ngilmezyPNFkUjuynuL2vNdiqIrio440nfTDdc0JJU0TS2KHLSVCs9gBbt4CFqM+HcBnjw==" - }, - "elliptic": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", - "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" } }, - "enhanced-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", - "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.4.0", - "tapable": "^1.0.0" - } - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "requires": { - "prr": "~1.0.1" - } - }, - "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" - } - }, - "es-abstract": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", - "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } - }, - "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==", + "node_modules/envinfo": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz", + "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==", "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" } }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } + "node_modules/es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", + "dev": true }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" } }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { + "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "requires": { - "estraverse": "^4.1.0" + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "peer": true, + "engines": { + "node": ">=0.8.0" } }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "eventemitter3": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", - "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", - "dev": true - }, - "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==" - }, - "eventsource": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", - "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, - "requires": { - "original": "^1.0.0" - } - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "exports-loader": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/exports-loader/-/exports-loader-0.7.0.tgz", - "integrity": "sha512-RKwCrO4A6IiKm0pG3c9V46JxIHcDplwwGJn6+JJ1RcVnh/WSGJa0xkmk5cRVtgOPzCAtTMGj2F7nluh9L0vpSA==", - "requires": { - "loader-utils": "^1.1.0", - "source-map": "0.5.0" + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" }, - "dependencies": { - "source-map": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.0.tgz", - "integrity": "sha1-D+llA6yGpa213mP05BKuSHLNvoY=" - } + "engines": { + "node": ">=8.0.0" } }, - "expose-loader": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/expose-loader/-/expose-loader-0.7.5.tgz", - "integrity": "sha512-iPowgKUZkTPX5PznYsmifVj9Bob0w2wTHVkt/eYNPSzyebkUgIedmskf/kcfEIWpiWjg3JRjnW+a17XypySMuw==" - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - } - } - }, - "ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "requires": { - "type": "^2.0.0" + "estraverse": "^5.2.0" }, - "dependencies": { - "type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", - "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==" - } + "engines": { + "node": ">=4.0" } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" } }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } }, - "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==" + "node_modules/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==", + "dev": true }, - "fast-json-stable-stringify": { + "node_modules/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==" + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" + "engines": { + "node": ">= 4.9.1" } }, - "figgy-pudding": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==" - }, - "file-loader": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-5.1.0.tgz", - "integrity": "sha512-u/VkLGskw3Ue59nyOwUwXI/6nuBCo7KBkniB/l7ICwr/7cPNGsL1WCXUp3GB0qgOOKU1TiP49bv4DZF/LJqprg==", - "requires": { - "loader-utils": "^1.4.0", - "schema-utils": "^2.5.0" - }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "dependencies": { - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "schema-utils": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", - "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", - "requires": { - "ajv": "^6.12.0", - "ajv-keywords": "^3.4.1" - } - } - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "to-regex-range": "^5.0.1" }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } + "engines": { + "node": ">=8" } }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "find-cache-dir": { + "node_modules/find-cache-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "requires": { + "dependencies": { "commondir": "^1.0.1", "make-dir": "^2.0.0", "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "find-up": { + "node_modules/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": { + "dependencies": { "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "flatten": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", - "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==" - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "follow-redirects": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.10.0.tgz", - "integrity": "sha512-4eyLK6s6lH32nOvLLwlIOnr9zrL8Sm+OvW4pVTJNoXeGzYIkHVf+pADQi+OJ0E67hiuSLezPVPyBcIZO50TmmQ==", + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, - "requires": { - "debug": "^3.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } + "bin": { + "flat": "cli.js" } }, - "font-awesome": { + "node_modules/font-awesome": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", - "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=" - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "integrity": "sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg==", + "engines": { + "node": ">=0.10.3" } }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "requires": { - "map-cache": "^0.2.2" + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" } }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" + "node_modules/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==", + "peer": true, + "engines": { + "node": ">=6.9.0" } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", - "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1", - "node-pre-gyp": "*" - }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.3", - "bundled": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "debug": { - "version": "3.2.6", - "bundled": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.7", - "bundled": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.6", - "bundled": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "bundled": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "optional": true - }, - "minipass": { - "version": "2.9.0", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "bundled": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "optional": true - }, - "needle": { - "version": "2.4.0", - "bundled": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "bundled": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.1.1", - "bundled": true, - "optional": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.7", - "bundled": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "optional": true, - "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" - } - }, - "rimraf": { - "version": "2.7.1", - "bundled": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "bundled": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "tar": { - "version": "4.4.13", - "bundled": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "yallist": { - "version": "3.1.1", - "bundled": true, - "optional": true - } - } - }, - "fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "node_modules/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==", "dev": true }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "gaze": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", - "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", - "requires": { - "globule": "^1.0.0" + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "peer": true, + "engines": { + "node": ">=4" } }, - "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-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "requires": { - "is-extglob": "^2.1.0" - } - } + "node_modules/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==", + "peer": true, + "engines": { + "node": ">=4" } }, - "global-modules": { + "node_modules/hasown": { "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" - }, + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, "dependencies": { - "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" - } - } + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "engines": { + "node": "^10 || ^12 || >= 14" }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "peerDependencies": { + "postcss": "^8.1.0" } }, - "globule": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz", - "integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==", - "requires": { - "glob": "~7.1.1", - "lodash": "~4.17.12", - "minimatch": "~3.0.2" - } - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" - }, - "handle-thing": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", - "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==", + "node_modules/immutable": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", + "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", "dev": true }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "^2.0.0" - }, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - } - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "requires": { - "parse-passwd": "^1.0.0" + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "node_modules/import-local/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "html-entities": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", - "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", - "dev": true - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": true - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "node_modules/import-local/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" } }, - "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", - "dev": true - }, - "http-proxy": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", - "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", + "node_modules/import-local/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "node_modules/import-local/node_modules/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==", "dev": true, - "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" + "engines": { + "node": ">=8" } }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/import-local/node_modules/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==", "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", - "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", - "requires": { - "postcss": "^7.0.14" - }, "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" - }, - "import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "requires": { - "import-from": "^2.1.0" - } - }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "import-from": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", - "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", - "requires": { - "resolve-from": "^3.0.0" - } - }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "in-publish": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz", - "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==" - }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "requires": { - "repeating": "^2.0.0" - } - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" - }, - "internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true, - "requires": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" + "engines": { + "node": ">=10.13.0" } }, - "interpret": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", - "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==" - }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "ip-regex": { + "node_modules/is-binary-path": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true - }, - "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==", - "dev": true - }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - }, + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" + "binary-extensions": "^2.0.0" }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } + "engines": { + "node": ">=8" } }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-extglob": { + "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "requires": { - "is-path-inside": "^2.1.0" + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "requires": { - "path-is-inside": "^1.0.2" + "engines": { + "node": ">=0.12.0" } }, - "is-plain-object": { + "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { + "dependencies": { "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { + "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, - "isobject": { + "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "jquery": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", - "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==" - }, - "jquery-ujs": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jquery-ujs/-/jquery-ujs-1.2.2.tgz", - "integrity": "sha1-ao7xAg5rbdo4W5CkvdwSjCHFY5c=", - "requires": { - "jquery": ">=1.8.0" + "node_modules/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==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" } }, - "js-base64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.2.tgz", - "integrity": "sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ==" + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==" }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + "node_modules/jquery-typeahead": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/jquery-typeahead/-/jquery-typeahead-2.11.1.tgz", + "integrity": "sha512-iuNRruN5bWtck+VPxdCTijD6BD9bVuBj3NCD25vITOdMb7P3fYlkBWcmnLEazD8O+VAtbcJ9aLxRi+qrpopNZA==", + "dependencies": { + "@babel/register": "^7.6.2", + "jquery": ">=1.7.2", + "lz-string": "^1.4.4" + } }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "node_modules/jquery-ujs": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jquery-ujs/-/jquery-ujs-1.2.3.tgz", + "integrity": "sha512-59wvfx5vcCTHMeQT1/OwFiAj+UffLIwjRIoXdpO7Z7BCFGepzq9T9oLVeoItjTqjoXfUrHJvV7QU6pUR+UzOoA==", + "peerDependencies": { + "jquery": ">=1.8.0" + } }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "peer": true }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "peer": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } }, - "json3": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", - "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", + "node_modules/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==", "dev": true }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "requires": { - "minimist": "^1.2.0" - } + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, - "killable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", - "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", - "dev": true - }, - "kind-of": { + "node_modules/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==" - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "requires": { - "invert-kv": "^2.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" } }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==" + "node_modules/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==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "requires": { + "node_modules/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==", + "dev": true, + "dependencies": { "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" } }, - "locate-path": { + "node_modules/locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { + "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "loglevel": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.7.tgz", - "integrity": "sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A==", - "dev": true - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, - "lru-cache": { + "node_modules/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": { + "peer": true, + "dependencies": { "yallist": "^3.0.2" } }, - "make-dir": { + "node_modules/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==", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "requires": { + "dependencies": { "pify": "^4.0.1", "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" } }, - "mamacro": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", - "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==" - }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "requires": { - "p-defer": "^1.0.0" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "requires": { - "object-visit": "^1.0.0" - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" } }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "node_modules/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==", "dev": true }, - "mime-db": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" - }, - "mime-types": { - "version": "2.1.26", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", - "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", - "requires": { - "mime-db": "1.43.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "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==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, + "node_modules/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==", + "dev": true, "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" + "mime-db": "1.52.0" }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - } + "engines": { + "node": ">= 0.6" } }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "node_modules/mini-css-extract-plugin": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.0.tgz", + "integrity": "sha512-CxmUYPFcTgET1zImteG/LZOy/4T5rTojesQXkSNBiquhydn78tfbCE9sjIjnJ/UcjNjOC1bphTCCW5rrS7cXAg==", "dev": true, - "requires": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" - } - }, - "multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", - "dev": true - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-forge": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", - "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", - "dev": true - }, - "node-gyp": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", - "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", - "requires": { - "fstream": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^2.0.0", - "which": "1" - }, "dependencies": { - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" - } - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "node-releases": { - "version": "1.1.52", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.52.tgz", - "integrity": "sha512-snSiT1UypkgGt2wxPqS6ImEUICbNCMb31yaxWrOLXjhlt2z2/IBpaOxzONExqSm4y5oLnAqjjRWu+wsDzK5yNQ==", - "requires": { - "semver": "^6.3.0" + "engines": { + "node": ">= 12.13.0" }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "node-sass": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.1.tgz", - "integrity": "sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw==", - "requires": { - "async-foreach": "^0.1.3", - "chalk": "^1.1.1", - "cross-spawn": "^3.0.0", - "gaze": "^1.0.0", - "get-stdin": "^4.0.1", - "glob": "^7.0.3", - "in-publish": "^2.0.0", - "lodash": "^4.17.15", - "meow": "^3.7.0", - "mkdirp": "^0.5.1", - "nan": "^2.13.2", - "node-gyp": "^3.8.0", - "npmlog": "^4.0.0", - "request": "^2.88.0", - "sass-graph": "^2.2.4", - "stdout-stream": "^1.4.0", - "true-case-path": "^1.0.2" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "cross-spawn": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", - "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - } + "peerDependencies": { + "webpack": "^5.0.0" } }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "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": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "peer": true }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "dev": true - }, - "object-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.2.tgz", - "integrity": "sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-path": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", - "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=" - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "requires": { - "isobject": "^3.0.1" - } - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "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==", + "node_modules/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==", "dev": true }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "requires": { - "url-parse": "^1.4.3" + "engines": { + "node": ">=0.10.0" } }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" + "node_modules/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==", + "engines": { + "node": ">=0.10.0" } }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==" - }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "requires": { + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-locate": { + "node_modules/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": { + "dependencies": { "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" } }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-retry": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", - "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", - "dev": true, - "requires": { - "retry": "^0.12.0" - } - }, - "p-try": { + "node_modules/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==" - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "requires": { - "error-ex": "^1.2.0" + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" } }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" - }, - "path-exists": { + "node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "node_modules/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==", "dev": true }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "pify": { + "node_modules/pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "engines": { + "node": ">=6" + } }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "engines": { + "node": ">= 6" } }, - "pkg-dir": { + "node_modules/pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "requires": { + "dependencies": { "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "popper.js": { + "node_modules/popper.js": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", - "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" - }, - "portfinder": { - "version": "1.0.25", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz", - "integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==", - "dev": true, - "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.1" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==", + "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" } }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" - }, - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", - "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "node_modules/postcss": { + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" }, - "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" - } - } - } - }, - "postcss-advanced-variables": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/postcss-advanced-variables/-/postcss-advanced-variables-3.0.1.tgz", - "integrity": "sha512-JqVjfkmqPoazMobVeQYzbt7djcDGJfMlpwBd9abTqmzWR40tvIUMXpTU5w3riqz7h+wYPY7V6GF8BIXL/ybEfg==", - "requires": { - "@csstools/sass-import-resolve": "^1.0.0", - "postcss": "^7.0.6" - }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + { + "type": "github", + "url": "https://github.com/sponsors/ai" } - } - }, - "postcss-atroot": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/postcss-atroot/-/postcss-atroot-0.1.3.tgz", - "integrity": "sha1-Z1LAIwx0UUBUk0WysOMOvtoBpAU=", - "requires": { - "postcss": "^5.0.5" - }, + ], "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "dependencies": { - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - } - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "postcss-attribute-case-insensitive": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz", - "integrity": "sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==", - "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^6.0.2" + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "engines": { + "node": "^10 || ^12 || >=14" } }, - "postcss-color-functional-notation": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz", - "integrity": "sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==", - "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "peerDependencies": { + "postcss": "^8.1.0" } }, - "postcss-color-gray": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz", - "integrity": "sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==", - "requires": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.5", - "postcss-values-parser": "^2.0.0" - }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz", + "integrity": "sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==", + "dev": true, "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-color-hex-alpha": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz", - "integrity": "sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==", - "requires": { - "postcss": "^7.0.14", - "postcss-values-parser": "^2.0.1" + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-color-mod-function": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz", - "integrity": "sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==", - "requires": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "engines": { + "node": "^10 || ^12 || >= 14" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "peerDependencies": { + "postcss": "^8.1.0" } }, - "postcss-color-rebeccapurple": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz", - "integrity": "sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==", - "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, + "node_modules/postcss-modules-scope": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz", + "integrity": "sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==", + "dev": true, "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-custom-media": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz", - "integrity": "sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==", - "requires": { - "postcss": "^7.0.14" + "postcss-selector-parser": "^6.0.4" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-custom-properties": { - "version": "8.0.11", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz", - "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==", - "requires": { - "postcss": "^7.0.17", - "postcss-values-parser": "^2.0.1" + "engines": { + "node": "^10 || ^12 || >= 14" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "peerDependencies": { + "postcss": "^8.1.0" } }, - "postcss-custom-selectors": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz", - "integrity": "sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==", - "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, + "node_modules/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==", + "dev": true, "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-dir-pseudo-class": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz", - "integrity": "sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==", - "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" + "icss-utils": "^5.0.0" }, - "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-double-position-gradients": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz", - "integrity": "sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==", - "requires": { - "postcss": "^7.0.5", - "postcss-values-parser": "^2.0.0" + "engines": { + "node": "^10 || ^12 || >= 14" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "peerDependencies": { + "postcss": "^8.1.0" } }, - "postcss-env-function": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz", - "integrity": "sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==", - "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, + "node_modules/postcss-selector-parser": { + "version": "6.0.15", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", + "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "dev": true, "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-extend-rule": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-extend-rule/-/postcss-extend-rule-2.0.0.tgz", - "integrity": "sha512-dgr1GJzW3lUBczZJO5Fm51rktn34Uc99xR1uQyC2Td8JPep/Y+TRx6TjK0yngikOd4LxV1xyuohMMpcaOBgrfA==", - "requires": { - "postcss": "^6.0.22", - "postcss-nesting": "^5.0.0" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" } }, - "postcss-flexbugs-fixes": { + "node_modules/postcss-value-parser": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.0.tgz", - "integrity": "sha512-QRE0n3hpkxxS/OGvzOa+PDuy4mh/Jg4o9ui22/ko5iGYOG3M5dfJabjnAZjTdh2G9F85c7Hv8hWcEDEKW/xceQ==", - "requires": { - "postcss": "^7.0.26" - }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, - "postcss-focus-visible": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz", - "integrity": "sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==", - "requires": { - "postcss": "^7.0.2" - }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" } }, - "postcss-focus-within": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz", - "integrity": "sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==", - "requires": { - "postcss": "^7.0.2" - }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "safe-buffer": "^5.1.0" } }, - "postcss-font-variant": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.0.tgz", - "integrity": "sha512-M8BFYKOvCrI2aITzDad7kWuXXTm0YhGdP9Q8HanmN4EF1Hmcgs1KK5rSHylt/lUJe8yLxiSwWAHdScoEiIxztg==", - "requires": { - "postcss": "^7.0.2" - }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-gap-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz", - "integrity": "sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==", - "requires": { - "postcss": "^7.0.2" + "picomatch": "^2.2.1" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "engines": { + "node": ">=8.10.0" } }, - "postcss-image-set-function": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz", - "integrity": "sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==", - "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-import": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", - "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", - "requires": { - "postcss": "^7.0.1", - "postcss-value-parser": "^3.2.3", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" + "resolve": "^1.20.0" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "engines": { + "node": ">= 10.13.0" } }, - "postcss-initial": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.2.tgz", - "integrity": "sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA==", - "requires": { - "lodash.template": "^4.5.0", - "postcss": "^7.0.2" - }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, - "postcss-lab-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz", - "integrity": "sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==", - "requires": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } + "node_modules/regex-parser": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", + "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==", + "dev": true }, - "postcss-load-config": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", - "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", - "requires": { - "cosmiconfig": "^5.0.0", - "import-cwd": "^2.0.0" + "node_modules/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==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "postcss-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", - "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", - "requires": { - "loader-utils": "^1.1.0", - "postcss": "^7.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^1.0.0" - }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "postcss-logical": { + "node_modules/resolve-cwd": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz", - "integrity": "sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==", - "requires": { - "postcss": "^7.0.2" - }, + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "postcss-media-minmax": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz", - "integrity": "sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==", - "requires": { - "postcss": "^7.0.2" - }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" } }, - "postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "requires": { - "postcss": "^7.0.5" - }, + "node_modules/resolve-url-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", + "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", + "dev": true, "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=12" } }, - "postcss-modules-local-by-default": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz", - "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==", - "requires": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.16", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.0" - }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } + "node_modules/resolve-url-loader/node_modules/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==", + "dev": true + }, + "node_modules/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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "postcss-value-parser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz", - "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==" + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + { + "type": "consulting", + "url": "https://feross.org/support" } - } + ] }, - "postcss-modules-scope": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.1.1.tgz", - "integrity": "sha512-OXRUPecnHCg8b9xWvldG/jUpRIGPNRka0r4D4j0ESUU2/5IOnpsjfPPmDprM3Ih8CgZ8FXjWqaniK5v4rWt3oQ==", - "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" - }, + "node_modules/sass": { + "version": "1.71.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.1.tgz", + "integrity": "sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==", + "dev": true, "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-modules-values": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", - "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", - "requires": { - "icss-utils": "^4.0.0", - "postcss": "^7.0.6" + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-nested": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-4.2.1.tgz", - "integrity": "sha512-AMayXX8tS0HCp4O4lolp4ygj9wBn32DJWXvG6gCv+ZvJrEa00GUxJcJEEzMh87BIe6FrWdYkpR2cuyqHKrxmXw==", - "requires": { - "postcss": "^7.0.21", - "postcss-selector-parser": "^6.0.2" + "bin": { + "sass": "sass.js" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "engines": { + "node": ">=14.0.0" } }, - "postcss-nesting": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-5.0.0.tgz", - "integrity": "sha512-Yoe3w2mcVslnEJl5zLyz1yBxCFUpYu138apEEOCwS2HRdDw/TDxTwD1fXBrIarL8J1cPzHfVwO1m40B2/UpGCw==", - "requires": { - "postcss": "^6.0.21" - } - }, - "postcss-overflow-shorthand": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz", - "integrity": "sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==", - "requires": { - "postcss": "^7.0.2" - }, + "node_modules/sass-loader": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-14.1.1.tgz", + "integrity": "sha512-QX8AasDg75monlybel38BZ49JP5Z+uSKfKwF2rO7S74BywaRmGQMUBw9dtkS+ekyM/QnP+NOrRYq8ABMZ9G8jw==", + "dev": true, "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-page-break": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz", - "integrity": "sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==", - "requires": { - "postcss": "^7.0.2" + "neo-async": "^2.6.2" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-place": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz", - "integrity": "sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==", - "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "engines": { + "node": ">= 18.12.0" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-preset-env": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz", - "integrity": "sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==", - "requires": { - "autoprefixer": "^9.6.1", - "browserslist": "^4.6.4", - "caniuse-lite": "^1.0.30000981", - "css-blank-pseudo": "^0.1.4", - "css-has-pseudo": "^0.10.0", - "css-prefers-color-scheme": "^3.1.1", - "cssdb": "^4.4.0", - "postcss": "^7.0.17", - "postcss-attribute-case-insensitive": "^4.0.1", - "postcss-color-functional-notation": "^2.0.1", - "postcss-color-gray": "^5.0.0", - "postcss-color-hex-alpha": "^5.0.3", - "postcss-color-mod-function": "^3.0.3", - "postcss-color-rebeccapurple": "^4.0.1", - "postcss-custom-media": "^7.0.8", - "postcss-custom-properties": "^8.0.11", - "postcss-custom-selectors": "^5.1.2", - "postcss-dir-pseudo-class": "^5.0.0", - "postcss-double-position-gradients": "^1.0.0", - "postcss-env-function": "^2.0.2", - "postcss-focus-visible": "^4.0.0", - "postcss-focus-within": "^3.0.0", - "postcss-font-variant": "^4.0.0", - "postcss-gap-properties": "^2.0.0", - "postcss-image-set-function": "^3.0.1", - "postcss-initial": "^3.0.0", - "postcss-lab-function": "^2.0.1", - "postcss-logical": "^3.0.0", - "postcss-media-minmax": "^4.0.0", - "postcss-nesting": "^7.0.0", - "postcss-overflow-shorthand": "^2.0.0", - "postcss-page-break": "^2.0.0", - "postcss-place": "^4.0.1", - "postcss-pseudo-class-any-link": "^6.0.0", - "postcss-replace-overflow-wrap": "^3.0.0", - "postcss-selector-matches": "^4.0.0", - "postcss-selector-not": "^4.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" }, - "dependencies": { - "autoprefixer": { - "version": "9.7.4", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.4.tgz", - "integrity": "sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g==", - "requires": { - "browserslist": "^4.8.3", - "caniuse-lite": "^1.0.30001020", - "chalk": "^2.4.2", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.26", - "postcss-value-parser": "^4.0.2" - } - }, - "browserslist": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.1.tgz", - "integrity": "sha512-Q0DnKq20End3raFulq6Vfp1ecB9fh8yUNV55s8sekaDDeqBaCtWlRHCUdaWyUeSSBJM7IbM6HcsyaeYqgeDhnw==", - "requires": { - "caniuse-lite": "^1.0.30001030", - "electron-to-chromium": "^1.3.363", - "node-releases": "^1.1.50" - } + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true }, - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } + "node-sass": { + "optional": true }, - "postcss-nesting": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz", - "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==", - "requires": { - "postcss": "^7.0.2" - } + "sass": { + "optional": true }, - "postcss-value-parser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz", - "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==" + "sass-embedded": { + "optional": true }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "webpack": { + "optional": true } } }, - "postcss-property-lookup": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-property-lookup/-/postcss-property-lookup-2.0.0.tgz", - "integrity": "sha512-KUb53a7UZWDMVb0SRODOonc4H1wlbgQ0VfYwmJaR1xWPorhariEz0U7x0ri3W/imFs6HqLYWP7hl2yMvi5Ty+w==", - "requires": { - "object-assign": "^4.0.1", - "postcss": "^6.0.6", - "tcomb": "^3.2.21" - } - }, - "postcss-pseudo-class-any-link": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz", - "integrity": "sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==", - "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, + "node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-replace-overflow-wrap": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz", - "integrity": "sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==", - "requires": { - "postcss": "^7.0.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-selector-matches": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz", - "integrity": "sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==", - "requires": { - "balanced-match": "^1.0.0", - "postcss": "^7.0.2" + "engines": { + "node": ">= 12.13.0" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "postcss-selector-not": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.0.tgz", - "integrity": "sha512-W+bkBZRhqJaYN8XAnbbZPLWMvZD1wKTu0UxtFKdhtGjWYmxhkUneoeOhRJKdAE5V7ZTlnbHfCR+6bNwK9e1dTQ==", - "requires": { - "balanced-match": "^1.0.0", - "postcss": "^7.0.2" - }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "postcss-selector-parser": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", - "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", - "requires": { - "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "postcss-values-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", - "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", - "requires": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "precss": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/precss/-/precss-4.0.0.tgz", - "integrity": "sha512-cRPZMKpHLZXR6gJlrXRjJe7SQMf+wYxg6rKp+TwYsYABjApSj9z8E8yIlagqADaWyikeIZttaNU6xqSjFIAP/g==", - "requires": { - "postcss": "^7.0.6", - "postcss-advanced-variables": "^3.0.0", - "postcss-atroot": "^0.1.3", - "postcss-extend-rule": "^2.0.0", - "postcss-nested": "^4.1.0", - "postcss-preset-env": "^6.4.0", - "postcss-property-lookup": "^2.0.0" + "lru-cache": "^6.0.0" }, - "dependencies": { - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - }, - "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-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" - }, - "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "psl": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", - "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "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" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "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==", + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - } + "randombytes": "^2.1.0" } }, - "read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", - "requires": { - "pify": "^2.3.0" - }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" + "kind-of": "^6.0.2" }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "requires": { - "pinkie-promise": "^2.0.0" - } - } + "engines": { + "node": ">=8" } }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/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" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - } - }, - "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regex-parser": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.10.tgz", - "integrity": "sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA==" - }, - "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "node_modules/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==", "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "requires": { - "is-finite": "^1.0.0" - } - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, "dependencies": { - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "requires": { - "resolve-from": "^3.0.0" - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" + "shebang-regex": "^3.0.0" }, - "dependencies": { - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - } + "engines": { + "node": ">=8" } }, - "resolve-from": { + "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" - }, - "resolve-url-loader": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.1.tgz", - "integrity": "sha512-K1N5xUjj7v0l2j/3Sgs5b8CjrrgtC70SmdCuZiJ8tSyb5J+uk3FoeZ4b7yTnH6j7ngI+Bc5bldHJIa8hYdu2gQ==", - "requires": { - "adjust-sourcemap-loader": "2.0.0", - "camelcase": "5.3.1", - "compose-function": "3.0.3", - "convert-source-map": "1.7.0", - "es6-iterator": "2.0.3", - "loader-utils": "1.2.3", - "postcss": "7.0.21", - "rework": "1.0.1", - "rework-visit": "1.0.0", - "source-map": "0.6.1" - }, - "dependencies": { - "postcss": { - "version": "7.0.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", - "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true - }, - "rework": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", - "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=", - "requires": { - "convert-source-map": "^0.3.3", - "css": "^2.0.0" - }, - "dependencies": { - "convert-source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", - "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=" - } - } - }, - "rework-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz", - "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=" - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" } }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "requires": { - "aproba": "^1.1.1" + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" } }, - "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==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "requires": { - "ret": "~0.1.10" + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" } }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sass-graph": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", - "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", - "requires": { - "glob": "^7.0.0", - "lodash": "^4.0.0", - "scss-tokenizer": "^0.2.3", - "yargs": "^7.0.0" - }, + "node_modules/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==", "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "requires": { - "invert-kv": "^1.0.0" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "requires": { - "lcid": "^1.0.0" - } - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" - }, - "yargs": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", - "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.0" - } - }, - "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", - "requires": { - "camelcase": "^3.0.0" - } - } + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "sass-loader": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", - "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", - "requires": { - "clone-deep": "^4.0.1", - "loader-utils": "^1.2.3", - "neo-async": "^2.6.1", - "schema-utils": "^2.6.1", - "semver": "^6.3.0" - }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "peer": true, "dependencies": { - "schema-utils": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", - "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", - "requires": { - "ajv": "^6.12.0", - "ajv-keywords": "^3.4.1" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "schema-utils": { + "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "scss-tokenizer": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", - "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", - "requires": { - "js-base64": "^2.1.8", - "source-map": "^0.4.2" + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "requires": { - "amdefine": ">=0.0.4" - } - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true - }, - "selfsigned": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", - "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, - "requires": { - "node-forge": "0.9.0" + "engines": { + "node": ">=6" } }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "node_modules/terser": { + "version": "5.27.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.2.tgz", + "integrity": "sha512-sHXmLSkImesJ4p5apTeT63DsV4Obe1s37qT8qvwHRmVxKTBH7Rv9Wr26VcAMmLbmk9UliiwK8z+657NyJHHy/w==", "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==" - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "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" + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" }, - "dependencies": { - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "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": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - } + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" } }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "requires": { - "kind-of": "^6.0.2" - } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "simple-html-tokenizer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.1.1.tgz", - "integrity": "sha1-BcLuxXn//+FFoDCsJs/qYbmA+r4=" - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" + "engines": { + "node": ">= 10.13.0" }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "requires": { - "kind-of": "^3.2.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "sockjs": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", - "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", - "dev": true, - "requires": { - "faye-websocket": "^0.10.0", - "uuid": "^3.0.1" - } - }, - "sockjs-client": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", - "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", - "dev": true, - "requires": { - "debug": "^3.2.5", - "eventsource": "^1.0.7", - "faye-websocket": "~0.11.1", - "inherits": "^2.0.3", - "json3": "^3.3.2", - "url-parse": "^1.4.3" + "peerDependencies": { + "webpack": "^5.1.0" }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } + "peerDependenciesMeta": { + "@swc/core": { + "optional": true }, - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } + "esbuild": { + "optional": true }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "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.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", - "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "uglify-js": { + "optional": true } } }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" - }, - "spdy": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.1.tgz", - "integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==", + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "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" - }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "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==", - "dev": true, - "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" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "requires": { - "extend-shallow": "^3.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" } }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "stdout-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", - "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", - "requires": { - "readable-stream": "^2.0.1" - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "string.prototype.trimleft": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", - "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string.prototype.trimright": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", - "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "requires": { - "get-stdin": "^4.0.1" - } - }, - "style-loader": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.1.3.tgz", - "integrity": "sha512-rlkH7X/22yuwFYK357fMN/BxYOorfnfq0eD7+vqlemSK4wEcejFF1dg4zxP0euBW8NrYx2WZzZ8PPFevr7D+Kw==", - "requires": { - "loader-utils": "^1.2.3", - "schema-utils": "^2.6.4" - }, "dependencies": { - "schema-utils": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", - "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", - "requires": { - "ajv": "^6.12.0", - "ajv-keywords": "^3.4.1" - } - } - } - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "svg-inline-loader": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/svg-inline-loader/-/svg-inline-loader-0.8.2.tgz", - "integrity": "sha512-kbrcEh5n5JkypaSC152eGfGcnT4lkR0eSfvefaUJkLqgGjRQJyKDvvEE/CCv5aTSdfXuc+N98w16iAojhShI3g==", - "requires": { - "loader-utils": "^1.1.0", - "object-assign": "^4.0.1", - "simple-html-tokenizer": "^0.1.1" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" - }, - "tar": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", - "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", - "requires": { - "block-stream": "*", - "fstream": "^1.0.12", - "inherits": "2" - } - }, - "tcomb": { - "version": "3.2.29", - "resolved": "https://registry.npmjs.org/tcomb/-/tcomb-3.2.29.tgz", - "integrity": "sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ==" - }, - "terser": { - "version": "4.6.6", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.6.tgz", - "integrity": "sha512-4lYPyeNmstjIIESr/ysHg2vUPRGf2tzF9z2yYwnowXVuVzLEamPN1Gfrz7f8I9uEPuHcbFlW4PLIAsJoxXyJ1g==", - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", - "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^2.1.2", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" + "engines": { + "node": ">= 10.13.0" }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "requires": { - "setimmediate": "^1.0.4" + "node_modules/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==", + "peer": true, + "engines": { + "node": ">=4" } }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "requires": { - "kind-of": "^3.0.2" - }, + "node_modules/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==", + "dev": true, "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" - }, - "true-case-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", - "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", - "requires": { - "glob": "^7.1.2" - } - }, - "tslib": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", - "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==" - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" } }, - "turbolinks": { + "node_modules/turbolinks": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/turbolinks/-/turbolinks-5.2.0.tgz", "integrity": "sha512-pMiez3tyBo6uRHFNNZoYMmrES/IaGgMhQQM+VFF36keryjb5ms0XkVpmKHkfW/4Vy96qiGW3K9bz0tF5sK9bBw==" }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - } - } + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, + ], "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - } + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "requires": { - "inherits": "2.0.3" - }, "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - } + "punycode": "^2.1.0" } }, - "util-deprecate": { + "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "v8-compile-cache": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", - "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==" - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" } }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" - }, - "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", - "requires": { - "chokidar": "^2.0.2", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "node_modules/webpack": { + "version": "5.90.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", + "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", "dev": true, - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "webpack": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.0.tgz", - "integrity": "sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w==", - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/wasm-edit": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "acorn": "^6.2.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.1", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.6.0", - "webpack-sources": "^1.4.1" - } - }, - "webpack-cli": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.11.tgz", - "integrity": "sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g==", - "requires": { - "chalk": "2.4.2", - "cross-spawn": "6.0.5", - "enhanced-resolve": "4.1.0", - "findup-sync": "3.0.0", - "global-modules": "2.0.0", - "import-local": "2.0.0", - "interpret": "1.2.0", - "loader-utils": "1.2.3", - "supports-color": "6.1.0", - "v8-compile-cache": "2.0.3", - "yargs": "13.2.4" - } - }, - "webpack-dev-middleware": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", - "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", - "dev": true, - "requires": { - "memory-fs": "^0.4.1", - "mime": "^2.4.4", - "mkdirp": "^0.5.1", - "range-parser": "^1.2.1", - "webpack-log": "^2.0.0" - }, "dependencies": { - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", - "dev": true + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "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.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true } } }, - "webpack-dev-server": { - "version": "3.10.3", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.10.3.tgz", - "integrity": "sha512-e4nWev8YzEVNdOMcNzNeCN947sWJNd43E5XvsJzbAL08kGc2frm1tQ32hTJslRS+H65LCb/AaUCYU7fjHCpDeQ==", + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, - "requires": { - "ansi-html": "0.0.7", - "bonjour": "^3.5.0", - "chokidar": "^2.1.8", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "debug": "^4.1.1", - "del": "^4.1.1", - "express": "^4.17.1", - "html-entities": "^1.2.1", - "http-proxy-middleware": "0.19.1", - "import-local": "^2.0.0", - "internal-ip": "^4.3.0", - "ip": "^1.1.5", - "is-absolute-url": "^3.0.3", - "killable": "^1.0.1", - "loglevel": "^1.6.6", - "opn": "^5.5.0", - "p-retry": "^3.0.1", - "portfinder": "^1.0.25", - "schema-utils": "^1.0.0", - "selfsigned": "^1.10.7", - "semver": "^6.3.0", - "serve-index": "^1.9.1", - "sockjs": "0.3.19", - "sockjs-client": "1.4.0", - "spdy": "^4.0.1", - "strip-ansi": "^3.0.1", - "supports-color": "^6.1.0", - "url": "^0.11.0", - "webpack-dev-middleware": "^3.7.2", - "webpack-log": "^2.0.0", - "ws": "^6.2.1", - "yargs": "12.0.5" - }, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true }, - "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } + "webpack-bundle-analyzer": { + "optional": true }, - "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "webpack-dev-server": { + "optional": true } } }, - "webpack-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", - "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "dev": true, - "requires": { - "ansi-colors": "^3.0.0", - "uuid": "^3.3.2" + "engines": { + "node": ">=14" } }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dev": true, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" } }, - "websocket-driver": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", - "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true, - "requires": { - "http-parser-js": ">=0.4.0 <0.4.11", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" + "engines": { + "node": ">=10.13.0" } }, - "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", - "dev": true - }, - "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" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "requires": { - "errno": "~0.1.7" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" } }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, - "requires": { - "async-limiter": "~1.0.0" + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true }, - "yallist": { + "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "yargs": { - "version": "13.2.4", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", - "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.0" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "peer": true } } } diff --git a/package.json b/package.json index a405b80..72b34f2 100644 --- a/package.json +++ b/package.json @@ -1,33 +1,21 @@ { "dependencies": { - "@gentoo/tyrian": "git+https://anongit.gentoo.org/git/sites/tyrian-theme.git", - "autoprefixer": "^9.7.4", - "bootstrap": "4.3.1", - "coffeescript": "^2.5.0", - "core-js": "^3.6.4", - "css-loader": "^3.4.2", - "d3": "^3.5.6", - "exports-loader": "^0.7.0", - "expose-loader": "^0.7.5", - "file-loader": "^5.1.0", - "jquery": "^3.4.1", - "jquery-ujs": "^1.2.2", - "node-sass": "^4.13.1", - "popper.js": "^1.16.0", - "postcss-flexbugs-fixes": "^4.2.0", - "postcss-import": "^12.0.1", - "postcss-loader": "^3.0.0", - "precss": "^4.0.0", - "regenerator-runtime": "^0.13.5", - "resolve-url-loader": "^3.1.1", - "sass-loader": "^8.0.2", - "style-loader": "^1.1.3", - "svg-inline-loader": "^0.8.2", - "turbolinks": "^5.2.0", - "webpack": "^4.42.0", - "webpack-cli": "^3.3.11" + "@gentoo/tyrian": "git+https://anongit.gentoo.org/git/sites/tyrian-theme.git#v2.0.2", + "core-js": "^3.36.0", + "d3": "3.5.17", + "jquery": "^3.6.4", + "jquery-typeahead": "^2.11.1", + "jquery-ujs": "^1.2.3", + "regenerator-runtime": "^0.14.1", + "turbolinks": "^5.2.0" }, "devDependencies": { - "webpack-dev-server": "^3.10.1" + "css-loader": "^6.10.0", + "mini-css-extract-plugin": "^2.8.0", + "resolve-url-loader": "^5.0.0", + "sass": "^1.71.1", + "sass-loader": "^14.1.1", + "webpack": "^5.90.3", + "webpack-cli": "^5.1.4" } } diff --git a/pkg/api/graphql/generated/generated.go b/pkg/api/graphql/generated/generated.go index 36b27a9..b7b9b89 100644 --- a/pkg/api/graphql/generated/generated.go +++ b/pkg/api/graphql/generated/generated.go @@ -9456,7 +9456,7 @@ func (ec *executionContext) _Application(ctx context.Context, sel ast.SelectionS panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -9508,7 +9508,7 @@ func (ec *executionContext) _Bug(ctx context.Context, sel ast.SelectionSet, obj panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -9545,7 +9545,7 @@ func (ec *executionContext) _Category(ctx context.Context, sel ast.SelectionSet, panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -9577,7 +9577,7 @@ func (ec *executionContext) _ChangedFile(ctx context.Context, sel ast.SelectionS panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -9614,7 +9614,7 @@ func (ec *executionContext) _ChangedFiles(ctx context.Context, sel ast.Selection panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -9701,7 +9701,7 @@ func (ec *executionContext) _Commit(ctx context.Context, sel ast.SelectionSet, o panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -9738,7 +9738,7 @@ func (ec *executionContext) _GitHubPullRequestFileNode(ctx context.Context, sel panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -9770,7 +9770,7 @@ func (ec *executionContext) _GitHubPullRequestLabelNode(ctx context.Context, sel panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -9852,7 +9852,7 @@ func (ec *executionContext) _GithubPullRequest(ctx context.Context, sel ast.Sele panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -9924,7 +9924,7 @@ func (ec *executionContext) _KeywordChange(ctx context.Context, sel ast.Selectio panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -9966,7 +9966,7 @@ func (ec *executionContext) _Maintainer(ctx context.Context, sel ast.SelectionSe panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -10013,7 +10013,7 @@ func (ec *executionContext) _Mask(ctx context.Context, sel ast.SelectionSet, obj panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -10050,7 +10050,7 @@ func (ec *executionContext) _OutdatedPackage(ctx context.Context, sel ast.Select panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -10137,7 +10137,7 @@ func (ec *executionContext) _Package(ctx context.Context, sel ast.SelectionSet, panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -10194,7 +10194,7 @@ func (ec *executionContext) _PkgCheckResult(ctx context.Context, sel ast.Selecti panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -10218,7 +10218,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out.Values[i] = graphql.MarshalString("Query") case "category": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10229,7 +10229,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "categories": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10240,7 +10240,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "commit": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10251,7 +10251,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "commits": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10262,7 +10262,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "mask": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10273,7 +10273,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "masks": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10284,7 +10284,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "outdatedPackage": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10295,7 +10295,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "outdatedPackages": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10306,7 +10306,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "pkgCheckResult": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10317,7 +10317,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "pkgCheckResults": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10328,7 +10328,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "package": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10339,7 +10339,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "packages": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10350,7 +10350,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "packageSearch": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10361,7 +10361,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "useflag": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10372,7 +10372,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "useflags": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10383,7 +10383,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "version": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10394,7 +10394,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "versions": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10405,7 +10405,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "application": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10416,7 +10416,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "lastCommitTime": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10427,7 +10427,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "addedPackages": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10438,7 +10438,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "updatedVersions": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10449,7 +10449,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "stabilizedVersions": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10460,7 +10460,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }) case "keywordedVersions": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + out.Concurrently(i, func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -10477,7 +10477,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -10526,7 +10526,7 @@ func (ec *executionContext) _ReverseDependency(ctx context.Context, sel ast.Sele panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -10578,7 +10578,7 @@ func (ec *executionContext) _Useflag(ctx context.Context, sel ast.SelectionSet, panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -10695,7 +10695,7 @@ func (ec *executionContext) _Version(ctx context.Context, sel ast.SelectionSet, panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -10734,7 +10734,7 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -10770,7 +10770,7 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -10816,7 +10816,7 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -10852,7 +10852,7 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -10893,7 +10893,7 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } @@ -10936,7 +10936,7 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o panic("unknown field " + strconv.Quote(field.Name)) } } - out.Dispatch() + out.Dispatch(ctx) if invalids > 0 { return graphql.Null } diff --git a/pkg/api/graphql/graphiql/graphiql.go b/pkg/api/graphql/graphiql/graphiql.go deleted file mode 100644 index afc58df..0000000 --- a/pkg/api/graphql/graphiql/graphiql.go +++ /dev/null @@ -1,17 +0,0 @@ -package graphiql - -import ( - "html/template" - "net/http" - "soko/pkg/config" -) - -func Show(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Content-Type", "text/html") - - templates := template.Must( - template.New("graphiql"). - ParseGlob("web/templates/api/explore/*.tmpl")) - - templates.ExecuteTemplate(w, "graphiql.tmpl", template.URL(config.GraphiqlEndpoint())) -} diff --git a/pkg/api/graphql/graphiql/graphiql.templ b/pkg/api/graphql/graphiql/graphiql.templ new file mode 100644 index 0000000..c392a54 --- /dev/null +++ b/pkg/api/graphql/graphiql/graphiql.templ @@ -0,0 +1,33 @@ +package graphiql + +import "net/http" +import "soko/pkg/config" + +templ show() { + <!DOCTYPE html> + <html lang="en"> + <head> + <title>GraphiQL - Gentoo Packages</title> + <meta charset="utf-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + <meta name="theme-color" content="#54487a"/> + <meta name="description" content="Gentoo Packages GraphiQL GraphQL API Explorer"/> + <link rel="icon" href="https://packages.gentoo.org/favicon.ico" type="image/x-icon"/> + <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> + <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> + <link rel="stylesheet" href="https://unpkg.com/graphiql/graphiql.min.css"/> + </head> + <body> + <div id="graphiql"> + Loading... + </div> + <script src="https://unpkg.com/graphiql@0.17.5/graphiql.min.js" type="application/javascript"></script> + @templ.Raw(`<script>window.graphqlEndpoint = '` + config.GraphiqlEndpoint() + `';</script>`) + <script src="/assets/graphiql.js" type="application/javascript"></script> + </body> + </html> +} + +func Show(w http.ResponseWriter, r *http.Request) { + show().Render(r.Context(), w) +} diff --git a/pkg/api/graphql/resolvers/resolver.go b/pkg/api/graphql/resolvers/resolver.go index 2712cf1..d1a7b6f 100644 --- a/pkg/api/graphql/resolvers/resolver.go +++ b/pkg/api/graphql/resolvers/resolver.go @@ -5,7 +5,6 @@ package resolvers import ( "context" "errors" - "github.com/go-pg/pg/v9/orm" "soko/pkg/api/graphql/generated" "soko/pkg/app/handler/packages" "soko/pkg/app/utils" @@ -13,6 +12,8 @@ import ( "soko/pkg/models" "strings" "time" + + "github.com/go-pg/pg/v10" ) type Resolver struct{} @@ -26,7 +27,7 @@ func (r *queryResolver) Application(ctx context.Context) (*models.Application, e func (r *queryResolver) LastCommitTime(ctx context.Context) (*time.Time, error) { data := utils.GetApplicationData() lastCommit := &models.Commit{Id: data.LastCommit} - err := database.DBCon.Select(lastCommit) + err := database.DBCon.Model(lastCommit).WherePK().Select() if err != nil { return nil, err } @@ -218,17 +219,15 @@ func (r *queryResolver) PackageSearch(ctx context.Context, searchTerm *string, r WhereOr("atom LIKE ? ", wildcardSearchTerm). WhereOr("name LIKE ? ", wildcardSearchTerm). Relation("PkgCheckResults").Relation("Bugs").Relation("PullRequests").Relation("ReverseDependencies").Relation("Commits").Relation("Versions").Relation("Versions.Masks").Relation("Versions.PkgCheckResults").Relation("Versions.Dependencies").Relation("PkgCheckResults").Relation("Outdated"). - OrderExpr("name <-> '" + *searchTerm + "'"). + OrderExpr("name <-> ?", searchTerm). Limit(limit). Select() } else { // if the query contains no wildcards do a fuzzy search - searchQuery := packages.BuildSearchQuery(*searchTerm) - err = database.DBCon.Model(&gpackages). - Where(searchQuery). - WhereOr("atom LIKE ? ", ("%" + *searchTerm + "%")). + err = packages.BuildSearchQuery(database.DBCon.Model(&gpackages), *searchTerm). + WhereOr("atom LIKE ? ", "%"+*searchTerm+"%"). Relation("PkgCheckResults").Relation("Bugs").Relation("PullRequests").Relation("ReverseDependencies").Relation("Commits").Relation("Versions").Relation("Versions.Masks").Relation("Versions.PkgCheckResults").Relation("Versions.Dependencies").Relation("PkgCheckResults").Relation("Outdated"). - OrderExpr("name <-> '" + *searchTerm + "'"). + OrderExpr("name <-> ?", searchTerm). Limit(limit). Select() } @@ -339,7 +338,7 @@ func getLimit(limit *int, defaultLimit int) int { return n } -func addStringParams(query *orm.Query, params map[string]*string) *orm.Query { +func addStringParams(query *pg.Query, params map[string]*string) *pg.Query { for key, value := range params { if value != nil { query = query.Where(key+" = ? ", *value) @@ -348,7 +347,7 @@ func addStringParams(query *orm.Query, params map[string]*string) *orm.Query { return query } -func addIntParams(query *orm.Query, params map[string]*int) *orm.Query { +func addIntParams(query *pg.Query, params map[string]*int) *pg.Query { for key, value := range params { if value != nil { query = query.Where(key+" = ? ", *value) @@ -357,7 +356,7 @@ func addIntParams(query *orm.Query, params map[string]*int) *orm.Query { return query } -func addTimeParams(query *orm.Query, params map[string]*time.Time) *orm.Query { +func addTimeParams(query *pg.Query, params map[string]*time.Time) *pg.Query { for key, value := range params { if value != nil { query = query.Where(key+" = ? ", *value) diff --git a/pkg/app/handler/about/feedback.go b/pkg/app/handler/about/feedback.go deleted file mode 100644 index 24889d5..0000000 --- a/pkg/app/handler/about/feedback.go +++ /dev/null @@ -1,8 +0,0 @@ -package about - -import "net/http" - -// Feedback shows the feedback about page -func Feedback(w http.ResponseWriter, r *http.Request) { - renderAboutTemplate(w, r, "feedback") -} diff --git a/pkg/app/handler/about/feedback.templ b/pkg/app/handler/about/feedback.templ new file mode 100644 index 0000000..edd20a2 --- /dev/null +++ b/pkg/app/handler/about/feedback.templ @@ -0,0 +1,80 @@ +package about + +import "net/http" +import "soko/pkg/app/layout" + +templ feedback() { + <div class="container mb-5"> + <div class="row"> + <div class="col-12"> + <ol class="breadcrumb"> + <li class="breadcrumb-item"><a href="/">Home</a></li> + <li class="breadcrumb-item"><a href="/about">About</a></li> + <li class="breadcrumb-item active">Feedback</li> + </ol> + <h1>Feedback</h1> + <p class="lead"> + Thanks for checking out the new packages.gentoo.org! + </p> + <p> + This site is currently in an <abbr title="minimum viable product">MVP</abbr> state and will be extended further to provide more useful features. + To help us prioritize new features and learn about your use case for the site, please share your ideas below. + <br/> + <br/> + </p> + <div class="row"> + <div class="col-md-8"> + <div class="card"> + <h4 class="card-header"> + Send Feedback + </h4> + <div class="card-body"> + <form class="form-horizontal" method="post" action="/about/feedback"> + <div class="form-group row"> + <label for="feedback" class="col-sm-2 col-form-label font-weight-bold text-right">Your Feedback:</label> + <div class="col-sm-10"> + <textarea name="feedback" id="feedback" class="form-control" rows="10" placeholder="Please be sure to explain issues in detail and with exact URL references."></textarea> + </div> + </div> + <div class="form-group row"> + <label for="contact" class="col-sm-2 col-form-label font-weight-bold text-right">Contact (optional):</label> + <div class="col-sm-10"> + <input type="text" name="contact" class="form-control" id="contact" placeholder="How can we reach you to follow up on your feedback?"/> + </div> + </div> + <div class="form-group row"> + <div class="offset-sm-2 col-sm-10"> + <button type="submit" class="btn btn-outline-primary">Send</button> + </div> + </div> + </form> + </div> + </div> + </div> + <div class="col-md-4"> + <div class="card"> + <h4 class="card-header"> + Other ways to get in touch + </h4> + <div class="list-group"> + <a href="mailto:gpackages@gentoo.org" class="list-group-item list-group-item-action text-dark"> + <span class="fa fa-fw fa-envelope"></span> + E-Mail: gpackages@gentoo.org + </a> + <a href="irc://irc.gentoo.org/gentoo-www" class="list-group-item list-group-item-action text-dark"> + <span class="fa fa-fw fa-comments-o"></span> + IRC: #gentoo-www + </a> + </div> + </div> + </div> + </div> + </div> + </div> + </div> +} + +// Feedback shows the feedback about page +func Feedback(w http.ResponseWriter, r *http.Request) { + layout.Layout("About", "about", feedback()).Render(r.Context(), w) +} diff --git a/pkg/app/handler/about/feeds.go b/pkg/app/handler/about/feeds.go deleted file mode 100644 index 3268d76..0000000 --- a/pkg/app/handler/about/feeds.go +++ /dev/null @@ -1,8 +0,0 @@ -package about - -import "net/http" - -// Feeds shows the feeds about page -func Feeds(w http.ResponseWriter, r *http.Request) { - renderAboutTemplate(w, r, "feeds") -} diff --git a/pkg/app/handler/about/feeds.templ b/pkg/app/handler/about/feeds.templ new file mode 100644 index 0000000..3b66538 --- /dev/null +++ b/pkg/app/handler/about/feeds.templ @@ -0,0 +1,38 @@ +package about + +import "net/http" +import "soko/pkg/app/layout" + +templ feeds() { + <div class="container mb-5"> + <div class="row"> + <div class="col-12"> + <ol class="breadcrumb"> + <li class="breadcrumb-item"><a href="/">Home</a></li> + <li class="breadcrumb-item"><a href="/about">About</a></li> + <li class="breadcrumb-item active">Update Feeds</li> + </ol> + <h1>Update Feeds</h1> + <p> + You can find Atom feeds here: + </p> + <ul> + <li> + For all packages: Right column on the <a href="/categories">category listing</a>. + </li> + <li> + For specific architectures: In the <a href="/arches">architectures section</a>. + </li> + <li> + For specific packages: In the <em>Resources</em> box on the respective package pages. + </li> + </ul> + </div> + </div> + </div> +} + +// Feeds shows the feeds about page +func Feeds(w http.ResponseWriter, r *http.Request) { + layout.Layout("About", "about", feeds()).Render(r.Context(), w) +} diff --git a/pkg/app/handler/about/help.go b/pkg/app/handler/about/help.go deleted file mode 100644 index d697146..0000000 --- a/pkg/app/handler/about/help.go +++ /dev/null @@ -1,8 +0,0 @@ -package about - -import "net/http" - -// Help shows the help about page -func Help(w http.ResponseWriter, r *http.Request) { - renderAboutTemplate(w, r, "help") -} diff --git a/pkg/app/handler/about/help.templ b/pkg/app/handler/about/help.templ new file mode 100644 index 0000000..4487600 --- /dev/null +++ b/pkg/app/handler/about/help.templ @@ -0,0 +1,42 @@ +package about + +import "net/http" +import "soko/pkg/app/layout" + +templ help() { + <div class="container mb-5"> + <div class="row"> + <div class="col-12"> + <ol class="breadcrumb"> + <li class="breadcrumb-item"><a href="/">Home</a></li> + <li class="breadcrumb-item"><a href="/about">About</a></li> + <li class="breadcrumb-item active">Help</li> + </ol> + <h1>Help</h1> + <h2 id="keyword-legend">Keyword table legend</h2> + <ul class="list-group kk-keyword-legend"> + <li class="list-group-item kk-keyword-stable"> + <svg height="16" class="octicon octicon-diff-added" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM6 9H3V7h3V4h2v3h3v2H8v3H6V9z"></path></svg> Stable + </li> + <li class="list-group-item kk-keyword-testing"> + <svg height="16" class="octicon octicon-diff-modified" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM4 8c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3-3-1.34-3-3z"></path></svg> Testing + </li> + <li class="list-group-item kk-keyword-unavailable"> + <svg height="16" class="octicon octicon-diff-removed" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-2-5H3V7h8v2z"></path></svg> Explicitly unavailable + </li> + <li class="list-group-item kk-keyword-masked"> + <svg height="16" class="octicon octicon-diff-ignored" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-8.5-2H3v-1.5L9.5 4H11v1.5L4.5 12z"></path></svg> Masked + </li> + <li class="list-group-item kk-keyword-unknown"> + <span class="kk-octicon-spacer"></span> Unknown + </li> + </ul> + </div> + </div> + </div> +} + +// Help shows the help about page +func Help(w http.ResponseWriter, r *http.Request) { + layout.Layout("About", "about", help()).Render(r.Context(), w) +} diff --git a/pkg/app/handler/about/index.go b/pkg/app/handler/about/index.go deleted file mode 100644 index d2b1bdf..0000000 --- a/pkg/app/handler/about/index.go +++ /dev/null @@ -1,10 +0,0 @@ -package about - -import ( - "net/http" -) - -// Index shows the landing page of the about pages -func Index(w http.ResponseWriter, r *http.Request) { - renderAboutTemplate(w, r, "index") -} diff --git a/pkg/app/handler/about/index.templ b/pkg/app/handler/about/index.templ new file mode 100644 index 0000000..033b09a --- /dev/null +++ b/pkg/app/handler/about/index.templ @@ -0,0 +1,59 @@ +package about + +import "net/http" +import "runtime/debug" +import "soko/pkg/app/layout" +import "soko/pkg/config" + +func getCommitId() string { + if info, ok := debug.ReadBuildInfo(); ok { + for _, setting := range info.Settings { + if setting.Key == "vcs.revision" { + return setting.Value[:8] + } + } + } + return "" +} + +func versionText() string { + commitId := getCommitId() + version := config.Version() + if commitId == "" { + return "Currently " + version + " is running." + } + return "Currently " + version + " is running, based on commit " + commitId + "." +} + +templ index() { + <div class="container mb-5"> + <div class="row"> + <div class="col-12 text-center"> + <h1 class="px-3 pt-5 pb-1" style="font-size: 3em;">About packages.gentoo.org</h1> + <span style="font-size: 90%;" class="text-muted"> + Feel free to <a href="/about/feedback">get in touch</a> { "if" } you have any questions that are not answered on this page. + <br/> + And welcome to the new packages.gentoo.org! + </span> + </div> + <div class="col-12 mt-5 pt-4"> + <h2>FAQ</h2> + <dl> + <dt>Which version is currently running?</dt> + <dd>{ versionText() }</dd> + <br/> + <dt>How often is the site updated?</dt> + <dd> + Updates are scheduled <strong>every 5 minutes now</strong>. + You can find the last time an import task was started in the footer. + </dd> + </dl> + </div> + </div> + </div> +} + +// Index shows the landing page of the about pages +func Index(w http.ResponseWriter, r *http.Request) { + layout.Layout("About", "about", index()).Render(r.Context(), w) +} diff --git a/pkg/app/handler/about/status.go b/pkg/app/handler/about/status.go deleted file mode 100644 index 611520d..0000000 --- a/pkg/app/handler/about/status.go +++ /dev/null @@ -1,35 +0,0 @@ -package about - -import ( - "html/template" - "net/http" - "soko/pkg/app/utils" - "soko/pkg/database" - "soko/pkg/models" - "time" -) - -// Index shows the landing page of the about pages -func Status(w http.ResponseWriter, r *http.Request) { - templates := template.Must( - template.Must( - template.New("status"). - Funcs(template.FuncMap{ - "timeSince": time.Since, - }). - ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/about/status.tmpl")) - - var applicationData []*models.Application - database.DBCon.Model(&applicationData).Select() - - templates.ExecuteTemplate(w, "status.tmpl", struct { - Header models.Header - Application models.Application - Applications []*models.Application - }{ - Header: models.Header{Title: "About – ", Tab: "about"}, - Application: utils.GetApplicationData(), - Applications: applicationData, - }) -} diff --git a/pkg/app/handler/about/status.templ b/pkg/app/handler/about/status.templ new file mode 100644 index 0000000..3c9193b --- /dev/null +++ b/pkg/app/handler/about/status.templ @@ -0,0 +1,49 @@ +package about + +import "net/http" +import "soko/pkg/app/layout" +import "soko/pkg/database" +import "soko/pkg/models" +import "time" + +templ status(applications []*models.Application) { + <div class="container mb-5"> + <div class="row"> + <div class="col-12 text-center"> + <h1 class="px-3 pt-5 pb-1" style="font-size: 3em;">About packages.gentoo.org</h1> + <span style="font-size: 90%;" class="text-muted"> + Feel free to <a href="/about/feedback">get in touch</a> { "if" } you have any questions that are not answered on this page. + <br/> + And welcome to the new packages.gentoo.org! + </span> + </div> + <div class="col-8 offset-md-2 mt-5 pt-4"> + <table class="table"> + <thead> + <tr> + <th scope="col">Type</th> + <th scope="col">Last Update</th> + <th scope="col">Age</th> + </tr> + </thead> + <tbody> + for _, app := range applications { + <tr> + <th scope="row" class="text-capitalize">{ app.Id }</th> + <td>{ app.LastUpdate.Format(time.DateTime) } UTC</td> + <td>{ time.Since(app.LastUpdate).Round(time.Second).String() }</td> + </tr> + } + </tbody> + </table> + </div> + </div> + </div> +} + +// Status shows the sync status of updater +func Status(w http.ResponseWriter, r *http.Request) { + var applicationData []*models.Application + database.DBCon.Model(&applicationData).Order("id").Column("id", "last_update").Select() + layout.Layout("About", "about", status(applicationData)).Render(r.Context(), w) +} diff --git a/pkg/app/handler/about/utils.go b/pkg/app/handler/about/utils.go deleted file mode 100644 index e7d692b..0000000 --- a/pkg/app/handler/about/utils.go +++ /dev/null @@ -1,33 +0,0 @@ -// miscellaneous utility functions used for the about pages - -package about - -import ( - "html/template" - "net/http" - "soko/pkg/app/utils" - "soko/pkg/models" -) - -// renderAboutTemplate renders a specific about template -func renderAboutTemplate(w http.ResponseWriter, r *http.Request, page string) { - templates := template.Must( - template.Must( - template.New(page). - ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/about/" + page + ".tmpl")) - - templates.ExecuteTemplate(w, page+".tmpl", getPageData()) -} - -// getPageData returns the data used -// in all about templates -func getPageData() interface{} { - return struct { - Header models.Header - Application models.Application - }{ - Header: models.Header{Title: "About – ", Tab: "about"}, - Application: utils.GetApplicationData(), - } -} diff --git a/pkg/app/handler/arches/changedVersions.templ b/pkg/app/handler/arches/changedVersions.templ new file mode 100644 index 0000000..fb65fc3 --- /dev/null +++ b/pkg/app/handler/arches/changedVersions.templ @@ -0,0 +1,49 @@ +package arches + +import "net/http" +import "soko/pkg/app/layout" +import "soko/pkg/app/utils" +import "soko/pkg/models" + +templ changedVersions(currentArch string, feedName string, versions []*models.Version) { + <div class="container mb-5"> + <div class="row"> + <div class="col-11"> + if feedName == "keyworded" { + <h3> + <a class="text-dark"><i class="fa fa-circle-o" aria-hidden="true"></i> Keyworded Packages</a> + <a href={ templ.URL("/arches/" + currentArch + "/stable") } class="ml-3 text-muted"><i class="fa fa-check-circle-o" aria-hidden="true"></i> Newly Stable Packages</a> + </h3> + } else { + <h3> + <a href={ templ.URL("/arches/" + currentArch + "/keyworded") } class="text-muted"><i class="fa fa-circle-o" aria-hidden="true"></i> Keyworded Packages</a> + <a class="ml-3 text-dark"><i class="fa fa-check-circle-o" aria-hidden="true"></i> Newly Stable Packages</a> + </h3> + } + </div> + <div class="col-1 text-right"> + <h3> + <a title="Atom feed" href={ templ.URL("/arches/" + currentArch + "/" + feedName + ".atom") } class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> + </h3> + </div> + <div class="col-12"> + <li class="list-group"> + @utils.ChangedVersionsTable(versions) + </li> + </div> + </div> + </div> +} + +var tabs []layout.SubTab + +func init() { + tabs = make([]layout.SubTab, len(models.AllArches)) + for i, arch := range models.AllArches { + tabs[i] = layout.SubTab{Name: arch, Link: templ.URL("/arches/" + arch + "/keyworded")} + } +} + +func renderPage(w http.ResponseWriter, r *http.Request, arch string, content templ.Component) { + layout.TabbedLayout("Architectures", "arches", "Architectures", "fa fa-fw fa-server", "", tabs, arch, content).Render(r.Context(), w) +} diff --git a/pkg/app/handler/arches/index.go b/pkg/app/handler/arches/index.go deleted file mode 100644 index 41e8178..0000000 --- a/pkg/app/handler/arches/index.go +++ /dev/null @@ -1,12 +0,0 @@ -package arches - -import ( - "net/http" - utils2 "soko/pkg/app/utils" -) - -// Index renders a template to show a the landing page containing links to all arches feeds -func Index(w http.ResponseWriter, r *http.Request) { - userPreferences := utils2.GetUserPreferences(r) - http.Redirect(w, r, "/arches/"+userPreferences.Arches.DefaultArch+"/"+userPreferences.Arches.DefaultPage, http.StatusSeeOther) -} diff --git a/pkg/app/handler/arches/show.go b/pkg/app/handler/arches/show.go index a8677b6..40fb048 100644 --- a/pkg/app/handler/arches/show.go +++ b/pkg/app/handler/arches/show.go @@ -3,48 +3,59 @@ package arches import ( "net/http" "soko/pkg/app/handler/feeds" - "soko/pkg/app/handler/packages" - "soko/pkg/app/utils" "strings" ) -// Show renders a template to show a list of recently changed version by arch -func Show(w http.ResponseWriter, r *http.Request) { - urlParts := strings.Split(r.URL.Path[len("/arches/"):], "/") - if len(urlParts) == 2 { - if urlParts[1] == "stable" { - stabilizedVersions, err := getStabilizedVersionsForArch(urlParts[0], 50) - if err != nil { - http.NotFound(w, r) - return - } - renderPackageTemplates("changedVersions", packages.GetFuncMap(), createFeedData(urlParts[0], "Newly Stable", "stable", stabilizedVersions, utils.GetUserPreferences(r)), w) - } else if urlParts[1] == "stable.atom" { - stabilizedVersions, err := getStabilizedVersionsForArch(urlParts[0], 250) - if err != nil { - http.NotFound(w, r) - return - } - feedTitle := "Stabilized packages in Gentoo on " + urlParts[0] - feedDescription := feedTitle - feeds.Changes(feedTitle, feedDescription, stabilizedVersions, w) - } else if urlParts[1] == "keyworded" { - keywordedVersions, err := getKeywordedVersionsForArch(urlParts[0], 50) - if err != nil { - http.NotFound(w, r) - return - } - renderPackageTemplates("changedVersions", packages.GetFuncMap(), createFeedData(urlParts[0], "Keyworded", "keyworded", keywordedVersions, utils.GetUserPreferences(r)), w) - } else if urlParts[1] == "keyworded.atom" { - keywordedVersions, err := getKeywordedVersionsForArch(urlParts[0], 250) - if err != nil { - http.NotFound(w, r) - return - } +func ShowStable(w http.ResponseWriter, r *http.Request) { + arch := r.PathValue("arch") + stabilizedVersions, err := getStabilizedVersionsForArch(arch, 50) + if err != nil { + http.NotFound(w, r) + return + } + renderPage(w, r, arch, changedVersions(arch, "stable", stabilizedVersions)) +} + +func ShowStableFeed(w http.ResponseWriter, r *http.Request) { + arch := r.PathValue("arch") + stabilizedVersions, err := getStabilizedVersionsForArch(arch, 250) + if err != nil { + http.NotFound(w, r) + return + } + feedTitle := "Stabilized packages in Gentoo on " + arch + feedDescription := feedTitle + feeds.Changes(feedTitle, feedDescription, stabilizedVersions, w) +} + +func ShowKeyworded(w http.ResponseWriter, r *http.Request) { + arch := r.PathValue("arch") + keywordedVersions, err := getKeywordedVersionsForArch(arch, 50) + if err != nil { + http.NotFound(w, r) + return + } + renderPage(w, r, arch, changedVersions(arch, "keyworded", keywordedVersions)) +} + +func ShowKeywordedFeed(w http.ResponseWriter, r *http.Request) { + arch := r.PathValue("arch") + keywordedVersions, err := getKeywordedVersionsForArch(arch, 250) + if err != nil { + http.NotFound(w, r) + return + } + feedTitle := "Keyworded packages in Gentoo on " + arch + feedDescription := feedTitle + feeds.Changes(feedTitle, feedDescription, keywordedVersions, w) +} - feedTitle := "Keyworded packages in Gentoo on " + urlParts[0] - feedDescription := feedTitle - feeds.Changes(feedTitle, feedDescription, keywordedVersions, w) - } +func ShowLeafPackages(w http.ResponseWriter, r *http.Request) { + arch := r.PathValue("arch") + leafs, err := getLeafPackagesForArch(arch) + if err != nil { + http.NotFound(w, r) + return } + w.Write([]byte(strings.Join(leafs, "\n"))) } diff --git a/pkg/app/handler/arches/utils.go b/pkg/app/handler/arches/utils.go index 3b5144d..8144a3d 100644 --- a/pkg/app/handler/arches/utils.go +++ b/pkg/app/handler/arches/utils.go @@ -3,111 +3,69 @@ package arches import ( - "html/template" - "net/http" - "soko/pkg/app/utils" "soko/pkg/database" "soko/pkg/models" ) -// getPageData creates the data used in all -// templates used in the arches section -func getPageData() interface{} { - return struct { - Header models.Header - Application models.Application - }{ - Header: models.Header{Title: "Architectures – ", Tab: "arches"}, - Application: utils.GetApplicationData(), - } -} - // getStabilizedVersionsForArch returns the given number of recently // stabilized versions of a specific arch func getStabilizedVersionsForArch(arch string, n int) ([]*models.Version, error) { - var stabilizedVersions []*models.Version var updates []models.KeywordChange err := database.DBCon.Model(&updates). Relation("Version"). Relation("Commit"). Order("commit.preceding_commits DESC"). Where("stabilized::jsonb @> ?", "\""+arch+"\""). + Where("version.id IS NOT NULL"). Limit(n). Select() if err != nil { return nil, err } - for _, update := range updates { - if update.Version != nil { - update.Version.Commits = []*models.Commit{update.Commit} - stabilizedVersions = append(stabilizedVersions, update.Version) - } + stabilizedVersions := make([]*models.Version, len(updates)) + for i, update := range updates { + update.Version.Commits = []*models.Commit{update.Commit} + stabilizedVersions[i] = update.Version } - return stabilizedVersions, err } // getKeywordedVersionsForArch returns the given number of recently // keyworded versions of a specific arch func getKeywordedVersionsForArch(arch string, n int) ([]*models.Version, error) { - var stabilizedVersions []*models.Version var updates []models.KeywordChange err := database.DBCon.Model(&updates). Relation("Version"). Relation("Commit"). Order("commit.preceding_commits DESC"). Where("added::jsonb @> ?", "\""+arch+"\""). + Where("version.id IS NOT NULL"). Limit(n). Select() if err != nil { return nil, err } - for _, update := range updates { - if update.Version != nil { - update.Version.Commits = []*models.Commit{update.Commit} - stabilizedVersions = append(stabilizedVersions, update.Version) - } + keywordedVersions := make([]*models.Version, len(updates)) + for i, update := range updates { + update.Version.Commits = []*models.Commit{update.Commit} + keywordedVersions[i] = update.Version } - - return stabilizedVersions, err + return keywordedVersions, err } -// RenderPackageTemplates renders the arches templates using the given data -func renderPackageTemplates(page string, funcMap template.FuncMap, data interface{}, w http.ResponseWriter) { - - templates := template.Must( - template.Must( - template.Must( - template.Must( - template.New(page). - Funcs(funcMap). - ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/arches/archesheader.tmpl")). - ParseGlob("web/templates/arches/changedVersionRows.tmpl")). - ParseGlob("web/templates/arches/changedVersions.tmpl")) - - templates.ExecuteTemplate(w, page+".tmpl", data) -} - -// CreateFeedData creates the data used in changedVersions template -func createFeedData(arch string, name string, feedtype string, versions []*models.Version, userPreferences models.UserPreferences) interface{} { - return struct { - Header models.Header - Arch string - Name string - FeedName string - Versions []*models.Version - Application models.Application - UserPreferences models.UserPreferences - }{ - Header: models.Header{Title: "Architectures – ", Tab: "arches"}, - Arch: arch, - Name: name, - FeedName: feedtype, - Versions: versions, - Application: utils.GetApplicationData(), - UserPreferences: userPreferences, - } +func getLeafPackagesForArch(arch string) ([]string, error) { + var atoms []string + atomsWithReverse := database.DBCon.Model((*models.ReverseDependency)(nil)). + Join("JOIN versions").JoinOn("reverse_dependency.reverse_dependency_atom = versions.atom"). + Where("keywords LIKE ?", "%"+arch+"%"). + ColumnExpr("DISTINCT reverse_dependency.atom") + err := database.DBCon.Model((*models.Version)(nil)). + Where("keywords LIKE ?", "%"+arch+"%"). + Where("atom NOT IN (?)", atomsWithReverse). + Order("atom"). + ColumnExpr("DISTINCT atom"). + Select(&atoms) + return atoms, err } diff --git a/pkg/app/handler/categories/feeds.go b/pkg/app/handler/categories/feeds.go new file mode 100644 index 0000000..0ccfdeb --- /dev/null +++ b/pkg/app/handler/categories/feeds.go @@ -0,0 +1,38 @@ +package categories + +import ( + "net/http" + "soko/pkg/app/utils" + "soko/pkg/database" + "soko/pkg/models" +) + +func OutdatedFeed(w http.ResponseWriter, r *http.Request) { + categoryName := r.PathValue("category") + var outdated []models.OutdatedPackages + err := database.DBCon.Model(&outdated). + Where("atom LIKE ?", categoryName+"/%"). + Order("atom"). + Select() + if err != nil { + http.NotFound(w, r) + return + } + utils.OutdatedFeed(w, "https://packages.gentoo.org/categories/"+categoryName+"/outdated", "category "+categoryName, outdated) +} + +func StabilizationFeed(w http.ResponseWriter, r *http.Request) { + categoryName := r.PathValue("category") + var results []*models.PkgCheckResult + err := database.DBCon.Model(&results). + Column("atom", "cpv", "message"). + Where("class = ?", "StableRequest"). + Where("atom LIKE ?", categoryName+"/%"). + OrderExpr("cpv"). + Select() + if err != nil { + http.NotFound(w, r) + return + } + utils.StabilizationFeed(w, "https://packages.gentoo.org/categories/"+categoryName+"/stabilization", "category "+categoryName, results) +} diff --git a/pkg/app/handler/categories/index.go b/pkg/app/handler/categories/index.go index 18b9f20..7214942 100644 --- a/pkg/app/handler/categories/index.go +++ b/pkg/app/handler/categories/index.go @@ -9,19 +9,6 @@ import ( "soko/pkg/models" ) -// Index renders a template to show all categories -func Index(w http.ResponseWriter, r *http.Request) { - - var categories []*models.Category - err := database.DBCon.Model(&categories).Order("name ASC").Select() - if err != nil { - http.NotFound(w, r) - return - } - - renderCategoryTemplate("index", createCategoriesData(categories), w) -} - // build the json for the categories overview page func JSONCategories(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/app/handler/categories/index.templ b/pkg/app/handler/categories/index.templ new file mode 100644 index 0000000..683e58d --- /dev/null +++ b/pkg/app/handler/categories/index.templ @@ -0,0 +1,51 @@ +package categories + +import "net/http" +import "soko/pkg/database" +import "soko/pkg/models" + +templ index(categories []*models.Category) { + <div class="container mb-5"> + <div class="row"> + <div class="col-12"> + <div class="row"> + <div class="col-md-12"> + <h3 class="d-none mb-2">Browse all Categories</h3> + <div class="card rounded" style="background: none;border: none;"> + <div class="card-body"> + <ul class="kk-col-list kk-6col-list kk-category-listing"> + for i, cat := range categories { + if i == 0 || cat.Name[0] != categories[i-1].Name[0] { + <li class="kk-col-list-header"><span class="kk-group-header">{ cat.Name[0:1] }</span></li> + } + <li> + <a + title={ cat.Description } + data-toggle="tooltip" + data-placement="right" + href={ templ.URL("/categories/" + cat.Name) } + > + { cat.Name } + </a> + </li> + } + </ul> + </div> + </div> + </div> + </div> + </div> + </div> + </div> +} + +// Index renders a template to show all categories +func Index(w http.ResponseWriter, r *http.Request) { + var categories []*models.Category + err := database.DBCon.Model(&categories).Order("name ASC").Select() + if err != nil { + http.NotFound(w, r) + return + } + RenderPage(w, r, "Categories", "Categories", index(categories)) +} diff --git a/pkg/app/handler/categories/show.go b/pkg/app/handler/categories/show.go index 381405b..5e9151b 100644 --- a/pkg/app/handler/categories/show.go +++ b/pkg/app/handler/categories/show.go @@ -4,93 +4,233 @@ package categories import ( "encoding/json" - "github.com/go-pg/pg/v9/orm" "net/http" + "strings" + + "github.com/go-pg/pg/v10" + + "soko/pkg/app/handler/packages/components" + "soko/pkg/app/utils" "soko/pkg/database" "soko/pkg/models" - "strings" ) -// Show renders a template to show a given category -func Show(w http.ResponseWriter, r *http.Request) { +func common(w http.ResponseWriter, r *http.Request) (categoryName string, category models.Category, err error) { + categoryName = r.PathValue("category") - if strings.HasSuffix(r.URL.Path, ".json") { - buildJson(w, r) + err = database.DBCon.Model(&category). + Where("category.name = ?", categoryName). + Relation("PackagesInformation").Select() + if err == pg.ErrNoRows { + http.NotFound(w, r) + return + } else if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } + return +} - category := new(models.Category) - err := database.DBCon.Model(category). - Where("name = ?", getCategoryName(r)). - Relation("Packages", func(q *orm.Query) (*orm.Query, error) { - return q.Order("name ASC"), nil - }). - Relation("Packages.Versions"). - Select() +type packageInfo struct { + Package string + Description string +} + +func ShowPackages(w http.ResponseWriter, r *http.Request) { + categoryName := r.PathValue("category") + if strings.HasSuffix(categoryName, ".json") { + buildJson(w, categoryName[:len(categoryName)-5]) + return + } + categoryName, category, err := common(w, r) if err != nil { - http.NotFound(w, r) return } - renderCategoryTemplate("show", createCategoryData(*category), w) + var packages []packageInfo + err = database.DBCon.Model((*models.Version)(nil)). + DistinctOn("package"). + Column("package", "description"). + Where("category = ?", categoryName). + Order("package ASC"). + Select(&packages) + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + renderShowPage(w, r, "Packages", &category, + showPackages(categoryName, packages)) } -// build the json for the category -func buildJson(w http.ResponseWriter, r *http.Request) { - - category := new(models.Category) - err := database.DBCon.Model(category). - Where("name = ?", getCategoryName(r)). - Relation("Packages"). - Relation("Packages.Versions"). - Select() +func ShowOutdated(w http.ResponseWriter, r *http.Request) { + categoryName, category, err := common(w, r) if err != nil { - http.NotFound(w, r) return } - categoryPackages := getJSONPackages(category) + var outdated []components.OutdatedItem + descriptionQuery := database.DBCon.Model((*models.Version)(nil)). + Column("description"). + Where("atom = outdated_packages.atom"). + Limit(1) + err = database.DBCon.Model((*models.OutdatedPackages)(nil)). + Column("atom").ColumnExpr("(?) AS description", descriptionQuery). + Where("atom LIKE ?", categoryName+"/%"). + Order("atom"). + Select(&outdated) + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + renderShowPage(w, r, "Outdated", &category, + components.Outdated(outdated)) +} - jsonCategory := Category{ - Name: category.Name, - Href: "https://packages.gentoo.org/categories/" + category.Name, - Packages: categoryPackages, +func ShowPullRequests(w http.ResponseWriter, r *http.Request) { + categoryName, category, err := common(w, r) + if err != nil { + return } - b, err := json.Marshal(jsonCategory) + var pullRequests []*models.GithubPullRequest + err = database.DBCon.Model(&pullRequests). + Join("JOIN package_to_github_pull_requests ON package_to_github_pull_requests.github_pull_request_id = github_pull_request.id"). + Where("package_to_github_pull_requests.package_atom LIKE ?", categoryName+"/%"). + Group("github_pull_request.id"). + Order("github_pull_request.created_at DESC"). + Select() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + renderShowPage(w, r, "Pull requests", &category, + components.PullRequests(pullRequests)) +} +func ShowBugs(w http.ResponseWriter, r *http.Request) { + categoryName, category, err := common(w, r) if err != nil { - http.Error(w, http.StatusText(http.StatusInternalServerError), - http.StatusInternalServerError) return } + var bugs []*models.Bug + err = database.DBCon.Model(&bugs). + DistinctOn("id::INT"). + Column("id", "summary", "component", "assignee"). + OrderExpr("id::INT"). + Where("id IN (?)", + database.DBCon.Model((*models.PackageToBug)(nil)). + Column("bug_id"). + Where("package_atom LIKE ?", categoryName+"/%")). + WhereOr("id IN (?)", + database.DBCon.Model((*models.VersionToBug)(nil)). + Column("bug_id"). + Join("JOIN versions").JoinOn("version_id = versions.id"). + Where("versions.atom LIKE ?", categoryName+"/%")). + Select() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + generalCount, stabilizationCount, keywordingCount := utils.CountBugsCategories(bugs) + renderShowPage(w, r, "Bugs", &category, + components.Bugs("", generalCount, stabilizationCount, keywordingCount, bugs)) +} - w.Header().Set("Content-Type", "application/json") - w.Write(b) +func ShowSecurity(w http.ResponseWriter, r *http.Request) { + categoryName, category, err := common(w, r) + if err != nil { + return + } + var bugs []*models.Bug + err = database.DBCon.Model(&bugs). + DistinctOn("id::INT"). + Column("id", "summary", "component", "assignee"). + OrderExpr("id::INT"). + Where("component = ?", "Vulnerabilities"). + Where("id IN (?)", + database.DBCon.Model((*models.PackageToBug)(nil)). + Column("bug_id"). + Where("package_atom LIKE ?", categoryName+"/%")). + Select() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + renderShowPage(w, r, "Security", &category, + components.SecurityBugs("", bugs)) } -// get all maintainers of the package in a format -// that is intended to be used to convert it to json -func getJSONPackages(category *models.Category) []Package { - var categoryPackages []Package - for _, gpackage := range category.Packages { - categoryPackages = append(categoryPackages, Package{ - Name: gpackage.Name, - Href: gpackage.Versions[0].Homepage[0], - Description: gpackage.Versions[0].Description, - }) - } - return categoryPackages +func ShowStabilizations(w http.ResponseWriter, r *http.Request) { + categoryName, category, err := common(w, r) + if err != nil { + return + } + + var results []*models.PkgCheckResult + err = database.DBCon.Model(&results). + Column("atom", "cpv", "message"). + Where("class = ?", "StableRequest"). + Where("atom LIKE ?", categoryName+"/%"). + OrderExpr("cpv"). + Select() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + renderShowPage(w, r, "Stabilization", &category, + components.Stabilizations(results)) } -type Category struct { - Name string `json:"name"` - Href string `json:"href"` - Packages []Package `json:"packages"` +func ShowStabilizationFile(w http.ResponseWriter, r *http.Request) { + categoryName := r.PathValue("category") + var results []*models.PkgCheckResult + err := database.DBCon.Model(&results). + Column("category", "package", "version", "message"). + Where("class = ?", "StableRequest"). + Where("atom LIKE ?", categoryName+"/%"). + OrderExpr("cpv"). + Select() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + pageName := r.URL.Path[strings.LastIndexByte(r.URL.Path, '/')+1:] + utils.StabilizationExport(w, pageName, results) } -type Package struct { - Name string `json:"name"` - Href string `json:"href"` - Description string `json:"description"` +// build the json for the category +func buildJson(w http.ResponseWriter, categoryName string) { + var jsonCategory struct { + Name string `json:"name"` + Href string `json:"href"` + Packages []struct { + Package string `json:"name"` + Href string `json:"href"` + Description string `json:"description"` + } `json:"packages"` + } + + err := database.DBCon.Model((*models.Version)(nil)). + DistinctOn("package"). + Column("package", "description"). + ColumnExpr("homepage ->> 0 AS href"). + Where("category = ?", categoryName). + Order("package ASC"). + Select(&jsonCategory.Packages) + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + + jsonCategory.Name = categoryName + jsonCategory.Href = "https://packages.gentoo.org/categories/" + categoryName + + b, err := json.Marshal(jsonCategory) + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + w.Write(b) } diff --git a/pkg/app/handler/categories/show.templ b/pkg/app/handler/categories/show.templ new file mode 100644 index 0000000..cf80fb6 --- /dev/null +++ b/pkg/app/handler/categories/show.templ @@ -0,0 +1,112 @@ +package categories + +import "net/http" +import "strconv" +import "strings" +import "soko/pkg/app/layout" +import "soko/pkg/models" + +func packageLetter(name string) string { + return strings.ToLower(strings.TrimLeft(name, "_")[:1]) +} + +script filter() { + const value = document.querySelector("#filter").value.toLowerCase(); + const rows = document.querySelectorAll("#table tr"); + for (let i = 0; i < rows.length; i++) { + rows[i].style.display = rows[i].cells[0].innerText.toLowerCase().includes(value) ? "" : "none"; + } +} + +templ showPackages(categoryName string, packages []packageInfo) { + <div class="row"> + <div class="col-12"> + <div class="row"> + <div class="col-md-9"> + <p> + <input onKeyup={ filter() } id="filter" type="text" class="form-control form-control-xl" placeholder={ "Search packages in " + categoryName }/> + </p> + <div class="card border-top-0 rounded"> + <table class="table mb-0 rounded" id="table"> + for i, pkg := range packages { + <tr + if i == 0 || packageLetter(pkg.Package) != packageLetter(packages[i-1].Package) { + id={ packageLetter(pkg.Package) } + } + > + <th class="kk-nobreak-cell"><a href={ templ.URL("/packages/" + categoryName + "/" + pkg.Package) }>{ pkg.Package }</a></th> + <td>{ pkg.Description }</td> + </tr> + } + </table> + </div> + @filter() + </div> + <div class="col-md-3"> + <h4>Statistics</h4> + <dd class="ml-3"> + <dl>Packages: { strconv.Itoa(len(packages)) }</dl> + </dd> + <h4 class="mt-4">Filter by Category</h4> + <div class="row pl-4 pr-5 mr-5"> + for i, pkg := range packages { + if i == 0 || packageLetter(pkg.Package) != packageLetter(packages[i-1].Package) { + <div class="col-md-2 px-2"> + <a href={ templ.URL("#" + packageLetter(pkg.Package)) } class="text-muted text-capitalize"> + { packageLetter(pkg.Package) } + </a> + </div> + } + } + </div> + </div> + </div> + </div> + </div> +} + +templ show(component templ.Component) { + <div class="container mb-5 tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="overview-tab"> + @component + </div> +} + +func renderShowPage(w http.ResponseWriter, r *http.Request, currentTab string, category *models.Category, component templ.Component) { + layout.TabbedLayout(category.Name, "packages", category.Name, "fa fa-fw fa-cubes", category.Description, []layout.SubTab{ + { + Name: "Packages", + Link: templ.URL("/categories/" + category.Name), + Icon: "fa fa-list-ul mr-1", + }, + { + Name: "Stabilization", + Link: templ.URL("/categories/" + category.Name + "/stabilization"), + Icon: "fa fa-check-circle-o mr-1", + BadgeValue: strconv.Itoa(category.PackagesInformation.StableRequests), + }, + { + Name: "Outdated", + Link: templ.URL("/categories/" + category.Name + "/outdated"), + Icon: "fa fa-tag mr-1", + BadgeValue: strconv.Itoa(category.PackagesInformation.Outdated), + }, + { + Name: "Pull requests", + Link: templ.URL("/categories/" + category.Name + "/pull-requests"), + Icon: "octicon octicon-git-pull-request opticon-resource-icon ml-1", + BadgeValue: strconv.Itoa(category.PackagesInformation.PullRequests), + }, + { + Name: "Bugs", + Link: templ.URL("/categories/" + category.Name + "/bugs"), + Icon: "fa fa-bug", + BadgeValue: strconv.Itoa(category.PackagesInformation.Bugs), + }, + { + Name: "Security", + Link: templ.URL("/categories/" + category.Name + "/security"), + Icon: "fa fa-shield", + BadgeValue: strconv.Itoa(category.PackagesInformation.SecurityBugs), + }, + }, currentTab, show(component)).Render(r.Context(), w) +} diff --git a/pkg/app/handler/categories/utils.go b/pkg/app/handler/categories/utils.go index bb0c6ee..7c75819 100644 --- a/pkg/app/handler/categories/utils.go +++ b/pkg/app/handler/categories/utils.go @@ -1,63 +1,41 @@ -// miscellaneous utility functions used for categories - package categories import ( - "html/template" "net/http" - "soko/pkg/app/utils" - "soko/pkg/models" - "strings" -) - -// getCategoryName returns the name of the -// category based on the given URL -func getCategoryName(r *http.Request) string { - return strings.ReplaceAll(r.URL.Path[len("/categories/"):], ".json", "") -} + "soko/pkg/app/layout" -// createCategoriesData creates the data used in -// the template to display all categories -func createCategoriesData(categories []*models.Category) interface{} { - return struct { - Header models.Header - Name string - Categories []*models.Category - Application models.Application - }{ - Header: models.Header{Title: "Categories – ", Tab: "packages"}, - Name: "Categories", - Categories: categories, - Application: utils.GetApplicationData(), - } -} + "github.com/a-h/templ" +) -// createCategoriesData creates the data used in -// the template to display a specific category -func createCategoryData(category models.Category) interface{} { - return struct { - Header models.Header - Category models.Category - Application models.Application - }{ - Header: models.Header{Title: category.Name + " – ", Tab: "packages"}, - Category: category, - Application: utils.GetApplicationData(), - } +var categoriesViewTabs = []layout.SubTab{ + { + Name: "Categories", + Link: "/categories", + Icon: "fa fa-list-ul mr-1", + }, + { + Name: "Added", + Link: "/packages/added", + Icon: "fa fa-history mr-1", + }, + { + Name: "Updated", + Link: "/packages/updated", + Icon: "fa fa-asterisk mr-1", + }, + { + Name: "Newly Stable", + Link: "/packages/stable", + Icon: "fa fa-check-circle-o mr-1", + }, + { + Name: "Keyworded", + Link: "/packages/keyworded", + Icon: "fa fa-circle-o mr-1", + }, } -// renderIndexTemplate renders all templates used for the categories section -func renderCategoryTemplate(page string, data interface{}, w http.ResponseWriter) { - templates := template.Must( - template.Must( - template.New(page). - Funcs(template.FuncMap{ - "add": func(a, b int) int { - return a + b - }, - }). - ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/categories/*.tmpl")) - - templates.ExecuteTemplate(w, page+".tmpl", data) +func RenderPage(w http.ResponseWriter, r *http.Request, title string, currentTab string, content templ.Component) { + layout.TabbedLayout(title, "packages", "Packages", "fa fa-fw fa-cubes", "", categoriesViewTabs, + currentTab, content).Render(r.Context(), w) } diff --git a/pkg/app/handler/feeds/changes.go b/pkg/app/handler/feeds/changes.go index 331d44f..a4adcfa 100644 --- a/pkg/app/handler/feeds/changes.go +++ b/pkg/app/handler/feeds/changes.go @@ -2,10 +2,12 @@ package feeds import ( "fmt" - "github.com/gorilla/feeds" + "html" "net/http" "soko/pkg/models" "time" + + "github.com/gorilla/feeds" ) // Show renders a template to show a given package @@ -19,17 +21,16 @@ func Changes(title string, description string, changedVersions []*models.Version } addFeedItems(feed, changedVersions) feed.WriteAtom(w) - } // addFeedItems is a helper to add items to a feed; most of the feeds use []*models.Version as the entity. func addFeedItems(f *feeds.Feed, versions []*models.Version) { for _, version := range versions { - cpv := fmt.Sprintf("%s-%s", version.Atom, version.Version) + cpv := version.Atom + "-" + version.Version item := &feeds.Item{ Title: cpv, - Link: &feeds.Link{Href: fmt.Sprintf("https://packages.gentoo.org/package/%s", version.Atom)}, - Description: version.Description, + Link: &feeds.Link{Href: "https://packages.gentoo.org/package/" + version.Atom}, + Description: html.EscapeString(version.Description), Author: &feeds.Author{Name: "unknown"}, Created: time.Now(), } diff --git a/pkg/app/handler/feeds/packages.go b/pkg/app/handler/feeds/packages.go index bbfea46..2186401 100644 --- a/pkg/app/handler/feeds/packages.go +++ b/pkg/app/handler/feeds/packages.go @@ -2,10 +2,12 @@ package feeds import ( "fmt" - "github.com/gorilla/feeds" + "html" "net/http" "soko/pkg/models" "time" + + "github.com/gorilla/feeds" ) // Show renders a template to show a given package @@ -26,8 +28,8 @@ func addPackageFeedItems(f *feeds.Feed, gpackages []models.Package) { for _, gpackage := range gpackages { item := &feeds.Item{ Title: gpackage.Atom, - Link: &feeds.Link{Href: fmt.Sprintf("https://packages.gentoo.org/package/%s", gpackage.Atom)}, - Description: gpackage.Longdescription, + Link: &feeds.Link{Href: "https://packages.gentoo.org/package/" + gpackage.Atom}, + Description: html.EscapeString(gpackage.Longdescription), Author: &feeds.Author{Name: "unknown"}, Created: time.Now(), } @@ -54,7 +56,7 @@ func addAddedPackageFeedItems(f *feeds.Feed, packages []*models.Package) { for _, gpackage := range packages { item := &feeds.Item{ Title: gpackage.Atom, - Link: &feeds.Link{Href: fmt.Sprintf("https://packages.gentoo.org/package/%s", gpackage.Atom)}, + Link: &feeds.Link{Href: "https://packages.gentoo.org/package/" + gpackage.Atom}, Description: gpackage.Description(), Author: &feeds.Author{Name: "unknown"}, Created: time.Now(), diff --git a/pkg/app/handler/index/index.go b/pkg/app/handler/index/index.go deleted file mode 100644 index cd2f438..0000000 --- a/pkg/app/handler/index/index.go +++ /dev/null @@ -1,26 +0,0 @@ -// Used to show the landing page of the application - -package index - -import ( - "net/http" - "soko/pkg/app/utils" - "soko/pkg/database" - "soko/pkg/models" -) - -// Show renders a template to show the landing page of the application -func Show(w http.ResponseWriter, r *http.Request) { - count, _ := database.DBCon.Model((*models.Package)(nil)).Count() - - var packagesList []models.Package - if utils.GetUserPreferences(r).General.LandingPageLayout == "classic" { - packagesList = getAddedPackages(10) - } else { - packagesList = getSearchHistoryPackages(r) - } - - updatedVersions := getUpdatedVersions(10) - - renderIndexTemplate(w, createPageData(count, packagesList, updatedVersions, utils.GetUserPreferences(r))) -} diff --git a/pkg/app/handler/index/index.templ b/pkg/app/handler/index/index.templ new file mode 100644 index 0000000..c3ddab1 --- /dev/null +++ b/pkg/app/handler/index/index.templ @@ -0,0 +1,113 @@ +package index + +import "net/http" +import "soko/pkg/app/layout" +import "soko/pkg/app/utils" +import "soko/pkg/database" +import "soko/pkg/models" + +templ header(packageCount int) { + <div class="col-12"> + <div class="jumbotron mb-3" style="background: none!important;"> + <h2 class="site-welcome stick-top"> + Welcome to the Home + <br/> + of <span class="text-primary">{ formatPackageCount(packageCount) }</span> Gentoo Packages + </h2> + <form action="/packages/search" method="get"> + <div class="typeahead__container px-5"> + <div class="typeahead__field"> + <span class="typeahead__query" style="font-size: 1.1em; height: 2.3em;"> + <input class="rounded-left" style="font-size: 1.1em; height: 2.3em;border-right: 0px;" id="q" name="q" type="search" autocomplete="off" placeholder="Find Packages" aria-label="Find Packages" autofocus/> + </span> + <span class="typeahead__button" style="font-size: 1.1em!important; height: 2.3em!important;border-left: 0px;"> + <button style="border-top-right-radius: 0.25rem !important; border-bottom-right-radius: 0.25rem !important; font-size: 1.1em!important; height: 2.3em!important;border-left: 0px;box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);!important;" type="submit" title="Find" aria-label="Find"> + <span class="typeahead__search-icon"></span><span class="sr-only">Find</span> + </button> + </span> + </div> + </div> + </form> + <br/> + <small class="mt-4 px-5 text-muted" style="font-size: 12px;"> + This is the new packages.gentoo.org site. If anything isn't working as expected, + <a href="mailto:gpackages@gentoo.org">contact us</a>. + </small> + <br/> + <small class="px-5 text-muted" style="font-size: 12px;"> + You can search by <a href="/packages/search?q=sys-kernel/gentoo-sources">atom</a>, <a href="/packages/search?q=sys-kernel">category</a>, <a href="/packages/search?q=gentoo-sources">name</a>, <a href="/packages/search?q=kernel@gentoo.org">maintainer</a> or <a href="/packages/search?q=x11-wm%20haskell@gentoo.org">combine</a> queries. Results similar to your query will be found as well. + </small> + </div> + </div> +} + +templ packagesList(addedPackages []packageInfo, landingPage string) { + <div class="col-12"> + <h3 class="mb-2"> + <span class="fa fa-fw fa-history"></span> + if landingPage == "classic" { + <a class="text-dark" href="/packages/added">Added Packages</a> + } else { + <a class="text-dark">Search History</a> + } + </h3> + <div class="card border-top-0 mb-4"> + <div class="table-responsive rounded"> + <table class="table table-striped rounded mb-0"> + <tbody> + for _, pkg := range addedPackages { + <tr> + <td> + <a href={ templ.URL("/packages/" + pkg.Category + "/" + pkg.Name) }> + <span class="text-muted">{ pkg.Category }</span>/<strong>{ pkg.Name }</strong> + </a> + </td> + <td>{ pkg.Description }</td> + </tr> + } + if landingPage == "full" && len(addedPackages) == 0 { + <tr><td class="text-center"><i>Visited packages will be displayed here in future</i></td></tr> + } + </tbody> + </table> + </div> + </div> + </div> +} + +templ page(packageCount int, addedPackages []packageInfo, updatedVersions []*models.Version, userPreferences models.UserPreferences) { + <div class="container mb-5"> + <div class="row"> + @header(packageCount) + @packagesList(addedPackages, userPreferences.General.LandingPageLayout) + <div class="col-12"> + <h3 class="pt-3 mb-2"> + <span class="fa fa-fw fa-asterisk"></span> + <a class="text-dark" href="/packages/updated">Updated Packages</a> + </h3> + <ul class="list-group"> + @utils.ChangedVersionsTable(updatedVersions) + </ul> + </div> + </div> + </div> + <script src="assets/index.js"></script> +} + +// Show renders a template to show the landing page of the application +func Show(w http.ResponseWriter, r *http.Request) { + count, _ := database.DBCon.Model((*models.Package)(nil)).Count() + + var packagesList []packageInfo + if utils.GetUserPreferences(r).General.LandingPageLayout == "classic" { + packagesList = getAddedPackages(10) + } else { + packagesList = getSearchHistoryPackages(r) + } + + updatedVersions := getUpdatedVersions(10) + + layout.Layout("", "home", page( + count, packagesList, updatedVersions, utils.GetUserPreferences(r), + )).Render(r.Context(), w) +} diff --git a/pkg/app/handler/index/utils.go b/pkg/app/handler/index/utils.go index 54adf76..f524058 100644 --- a/pkg/app/handler/index/utils.go +++ b/pkg/app/handler/index/utils.go @@ -4,73 +4,77 @@ package index import ( b64 "encoding/base64" - "github.com/go-pg/pg/v9/orm" - "html/template" "net/http" - "reflect" - "soko/pkg/app/handler/packages" - "soko/pkg/app/utils" + "slices" "soko/pkg/database" "soko/pkg/models" "strconv" "strings" + + "github.com/go-pg/pg/v10" ) +type packageInfo struct { + Name string + Category string + Description string +} + // getAddedPackages returns a list of a // given number of recently added Versions -func getAddedPackages(n int) []models.Package { - var addedPackages []models.Package - err := database.DBCon.Model(&addedPackages). +func getAddedPackages(n int) (packages []packageInfo) { + descriptionQuery := database.DBCon.Model((*models.Version)(nil)). + Column("description"). + Where("atom = package.atom"). + Limit(1) + err := database.DBCon.Model((*models.Package)(nil)). + Column("name", "category"). + ColumnExpr("(?) AS description", descriptionQuery). Order("preceding_commits DESC"). Limit(n). - Relation("Versions"). - Select() + Select(&packages) if err != nil { - return addedPackages + return nil } - return addedPackages + return } -func getSearchHistoryPackages(r *http.Request) []models.Package { - var cookie, err = r.Cookie("search_history") - var searchedPackages []models.Package - if err == nil { - packagesList := getSearchHistoryFromCookie(cookie) - err := database.DBCon.Model(&searchedPackages). - Where(getSearchHistoryQuery(packagesList)). - Relation("Versions"). - Select() - return getSortedSearchHistory(packagesList, searchedPackages) - if err != nil { - return searchedPackages - } +func getSearchHistoryPackages(r *http.Request) (packages []packageInfo) { + cookie, err := r.Cookie("search_history") + if err != nil { + return nil } - return searchedPackages + packagesList := getSearchHistoryFromCookie(cookie) + + descriptionQuery := database.DBCon.Model((*models.Version)(nil)). + Column("description"). + Where("atom = package.atom"). + Limit(1) + err = database.DBCon.Model((*models.Package)(nil)). + Column("name", "category"). + ColumnExpr("(?) AS description", descriptionQuery). + Where("atom in (?)", pg.In(packagesList)). + Select(&packages) + if err != nil { + return nil + } + + return getSortedSearchHistory(packagesList, packages) } -func getSortedSearchHistory(sortedPackagesList []string, packagesList []models.Package) []models.Package { - var result []models.Package +func getSortedSearchHistory(sortedPackagesList []string, packagesList []packageInfo) (result []packageInfo) { for _, gpackage := range sortedPackagesList { for _, gpackageObject := range packagesList { - if gpackageObject.Atom == gpackage { + if gpackageObject.Category+"/"+gpackageObject.Name == gpackage { result = append(result, gpackageObject) } } } - reverse(result) - return result -} - -func reverse(s interface{}) { - n := reflect.ValueOf(s).Len() - swap := reflect.Swapper(s) - for i, j := 0, n-1; i < j; i, j = i+1, j-1 { - swap(i, j) - } + slices.Reverse(result) + return } -func getSearchHistoryFromCookie(cookie *http.Cookie) []string { - var packagesList []string +func getSearchHistoryFromCookie(cookie *http.Cookie) (packagesList []string) { cookieValue, err := b64.StdEncoding.DecodeString(cookie.Value) if err == nil { packagesList = strings.Split(string(cookieValue), ",") @@ -78,15 +82,7 @@ func getSearchHistoryFromCookie(cookie *http.Cookie) []string { packagesList = packagesList[len(packagesList)-10:] } } - return packagesList -} - -func getSearchHistoryQuery(packagesList []string) string { - var queryParts []string - for _, gpackage := range packagesList { - queryParts = append(queryParts, "atom = '"+gpackage+"'") - } - return strings.Join(queryParts, " OR ") + return } // getUpdatedVersions returns a list of a @@ -97,10 +93,10 @@ func getUpdatedVersions(n int) []*models.Version { err := database.DBCon.Model(&updates). Order("preceding_commits DESC"). Limit(3*n). - Relation("ChangedVersions", func(q *orm.Query) (*orm.Query, error) { + Relation("ChangedVersions", func(q *pg.Query) (*pg.Query, error) { return q.Limit(30 * n), nil }). - Relation("ChangedVersions.Commits", func(q *orm.Query) (*orm.Query, error) { + Relation("ChangedVersions.Commits", func(q *pg.Query) (*pg.Query, error) { return q.Order("preceding_commits DESC"), nil }). Select() @@ -119,53 +115,11 @@ func getUpdatedVersions(n int) []*models.Version { return updatedVersions } -// createPageData creates the data used in the template of the landing page -func createPageData(packagecount int, addedPackages []models.Package, updatedVersions []*models.Version, userPreferences models.UserPreferences) interface{} { - return struct { - Header models.Header - PackageCount string - AddedPackages []models.Package - UpdatedPackages []*models.Version - Application models.Application - UserPreferences models.UserPreferences - }{ - Header: models.Header{Title: "", Tab: "home"}, - Application: utils.GetApplicationData(), - PackageCount: formatPackageCount(packagecount), - AddedPackages: addedPackages, - UpdatedPackages: updatedVersions, - UserPreferences: userPreferences, - } -} - -// renderIndexTemplate renders all templates used for the landing page -func renderIndexTemplate(w http.ResponseWriter, pageData interface{}) { - templates := template.Must( - template.Must( - template.Must( - template.New("Show"). - Funcs(getFuncMap()). - ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/packages/changedVersionRow.tmpl")). - ParseGlob("web/templates/index/*.tmpl")) - - templates.ExecuteTemplate(w, "show.tmpl", pageData) -} - -// GetFuncMap returns the FuncMap used in templates -func getFuncMap() template.FuncMap { - return template.FuncMap{ - "contains": strings.Contains, - "mkSlice": mkSlice, - "formatRestricts": packages.FormatRestricts, - } -} - // formatPackageCount returns the formatted number of // packages containing a thousands comma func formatPackageCount(packageCount int) string { packages := strconv.Itoa(packageCount) - if len(string(packageCount)) == 6 { + if len(packages) == 6 { return packages[:3] + "," + packages[3:] } else if len(packages) == 5 { return packages[:2] + "," + packages[2:] @@ -175,8 +129,3 @@ func formatPackageCount(packageCount int) string { return packages } } - -// mkSlice creates a slice based on the given arguments -func mkSlice(args ...interface{}) []interface{} { - return args -} diff --git a/pkg/app/handler/maintainer/browse.go b/pkg/app/handler/maintainer/browse.go deleted file mode 100644 index e661d5f..0000000 --- a/pkg/app/handler/maintainer/browse.go +++ /dev/null @@ -1,32 +0,0 @@ -package maintainer - -import ( - "net/http" - "soko/pkg/database" - "soko/pkg/models" - "sort" - "strings" -) - -// Show renders a template to show a given maintainer page -func Browse(w http.ResponseWriter, r *http.Request) { - - tabName := "projects" - if strings.HasSuffix(r.URL.Path, "/gentoo-projects") { - tabName = "projects" - } else if strings.HasSuffix(r.URL.Path, "/gentoo-developers") { - tabName = "gentoo-developers" - } else if strings.HasSuffix(r.URL.Path, "/proxied-maintainers") { - tabName = "proxied-maintainers" - } - - var maintainers []*models.Maintainer - database.DBCon.Model(&maintainers).Select() - - sort.Slice(maintainers, func(i, j int) bool { - return maintainers[i].Name < maintainers[j].Name - }) - - renderBrowseTemplate(createBrowseData(tabName, maintainers), w) - -} diff --git a/pkg/app/handler/maintainer/browse.templ b/pkg/app/handler/maintainer/browse.templ new file mode 100644 index 0000000..f7bc8b6 --- /dev/null +++ b/pkg/app/handler/maintainer/browse.templ @@ -0,0 +1,94 @@ +package maintainer + +import "soko/pkg/models" +import "soko/pkg/app/layout" +import "net/http" +import "soko/pkg/database" + +templ browsePage(maintainers []*models.Maintainer) { + <div class="container mb-5"> + <div class="row"> + <div class="col-12"> + <div class="row"> + <div class="col-md-12"> + <ul class="kk-col-list kk-6col-list kk-category-listing"> + for i, maintainer := range maintainers { + if i == 0 || maintainer.Name[0] != maintainers[i-1].Name[0] { + <li class="kk-col-list-header"> + <span class="kk-group-header"> + if maintainer.Name != "" { + { maintainer.Name[0:1] } + } else { + # + } + </span> + </li> + } + <li> + <a + title={ maintainer.Name } + data-toggle="tooltip" + data-placement="right" + href={ templ.URL("/maintainer/" + maintainer.Email) } + > + if maintainer.Name != "" { + { maintainer.Name } + } else { + { maintainer.Email } + } + </a> + </li> + } + </ul> + </div> + </div> + </div> + </div> + </div> +} + +var browseViewTabs = []layout.SubTab{ + { + Name: "Gentoo Projects", + Link: "/maintainers", + Icon: "fa fa-users mr-1", + }, + { + Name: "Gentoo Developers", + Link: "/maintainers/gentoo-developers", + Icon: "fa fa-user mr-1", + }, + { + Name: "Proxied Maintainers", + Link: "/maintainers/proxied-maintainers", + Icon: "fa fa-user-o mr-1", + }, +} + +func renderBrowsePage(w http.ResponseWriter, r *http.Request, title string, dbType string) { + var maintainers []*models.Maintainer + err := database.DBCon.Model(&maintainers). + Where("type = ?", dbType). + Order("name"). + Select() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), + http.StatusInternalServerError) + return + } + + layout.TabbedLayout(title, "maintainers", "Maintainers", "fa fa-fw fa-users", "", browseViewTabs, + title, browsePage(maintainers)).Render(r.Context(), w) +} + +func BrowseProjects(w http.ResponseWriter, r *http.Request) { + renderBrowsePage(w, r, "Gentoo Projects", "project") +} + +func BrowseDevs(w http.ResponseWriter, r *http.Request) { + renderBrowsePage(w, r, "Gentoo Developers", "gentoo-developer") +} + +func BrowseProxyDevs(w http.ResponseWriter, r *http.Request) { + renderBrowsePage(w, r, "Proxied Maintainers", "proxied-maintainer") +} diff --git a/pkg/app/handler/maintainer/show.go b/pkg/app/handler/maintainer/show.go index fec48be..c6262b1 100644 --- a/pkg/app/handler/maintainer/show.go +++ b/pkg/app/handler/maintainer/show.go @@ -1,115 +1,348 @@ package maintainer import ( - "github.com/go-pg/pg/v9/orm" + "encoding/json" + "html" "net/http" + "soko/pkg/app/handler/packages/components" + "soko/pkg/app/layout" "soko/pkg/app/utils" "soko/pkg/database" "soko/pkg/models" - "sort" "strings" + "time" + + "github.com/go-pg/pg/v10" + "github.com/gorilla/feeds" ) -// Show renders a template to show a given maintainer page -func Show(w http.ResponseWriter, r *http.Request) { - maintainerEmail := r.URL.Path[len("/maintainer/"):] - maintainerEmail = strings.Split(maintainerEmail, "/")[0] +func common(w http.ResponseWriter, r *http.Request) (maintainer models.Maintainer, packagesQuery *pg.Query, packagesCount int, err error) { + maintainerEmail := r.PathValue("email") if !strings.Contains(maintainerEmail, "@") { - maintainerEmail = maintainerEmail + "@gentoo.org" + maintainerEmail += "@gentoo.org" } - whereClause := "maintainers @> '[{\"Email\": \"" + maintainerEmail + "\"}]'" + packagesQuery = database.DBCon.Model((*models.Package)(nil)).Column("atom") + if maintainerEmail == "maintainer-needed@gentoo.org" { - whereClause = "maintainers IS null" + packagesQuery = packagesQuery.Where("NULLIF(maintainers, '[]') IS null") + } else { + packagesQuery = packagesQuery.Where("maintainers @> ?", `[{"Email": "`+maintainerEmail+`"}]`) } - maintainer := models.Maintainer{ - Email: maintainerEmail, + maintainer = models.Maintainer{Email: maintainerEmail} + err = database.DBCon.Model(&maintainer).WherePK().Relation("Project").Relation("Projects").Select() + if err != nil { + http.NotFound(w, r) + return } - database.DBCon.Model(&maintainer).WherePK().Relation("Project").Relation("Projects").Select() userPreferences := utils.GetUserPreferences(r) if userPreferences.Maintainers.IncludeProjectPackages && maintainer.Projects != nil && len(maintainer.Projects) > 0 { - whereParts := []string{"maintainers @> '[{\"Email\": \"" + maintainerEmail + "\"}]'"} + excludeList := strings.Join(userPreferences.Maintainers.ExcludedProjects, ",") for _, proj := range maintainer.Projects { - if !strings.Contains(strings.Join(userPreferences.Maintainers.ExcludedProjects, ","), proj.Email) { - whereParts = append(whereParts, "maintainers @> '[{\"Email\": \""+proj.Email+"\"}]'") + if !strings.Contains(excludeList, proj.Email) { + packagesQuery = packagesQuery.WhereOr("maintainers @> ?", `[{"Email": "`+proj.Email+`"}]`) } } - whereClause = strings.Join(whereParts, " OR ") } - var gpackages []*models.Package - query := database.DBCon.Model(&gpackages). - Where(whereClause) - - pageName := "packages" - if strings.HasSuffix(r.URL.Path, "/changelog") { - pageName = "changelog" - query = query. - Relation("Versions"). - Relation("Commits", func(q *orm.Query) (*orm.Query, error) { - return q.Order("preceding_commits DESC").Limit(50), nil - }) - } else if strings.HasSuffix(r.URL.Path, "/outdated") { - pageName = "outdated" - query = query. - Relation("Versions"). - Relation("Outdated") - } else if strings.HasSuffix(r.URL.Path, "/qa-report") { - pageName = "qa-report" - query = query. - Relation("Versions"). - Relation("PkgCheckResults"). - Relation("Versions.PkgCheckResults") - } else if strings.HasSuffix(r.URL.Path, "/pull-requests") { - pageName = "pull-requests" - query = query. - Relation("Versions"). - Relation("PullRequests") - } else if strings.HasSuffix(r.URL.Path, "/stabilization") { - pageName = "stabilization" - query = query. - Relation("Versions"). - Relation("PkgCheckResults"). - Relation("Versions.PkgCheckResults"). - Relation("Bugs") - } else if strings.HasSuffix(r.URL.Path, "/bugs") { - pageName = "bugs" - query = query. - Relation("Versions"). - Relation("Versions.Bugs"). - Relation("Bugs") - } else if strings.HasSuffix(r.URL.Path, "/security") { - pageName = "security" - query = query. - Relation("Versions"). - Relation("Versions.Bugs"). - Relation("Bugs") - } else { - query = query. - Relation("Versions"). - Relation("Versions.Masks") + packagesCount, err = packagesQuery.Clone().Count() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + + return +} + +func ShowChangelog(w http.ResponseWriter, r *http.Request) { + maintainer, query, packagesCount, err := common(w, r) + if err != nil { + return + } + var commits []*models.Commit + err = database.DBCon.Model(&commits). + Join("JOIN commit_to_packages").JoinOn("commit.id = commit_to_packages.commit_id"). + Where("commit_to_packages.package_atom IN (?)", query). + Order("preceding_commits DESC"). + Limit(50). + Select() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + layout.Layout(maintainer.Name, "maintainers", + show(packagesCount, &maintainer, "Changelog", components.Changelog("", commits)), + ).Render(r.Context(), w) +} + +func ShowChangelogFeed(w http.ResponseWriter, r *http.Request) { + maintainer, query, _, err := common(w, r) + if err != nil { + return + } + var commits []*models.Commit + err = database.DBCon.Model(&commits). + Join("JOIN commit_to_packages").JoinOn("commit.id = commit_to_packages.commit_id"). + Where("commit_to_packages.package_atom IN (?)", query). + Order("preceding_commits DESC"). + Limit(100). + Select() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + + feed := &feeds.Feed{ + Title: "100 latest commits for " + maintainer.Name, + Description: "100 latest commits for " + maintainer.Name, + Author: &feeds.Author{Name: "Gentoo Packages Database"}, + Created: time.Now(), + Link: &feeds.Link{Href: "https://packages.gentoo.org/maintainer/" + maintainer.Email + "/changelog"}, + } + + for _, commit := range commits { + feed.Add(&feeds.Item{ + Title: html.EscapeString(commit.Message), + Updated: commit.CommitterDate, + Created: commit.AuthorDate, + Author: &feeds.Author{Name: commit.CommitterName, Email: commit.CommitterEmail}, + Link: &feeds.Link{Href: "https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=" + commit.Id, Type: "text/html", Rel: "alternate"}, + Id: commit.Id, + }) + } + feed.WriteAtom(w) +} + +func ShowOutdated(w http.ResponseWriter, r *http.Request) { + maintainer, query, packagesCount, err := common(w, r) + if err != nil { + return + } + var outdated []components.OutdatedItem + descriptionQuery := database.DBCon.Model((*models.Version)(nil)). + Column("description"). + Where("atom = outdated_packages.atom"). + Limit(1) + err = database.DBCon.Model((*models.OutdatedPackages)(nil)). + Column("atom").ColumnExpr("(?) AS description", descriptionQuery). + Where("atom IN (?)", query). + Order("atom"). + Select(&outdated) + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + layout.Layout(maintainer.Name, "maintainers", + show(packagesCount, &maintainer, "Outdated", components.Outdated(outdated)), + ).Render(r.Context(), w) +} + +func ShowOutdatedFeed(w http.ResponseWriter, r *http.Request) { + maintainer, query, _, err := common(w, r) + if err != nil { + return + } + var outdated []models.OutdatedPackages + err = database.DBCon.Model(&outdated). + Where("atom IN (?)", query). + Order("atom"). + Select() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + utils.OutdatedFeed(w, "https://packages.gentoo.org/maintainer/"+maintainer.Email+"/outdated", maintainer.Name+" <"+maintainer.Email+">", outdated) +} + +func ShowPullRequests(w http.ResponseWriter, r *http.Request) { + maintainer, query, packagesCount, err := common(w, r) + if err != nil { + return + } + var pullRequests []*models.GithubPullRequest + err = database.DBCon.Model(&pullRequests). + DistinctOn("github_pull_request.id"). + OrderExpr("github_pull_request.id DESC"). + Join("JOIN package_to_github_pull_requests").JoinOn("github_pull_request.id = package_to_github_pull_requests.github_pull_request_id"). + Where("package_atom IN (?)", query). + Select() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + layout.Layout(maintainer.Name, "maintainers", + show(packagesCount, &maintainer, "Pull requests", components.PullRequests(pullRequests)), + ).Render(r.Context(), w) +} + +func ShowStabilization(w http.ResponseWriter, r *http.Request) { + maintainer, query, packagesCount, err := common(w, r) + if err != nil { + return + } + var results []*models.PkgCheckResult + err = database.DBCon.Model(&results). + Column("atom", "cpv", "message"). + Where("class = ?", "StableRequest"). + Where("atom IN (?)", query). + OrderExpr("cpv"). + Select() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + layout.Layout(maintainer.Name, "maintainers", + show(packagesCount, &maintainer, "Stabilization", components.Stabilizations(results)), + ).Render(r.Context(), w) +} + +func ShowBugs(w http.ResponseWriter, r *http.Request) { + maintainer, query, packagesCount, err := common(w, r) + if err != nil { + return + } + var bugs []*models.Bug + err = database.DBCon.Model(&bugs). + DistinctOn("id::INT"). + Column("id", "summary", "component", "assignee"). + OrderExpr("id::INT"). + With("wanted", query). + Where("id IN (?)", + database.DBCon.Model((*models.PackageToBug)(nil)). + Column("bug_id"). + Join("JOIN wanted").JoinOn("package_atom = wanted.atom")). + WhereOr("id IN (?)", + database.DBCon.Model((*models.VersionToBug)(nil)). + Column("bug_id"). + Join("JOIN versions").JoinOn("version_id = versions.id"). + Join("JOIN wanted").JoinOn("versions.atom = wanted.atom")). + Select() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + generalCount, stabilizationCount, keywordingCount := utils.CountBugsCategories(bugs) + layout.Layout(maintainer.Name, "maintainers", + show(packagesCount, &maintainer, "Bugs", components.Bugs("", generalCount, stabilizationCount, keywordingCount, bugs)), + ).Render(r.Context(), w) +} + +func ShowSecurity(w http.ResponseWriter, r *http.Request) { + maintainer, query, packagesCount, err := common(w, r) + if err != nil { + return + } + var bugs []*models.Bug + err = database.DBCon.Model(&bugs). + DistinctOn("id::INT"). + Column("id", "summary", "component", "assignee"). + OrderExpr("id::INT"). + With("wanted", query). + Where("component = ?", "Vulnerabilities"). + Where("id IN (?)", + database.DBCon.Model((*models.PackageToBug)(nil)). + Column("bug_id"). + Join("JOIN wanted").JoinOn("package_atom = wanted.atom")). + Select() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + layout.Layout(maintainer.Name, "maintainers", + show(packagesCount, &maintainer, "Security", components.SecurityBugs("", bugs)), + ).Render(r.Context(), w) +} + +func ShowStabilizationFile(w http.ResponseWriter, r *http.Request) { + _, query, _, err := common(w, r) + if err != nil { + return + } + pageName := r.URL.Path[strings.LastIndexByte(r.URL.Path, '/')+1:] + + var results []*models.PkgCheckResult + err = database.DBCon.Model(&results). + Column("category", "package", "version", "message"). + Where("class = ?", "StableRequest"). + Where("atom IN (?)", query). + OrderExpr("cpv"). + Select() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return } + utils.StabilizationExport(w, pageName, results) +} - err := query.Select() +func ShowStabilizationFeed(w http.ResponseWriter, r *http.Request) { + maintainer, query, _, err := common(w, r) + if err != nil { + return + } - if err != nil || len(gpackages) == 0 { + var results []*models.PkgCheckResult + err = database.DBCon.Model(&results). + Column("atom", "cpv", "message"). + Where("class = ?", "StableRequest"). + Where("atom IN (?)", query). + OrderExpr("cpv"). + Select() + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + utils.StabilizationFeed(w, "https://packages.gentoo.org/maintainer/"+maintainer.Email+"/stabilization", maintainer.Name+" <"+maintainer.Email+">", results) +} + +func ShowPackages(w http.ResponseWriter, r *http.Request) { + maintainer, query, packagesCount, err := common(w, r) + if err != nil { + return + } + var gpackages []*models.Package + err = query.Model(&gpackages). + Column("category"). + Order("category", "name"). + Relation("Versions").Select() + if err != nil { http.NotFound(w, r) return } + layout.Layout(maintainer.Name, "maintainers", + show(packagesCount, &maintainer, "Packages", showPackages(gpackages, &maintainer)), + ).Render(r.Context(), w) +} - sort.Slice(gpackages, func(i, j int) bool { - if gpackages[i].Category != gpackages[j].Category { - return gpackages[i].Category < gpackages[j].Category - } - return gpackages[i].Name < gpackages[j].Name - }) +func ShowInfoJson(w http.ResponseWriter, r *http.Request) { + maintainer, _, _, err := common(w, r) + if err != nil { + return + } - renderMaintainerTemplate("show", - "*", - GetFuncMap(), - createMaintainerData(pageName, &maintainer, gpackages), - w) + var reply struct { + Email string `json:"email"` + Name string `json:"name"` + IsProject bool `json:"is_project"` + Members []string `json:"members"` + MemberOf []string `json:"member_of"` + } + reply.Email = maintainer.Email + reply.Name = maintainer.Name + reply.IsProject = maintainer.Type == "project" + + for _, member := range maintainer.Project.Members { + reply.Members = append(reply.Members, member.Email) + } + for _, project := range maintainer.Projects { + reply.MemberOf = append(reply.MemberOf, project.Email) + } + + w.Header().Set("Content-Type", "application/json") + err = json.NewEncoder(w).Encode(reply) + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + } } diff --git a/pkg/app/handler/maintainer/show.templ b/pkg/app/handler/maintainer/show.templ new file mode 100644 index 0000000..317ce70 --- /dev/null +++ b/pkg/app/handler/maintainer/show.templ @@ -0,0 +1,256 @@ +package maintainer + +import "strconv" +import "strings" +import "soko/pkg/app/layout" +import "soko/pkg/models" + +func showViewTabs(email string, packagesCount int, info *models.MaintainerPackagesInformation) []layout.SubTab { + return []layout.SubTab{ + { + Name: "Packages", + Link: templ.URL("/maintainer/" + email), + Icon: "fa fa-info mr-1", + BadgeValue: strconv.Itoa(packagesCount), + }, + { + Name: "Stabilization", + Link: templ.URL("/maintainer/" + email + "/stabilization"), + Icon: "fa fa-check-circle-o mr-1", + BadgeValue: strconv.Itoa(info.StableRequests), + }, + { + Name: "Outdated", + Link: templ.URL("/maintainer/" + email + "/outdated"), + Icon: "fa fa-tag mr-1", + BadgeValue: strconv.Itoa(info.Outdated), + }, + { + Name: "Pull requests", + Link: templ.URL("/maintainer/" + email + "/pull-requests"), + Icon: "octicon octicon-git-pull-request opticon-resource-icon ml-1", + BadgeValue: strconv.Itoa(info.PullRequests), + }, + { + Name: "Bugs", + Link: templ.URL("/maintainer/" + email + "/bugs"), + Icon: "fa fa-bug", + BadgeValue: strconv.Itoa(info.Bugs), + }, + { + Name: "Security", + Link: templ.URL("/maintainer/" + email + "/security"), + Icon: "fa fa-shield", + BadgeValue: strconv.Itoa(info.SecurityBugs), + }, + { + Name: "Changelog", + Link: templ.URL("/maintainer/" + email + "/changelog"), + Icon: "fa fa-fw fa-history", + }, + } +} + +templ tabbedHeader(maintainer *models.Maintainer, packagesCount int, currentSubTab string) { + <div class="kk-header-container"> + <div class="container"> + <div class="row"> + <div class="col-12"> + <div class="row mt-3"> + <div class="col-md-5"> + <h1 class="stick-top kk-package-title" id="package-title"> + <small class="kk-package-cat"> + if maintainer.Email == "maintainer-needed@gentoo.org" { + } else if maintainer.Type == "project" { + Gentoo Project + } else if strings.Contains(maintainer.Email, "@gentoo.org") { + Gentoo Developer + } else if maintainer.Email != "" { + Proxied Maintainer + } + </small> + <div> + <svg height="32" class="octicon octicon-person right left kk-package-icon" aria-label="Package icon" viewBox="0 0 16 16" version="1.1" width="32" role="img"><path fill-rule="evenodd" d="M10.5 5a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm.061 3.073a4 4 0 10-5.123 0 6.004 6.004 0 00-3.431 5.142.75.75 0 001.498.07 4.5 4.5 0 018.99 0 .75.75 0 101.498-.07 6.005 6.005 0 00-3.432-5.142z"></path></svg> + <div class="kk-package-name"> + if len(maintainer.Name) > 0 { + { maintainer.Name } + } else if len(maintainer.Email) > 0 { + { maintainer.Email } + } else { + Maintainer Needed + } + </div> + </div> + </h1> + </div> + <div class="col-md-7"></div> + <div class="col-md-12 pt-4 mt-1"> + <nav class="nav kk-package-nav"> + for _, tab := range showViewTabs(maintainer.Email, packagesCount, &maintainer.PackagesInformation) { + <a class={ "nav-link", templ.KV("active", tab.Name == currentSubTab) } href={ tab.Link }> + <i class={ tab.Icon } aria-hidden="true"></i> { tab.Name } + if tab.BadgeValue != "" { + <span class="ml-1 badge badge-pill kk-misc-badge">{ tab.BadgeValue }</span> + } + </a> + } + </nav> + </div> + </div> + </div> + </div> + </div> + </div> +} + +templ show(packagesCount int, maintainer *models.Maintainer, currentSubTab string, component templ.Component) { + @tabbedHeader(maintainer, packagesCount, currentSubTab) + <div class="tab-content" id="myTabContent"> + <div class="container mb-5 tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="overview-tab"> + @component + </div> + </div> +} + +script filter() { + const value = document.querySelector("#filter").value.toLowerCase(); + const groups = document.querySelectorAll("#pkglist .list-group"); + for (let i = 0; i < groups.length; i++) { + let visible = false; + const rows = groups[i].querySelectorAll(".list-group-item"); + for (let j = 0; j < rows.length; j++) { + const flag = rows[j].children[0].children[0].innerText.toLowerCase().includes(value); + rows[j].style.display = flag ? "" : "none"; + visible ||= flag; + } + groups[i].style.display = visible ? "" : "none"; + } +} + +templ showPackages(packages []*models.Package, maintainer *models.Maintainer) { + <div class="row"> + <div class="col-md-9" id="pkglist"> + if len(packages) > 0 { + <p> + <input onKeyup={ filter() } id="filter" type="text" class="form-control form-control-xl" placeholder={ "Search packages maintained by " + maintainer.Email }/> + </p> + <ul class="list-group"> + <h3 id={ packages[0].Category }>{ packages[0].Category }</h3> + for i, pkg := range packages { + if i != 0 && pkg.Category != packages[i-1].Category { + @templ.Raw("</ul>") + <h3 class="mt-4" id={ pkg.Category }>{ pkg.Category }</h3> + @templ.Raw(`<ul class="list-group">`) + } + <li class="list-group-item"> + <div class="row"> + <div class="col-md-4"> + <a href={ templ.URL("/packages/" + pkg.Atom) } class="text-dark"><b>{ pkg.Atom }</b></a> + </div> + <div class="col-md-8 text-muted"> + { pkg.Description() } + </div> + </div> + </li> + } + </ul> + @filter() + } else { + <div class="row"> + <div class="col-md-8"></div> + <div class="col-md-4"> + <img + style="width: 100%;" + src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png" + /> + </div> + </div> + } + </div> + <div class="col-md-3 pt-4"> + if maintainer.Project.Description != "" { + <h4 class=""> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> + Description + </a> + </h4> + <div class="collapse show" id="collapseDescription"> + <dl> + <dd class="ml-3 mb-0 text-muted"> + { maintainer.Project.Description } + </dd> + </dl> + </div> + } + <h4 class={ templ.KV("mt-4", maintainer.Project.Description != "") }> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseExternalResources" role="button" aria-expanded="false" aria-controls="collapseDescription"> + External Resources + </a> + </h4> + <div class="collapse show" id="collapseExternalResources"> + <dl class="ml-3"> + <dd> + <span class="fa fa-fw fa-chain-broken"></span> + <a href={ templ.URL("https://qa-reports.gentoo.org/output/gentoo-ci/output.html;maintainer=" + maintainer.Email) } title="CI report" target="_blank">CI Report</a> + (<a href={ templ.URL("https://qa-reports.gentoo.org/output/gentoo-ci/output.verbose.html;maintainer=" + maintainer.Email) } title="Verbose CI report" target="_blank">verbose</a>) + </dd> + <dd> + <span class="fa fa-fw fa-book"></span> + <a href={ templ.URL(maintainer.Project.Url) } target="_blank">Documentation</a> + </dd> + </dl> + </div> + if maintainer.Project.Description != "" { + <h4 class="mt-4"> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseMembers" role="button" aria-expanded="false" aria-controls="collapseMembers"> + Members + </a> + </h4> + <div class="collapse show" id="collapseMembers"> + <dl> + for _, member := range maintainer.Project.Members { + <dd class="ml-3 mb-0"> + <a href={ templ.URL("/maintainer/" + member.Email) }>{ member.Name }</a> + if member.IsLead { + (Lead) + } + </dd> + } + </dl> + </div> + } + if len(maintainer.Projects) > 0 { + <h4> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseProjects" role="button" aria-expanded="false" aria-controls="collapseProjects"> + Projects + </a> + </h4> + <div class="collapse show" id="collapseProjects"> + <dl> + for _, project := range maintainer.Projects { + <dd class="ml-3 mb-0"><a href={ templ.URL("/maintainer/" + project.Email) }>{ project.Name }</a></dd> + } + </dl> + </div> + } + if len(packages) > 0 { + <h4 class="mt-4"> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseShortcuts" role="button" aria-expanded="false" aria-controls="collapseShortcuts"> + Shortcuts + </a> + </h4> + <div class="collapse show" id="collapseShortcuts"> + <dl> + for i, pkg := range packages { + if i == 0 || pkg.Category != packages[i-1].Category { + <dd class="ml-3 mb-0"> + <a href={ templ.URL("#" + pkg.Category) }>{ pkg.Category }</a> + </dd> + } + } + </dl> + </div> + } + </div> + </div> +} diff --git a/pkg/app/handler/maintainer/utils.go b/pkg/app/handler/maintainer/utils.go deleted file mode 100644 index c59a19f..0000000 --- a/pkg/app/handler/maintainer/utils.go +++ /dev/null @@ -1,142 +0,0 @@ -package maintainer - -import ( - "crypto/md5" - "encoding/hex" - "html/template" - "net/http" - "soko/pkg/app/handler/packages" - "soko/pkg/app/utils" - "soko/pkg/models" - "sort" - "strings" -) - -// RenderPackageTemplates renders the given templates using the given data -// One pattern can be used to specify templates -func renderMaintainerTemplate(page string, templatepattern string, funcMap template.FuncMap, data interface{}, w http.ResponseWriter) { - templates := template.Must( - template.Must( - template.Must( - template.New(page). - Funcs(funcMap). - ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/maintainer/components/*.tmpl")). - ParseGlob("web/templates/maintainer/" + templatepattern + ".tmpl")) - templates.ExecuteTemplate(w, page+".tmpl", data) -} - -// renderIndexTemplate renders all templates used for the categories section -func renderBrowseTemplate(data interface{}, w http.ResponseWriter) { - templates := template.Must( - template.Must( - template.Must( - template.New("browse"). - ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/maintainer/maintainersbrowseheader.tmpl")). - ParseGlob("web/templates/maintainer/browse.tmpl")) - - templates.ExecuteTemplate(w, "browse.tmpl", data) -} - -// createPackageData creates the data used in the show package template -func createMaintainerData(pageName string, maintainer *models.Maintainer, gpackages []*models.Package) interface{} { - return struct { - PageName string - Maintainer *models.Maintainer - Header models.Header - Packages []*models.Package - Application models.Application - }{ - PageName: pageName, - Maintainer: maintainer, - Header: models.Header{Title: maintainer.Name + " – ", Tab: "maintainers"}, - Packages: gpackages, - Application: utils.GetApplicationData(), - } -} - -// createCategoriesData creates the data used in -// the template to display a specific category -func createBrowseData(tabName string, data interface{}) interface{} { - return struct { - Header models.Header - TabName string - Maintainers interface{} - Application models.Application - }{ - Header: models.Header{Title: "Maintainers – ", Tab: "maintainers"}, - TabName: tabName, - Maintainers: data, - Application: utils.GetApplicationData(), - } -} - -func getAllBugs(packages []*models.Package) []*models.Bug { - allBugs := make(map[string]*models.Bug) - - for _, gpackage := range packages { - for _, bug := range gpackage.AllBugs() { - allBugs[bug.Id] = bug - } - } - - var allBugsList []*models.Bug - for _, bug := range allBugs { - allBugsList = append(allBugsList, bug) - } - - sort.Slice(allBugsList, func(i, j int) bool { - return allBugsList[i].Id < allBugsList[j].Id - }) - - return allBugsList -} - -// GetFuncMap returns the FuncMap used in templates -func GetFuncMap() template.FuncMap { - return template.FuncMap{ - "contains": strings.Contains, - "replaceall": strings.ReplaceAll, - "tolower": strings.ToLower, - "getAllBugs": getAllBugs, - "formatRestricts": packages.FormatRestricts, - "appendCommits": func(a []*models.Commit, b []*models.Commit) []*models.Commit { - return append(a, b...) - }, - "gravatar": func(email string) string { - hasher := md5.Sum([]byte(email)) - hash := hex.EncodeToString(hasher[:]) - return "https://www.gravatar.com/avatar/" + hash + "?s=13&d=retro" - }, - "getReverse": func(index int, versions []*models.Version) *models.Version { - return versions[len(versions)-1-index] - }, - "mkSlice": func(args ...interface{}) []interface{} { - return args - }, - "add": func(a, b int) int { - return a + b - }, - "sortCommits": func(commits []*models.Commit) []*models.Commit { - sort.Slice(commits, func(i, j int) bool { - return commits[i].PrecedingCommits > commits[j].PrecedingCommits - }) - return commits - }, - "getPullRequests": func(packages []*models.Package) []*models.GithubPullRequest { - pullrequestsMap := map[string]*models.GithubPullRequest{} - for _, gpackage := range packages { - for _, pr := range gpackage.PullRequests { - pullrequestsMap[pr.Id] = pr - } - } - - var pullrequests []*models.GithubPullRequest - for _, pr := range pullrequestsMap { - pullrequests = append(pullrequests, pr) - } - return pullrequests - }, - } -} diff --git a/pkg/app/handler/packages/added.go b/pkg/app/handler/packages/added.go deleted file mode 100644 index 11102b4..0000000 --- a/pkg/app/handler/packages/added.go +++ /dev/null @@ -1,19 +0,0 @@ -// Used to show recently added versions - -package packages - -import ( - "net/http" - "soko/pkg/app/handler/feeds" -) - -// Added renders a template containing a list of 50 recently added versions. -func Added(w http.ResponseWriter, r *http.Request) { - addedVersions := GetAddedVersions(50) - RenderPackageTemplates("changedVersions", "changedVersions", "changedVersionRow", GetFuncMap(), CreateFeedData("Added", addedVersions), w) -} - -func AddedFeed(w http.ResponseWriter, r *http.Request) { - addedPackages := GetAddedPackages(250) - feeds.AddedPackages("Added packages in Gentoo.", "Added packages in Gentoo.", addedPackages, w) -} diff --git a/pkg/app/handler/packages/changed_versions.templ b/pkg/app/handler/packages/changed_versions.templ new file mode 100644 index 0000000..3b268ad --- /dev/null +++ b/pkg/app/handler/packages/changed_versions.templ @@ -0,0 +1,76 @@ +package packages + +import "soko/pkg/app/utils" +import "soko/pkg/models" +import "net/http" +import "soko/pkg/app/handler/categories" +import "soko/pkg/app/handler/feeds" + +templ changedVersionsPage(pageType string, versions []*models.Version) { + <div class="container mb-5"> + <div class="row"> + <div class="col-12"> + <h3 class="mb-2" style="text-transform: capitalize;"> + { pageType } Packages + <a + title="Atom feed" + class="kk-feed-icon" + href={ templ.URL("/packages/" + pageType + ".atom") } + > + <span class="fa fa-fw fa-rss-square"></span> + </a> + </h3> + <li class="list-group rounded"> + @utils.ChangedVersionsTable(versions) + </li> + </div> + </div> + </div> +} + +// Added renders a template containing a list of 50 recently added versions. +func Added(w http.ResponseWriter, r *http.Request) { + addedVersions := GetAddedVersions(50) + categories.RenderPage(w, r, "Added Packages", "Added", changedVersionsPage("added", addedVersions)) +} + +func AddedFeed(w http.ResponseWriter, r *http.Request) { + addedPackages := GetAddedPackages(250) + feeds.AddedPackages("Added packages in Gentoo.", "Added packages in Gentoo.", addedPackages, w) +} + +// Updated renders a template containing +// a list of 50 recently updated versions +func Updated(w http.ResponseWriter, r *http.Request) { + updatedVersions := GetUpdatedVersions(50) + categories.RenderPage(w, r, "Updated Packages", "Updated", changedVersionsPage("updated", updatedVersions)) +} + +func UpdatedFeed(w http.ResponseWriter, r *http.Request) { + updatedVersions := GetUpdatedVersions(250) + feeds.Changes("Added packages in Gentoo.", "Added packages in Gentoo.", updatedVersions, w) +} + +// Stabilized renders a template containing +// a list of 50 recently stabilized versions +func Stabilized(w http.ResponseWriter, r *http.Request) { + stabilizedVersions := GetStabilizedVersions(50) + categories.RenderPage(w, r, "Stabilized Packages", "Newly Stable", changedVersionsPage("stabilized", stabilizedVersions)) +} + +func StabilizedFeed(w http.ResponseWriter, r *http.Request) { + stabilizedVersions := GetStabilizedVersions(250) + feeds.Changes("Stabilized packages in Gentoo.", "Stabilized packages in Gentoo.", stabilizedVersions, w) +} + +// Keyworded renders a template containing +// a list of 50 recently keyworded versions +func Keyworded(w http.ResponseWriter, r *http.Request) { + keywordedVersions := GetKeywordedVersions(50) + categories.RenderPage(w, r, "Keyworded Packages", "Keyworded", changedVersionsPage("keyworded", keywordedVersions)) +} + +func KeywordedFeed(w http.ResponseWriter, r *http.Request) { + keywordedVersions := GetKeywordedVersions(250) + feeds.Changes("Keyworded packages in Gentoo.", "Keyworded packages in Gentoo.", keywordedVersions, w) +} diff --git a/pkg/app/handler/packages/components/bugs.templ b/pkg/app/handler/packages/components/bugs.templ new file mode 100644 index 0000000..ee49df2 --- /dev/null +++ b/pkg/app/handler/packages/components/bugs.templ @@ -0,0 +1,152 @@ +package components + +import "soko/pkg/models" +import "strconv" + +templ bugsList(title, component string, bugs []*models.Bug, titleClass, id string) { + <h3 id={ id } class={ titleClass }>{ title }</h3> + <ul class="list-group"> + for _, bug := range bugs { + if bug.Component == component { + <li class="list-group-item"> + <div class="row"> + <div class="col-md-12"> + <i class="fa fa-bug" aria-hidden="true"></i> + <a href={ templ.URL("https://bugs.gentoo.org/" + bug.Id) } class="text-dark"><b>{ bug.Summary }</b></a> + </div> + <div class="col-md-12 text-muted"> + { bug.Id } - Assigned to { bug.Assignee } + </div> + </div> + </li> + } + } + </ul> +} + +func bugAtomLink(atom string) templ.SafeURL { + if atom == "" { + return templ.URL("https://bugs.gentoo.org/") + } + return templ.URL("https://bugs.gentoo.org/enter_bug.cgi?product=Gentoo Linux&component=Current packages&short_desc=" + atom + ": <ADD SUMMARY HERE>") +} + +templ Bugs(atom string, generalCount, stabilizationCount, keywordingCount int, bugs []*models.Bug) { + <div class="row"> + <div class="col-md-9"> + if len(bugs) > 0 { + if generalCount > 0 { + @bugsList("Bug Reports", "Current packages", bugs, "mb-4", "packages") + } + if stabilizationCount > 0 { + @bugsList("Stabilization Bug Reports", "Stabilization", bugs, "my-4", "stabilization") + } + if keywordingCount > 0 { + @bugsList("Keywording Bug Reports", "Keywording", bugs, "my-4", "keywording") + } + } else { + <div class="row pt-5"> + <div class="col-md-4"> + <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/> + </div> + <div class="col-md-8 pt-3"> + <h2>Good job! There are no bugs.</h2> + <span>You think something is missing here? <br/> Start with filling a <a href={ bugAtomLink(atom) }>new bug</a>.</span> + </div> + </div> + } + </div> + <div class="col-md-3 pt-5"> + <h4 class=""> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> + Description + </a> + </h4> + <div class="collapse show" id="collapseDescription"> + <span class="text-muted"> + Gentoo Bugzilla is where we track bugs of Gentoo and its packages; you are welcome to report, confirm and resolve bugs: + <ul> + <li><a href={ bugAtomLink(atom) }>File a new Bug</a></li> + <li><a href="https://bugs.gentoo.org/">Confirm a bug</a></li> + <li><a href="https://wiki.gentoo.org/wiki/Bugday">Participate in our monthly Bugday</a></li> + </ul> + </span> + </div> + <h4 class=""> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseShortcuts" role="button" aria-expanded="false" aria-controls="collapseShortcuts"> + Shortcuts + </a> + </h4> + <div class="collapse show" id="collapseShortcuts"> + <ul> + <li> + <a + if generalCount > 0 { + href="#packages" + } + > + Packages Bugs ({ strconv.Itoa(generalCount) }) + </a> + </li> + <li> + <a + if stabilizationCount > 0 { + href="#stabilization" + } + > + Stabilization Bugs ({ strconv.Itoa(stabilizationCount) }) + </a> + </li> + <li> + <a + if keywordingCount > 0 { + href="#keywording" + } + > + Keywording Bugs ({ strconv.Itoa(keywordingCount) }) + </a> + </li> + </ul> + </div> + </div> + </div> +} + +func securityBugAtomLink(atom string) templ.SafeURL { + if atom == "" { + return templ.URL("https://bugs.gentoo.org/enter_bug.cgi?product=Gentoo Security&component=Vulnerabilities") + } + return templ.URL("https://bugs.gentoo.org/enter_bug.cgi?product=Gentoo Security&component=Vulnerabilities&short_desc=" + atom + ": <ADD SUMMARY HERE>") +} + +templ SecurityBugs(atom string, bugs []*models.Bug) { + <div class="row"> + <div class="col-md-9"> + if len(bugs) > 0 { + @bugsList("Security Bug Reports", "Vulnerabilities", bugs, "mb-4", "security") + } else { + <div class="row pt-5"> + <div class="col-md-4"> + <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/> + </div> + <div class="col-md-8 pt-3"> + <h2>There are no open security bugs.</h2> + <span>You think something is missing here? <br/> Start with filling a <a href={ securityBugAtomLink(atom) }>new security bug</a>.</span> + </div> + </div> + } + </div> + <div class="col-md-3 pt-5"> + <h4> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> + Contact Information + </a> + </h4> + <div class="collapse show" id="collapseDescription"> + <span class="text-muted"> + Please file new vulnerability reports on <a href={ securityBugAtomLink(atom) }>Gentoo Bugzilla</a> and assign them to the Gentoo Security product and Vulnerabilities component. + </span> + </div> + </div> + </div> +} diff --git a/pkg/app/handler/packages/components/changelog.templ b/pkg/app/handler/packages/components/changelog.templ new file mode 100644 index 0000000..9e86328 --- /dev/null +++ b/pkg/app/handler/packages/components/changelog.templ @@ -0,0 +1,121 @@ +package components + +import "crypto/md5" +import "encoding/hex" +import "time" +import "soko/pkg/models" + +func gravatar(email string) string { + hasher := md5.Sum([]byte(email)) + hash := hex.EncodeToString(hasher[:]) + return "https://www.gravatar.com/avatar/" + hash + "?s=13&d=retro" +} + +templ chagedPaths(commitId string, badgeClass string, files []*models.ChangedFile) { + for idx, value := range files { + if idx < 20 { + <span class={ "badge badge-pill badge-light", badgeClass }> + <a class="text-muted" href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/diff/" + value.Path + "?id=" + commitId) }>{ value.Path }</a> + </span> + } + } +} + +templ Changelog(atom string, commits []*models.Commit) { + <div class="row"> + <div class="col-md-9"> + if len(commits) > 0 { + <span class="d-flex justify-content-between"> + <h3>Latest Commits</h3> + <span> + <a + if atom != "" { + href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/atom/" + atom + "?h=master") } + } else { + href="./changelog.atom" + } + target="_blank" + > + <span class="fa fa-fw fa-rss text-dark"></span> Atom feed + </a> + </span> + </span> + <style> + .kk-added-file-badge { + background-color: #dff0d8; + font-weight: normal; + } + .kk-added-file-badge > a { + color: #424242!important; + } + .kk-modified-file-badge { + background-color: #fcf8e3; + font-weight: normal; + } + .kk-modified-file-badge > a { + color: #424242!important; + } + .kk-deleted-file-badge { + background-color: #f2dede; + font-weight: normal; + } + .kk-deleted-file-badge > a { + color: #424242!important; + } + </style> + <ul class="timeline"> + <li> + <span class="text-muted">Commits on { commits[0].CommitterDate.Format(time.DateOnly) }</span> + <ul class="list-group"> + for i, commit := range commits { + if currentDate := commit.CommitterDate.Format(time.DateOnly); i > 0 && currentDate != commits[i-1].CommitterDate.Format(time.DateOnly) { + @templ.Raw("</ul></li><li>") + <span class="text-muted">Commits on { currentDate }</span> + @templ.Raw(`<ul class="list-group">`) + } + <li class="list-group-item"> + <div class="row"> + <div class="col-md-8"> + <a href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=" + commit.Id) }><b style="color:#424242!important;">{ commit.Message }</b></a> + </div> + <div class="col-md-4 text-right text-muted"> + <a title={ commit.Id } class="kk-commit" href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=" + commit.Id) }>{ commit.Id[:7] }</a> + </div> + <div class="col-md-12" style="color:#424242!important;"> + if commit.AuthorName != commit.CommitterName { + <span data-toggle="tooltip" title={ "authored on " + commit.AuthorDate.Format(time.DateTime) + " UTC" }> + <img class="rounded-sm inline" data-toggle="popover" data-img="http://placehold.it/400x200" src={ gravatar(commit.AuthorEmail) }/> + <a href={ templ.URL("mailto:" + commit.AuthorEmail) }>{ commit.AuthorName }</a> authored + </span> and + } + <img class="rounded-sm inline" src={ gravatar(commit.CommitterEmail) }/> + <a href={ templ.URL("mailto:" + commit.CommitterEmail) }>{ commit.CommitterName }</a> committed on { commit.CommitterDate.Format(time.DateTime) } UTC + </div> + <div class="col-md-12"> + @chagedPaths(commit.Id, "kk-added-file-badge", commit.ChangedFiles.Added) + @chagedPaths(commit.Id, "kk-modified-file-badge", commit.ChangedFiles.Modified) + @chagedPaths(commit.Id, "kk-deleted-file-badge", commit.ChangedFiles.Deleted) + if len(commit.ChangedFiles.Added)> 20 || len(commit.ChangedFiles.Modified) > 20 || len(commit.ChangedFiles.Deleted) > 20 { + <a href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=" + commit.Id) } class="text-muted">...</a> + } + </div> + </div> + </li> + } + </ul> + </li> + </ul> + } else if atom != "" { + <li class="list-group-item kk-panel-content-sorry"> + This package has not been changed since our repository has moved to Git. + <br/> + <br/> + <a href={ templ.URL("https://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/" + atom + "/ChangeLog?view=markup") } class="btn btn-default"> + <span class="fa fa-fw fa-history"></span> + View old CVS Changelog + </a> + </li> + } + </div> + </div> +} diff --git a/pkg/app/handler/packages/components/outdated.templ b/pkg/app/handler/packages/components/outdated.templ new file mode 100644 index 0000000..30a7ce1 --- /dev/null +++ b/pkg/app/handler/packages/components/outdated.templ @@ -0,0 +1,66 @@ +package components + +type OutdatedItem struct { + Atom string + Description string +} + +templ Outdated(outdated []OutdatedItem) { + <div class="row"> + <div class="col-md-9"> + if len(outdated) > 0 { + <span class="d-flex justify-content-between"> + <h3 class="mb-4">Outdated Packages</h3> + <span> + <a href="./outdated.atom"> + <span class="fa fa-fw fa-rss text-dark"></span> Atom feed + </a> + </span> + </span> + <ul class="list-group"> + for _, pkg := range outdated { + <li class="list-group-item"> + <div class="row"> + <div class="col-md-4"> + <a href={ templ.URL("/packages/" + pkg.Atom) } class="text-dark"><b>{ pkg.Atom }</b></a> + </div> + <div class="col-md-8 text-muted">{ pkg.Description }</div> + </div> + </li> + } + </ul> + } else { + <div class="row pt-5"> + <div class="col-md-4"> + <img + style="width: 100%;" + src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png" + /> + </div> + <div class="col-md-8 pt-3"> + <h2>Good job!</h2> + <span> + According to repology.org there are no outdated packages here. + <br/> + Please use this information with care though. The repology data might not be accurate. + </span> + </div> + </div> + } + </div> + <div class="col-md-3 pt-4"> + <h4 class=""> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> + Description + </a> + </h4> + <div class="collapse show" id="collapseDescription"> + <span class="text-muted"> + Based on the data of <a href="https://repology.org/">repology.org</a>, there might be a new version available for these packages. + <br/> + Please don't solely rely on this information, as the repology data might not be accurate. + </span> + </div> + </div> + </div> +} diff --git a/pkg/app/handler/packages/components/pullrequests.templ b/pkg/app/handler/packages/components/pullrequests.templ new file mode 100644 index 0000000..0f2cc2a --- /dev/null +++ b/pkg/app/handler/packages/components/pullrequests.templ @@ -0,0 +1,91 @@ +package components + +import "soko/pkg/models" +import "strconv" + +css badgeColor(color string) { + font-weight: normal; + background-color: { "#" + color + "!important" }; +} + +func isDarkBadgeColor(color string) bool { + return color == "5319e7" || color == "0052cc" || color == "b60205" +} + +templ PullRequests(pullRequests []*models.GithubPullRequest) { + <div class="row"> + <div class="col-md-9"> + if len(pullRequests) > 0 { + <h3 class="mb-4">Pull Requests</h3> + <ul class="list-group"> + for _, pr := range pullRequests { + <li class="list-group-item"> + <div class="row"> + <div class="col-md-11"> + <span class="octicon octicon-git-pull-request opticon-resource-icon ml-1" style="color:SeaGreen;"></span> + <a href={ templ.URL("https://github.com/gentoo/gentoo/pull/" + pr.Id) } class="text-dark"> + <b>{ pr.Title }</b> + </a> + <a href={ templ.URL(pr.CiStateLink) }> + if pr.CiState == "SUCCESS" { + <i class="fa fa-check mx-1" aria-hidden="true" style="color: SeaGreen;"></i> + } else { + <i class="fa fa-times mx-1" aria-hidden="true" style="color: #b60205;"></i> + } + </a> + for _, label := range pr.Labels { + <span + class={ + "badge badge-pill p-1", + badgeColor(label.Color), + templ.KV("badge-light", !isDarkBadgeColor(label.Color)), + templ.KV("badge-dark", isDarkBadgeColor(label.Color)), + } + > + { label.Name } + </span> + } + </div> + <div class="col-md-1 text-right"> + <a href={ templ.URL("https://github.com/gentoo/gentoo/pull/" + pr.Id) } class="text-muted"> + <i class="fa fa-comment-o" aria-hidden="true"></i> + { strconv.Itoa(pr.Comments) } + </a> + </div> + <div class="col-md-12 text-muted"> + <span style="font-size: 90%;"> + #{ pr.Id } opened { pr.CreatedAt } by { pr.Author } + </span> + </div> + </div> + </li> + } + </ul> + } else { + <div class="row pt-5"> + <div class="col-md-4"> + <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/> + </div> + <div class="col-md-8 pt-3"> + <h2>There are no pull requests</h2> + <span>You think something is missing here? <br/> Start with filling a <a href="https://wiki.gentoo.org/wiki/Gentoo_GitHub">new pull requests</a>.</span> + </div> + </div> + } + </div> + <div class="col-md-3 pt-4"> + <h4 class=""> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> + Description + </a> + </h4> + <div class="collapse show" id="collapseDescription"> + <span class="text-muted"> + If you also like to help the Gentoo project, you can consider sending a Pull Request via GitHub. + <br/> + Before doing so, you might want to take a look at <a href="https://wiki.gentoo.org/wiki/Gentoo_GitHub">the wiki page</a>. + </span> + </div> + </div> + </div> +} diff --git a/pkg/app/handler/packages/components/stabilization.templ b/pkg/app/handler/packages/components/stabilization.templ new file mode 100644 index 0000000..1bdd1c2 --- /dev/null +++ b/pkg/app/handler/packages/components/stabilization.templ @@ -0,0 +1,58 @@ +package components + +import "soko/pkg/models" + +templ Stabilizations(results []*models.PkgCheckResult) { + <div class="row"> + <div class="col-md-9"> + <span class="d-flex justify-content-between"> + <h3>Stable Requests</h3> + <span> + <a href="./stabilization.atom"> + <span class="fa fa-fw fa-rss text-dark"></span> Atom feed + </a> + + <button type="button" class="kk-btn-xs btn btn-outline-secondary" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + <span class="fa fa-fw fa-download"></span> + </button> + <span class="dropdown-menu dropdown-menu-right"> + <a class="dropdown-item" href="./stabilization.list" target="_blank">Plain Text</a> + <a class="dropdown-item" href="./stabilization.json" target="_blank">JSON file</a> + <a class="dropdown-item" href="./stabilization.xml" target="_blank">XML file</a> + </span> + </span> + </span> + if len(results) > 0 { + <ul class="timeline"> + for _, res := range results { + <li> + <ul class="list-group"> + <li class="list-group-item"> + <a href={ templ.URL("/packages/" + res.Atom) } class="text-dark"> + <strong>{ res.CPV }</strong> + </a> + <br/> + <span class="kk-version kk-cell-sep-right text-muted">{ res.Message }</span> + </li> + </ul> + </li> + } + </ul> + } else { + <div class="text-center w-100"><i>- No Stable Requests found -</i></div> + } + </div> + <div class="col-md-3 pt-4"> + <h4> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> + Description + </a> + </h4> + <div class="collapse show" id="collapseDescription"> + <span class="text-muted"> + This page lists potential stabilization candidates. Please have a look at the <a href="https://wiki.gentoo.org/wiki/Stable_request">wiki page</a> { "for" } more information. + </span> + </div> + </div> + </div> +} diff --git a/pkg/app/handler/packages/dependencies.templ b/pkg/app/handler/packages/dependencies.templ new file mode 100644 index 0000000..ea4e00b --- /dev/null +++ b/pkg/app/handler/packages/dependencies.templ @@ -0,0 +1,139 @@ +package packages + +import "soko/pkg/models" + +var dependenciesInnerTypes = []string{"rindex", "dindex", "bindex", "iindex", "pindex"} + +templ dependencies(pkg *models.Package) { + <div class="row"> + <div class="col-md-9"> + <h3> + <a class="text-dark"> + <i class="fa fa-level-down" aria-hidden="true"></i> Dependencies + </a> + <a href={ templ.URL("/packages/" + pkg.Atom + "/reverse-dependencies") } class="ml-3 text-muted"> + <i class="fa fa-level-up" aria-hidden="true"></i> Reverse-Dependencies + </a> + </h3> + <ul class="timeline"> + for _, version := range pkg.Versions { + <li> + <span class="text-muted">{ version.Version }</span> + if depMap := version.BuildDepMap(); len(depMap) != 0 { + <div class="card mt-4"> + <div class="table-responsive border-0"> + <table class="table mb-0"> + <thead> + <tr> + <th scope="col">Version</th> + <th scope="col">RDEPEND</th> + <th scope="col">DEPEND</th> + <th scope="col">BDEPEND</th> + <th scope="col">IDEPEND</th> + <th scope="col">PDEPEND</th> + </tr> + </thead> + <tbody> + for _, atomMap := range depMap { + <tr> + <th scope="row"><a class="text-dark" href={ templ.URL("/packages/" + atomMap.Atom) }>{ atomMap.Atom }</a></th> + for _, key := range dependenciesInnerTypes { + <td> + if _, found := atomMap.Map[key]; found { + <i class="fa fa-check" style="color:green;" aria-hidden="true"></i> + } else { + <i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i> + } + </td> + } + </tr> + } + </tbody> + </table> + </div> + </div> + } + </li> + } + </ul> + </div> + <div class="col-md-3 pt-5"> + <h4 class=""> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> + Description + </a> + </h4> + <div class="collapse show" id="collapseDescription"> + <span class="text-muted"> + The dependencies are regularly computed based on the <a href="https://qa-reports.gentoo.org/">qa-reports</a>. + </span> + </div> + </div> + </div> +} + +templ reverseDependencies(pkg *models.Package) { + <div class="row"> + <div class="col-md-9"> + <h3> + <a class="text-muted" href={ templ.URL("/packages/" + pkg.Atom + "/dependencies") }> + <i class="fa fa-level-down" aria-hidden="true"></i> Dependencies + </a> + <a class="ml-3 text-dark"> + <i class="fa fa-level-up" aria-hidden="true"></i> Reverse-Dependencies + </a> + </h3> + <div class="card mt-4"> + <div class="table-responsive border-0"> + <table class="table mb-0"> + <thead> + <tr> + <th scope="col">Version</th> + <th scope="col">RDEPEND</th> + <th scope="col">DEPEND</th> + <th scope="col">BDEPEND</th> + <th scope="col">IDEPEND</th> + <th scope="col">PDEPEND</th> + </tr> + </thead> + <tbody> + for _, dep := range pkg.BuildRevDepMap() { + <tr> + <th scope="row"><a class="text-dark" href={ templ.URL("/packages/" + dep.Atom) }>{ dep.Version }</a></th> + for _, key := range dependenciesInnerTypes { + <td> + if _, found := dep.Map[key]; found { + <i class="fa fa-check" style="color:green;" aria-hidden="true"></i> + } else { + <i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i> + } + </td> + } + </tr> + } + </tbody> + </table> + </div> + </div> + </div> + <div class="col-md-3 pt-5"> + <h4 class=""> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> + Description + </a> + </h4> + <div class="collapse show" id="collapseDescription"> + <span class="text-muted"> + The reverse dependencies are regularly parsed from the <a href="https://qa-reports.gentoo.org/">qa-reports</a>. The sources can be found at: + <ul> + <li><a href={ templ.URL("https://qa-reports.gentoo.org/output/genrdeps/rindex/" + pkg.Atom) }>rdepend</a></li> + <li><a href={ templ.URL("https://qa-reports.gentoo.org/output/genrdeps/dindex/" + pkg.Atom) }>depend</a></li> + <li><a href={ templ.URL("https://qa-reports.gentoo.org/output/genrdeps/bindex/" + pkg.Atom) }>bdepend</a></li> + <li><a href={ templ.URL("https://qa-reports.gentoo.org/output/genrdeps/iindex/" + pkg.Atom) }>idepend</a></li> + <li><a href={ templ.URL("https://qa-reports.gentoo.org/output/genrdeps/pindex/" + pkg.Atom) }>pdepend</a></li> + </ul> + </span> + </div> + </div> + </div> +} diff --git a/pkg/app/handler/packages/json.go b/pkg/app/handler/packages/json.go index 24cb2e7..8621736 100644 --- a/pkg/app/handler/packages/json.go +++ b/pkg/app/handler/packages/json.go @@ -2,13 +2,13 @@ package packages import ( "encoding/json" - "github.com/go-pg/pg" - "github.com/go-pg/pg/v9/orm" "net/http" "soko/pkg/database" "soko/pkg/models" "strings" "time" + + "github.com/go-pg/pg/v10" ) // build the json for the package @@ -20,12 +20,15 @@ func buildJson(w http.ResponseWriter, r *http.Request) { Where("atom = ?", atom). Relation("Versions"). Relation("Versions.Masks"). - Relation("Commits", func(q *orm.Query) (*orm.Query, error) { + Relation("Commits", func(q *pg.Query) (*pg.Query, error) { return q.Order("preceding_commits DESC").Limit(1), nil }). Select() - if err != nil && err != pg.ErrNoRows { + if err == pg.ErrNoRows { + http.NotFound(w, r) + return + } else if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return @@ -33,6 +36,11 @@ func buildJson(w http.ResponseWriter, r *http.Request) { sortVersionsDesc(gpackage.Versions) + if len(gpackage.Versions) == 0 || len(gpackage.Commits) == 0 { + http.NotFound(w, r) + return + } + versions := getJSONVersions(gpackage) maintainers := getJSONMaintainers(gpackage) useflags := getJSONUseflag(gpackage) diff --git a/pkg/app/handler/packages/keyworded.go b/pkg/app/handler/packages/keyworded.go deleted file mode 100644 index 27e2a15..0000000 --- a/pkg/app/handler/packages/keyworded.go +++ /dev/null @@ -1,20 +0,0 @@ -// Used to show recently keyworded versions - -package packages - -import ( - "net/http" - "soko/pkg/app/handler/feeds" -) - -// Keyworded renders a template containing -// a list of 50 recently keyworded versions -func Keyworded(w http.ResponseWriter, r *http.Request) { - keywordedVersions := GetKeywordedVersions(50) - RenderPackageTemplates("changedVersions", "changedVersions", "changedVersionRow", GetFuncMap(), CreateFeedData("Keyworded", keywordedVersions), w) -} - -func KeywordedFeed(w http.ResponseWriter, r *http.Request) { - keywordedVersions := GetKeywordedVersions(250) - feeds.Changes("Keyworded packages in Gentoo.", "Keyworded packages in Gentoo.", keywordedVersions, w) -} diff --git a/pkg/app/handler/packages/overview.templ b/pkg/app/handler/packages/overview.templ new file mode 100644 index 0000000..7bf34d2 --- /dev/null +++ b/pkg/app/handler/packages/overview.templ @@ -0,0 +1,467 @@ +package packages + +import "slices" +import "strings" +import "time" +import "soko/pkg/app/handler/packages/components" +import "soko/pkg/app/utils" +import "soko/pkg/models" + +func overviewSlotText(version *models.Version) string { + if version.Subslot != "" { + return version.Slot + "/" + version.Subslot + } + return version.Slot +} + +templ overviewVersionRow(version *models.Version, userPreferences *models.UserPreferences) { + <tr> + <td class="kk-version "> + <strong> + <a + class="kk-ebuild-link" + href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/tree/" + version.Atom + "/" + version.Package + "-" + version.Version + ".ebuild") } + > + { version.Version } + </a> + </strong> + <span class="kk-slot"> : { overviewSlotText(version) }</span> + if len(version.Restricts) > 0 { + <span + class="badge badge-danger kk-restrict-label" + title={ "The following features are restricted: " + strings.Join(version.Restricts, " ") } + > + { utils.FormatRestricts(version.Restricts) } + </span> + } + if userPreferences.Packages.Overview.EAPI == "inline" { + <span style="background-color: white;border:1px solid grey;color: grey;" class="badge badge-danger kk-restrict-label" title="The following features are restricted:">EAPI { version.EAPI }</span> + } + </td> + if userPreferences.Packages.Overview.EAPI == "column" { + <td class="text-center"> + { version.EAPI } + </td> + } + for _, arch := range models.ArchesToShow { + if keywords := strings.Fields(version.Keywords); slices.Contains(keywords, "~"+arch) { + if len(version.Masks) > 0 { + <td class="kk-keyword kk-keyword-masked" title={ version.Version + " is masked (testing) on " + arch }> + <svg height="16" class="octicon octicon-diff-modified" version="1.1" width="14" aria-hidden="true"><use href="#svg-ver-mask" xlink:href="#svg-ver-mask"></use></svg> + <span class="sr-only">~{ arch }</span> + </td> + } else { + <td class="kk-keyword kk-keyword-testing" title={ version.Version + " is testing on " + arch }> + <svg height="16" class="octicon octicon-diff-modified" version="1.1" width="14" aria-hidden="true"><use href="#svg-ver-testing" xlink:href="#svg-ver-testing"></use></svg> + <span class="sr-only">~{ arch }</span> + </td> + } + } else if slices.Contains(keywords, "-"+arch) { + <td class="kk-keyword kk-keyword-unavailable" title={ version.Version + " is unavailable on " + arch }> + <svg height="16" class="octicon octicon-diff-removed" version="1.1" width="14" aria-hidden="true"><use href="#svg-ver-unavailable" xlink:href="#svg-ver-unavailable"></use></svg> + <span class="sr-only">-{ arch }</span> + </td> + } else if slices.Contains(keywords, arch) { + if len(version.Masks) > 0 { + <td class="kk-keyword kk-keyword-masked" title={ version.Version + " is masked (stable) on " + arch }> + <svg height="16" class="octicon octicon-diff-added" version="1.1" width="14" aria-hidden="true"><use href="#svg-ver-mask" xlink:href="#svg-ver-mask"></use></svg> + <span class="sr-only">{ arch }</span> + </td> + } else { + <td class="kk-keyword kk-keyword-stable" title={ version.Version + " is stable on " + arch }> + <svg height="16" class="octicon octicon-diff-added" version="1.1" width="14" aria-hidden="true"><use href="#svg-ver-stable" xlink:href="#svg-ver-stable"></use></svg> + <span class="sr-only">{ arch }</span> + </td> + } + } else if slices.Contains(keywords, "-*") { + <td class="kk-keyword kk-keyword-unavailable" title={ version.Version + " is unavailable on " + arch }> + <svg height="16" class="octicon octicon-diff-removed" version="1.1" width="14" aria-hidden="true"><use href="#svg-ver-unavailable" xlink:href="#svg-ver-unavailable"></use></svg> + <span class="sr-only">-{ arch }</span> + </td> + } else { + <td class="kk-keyword kk-keyword-unkown" title={ version.Version + " is unknown on " + arch }> + <span class="sr-only">?{ arch }</span> + </td> + } + } + </tr> +} + +templ overviewVersions(pkg *models.Package, userPreferences *models.UserPreferences) { + <h3 class="mb-2">Available Versions</h3> + <div class="card mb-4 rounded"> + <svg style="display: none" version="1.1"> + <defs> + <symbol id="svg-ver-mask" viewBox="0 0 14 16"> + <path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-8.5-2H3v-1.5L9.5 4H11v1.5L4.5 12z"></path> + </symbol> + <symbol id="svg-ver-testing" viewBox="0 0 14 16"> + <path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM4 8c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3-3-1.34-3-3z"></path> + </symbol> + <symbol id="svg-ver-unavailable" viewBox="0 0 14 16"> + <path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-2-5H3V7h8v2z"></path> + </symbol> + <symbol id="svg-ver-stable" viewBox="0 0 14 16"> + <path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM6 9H3V7h3V4h2v3h3v2H8v3H6V9z"></path> + </symbol> + </defs> + </svg> + <div class="table-responsive border-0"> + <table class="table table-bordered kk-versions-table mb-0 overflow-hidden border-0"> + <thead class="border-0"> + <tr class="border-0"> + <th class="kk-version border-left-0 border-top-0">Version</th> + if userPreferences.Packages.Overview.EAPI == "column" { + <th class="kk-keyword-header kk-keyword border-left-0 border-top-0">EAPI</th> + } + for _, arch := range models.ArchesToShow { + <th class="kk-keyword-header kk-keyword border-left-0 border-top-0">{ arch }</th> + } + </tr> + </thead> + <tbody> + for _, version := range pkg.Versions { + @overviewVersionRow(version, userPreferences) + } + </tbody> + </table> + </div> + </div> +} + +templ overview(pkg *models.Package, userPreferences *models.UserPreferences) { + <div class="row"> + <div class="col-md-9"> + if len(pkg.Outdated) > 0 { + if !pkg.HasVersion(pkg.Outdated[0].NewestVersion) { + <div class="alert alert-info"> + <strong><span class="fa fa-fw fa-lightbulb-o"></span> Version { pkg.Outdated[0].NewestVersion } is available upstream. Please consider updating!</strong> + <br/> + It seems that version { pkg.Outdated[0].NewestVersion } is available upstream, while the latest version in the Gentoo tree is { pkg.Outdated[0].GentooVersion }. + <br/> + <small><i>You think this warning is false? Read more about it <a href="https://archives.gentoo.org/gentoo-dev/message/b793f4da5a5b5e20a063ea431500a820">here</a>.</i></small> + </div> + } + } + @overviewVersions(pkg, userPreferences) + if mask := getMask(pkg.Versions); mask != nil { + <h3 class="pt-3 mb-2">Masks</h3> + <div class="card kk-mask mb-3"> + <ul class="list-group list-group-flush kk-mask"> + <li class="list-group-item kk-mask"> + if showRemovalNotice(pkg.Versions) { + <p style="color:#721c24;"> + <strong><span class="fa fa-fw fa-warning"></span> This package is masked and could be removed soon!</strong> + <br/> + The mask comment indicates that this package is scheduled for removal from our package repository. + <br/> + Please review the mask information below for more details. + </p> + } + <strong class="kk-mask-reason"> + @templ.Raw(mask.Reason) + </strong> + <div class="kk-mask-details"> + <div class="row"> + <div class="col-xs-12 col-md-3 kk-metadata-key"> + Affected packages + </div> + <div class="col-xs-12 col-md-9 kk-mask-atoms overflow-hidden"> + { mask.Versions } + </div> + </div> + <div class="row"> + <div class="col-xs-12 col-md-3 kk-metadata-key"> + Author/Date + </div> + <div class="col-xs-12 col-md-9"> + { mask.Author } <{ mask.AuthorEmail }> <span class="text-muted">({ mask.Date.Format(time.DateOnly) })</span> + </div> + </div> + </div> + </li> + </ul> + </div> + } else if deprecation := getDeprecation(pkg.Versions); deprecation != nil { + <h3 class="pt-3 mb-2">Deprecation Warning</h3> + <div class="card bg-warning mb-3"> + <ul class="list-group list-group-flush bg-warning"> + <li class="list-group-item bg-warning"> + <strong class="kk-mask-reason"> + @templ.Raw(deprecation.Reason) + </strong> + <div class="kk-mask-details"> + <div class="row"> + <div class="col-xs-12 col-md-3 kk-metadata-key"> + Affected packages + </div> + <div class="col-xs-12 col-md-9 kk-mask-atoms overflow-hidden"> + { deprecation.Versions } + </div> + </div> + <div class="row"> + <div class="col-xs-12 col-md-3 kk-metadata-key"> + Author/Date + </div> + <div class="col-xs-12 col-md-9"> + { deprecation.Author } <{ deprecation.AuthorEmail }> <span class="text-muted">({ deprecation.Date.Format(time.DateOnly) })</span> + </div> + </div> + </div> + </li> + </ul> + </div> + } + if len(pkg.Maintainers) == 0 { + <div class="alert alert-info"> + <strong><span class="fa fa-fw fa-wrench"></span> This package needs a new maintainer!</strong> + <br/> + If you are interested in helping with the maintenance of { pkg.Name }, please get in touch with our + <a href="https://wiki.gentoo.org/wiki/Project:Proxy_Maintainers" class="alert-link">Proxy Maintainers team</a>. + </div> + } + <h3 class="pt-3 mb-2">Package Metadata</h3> + <div class="card border-0 mb-3"> + <ul class="list-group kk-metadata-list"> + if len(pkg.Versions[0].Homepage) > 1 { + <li class="kk-metadata-item list-group-item"> + <div class="row"> + <div class="col-xs-12 col-md-3 kk-metadata-key"> + <span class="fa fa-fw fa-home"></span> + Other homepage(s) + </div> + <div class="col-xs-12 col-md-9"> + for i, url := range pkg.Versions[0].Homepage[1:] { + if i > 0 { + <br/> + } + <a href={ templ.URL(url) }>{ url }</a> + } + </div> + </div> + </li> + } + if len(pkg.Upstream.Doc) > 0 || len(pkg.Upstream.Changelog) > 0 || len(pkg.Upstream.BugsTo) > 0 || len(pkg.Upstream.RemoteIds) > 0 { + <li class="kk-metadata-item list-group-item"> + <div class="row"> + <div class="col-xs-12 col-md-3 kk-metadata-key"> + <span class="fa fa-fw fa-code-fork"></span> + Upstream + </div> + <div class="col-xs-12 col-md-9"> + <table> + for i, url := range pkg.Upstream.Doc { + <tr> + <td> + if i == 0 { + <span class="kk-useflag-group float-right mr-2">Documentation</span> + } + </td> + <td><a href={ templ.URL(url) }>{ url }</a></td> + </tr> + } + for i, url := range pkg.Upstream.Changelog { + <tr> + <td> + if i == 0 { + <span class="kk-useflag-group float-right mr-2">Changelog</span> + } + </td> + <td><a href={ templ.URL(url) }>{ url }</a></td> + </tr> + } + for i, url := range pkg.Upstream.BugsTo { + <tr> + <td> + if i == 0 { + <span class="kk-useflag-group float-right mr-2">Bugs-To</span> + } + </td> + <td><a href={ templ.URL(url) }>{ url }</a></td> + </tr> + } + for i, remote := range pkg.Upstream.RemoteIds { + <tr> + <td> + if i == 0 { + <span class="kk-useflag-group float-right mr-2">Remote-Id</span> + } + </td> + <td> + if url := remoteIdLink(remote); url != "" { + <a href={ templ.URL(url) }>{ url }</a> + } else { + <a>({ remote.Type }) { remote.Id }</a> + } + </td> + </tr> + } + </table> + </div> + </div> + </li> + } + if pkg.Longdescription != "" { + <li class="kk-metadata-item list-group-item"> + <div class="row"> + <div class="col-xs-12 col-md-3 kk-metadata-key"> + <span class="fa fa-fw fa-info"></span>Full description + </div> + <div class="col-xs-12 col-md-9"> + { pkg.Longdescription } + </div> + </div> + </li> + } + if localUseflags, globalUseflags, useExpands := getPackageUseflags(pkg); len(localUseflags) > 0 || len(globalUseflags) > 0 || len(useExpands) > 0 { + <li class="kk-metadata-item list-group-item"> + <div class="row"> + <div class="col-xs-12 col-md-3 kk-metadata-key"> + <span class="fa fa-fw fa-sliders"></span> + USE flags + </div> + <div class="col-xs-12 col-md-9"> + if len(localUseflags) > 0 { + <span class="kk-useflag-group">Local Use Flags</span> + <ul class={ "kk-useflag-container", templ.KV("kk-useflag-container-many", len(localUseflags) >= 10), templ.KV("kk-useflag-container-few", len(localUseflags) < 10) }> + for _, use := range localUseflags { + <li class="kk-useflag"> + <a title={ use.Description } data-toggle="tooltip" href={ templ.URL("/useflags/" + use.Name) }>{ use.Name }</a> + </li> + } + </ul> + } + if len(globalUseflags) > 0 { + <span class="kk-useflag-group">Global Use Flags</span> + <ul class={ "kk-useflag-container", templ.KV("kk-useflag-container-many", len(localUseflags) >= 10), templ.KV("kk-useflag-container-few", len(localUseflags) < 10) }> + for _, use := range globalUseflags { + <li class="kk-useflag"> + <a title={ use.Description } data-toggle="tooltip" href={ templ.URL("/useflags/" + use.Name) }>{ use.Name }</a> + </li> + } + </ul> + } + if len(useExpands) > 0 { + for groupName, flags := range useExpands { + <span class="kk-useflag-group">{ groupName } (Use Expand)</span> + <ul class={ "kk-useflag-container", templ.KV("kk-useflag-container-many", len(localUseflags) >= 10), templ.KV("kk-useflag-container-few", len(localUseflags) < 10) }> + for _, use := range flags { + <li class="kk-useflag"> + <a title={ use.Description } data-toggle="tooltip" href={ templ.URL("/useflags/" + use.Name) }>{ strings.TrimPrefix(use.Name, use.UseExpand + "_") }</a> + </li> + } + </ul> + } + } + </div> + </div> + </li> + } + if pkg.Versions[0].License != "" { + <li class="kk-metadata-item list-group-item"> + <div class="row"> + <div class="col-xs-12 col-md-3 kk-metadata-key"> + <span class="fa fa-fw fa-legal"></span> + License + </div> + <div class="col-xs-12 col-md-9"> + { pkg.Versions[0].License } + </div> + </div> + </li> + } + if len(pkg.Maintainers) > 0 { + <li class="kk-metadata-item list-group-item"> + <div class="row"> + <div class="col-xs-12 col-md-3 kk-metadata-key"> + <span class="fa fa-fw fa-user"></span> + Maintainer(s) + </div> + <div class="col-xs-12 col-md-9"> + for i, maintainer := range pkg.Maintainers { + if i > 0 { + , + } + <a title={ maintainer.PrintName() } href={ templ.URL("/maintainer/" + maintainer.Email) }> + { maintainer.PrintName() } + </a> + <a href={ templ.URL("mailto:" + maintainer.Email) }> + <i class="fa fa-envelope-o" style="font-size: .925em;" aria-hidden="true"></i> + </a> + } + </div> + </div> + </li> + } + </ul> + </div> + if userPreferences.Packages.Overview.Layout == "full" { + <div class="mt-4 pt-4"></div> + @components.Changelog(pkg.Atom, pkg.Commits) + } + </div> + <div class="col-md-3 pl-4 pt-4 mt-2"> + <h4 class="mb-2 ml-1"> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseExternalResources" role="button" aria-expanded="false" aria-controls="collapseExternalResources"> + External Resources + </a> + </h4> + <div class="collapse show" id="collapseExternalResources"> + <dl class="ml-3"> + <dd> + <span class="fa fa-fw fa-bug"></span> + <a href={ templ.URL("https://bugs.gentoo.org/buglist.cgi?quicksearch=" + pkg.Atom) } class="" target="_blank"> + Related bugs + </a> + </dd> + <dd> + <span class="fa fa-fw fa-chain-broken"></span> + <a href={ templ.URL("https://qa-reports.gentoo.org/output/gentoo-ci/output.html;pkg=" + pkg.Category + ":" + pkg.Name) } title="CI report" target="_blank">CI Report</a> + (<a href={ templ.URL("https://qa-reports.gentoo.org/output/gentoo-ci/output.verbose.html;pkg=" + pkg.Category + ":" + pkg.Name) } title="Verbose CI report" target="_blank">verbose</a>) + </dd> + <dd> + <span class="fa fa-fw fa-sort-numeric-desc"></span> + <a href={ templ.URL("https://repology.org/tools/project-by?repo=gentoo&name_type=srcname&target_page=project_versions&name=" + pkg.Atom) } target="_blank"> + Repology + </a> + </dd> + <dd> + <span class="octicon octicon-git-pull-request opticon-resource-icon ml-1"></span> + <a href={ templ.URL("https://github.com/gentoo/gentoo/pulls?q=is%3Apr+is%3Aopen+in%3Atitle+" + pkg.Atom) } target="_blank"> + Open Pull Requests + </a> + </dd> + <dd> + <span class="fa fa-fw fa-book"></span> + <a href={ templ.URL("https://wiki.gentoo.org/wiki/Special:Search/" + pkg.Name) } target="_blank"> + Documentation + </a> + </dd> + <dd> + <span class="fa fa-fw fa-comments-o"></span> + <a href={ templ.URL("https://forums.gentoo.org/search.php?search_terms=all&show_results=topics&search_keywords=" + pkg.Name + "&mode=results") } target="_blank"> + Forums posts + </a> + </dd> + <dd> + <span class="fa fa-fw fa-code-fork"></span> + <a href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/tree/" + pkg.Atom) } target="_blank"> + Git repository browser + </a> + </dd> + <dd> + <span class="fa fa-fw fa-history"></span> + <a href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/log/" + pkg.Atom + "?showmsg=1") } title="Git log" target="_blank">Git log</a> + (<a href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/log/" + pkg.Atom) } title="Short git log" target="_blank">short</a>) + </dd> + <dd> + <span class="fa fa-fw fa-rss"></span> + <a href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/atom/" + pkg.Atom + "?h=master") } target="_blank"> + Changes Feed + </a> + </dd> + </dl> + </div> + </div> + </div> +} diff --git a/pkg/app/handler/packages/qareport.templ b/pkg/app/handler/packages/qareport.templ new file mode 100644 index 0000000..619b7f5 --- /dev/null +++ b/pkg/app/handler/packages/qareport.templ @@ -0,0 +1,70 @@ +package packages + +import "soko/pkg/models" + +templ qaReport(pkg *models.Package) { + <div class="row"> + <div class="col-md-9"> + <h3>Pkgcheck Warnings</h3> + <ul class="timeline"> + <li> + <span class="text-muted">All Versions</span> + <ul class="list-group"> + for _, res := range pkg.PkgCheckResults { + <li class="list-group-item"> + <strong>{ res.Class }</strong> + <br/> + <span class="kk-version kk-cell-sep-right text-muted">{ res.Message }</span> + </li> + } + </ul> + </li> + for _, ver := range pkg.Versions { + <li> + <span class="text-muted">{ ver.Version }</span> + <ul class="list-group"> + for _, res := range ver.PkgCheckResults { + <li class="list-group-item"> + <strong>{ res.Class }</strong> + <br/> + <span class="kk-version kk-cell-sep-right text-muted">{ res.Message }</span> + </li> + } + </ul> + </li> + } + </ul> + </div> + <div class="col-md-3 pt-5"> + <h4 class=""> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> + Description + </a> + </h4> + <div class="collapse show" id="collapseDescription"> + <span class="text-muted"> + Pkgcheck is used regularly to generate QA reports. Pkgcheck is a pkgcore-based QA utility for ebuild repos. + </span> + </div> + <h4 class="mt-4"> + <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseExternalResources" role="button" aria-expanded="false" aria-controls="collapseExternalResources"> + External Resources + </a> + </h4> + <div class="collapse show" id="collapseExternalResources"> + <ul> + <li> + <a href={ templ.URL("https://qa-reports.gentoo.org/output/gentoo-ci/output.html;pkg=" + pkg.Category + ":" + pkg.Name) } target="_blank"> + CI Report + </a> + </li> + <li> + <a href={ templ.URL("https://qa-reports.gentoo.org/output/gentoo-ci/output.verbose.html;pkg=" + pkg.Category + ":" + pkg.Name) } target="_blank"> + CI Report (verbose) + </a> + </li> + </ul> + </div> + </div> + </div> +} diff --git a/pkg/app/handler/packages/resolve.go b/pkg/app/handler/packages/resolve.go index f3027db..8939bea 100644 --- a/pkg/app/handler/packages/resolve.go +++ b/pkg/app/handler/packages/resolve.go @@ -2,11 +2,11 @@ package packages import ( "encoding/json" - "github.com/go-pg/pg" - "github.com/go-pg/pg/v9/orm" "net/http" "soko/pkg/database" "soko/pkg/models" + + "github.com/go-pg/pg/v10" ) // Show renders a template to show a given package @@ -18,7 +18,7 @@ func Resolve(w http.ResponseWriter, r *http.Request) { Where("atom LIKE ?", "%"+atom). Relation("Versions"). Relation("Versions.Masks"). - Relation("Commits", func(q *orm.Query) (*orm.Query, error) { + Relation("Commits", func(q *pg.Query) (*pg.Query, error) { return q.Order("preceding_commits DESC").Limit(1), nil }). Limit(1). diff --git a/pkg/app/handler/packages/search.go b/pkg/app/handler/packages/search.go index 69cda9f..ade3982 100644 --- a/pkg/app/handler/packages/search.go +++ b/pkg/app/handler/packages/search.go @@ -3,62 +3,70 @@ package packages import ( - "github.com/go-pg/pg" + "encoding/json" "net/http" "soko/pkg/app/handler/feeds" + "soko/pkg/app/layout" "soko/pkg/database" "soko/pkg/models" "strings" + + "github.com/go-pg/pg/v10" ) // Search renders a template containing a list of search results // for a given query of packages func Search(w http.ResponseWriter, r *http.Request) { - searchTerm := getParameterValue("q", r) - var packages []models.Package - var err error - if strings.Contains(searchTerm, "@") { + if searchTerm == "" { + http.Redirect(w, r, "/", http.StatusMovedPermanently) + return + } else if strings.Contains(searchTerm, "@") { var maintainers []models.Maintainer database.DBCon.Model(&maintainers).Where("email = ?", searchTerm).Select() if len(maintainers) > 0 { - http.Redirect(w, r, "/maintainer/"+searchTerm, 301) + http.Redirect(w, r, "/maintainer/"+searchTerm, http.StatusMovedPermanently) + return + } + } else if strings.Contains(searchTerm, "/") { + var packages []models.Package + database.DBCon.Model(&packages).Where("atom = ?", searchTerm).Select() + if len(packages) > 0 { + http.Redirect(w, r, "/packages/"+searchTerm, http.StatusMovedPermanently) return } } + var packages []models.Package + query := database.DBCon.Model(&packages). + Relation("Versions") + if strings.Contains(searchTerm, "*") { // if the query contains wildcards wildcardSearchTerm := strings.ReplaceAll(searchTerm, "*", "%") - err = database.DBCon.Model(&packages). - WhereOr("atom LIKE ? ", wildcardSearchTerm). - WhereOr("name LIKE ? ", wildcardSearchTerm). - Relation("Versions"). - OrderExpr("name <-> '" + searchTerm + "'"). - Select() + query = query. + WhereOr("atom LIKE ?", wildcardSearchTerm). + WhereOr("name LIKE ?", wildcardSearchTerm) } else { // if the query contains no wildcards do a fuzzy search - searchQuery := BuildSearchQuery(searchTerm) - err = database.DBCon.Model(&packages). - Where(searchQuery). - WhereOr("atom LIKE ? ", ("%" + searchTerm + "%")). - Relation("Versions"). - OrderExpr("name <-> '" + searchTerm + "'"). - Select() + query = BuildSearchQuery(query, searchTerm). + WhereOr("atom LIKE ?", "%"+searchTerm+"%") } + err := query.OrderExpr("name <-> ?", searchTerm). + Select() if err != nil && err != pg.ErrNoRows { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } + if len(packages) == 1 { + http.Redirect(w, r, "/packages/"+packages[0].Atom, http.StatusMovedPermanently) + return + } - renderPackageTemplate("search", - "search", - GetFuncMap(), - getSearchData(packages, searchTerm), - w) + layout.Layout(searchTerm, "packages", search(searchTerm, packages)).Render(r.Context(), w) } // Search renders a template containing a list of search results @@ -67,13 +75,11 @@ func SearchFeed(w http.ResponseWriter, r *http.Request) { searchTerm := getParameterValue("q", r) searchTerm = strings.ReplaceAll(searchTerm, "*", "") - searchQuery := BuildSearchQuery(searchTerm) var packages []models.Package - err := database.DBCon.Model(&packages). - Where(searchQuery). + err := BuildSearchQuery(database.DBCon.Model(&packages), searchTerm). Relation("Versions"). - OrderExpr("name <-> '" + searchTerm + "'"). + OrderExpr("name <-> ?", searchTerm). Select() if err != nil && err != pg.ErrNoRows { http.Error(w, http.StatusText(http.StatusInternalServerError), @@ -84,13 +90,21 @@ func SearchFeed(w http.ResponseWriter, r *http.Request) { feeds.Packages(searchTerm, packages, w) } -func BuildSearchQuery(searchString string) string { - var searchClauses []string +func BuildSearchQuery(query *pg.Query, searchString string) *pg.Query { for _, searchTerm := range strings.Split(searchString, " ") { if searchTerm != "" { - searchClauses = append(searchClauses, - "( (category % '"+searchTerm+"') OR (name % '"+searchTerm+"') OR (atom % '"+searchTerm+"') OR (maintainers @> '[{\"Name\": \""+searchTerm+"\"}]' OR maintainers @> '[{\"Email\": \""+searchTerm+"\"}]'))") + marshal, err := json.Marshal(searchTerm) + if err != nil { + continue + } + query = query.WhereGroup(func(q *pg.Query) (*pg.Query, error) { + return q.WhereOr("category % ?", searchTerm). + WhereOr("name % ?", searchTerm). + WhereOr("atom % ?", searchTerm). + WhereOr("maintainers @> ?", `[{"Name": `+string(marshal)+`}]`). + WhereOr("maintainers @> ?", `[{"Email": `+string(marshal)+`}]`), nil + }) } } - return strings.Join(searchClauses, " AND ") + return query } diff --git a/pkg/app/handler/packages/search.templ b/pkg/app/handler/packages/search.templ new file mode 100644 index 0000000..6fb168f --- /dev/null +++ b/pkg/app/handler/packages/search.templ @@ -0,0 +1,61 @@ +package packages + +import "strconv" +import "soko/pkg/models" + +templ search(query string, packages []models.Package) { + <div class="container mb-5"> + <div class="row"> + <div class="col-12"> + <h1 class="first-header"> + Search Results <small>{ "for " + query }</small> + <a title="Atom feed" href={ templ.URL("/packages/search.atom?q=" + query) } class="kk-feed-icon"> + <span class="fa fa-fw fa-rss-square"></span> + </a> + </h1> + if len(packages) > 0 { + <div class="panel panel-default"> + <div class="panel-heading"> + Results 1—{ strconv.Itoa(len(packages)) } of { strconv.Itoa(len(packages)) } + </div> + <div class="list-group"> + for _, pkg := range packages { + <a class="list-group-item list-group-item-action" href={ templ.URL("/packages/" + pkg.Atom) }> + <h3 class="kk-search-result-header"><span class="text-muted">{ pkg.Category }/</span>{ pkg.Name }</h3> + { pkg.Versions[0].Description } + </a> + } + </div> + // TODO paging + // <div class="panel-footer"> + // <div class="btn-group" role="group" aria-label="Result navigation"> + // <%= link_to '< Prev', search_packages_path(q: params[:q], o: [@offset - PackageRepository.default_search_size, 0].max), class: 'btn btn-default' + (@offset > 0 ? '' : ' disabled') %> + // <%= link_to 'Next >', search_packages_path(q: params[:q], o: @offset + PackageRepository.default_search_size), class: 'btn btn-default ' + ((@offset + PackageRepository.default_search_size) > @packages.total ? 'disabled' : '') %> + // </div> + // </div> + </div> + // TODO in head: alternate_feed_link(search_packages_url(format: :atom, params: request.query_parameters), t(:atom_feed)) + } else { + <div class="jumbotron"> + <h2 class="site-welcome stick-top">Nothing found. :( Try again?</h2> + <form action="/packages/search" method="get"> + <div class="typeahead__container"> + <div class="typeahead__field"> + <span class="typeahead__query"> + <input id="q" name="q" type="search" autocomplete="off" placeholder="Find Packages" aria-label="Find Packages" autofocus/> + </span> + <span class="typeahead__button"> + <button type="submit" title="Find" aria-label="Find"> + <span class="typeahead__search-icon"></span><span class="sr-only">Find</span> + </button> + </span> + </div> + </div> + </form> + </div> + <script src="/assets/index.js"></script> + } + </div> + </div> + </div> +} diff --git a/pkg/app/handler/packages/show.go b/pkg/app/handler/packages/show.go index 75ca8ea..27d8b29 100644 --- a/pkg/app/handler/packages/show.go +++ b/pkg/app/handler/packages/show.go @@ -5,101 +5,124 @@ package packages import ( b64 "encoding/base64" "encoding/json" - "github.com/go-pg/pg" - "github.com/go-pg/pg/v9/orm" + "fmt" "net/http" + "soko/pkg/app/layout" "soko/pkg/app/utils" "soko/pkg/database" "soko/pkg/models" "strings" "time" + + "github.com/go-pg/pg/v10" ) // Show renders a template to show a given package func Show(w http.ResponseWriter, r *http.Request) { + category := r.PathValue("category") + packageName := r.PathValue("package") + pageName := r.PathValue("pageName") + atom := category + "/" + packageName - if strings.HasSuffix(r.URL.Path, "/changelog.json") { - changelogJSON(w, r) - return - } else if strings.HasSuffix(r.URL.Path, ".json") { + if pageName == "" && strings.HasSuffix(packageName, ".json") { buildJson(w, r) return } - atom := r.URL.Path[len("/packages/"):] - pageName := "overview" - userPreferences := utils.GetUserPreferences(r) + var currentSubTab string + userPreferences := utils.GetUserPreferences(r) if userPreferences.General.LandingPageLayout == "full" { updateSearchHistory(atom, w, r) } - if strings.HasSuffix(r.URL.Path, "/changelog") { - atom = strings.ReplaceAll(atom, "/changelog", "") - pageName = "changelog" - } else if strings.HasSuffix(r.URL.Path, "/qa-report") { - atom = strings.ReplaceAll(atom, "/qa-report", "") - pageName = "qa-report" - } else if strings.HasSuffix(r.URL.Path, "/pull-requests") { + var gpackage models.Package + query := database.DBCon.Model(&gpackage). + Relation("Bugs"). + Relation("PullRequests"). + Relation("Versions", func(q *pg.Query) (*pg.Query, error) { + // performs mostly correct ordering of versions, which is perfected by sortVersionsDesc + return q.Order("version DESC"), nil + }). + Relation("Versions.Bugs") + + switch pageName { + case "changelog": + currentSubTab = "Changelog" + query = query.Relation("Commits", func(q *pg.Query) (*pg.Query, error) { + // here be dragons + const template = (`'%[1]s', (SELECT ARRAY_AGG("%[1]s") ` + + `FROM jsonb_array_elements(COALESCE(NULLIF(changed_files -> '%[1]s', 'null'), '[]')) AS "%[1]s" ` + + `WHERE "%[1]s" ->> 'Path' LIKE ?)`) + return q.Column("commit_to_package.*", + "commit.id", "preceding_commits", "message", + "author_name", "author_email", "author_date", + "committer_name", "committer_email", "committer_date"). + ColumnExpr(("json_build_object(" + + fmt.Sprintf(template, "Modified") + "," + + fmt.Sprintf(template, "Added") + "," + + fmt.Sprintf(template, "Deleted") + + ") AS changed_files"), atom+"/%", atom+"/%", atom+"/%"). + Order("preceding_commits DESC"). + Limit(50), nil + }) + case "changelog.json": + changelogJSON(w, r) + return + case "qa-report": + currentSubTab = "QA report" + query = query. + Relation("PkgCheckResults"). + Relation("Versions.PkgCheckResults") + case "pull-requests": atom = strings.ReplaceAll(atom, "/pull-requests", "") - pageName = "pull-requests" - } else if strings.HasSuffix(r.URL.Path, "/bugs") { + currentSubTab = "Pull requests" + case "bugs": atom = strings.ReplaceAll(atom, "/bugs", "") - pageName = "bugs" - } else if strings.HasSuffix(r.URL.Path, "/security") { + currentSubTab = "Bugs" + case "security": atom = strings.ReplaceAll(atom, "/security", "") - pageName = "security" - } else if strings.HasSuffix(r.URL.Path, "/dependencies") { + currentSubTab = "Security" + case "dependencies": atom = strings.ReplaceAll(atom, "/dependencies", "") - pageName = "dependencies" - } else if strings.HasSuffix(r.URL.Path, "/reverse-dependencies") { + currentSubTab = "Dependencies" + query = query.Relation("Versions.Dependencies") + case "reverse-dependencies": atom = strings.ReplaceAll(atom, "/reverse-dependencies", "") - pageName = "reverse-dependencies" + currentSubTab = "Reverse Dependencies" + query = query.Relation("ReverseDependencies") + case "", "overview": + query = query.Relation("Outdated"). + Relation("Versions.Masks"). + Relation("Versions.Deprecates") + currentSubTab = "Overview" + default: + http.NotFound(w, r) + return } - gpackage := new(models.Package) - err := database.DBCon.Model(gpackage). - Where("atom = ?", atom). - Relation("Outdated"). - Relation("PkgCheckResults"). - Relation("Bugs"). - Relation("PullRequests"). - Relation("Versions"). - Relation("Versions.Bugs"). - Relation("Versions.Masks"). - Relation("Versions.PkgCheckResults"). - Relation("Versions.Dependencies"). - Relation("ReverseDependencies"). - Relation("Commits", func(q *orm.Query) (*orm.Query, error) { - return q.Order("preceding_commits DESC").Limit(userPreferences.Packages.Overview.ChangelogLength), nil - }). - Select() - - if err != nil { + err := query.Where("atom = ?", atom).Select() + if err != nil || len(gpackage.Versions) == 0 { http.NotFound(w, r) return } sortVersionsDesc(gpackage.Versions) - localUseflags, globalUseflags, useExpands := getPackageUseflags(gpackage) - - renderPackageTemplate("show", - "*", - GetFuncMap(), - createPackageData(pageName, gpackage, localUseflags, globalUseflags, useExpands, userPreferences), - w) + layout.Layout(gpackage.Atom, "packages", + show(&gpackage, currentSubTab, utils.GetUserPreferences(r)), + ).Render(r.Context(), w) } func updateSearchHistory(atom string, w http.ResponseWriter, r *http.Request) { - var cookie, err = r.Cookie("search_history") + cookie, err := r.Cookie("search_history") var packages string if err == nil { cookieValue, err := b64.StdEncoding.DecodeString(cookie.Value) if err == nil { packagesList := strings.Split(string(cookieValue), ",") if strings.Contains(string(cookieValue), atom) { - newPackagesList := []string{} + newPackagesList := make([]string, 0, len(packagesList)-1) for _, gpackage := range packagesList { if gpackage != atom { newPackagesList = append(newPackagesList, gpackage) @@ -135,7 +158,7 @@ func changelogJSON(w http.ResponseWriter, r *http.Request) { gpackage := new(models.Package) err := database.DBCon.Model(gpackage). Where("atom = ?", atom). - Relation("Commits", func(q *orm.Query) (*orm.Query, error) { + Relation("Commits", func(q *pg.Query) (*pg.Query, error) { return q.Order("preceding_commits DESC").Limit(5), nil }). Select() @@ -191,6 +214,17 @@ func changelogJSON(w http.ResponseWriter, r *http.Request) { w.Write(b) } +func countBugs(gpackage *models.Package) (securityBugs, nonSecurityBugs int) { + for _, bug := range gpackage.Bugs { + if bug.Component == "Vulnerabilities" { + securityBugs++ + } else { + nonSecurityBugs++ + } + } + return +} + type Changes struct { Changes []Change `json:"changes"` } diff --git a/pkg/app/handler/packages/show.templ b/pkg/app/handler/packages/show.templ new file mode 100644 index 0000000..fa3b33f --- /dev/null +++ b/pkg/app/handler/packages/show.templ @@ -0,0 +1,163 @@ +package packages + +import "strconv" +import "soko/pkg/app/handler/packages/components" +import "soko/pkg/app/layout" +import "soko/pkg/models" + +func showViewTabs(pkg *models.Package) []layout.SubTab { + securityBugs, nonSecurityBugs := countBugs(pkg) + return []layout.SubTab{ + { + Name: "Overview", + Link: templ.URL("/packages/" + pkg.Atom), + Icon: "fa fa-info mr-1", + }, + { + Name: "Dependencies", + Link: templ.URL("/packages/" + pkg.Atom + "/dependencies"), + Icon: "fa fa-link", + }, + { + Name: "QA report", + Link: templ.URL("/packages/" + pkg.Atom + "/qa-report"), + Icon: "fa fa-fw fa-chain-broken", + }, + { + Name: "Pull requests", + Link: templ.URL("/packages/" + pkg.Atom + "/pull-requests"), + Icon: "octicon octicon-git-pull-request opticon-resource-icon ml-1", + BadgeValue: strconv.Itoa(len(pkg.PullRequests)), + }, + { + Name: "Bugs", + Link: templ.URL("/packages/" + pkg.Atom + "/bugs"), + Icon: "fa fa-bug", + BadgeValue: strconv.Itoa(nonSecurityBugs), + }, + { + Name: "Security", + Link: templ.URL("/packages/" + pkg.Atom + "/security"), + Icon: "fa fa-shield", + BadgeValue: strconv.Itoa(securityBugs), + }, + { + Name: "Changelog", + Link: templ.URL("/packages/" + pkg.Atom + "/changelog"), + Icon: "fa fa-fw fa-history", + }, + } +} + +templ tabbedHeader(pkg *models.Package, currentSubTab string) { + <div class="kk-header-container"> + <div class="container"> + <div class="row"> + <div class="col-12"> + <div class="row mt-3"> + <div class="col-md-5"> + <h1 class="stick-top kk-package-title" id="package-title" data-atom={ pkg.Atom } data-category={ pkg.Category } data-name={ pkg.Name }> + <small class="kk-package-cat"> + <a href={ templ.URL("/categories/" + pkg.Category) } class="text-dark">{ pkg.Category }</a>/ + </small> + <div> + <svg height="32" class="octicon octicon-package right left kk-package-icon" aria-label="Package icon" viewBox="0 0 16 16" version="1.1" width="32" role="img"><path fill-rule="evenodd" d="M1 4.27v7.47c0 .45.3.84.75.97l6.5 1.73c.16.05.34.05.5 0l6.5-1.73c.45-.13.75-.52.75-.97V4.27c0-.45-.3-.84-.75-.97l-6.5-1.74a1.4 1.4 0 0 0-.5 0L1.75 3.3c-.45.13-.75.52-.75.97zm7 9.09l-6-1.59V5l6 1.61v6.75zM2 4l2.5-.67L11 5.06l-2.5.67L2 4zm13 7.77l-6 1.59V6.61l2-.55V8.5l2-.53V5.53L15 5v6.77zm-2-7.24L6.5 2.8l2-.53L15 4l-2 .53z"></path></svg> + <div class="kk-package-name">{ pkg.Name }</div> + </div> + </h1> + </div> + <div class="col-md-7"> + <p class="lead kk-package-maindesc">{ pkg.Description() }</p> + if len(pkg.Versions[0].Homepage) > 0 { + <p class="kk-package-homepage"> + <a href={ templ.URL(pkg.Versions[0].Homepage[0]) }>{ pkg.Versions[0].Homepage[0] }</a> + </p> + } + </div> + <div class="col-md-12 pt-4 mt-1"> + <nav class="nav kk-package-nav"> + for _, tab := range showViewTabs(pkg) { + <a class={ "nav-link", templ.KV("active", tab.Name == currentSubTab) } href={ tab.Link }> + <i class={ tab.Icon } aria-hidden="true"></i> { tab.Name } + if tab.BadgeValue != "" { + <span class="ml-1 badge badge-pill kk-misc-badge">{ tab.BadgeValue }</span> + } + </a> + } + </nav> + </div> + </div> + </div> + </div> + </div> + </div> +} + +func collectAllBugs(pkg *models.Package) (atom string, generalCount, stabilizationCount, keywordingCount int, bugs []*models.Bug) { + atom = pkg.Atom + bugs = make([]*models.Bug, 0, len(pkg.Bugs)) + handled := make(map[string]struct{}, len(pkg.Bugs)) + for _, bug := range pkg.Bugs { + if bug.Component == "Current packages" { + generalCount++ + bugs = append(bugs, bug) + handled[bug.Id] = struct{}{} + } + } + for _, ver := range pkg.Versions { + for _, bug := range ver.Bugs { + if _, found := handled[bug.Id]; found { + continue + } + if bug.Component == "Stabilization" { + stabilizationCount++ + bugs = append(bugs, bug) + } else if bug.Component == "Keywording" { + keywordingCount++ + bugs = append(bugs, bug) + } + handled[bug.Id] = struct{}{} + } + } + return +} + +func collectSecurityBugs(pkg *models.Package) (string, []*models.Bug) { + bugs := make([]*models.Bug, 0, len(pkg.Bugs)) + for _, bug := range pkg.Bugs { + if bug.Component == "Vulnerabilities" { + bugs = append(bugs, bug) + } + } + return pkg.Atom, bugs +} + +templ show(pkg *models.Package, currentSubTab string, userPreferences models.UserPreferences) { + if currentSubTab == "Reverse Dependencies" { + @tabbedHeader(pkg, "Dependencies") + } else { + @tabbedHeader(pkg, currentSubTab) + } + <div class="tab-content" id="myTabContent"> + <div class="container mb-5 tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="overview-tab"> + switch currentSubTab { + case "QA report": + @qaReport(pkg) + case "Pull requests": + @components.PullRequests(pkg.PullRequests) + case "Bugs": + @components.Bugs(collectAllBugs(pkg)) + case "Security": + @components.SecurityBugs(collectSecurityBugs(pkg)) + case "Changelog": + @components.Changelog(pkg.Atom, pkg.Commits) + case "Dependencies": + @dependencies(pkg) + case "Reverse Dependencies": + @reverseDependencies(pkg) + default: + @overview(pkg, &userPreferences) + } + </div> + </div> +} diff --git a/pkg/app/handler/packages/stabilized.go b/pkg/app/handler/packages/stabilized.go deleted file mode 100644 index 79e80b0..0000000 --- a/pkg/app/handler/packages/stabilized.go +++ /dev/null @@ -1,20 +0,0 @@ -// Used to show recently stabilized versions - -package packages - -import ( - "net/http" - "soko/pkg/app/handler/feeds" -) - -// Stabilized renders a template containing -// a list of 50 recently stabilized versions -func Stabilized(w http.ResponseWriter, r *http.Request) { - stabilizedVersions := GetStabilizedVersions(50) - RenderPackageTemplates("changedVersions", "changedVersions", "changedVersionRow", GetFuncMap(), CreateFeedData("Stabilized", stabilizedVersions), w) -} - -func StabilizedFeed(w http.ResponseWriter, r *http.Request) { - stabilizedVersions := GetStabilizedVersions(250) - feeds.Changes("Stabilized packages in Gentoo.", "Stabilized packages in Gentoo.", stabilizedVersions, w) -} diff --git a/pkg/app/handler/packages/suggest.go b/pkg/app/handler/packages/suggest.go index 9c2d082..2d9759b 100644 --- a/pkg/app/handler/packages/suggest.go +++ b/pkg/app/handler/packages/suggest.go @@ -4,55 +4,44 @@ package packages import ( "encoding/json" - "github.com/go-pg/pg" "net/http" "soko/pkg/database" "soko/pkg/models" + + "github.com/go-pg/pg" ) // Suggest returns json encoded suggestions of // packages based on the given query func Suggest(w http.ResponseWriter, r *http.Request) { - searchTerm := getParameterValue("q", r) - var packages []models.Package - err := database.DBCon.Model(&packages). - Where("atom LIKE ? ", ("%" + searchTerm + "%")). - Relation("Versions"). - Select() + var suggestions struct { + Results []struct { + Name string `json:"name"` + Category string `json:"category"` + Description string `json:"description"` + } `json:"results"` + } + + descriptionQuery := database.DBCon.Model((*models.Version)(nil)). + Column("description"). + Where("atom = package.atom"). + Limit(1) + err := database.DBCon.Model((*models.Package)(nil)). + Column("name", "category"). + ColumnExpr("(?) AS description", descriptionQuery). + Where("atom LIKE ? ", "%"+searchTerm+"%"). + OrderExpr("name <-> ?", searchTerm). + Limit(10). + Select(&suggestions.Results) if err != nil && err != pg.ErrNoRows { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } - type Result struct { - Name string `json:"name"` - Category string `json:"category"` - description string `json:"description"` - } - - type Results struct { - Results []*Result `json:"results"` - } - - var results []*Result - - for _, gpackage := range packages { - results = append(results, &Result{ - Name: gpackage.Name, - Category: gpackage.Category, - description: gpackage.Versions[0].Description, - }) - } - - result := Results{ - Results: results, - } - - b, err := json.Marshal(result) - + b, err := json.Marshal(suggestions) if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) diff --git a/pkg/app/handler/packages/updated.go b/pkg/app/handler/packages/updated.go deleted file mode 100644 index f94e9b4..0000000 --- a/pkg/app/handler/packages/updated.go +++ /dev/null @@ -1,20 +0,0 @@ -// Used to show recently updated versions - -package packages - -import ( - "net/http" - "soko/pkg/app/handler/feeds" -) - -// Updated renders a template containing -// a list of 50 recently updated versions -func Updated(w http.ResponseWriter, r *http.Request) { - updatedVersions := GetUpdatedVersions(50) - RenderPackageTemplates("changedVersions", "changedVersions", "changedVersionRow", GetFuncMap(), CreateFeedData("Updated", updatedVersions), w) -} - -func UpdatedFeed(w http.ResponseWriter, r *http.Request) { - updatedVersions := GetUpdatedVersions(250) - feeds.Changes("Added packages in Gentoo.", "Added packages in Gentoo.", updatedVersions, w) -} diff --git a/pkg/app/handler/packages/utils.go b/pkg/app/handler/packages/utils.go index ccc03c3..423f937 100644 --- a/pkg/app/handler/packages/utils.go +++ b/pkg/app/handler/packages/utils.go @@ -3,26 +3,19 @@ package packages import ( - "crypto/md5" - "encoding/hex" - "github.com/go-pg/pg" - "github.com/go-pg/pg/v9/orm" - "html/template" + "log/slog" "net/http" - "soko/pkg/app/utils" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" - utils2 "soko/pkg/utils" "sort" "strings" - textTemplate "text/template" + + "github.com/go-pg/pg/v10" ) // GetAddedPackages returns a list of recently added // packages containing a given number of packages -func GetAddedPackages(n int) []*models.Package { - var addedPackages []*models.Package +func GetAddedPackages(n int) (addedPackages []*models.Package) { err := database.DBCon.Model(&addedPackages). Order("preceding_commits DESC"). Limit(n). @@ -30,40 +23,37 @@ func GetAddedPackages(n int) []*models.Package { Relation("Versions.Commits"). Select() if err != nil && err != pg.ErrNoRows { - logger.Error.Println("Error during fetching added packages from database") - logger.Error.Println(err) + slog.Error("Failed fetching added packages from database", slog.Any("err", err)) } - return addedPackages + return } // GetAddedVersions returns a list of recently added // versions containing a given number of versions -func GetAddedVersions(n int) []*models.Version { +func GetAddedVersions(n int) (addedVersions []*models.Version) { addedPackages := GetAddedPackages(n) - var addedVersions []*models.Version for _, addedPackage := range addedPackages { addedVersions = append(addedVersions, addedPackage.Versions...) } - return addedVersions + return } // GetUpdatedVersions returns a list of recently updated // versions containing a given number of versions -func GetUpdatedVersions(n int) []*models.Version { - var updatedVersions []*models.Version +func GetUpdatedVersions(n int) (updatedVersions []*models.Version) { var updates []models.Commit err := database.DBCon.Model(&updates). Order("preceding_commits DESC"). Limit(n). - Relation("ChangedVersions", func(q *orm.Query) (*orm.Query, error) { + Relation("ChangedVersions", func(q *pg.Query) (*pg.Query, error) { return q.Limit(10 * n), nil }). - Relation("ChangedVersions.Commits", func(q *orm.Query) (*orm.Query, error) { + Relation("ChangedVersions.Commits", func(q *pg.Query) (*pg.Query, error) { return q.Order("preceding_commits DESC"), nil }). Select() if err != nil { - return updatedVersions + return } for _, commit := range updates { for _, changedVersion := range commit.ChangedVersions { @@ -72,87 +62,57 @@ func GetUpdatedVersions(n int) []*models.Version { updatedVersions = append(updatedVersions, commit.ChangedVersions...) } if len(updatedVersions) > n { - updatedVersions = updatedVersions[:10] + updatedVersions = updatedVersions[:n] } - return updatedVersions + return } // GetStabilizedVersions returns a list of recently stabilized // versions containing a given number of versions -func GetStabilizedVersions(n int) []*models.Version { - var stabilizedVersions []*models.Version +func GetStabilizedVersions(n int) (stabilizedVersions []*models.Version) { var updates []models.KeywordChange err := database.DBCon.Model(&updates). Relation("Version"). Relation("Commit"). Order("commit.preceding_commits DESC"). Where("stabilized IS NOT NULL"). + Where("version.id IS NOT NULL"). Limit(n). Select() if err != nil { - return stabilizedVersions + return } - for _, update := range updates { - if update.Version != nil { - update.Version.Commits = []*models.Commit{update.Commit} - stabilizedVersions = append(stabilizedVersions, update.Version) - } + + stabilizedVersions = make([]*models.Version, len(updates)) + for i, update := range updates { + update.Version.Commits = []*models.Commit{update.Commit} + stabilizedVersions[i] = update.Version } - return stabilizedVersions + return } // GetKeywordedVersions returns a list of recently keyworded // versions containing a given number of versions -func GetKeywordedVersions(n int) []*models.Version { - var keywordedVersions []*models.Version +func GetKeywordedVersions(n int) (keywordedVersions []*models.Version) { var updates []models.KeywordChange err := database.DBCon.Model(&updates). Relation("Version"). Relation("Commit"). Order("commit.preceding_commits DESC"). Where("added IS NOT NULL"). + Where("version.id IS NOT NULL"). Limit(n). Select() if err != nil { - return keywordedVersions + return } - for _, update := range updates { - if update.Version != nil { - update.Version.Commits = []*models.Commit{update.Commit} - keywordedVersions = append(keywordedVersions, update.Version) - } - } - return keywordedVersions -} -// RenderPackageTemplates renders the given templates using the given data -// One pattern can be used to specify templates -func renderPackageTemplate(page string, templatepattern string, funcMap template.FuncMap, data interface{}, w http.ResponseWriter) { - templates := template.Must( - template.Must( - template.Must( - template.New(page). - Funcs(funcMap). - ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/packages/components/*.tmpl")). - ParseGlob("web/templates/packages/" + templatepattern + ".tmpl")) - templates.ExecuteTemplate(w, page+".tmpl", data) -} - -// RenderPackageTemplates renders the given templates using the given data -// Two patterns can be used to specify templates -func RenderPackageTemplates(page string, templatepattern1 string, templatepattern2 string, funcMap template.FuncMap, data interface{}, w http.ResponseWriter) { - templates := template.Must( - template.Must( - template.Must( - template.Must( - template.New(page). - Funcs(funcMap). - ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/packages/browsepackagesheader.tmpl")). - ParseGlob("web/templates/packages/" + templatepattern1 + ".tmpl")). - ParseGlob("web/templates/packages/" + templatepattern2 + ".tmpl")) - templates.ExecuteTemplate(w, page+".tmpl", data) + keywordedVersions = make([]*models.Version, len(updates)) + for i, update := range updates { + update.Version.Commits = []*models.Commit{update.Commit} + keywordedVersions[i] = update.Version + } + return } // getAtom returns the atom of the package from the given url @@ -164,92 +124,6 @@ func getAtom(r *http.Request) string { return atom } -// getSearchData returns the data used in search templates -func getSearchData(packages []models.Package, search string) interface{} { - return struct { - Header models.Header - Search string - Packages []models.Package - Application models.Application - }{ - Header: models.Header{Title: search + " – ", Tab: "packages"}, - Search: search, - Packages: packages, - Application: utils.GetApplicationData(), - } -} - -// getChangelogData returns the data used in changelog templates -func getChangelogData(commits []*models.Commit, atom string) interface{} { - return struct { - Commits []*models.Commit - Atom string - }{ - Commits: commits, - Atom: atom, - } -} - -// GetFuncMap returns the FuncMap used in templates -func GetFuncMap() template.FuncMap { - return template.FuncMap{ - "contains": strings.Contains, - "listContains": listContains, - "replaceall": strings.ReplaceAll, - "gravatar": gravatar, - "mkSlice": mkSlice, - "getReverse": getReverse, - "tolower": strings.ToLower, - "formatRestricts": FormatRestricts, - "RemoteIdLink": RemoteIdLink, - "isMasked": isMasked, - "getMask": getMask, - "showRemovalNotice": showRemovalNotice, - "add": func(a, b int) int { - return a + b - }, - } -} - -// GetFuncMap returns the FuncMap used in templates -func GetTextFuncMap() textTemplate.FuncMap { - return textTemplate.FuncMap{ - "contains": strings.Contains, - "replaceall": strings.ReplaceAll, - "gravatar": gravatar, - "mkSlice": mkSlice, - "getReverse": getReverse, - "tolower": strings.ToLower, - "formatRestricts": FormatRestricts, - "isMasked": isMasked, - "getMask": getMask, - "showRemovalNotice": showRemovalNotice, - } -} - -func listContains(list []string, item string) bool { - return strings.Contains(" "+strings.Join(list, " ")+" ", " "+item+" ") -} - -// gravatar creates a link to the gravatar -// based on the email -func gravatar(email string) string { - hasher := md5.Sum([]byte(email)) - hash := hex.EncodeToString(hasher[:]) - return "https://www.gravatar.com/avatar/" + hash + "?s=13&d=retro" -} - -// mkSlice creates a slice of the given arguments -func mkSlice(args ...interface{}) []interface{} { - return args -} - -// getReverse returns the element of a slice in -// reverse direction based on the index -func getReverse(index int, versions []*models.Version) *models.Version { - return versions[len(versions)-1-index] -} - // getParameterValue returns the value of a given parameter func getParameterValue(parameterName string, r *http.Request) string { results, ok := r.URL.Query()[parameterName] @@ -264,36 +138,38 @@ func getParameterValue(parameterName string, r *http.Request) string { // getPackageUseflags retrieves all local USE flags, global USE // flags and use expands for a given package -func getPackageUseflags(gpackage *models.Package) ([]models.Useflag, []models.Useflag, map[string][]models.Useflag) { - var localUseflags, allGlobalUseflags, filteredGlobalUseflags []models.Useflag - useExpands := make(map[string][]models.Useflag) - for _, rawUseflag := range gpackage.Versions[0].Useflags { - - var tmp_useflags []models.Useflag - err := database.DBCon.Model(&tmp_useflags). - Where("Name = ?", strings.Replace(rawUseflag, "+", "", 1)). - Select() +func getPackageUseflags(gpackage *models.Package) (localUseflags []models.Useflag, filteredGlobalUseflags []models.Useflag, useExpands map[string][]models.Useflag) { + rawUseFlags := gpackage.AllUseflags() + if len(rawUseFlags) == 0 { + return + } - if err != nil && err != pg.ErrNoRows { - logger.Error.Println("Error during fetching added packages from database") - logger.Error.Println(err) - continue - } + var tmp_useflags []models.Useflag + err := database.DBCon.Model(&tmp_useflags). + WhereGroup(func(q *pg.Query) (*pg.Query, error) { + return q.Where("scope = ?", "local").Where("package = ?", gpackage.Atom), nil + }). + WhereOrGroup(func(q *pg.Query) (*pg.Query, error) { + return q.Where("scope != ?", "local").Where("name in (?)", pg.In(rawUseFlags)), nil + }). + Order("name ASC"). + Select() + if err != nil && err != pg.ErrNoRows { + slog.Error("Failed fetching use flags", slog.Any("err", err)) + return + } - for _, useflag := range tmp_useflags { - if useflag.Scope == "global" { - allGlobalUseflags = append(allGlobalUseflags, useflag) - } else if useflag.Scope == "local" { - if useflag.Package == gpackage.Atom { - localUseflags = append(localUseflags, useflag) - } - } else { - if _, ok := useExpands[useflag.UseExpand]; !ok { - useExpands[useflag.UseExpand] = []models.Useflag{useflag} - } else { - useExpands[useflag.UseExpand] = append(useExpands[useflag.UseExpand], useflag) - } + var allGlobalUseflags []models.Useflag + useExpands = make(map[string][]models.Useflag) + for _, useflag := range tmp_useflags { + if useflag.Scope == "global" { + allGlobalUseflags = append(allGlobalUseflags, useflag) + } else if useflag.Scope == "local" { + if useflag.Package == gpackage.Atom { + localUseflags = append(localUseflags, useflag) } + } else { + useExpands[useflag.UseExpand] = append(useExpands[useflag.UseExpand], useflag) } } @@ -307,107 +183,66 @@ func getPackageUseflags(gpackage *models.Package) ([]models.Useflag, []models.Us return localUseflags, filteredGlobalUseflags, useExpands } -// createPackageData creates the data used in the show package template -func createPackageData(pageName string, gpackage *models.Package, localUseflags []models.Useflag, globalUseflags []models.Useflag, useExpands map[string][]models.Useflag, userPreferences models.UserPreferences) interface{} { - return struct { - PageName string - Header models.Header - Package models.Package - Versions []*models.Version - Masks []models.Mask - LocalUseflags []models.Useflag - GlobalUseflags []models.Useflag - UseExpands map[string][]models.Useflag - Application models.Application - UserPreferences models.UserPreferences - }{ - PageName: pageName, - Header: models.Header{Title: gpackage.Atom + " – ", Tab: "packages"}, - Package: *gpackage, - Versions: gpackage.Versions, - LocalUseflags: localUseflags, - GlobalUseflags: globalUseflags, - UseExpands: useExpands, - Masks: nil, - Application: utils.GetApplicationData(), - UserPreferences: userPreferences, - } -} - -// CreateFeedData creates the data used in changedVersions template -func CreateFeedData(name string, versions []*models.Version) interface{} { - return struct { - Header models.Header - Name string - Versions []*models.Version - Application models.Application - }{ - Header: models.Header{Title: "Packages – ", Tab: "packages"}, - Name: name, - Versions: versions, - Application: utils.GetApplicationData(), - } -} - -// FormatRestricts returns a string containing a comma separated -// list of capitalized first letters of the package restricts -func FormatRestricts(restricts []string) string { - var result []string - for _, restrict := range restricts { - if restrict != "" && restrict != "(" && restrict != ")" && !strings.HasSuffix(restrict, "?") { - result = append(result, strings.ToUpper(string(restrict[0]))) - } - } - result = utils2.Deduplicate(result) - return strings.Join(result, ", ") -} - -// RemoteIdLink returns a link to the homepage of a given remote id -func RemoteIdLink(remoteId models.RemoteId) string { +// remoteIdLink returns a link to the homepage of a given remote id +func remoteIdLink(remoteId models.RemoteId) string { switch remoteId.Type { + case "bitbucket": + return "https://bitbucket.org/" + remoteId.Id + case "codeberg": + return "https://codeberg.org/" + remoteId.Id + case "cpan": + return "https://metacpan.org/dist/" + remoteId.Id case "cpan-module": return "https://metacpan.org/pod/" + remoteId.Id - case "cpan": - return "https://metacpan.org/release/" + remoteId.Id + case "cran": + return "https://cran.r-project.org/web/packages/" + remoteId.Id + "/" + case "ctan": + return "https://ctan.org/pkg/" + remoteId.Id + case "freedesktop-gitlab": + return "https://gitlab.freedesktop.org/" + remoteId.Id + ".git/" + case "gentoo": + return "https://gitweb.gentoo.org/" + remoteId.Id + ".git/" case "github": return "https://github.com/" + remoteId.Id - case "sourceforge": - return "https://sourceforge.net/projects/" + remoteId.Id + "/" + case "gitlab": + return "https://gitlab.com/" + remoteId.Id + case "gnome-gitlab": + return "https://gitlab.gnome.org/" + remoteId.Id + ".git/" case "google-code": return "https://code.google.com/archive/p/" + remoteId.Id + "/" - case "bitbucket": - return "https://bitbucket.org/" + remoteId.Id - case "pypi": - return "https://pypi.org/project/" + remoteId.Id + "/" + case "hackage": + return "https://hackage.haskell.org/package/" + remoteId.Id + case "heptapod": + return "https://foss.heptapod.net/" + remoteId.Id + case "kde-invent": + return "https://invent.kde.org/" + remoteId.Id case "launchpad": return "https://launchpad.net/" + remoteId.Id - case "sourceforge-jp": - return "https://sourceforge.net/projects/" + remoteId.Id + "/" - case "rubygems": - return "https://rubygems.org/gems/" + remoteId.Id + "/" + case "osdn": + return "https://osdn.net/projects/" + remoteId.Id + "/" case "pear": return "https://pear.php.net/package/" + remoteId.Id - case "freshmeat": - return "http://freshmeat.sourceforge.net/projects/" + remoteId.Id - case "gitlab": - return "https://gitlab.com/" + remoteId.Id - case "heptapod": - return "https://foss.heptapod.net/" + remoteId.Id + case "pecl": + return "https://pecl.php.net/package/" + remoteId.Id + case "pypi": + return "https://pypi.org/project/" + remoteId.Id + "/" + case "rubygems": + return "https://rubygems.org/gems/" + remoteId.Id + "/" + case "savannah": + return "https://savannah.gnu.org/projects/" + remoteId.Id + case "savannah-nongnu": + return "https://savannah.nongnu.org/projects/" + remoteId.Id + case "sourceforge": + return "https://sourceforge.net/projects/" + remoteId.Id + "/" + case "sourcehut": + return "https://sr.ht/" + remoteId.Id + "/" + case "vim": + return "https://vim.org/scripts/script.php?script_id=" + remoteId.Id default: return "" } } -// isMasked returns true if any version is masked -func isMasked(versions []*models.Version) bool { - for _, version := range versions { - if len(version.Masks) > 0 { - return true - } - } - return false -} - // getMask returns the mask entry of the first version that is masked func getMask(versions []*models.Version) *models.Mask { for _, version := range versions { @@ -420,20 +255,22 @@ func getMask(versions []*models.Version) *models.Mask { // showRemovalNotice if all versions of the package are masked func showRemovalNotice(versions []*models.Version) bool { - showNotice := false for _, version := range versions { if len(version.Masks) > 0 && version.Masks[0].Versions == version.Atom { - showNotice = true + return true } } - return showNotice + return false } -// sort the versions in ascending order -func sortVersionsAsc(versions []*models.Version) { - sort.Slice(versions, func(i, j int) bool { - return versions[i].SmallerThan(*versions[j]) - }) +// getDeprecation returns the deprecation entry of the first version that is deprecated +func getDeprecation(versions []*models.Version) *models.DeprecatedPackage { + for _, version := range versions { + if len(version.Deprecates) > 0 { + return version.Deprecates[0] + } + } + return nil } // sort the versions in descending order diff --git a/pkg/app/handler/useflags/expand.templ b/pkg/app/handler/useflags/expand.templ new file mode 100644 index 0000000..c73d95b --- /dev/null +++ b/pkg/app/handler/useflags/expand.templ @@ -0,0 +1,60 @@ +package useflags + +import "net/http" +import "soko/pkg/database" +import "soko/pkg/models" +import "github.com/go-pg/pg/v10" + +templ expand(useflags []models.Useflag) { + <div class="container mb-5"> + <div class="row"> + <div class="col-md-9"> + <div class="card border-0"> + <div class="list-group"> + for i, use := range useflags { + if i == 0 || use.UseExpand != useflags[i-1].UseExpand { + @templ.Raw("</div></div>") + <h3 class={ templ.KV("mt-4", i > 0) } id={ use.UseExpand }>{ use.UseExpand }</h3> + @templ.Raw(`<div class="card border-0"><div class="list-group">`) + } + <a + class="list-group-item list-group-item-action text-dark" + href={ templ.SafeURL("/useflags/" + use.Name) } + > + <h3 class="kk-search-result-header">{ use.Name }</h3> + { use.Description } + </a> + } + </div> + </div> + </div> + <div class="col-md-3"> + <dl> + <dd class="ml-3 mb-0"> + for i, use := range useflags { + if i == 0 || use.UseExpand != useflags[i-1].UseExpand { + <a href={ templ.URL("#" + use.UseExpand) } class="text-muted">{ use.UseExpand }</a> + <br/> + } + } + </dd> + </dl> + </div> + </div> + </div> +} + +func Expand(w http.ResponseWriter, r *http.Request) { + var useflags []models.Useflag + err := database.DBCon.Model(&useflags). + Where("scope = 'use_expand'"). + Order("use_expand", "name"). + Column("use_expand", "name", "description"). + Select() + if err != nil && err != pg.ErrNoRows { + http.Error(w, http.StatusText(http.StatusInternalServerError), + http.StatusInternalServerError) + return + } + RenderPage(w, r, "USE Expand", "USE Expand", expand(useflags)) +} diff --git a/pkg/app/handler/useflags/global.go b/pkg/app/handler/useflags/global.go deleted file mode 100644 index 45a9e06..0000000 --- a/pkg/app/handler/useflags/global.go +++ /dev/null @@ -1,46 +0,0 @@ -// Used to search for USE flags - -package useflags - -import ( - "github.com/go-pg/pg" - "html/template" - "net/http" - utils2 "soko/pkg/app/utils" - "soko/pkg/database" - "soko/pkg/models" -) - -// Search renders a template containing a list of search results -// for a given query of USE flags -func Global(w http.ResponseWriter, r *http.Request) { - - var useflags []models.Useflag - err := database.DBCon.Model(&useflags).Where("scope = 'global'").Select() - if err != nil && err != pg.ErrNoRows { - http.Error(w, http.StatusText(http.StatusInternalServerError), - http.StatusInternalServerError) - return - } - - data := struct { - Header models.Header - Page string - Useflags []models.Useflag - Application models.Application - }{ - Header: models.Header{Title: "Global" + " – ", Tab: "useflags"}, - Page: "global", - Useflags: useflags, - Application: utils2.GetApplicationData(), - } - - templates := template.Must( - template.Must( - template.Must( - template.New("Show").ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/useflags/browseuseflagsheader.tmpl")). - ParseGlob("web/templates/useflags/list.tmpl")) - - templates.ExecuteTemplate(w, "list.tmpl", data) -} diff --git a/pkg/app/handler/useflags/global.templ b/pkg/app/handler/useflags/global.templ new file mode 100644 index 0000000..edfcda2 --- /dev/null +++ b/pkg/app/handler/useflags/global.templ @@ -0,0 +1,44 @@ +package useflags + +import "net/http" +import "soko/pkg/database" +import "soko/pkg/models" +import "github.com/go-pg/pg/v10" + +templ global(useflags []models.Useflag) { + <div class="container mb-5"> + <div class="row"> + <div class="col-12"> + <h3><span class="text-capitalize">Global</span> USE flags</h3> + <div class="card border-0"> + <div class="list-group"> + for _, use := range useflags { + <a + class="list-group-item list-group-item-action text-dark" + href={ templ.SafeURL("/useflags/" + use.Name) } + > + <h3 class="kk-search-result-header">{ use.Name }</h3> + { use.Description } + </a> + } + </div> + </div> + </div> + </div> + </div> +} + +func Global(w http.ResponseWriter, r *http.Request) { + var useflags []models.Useflag + err := database.DBCon.Model(&useflags). + Where("scope = 'global'"). + Order("name"). + Column("name", "description"). + Select() + if err != nil && err != pg.ErrNoRows { + http.Error(w, http.StatusText(http.StatusInternalServerError), + http.StatusInternalServerError) + return + } + RenderPage(w, r, "Global", "Global", global(useflags)) +} diff --git a/pkg/app/handler/useflags/index.go b/pkg/app/handler/useflags/index.go deleted file mode 100644 index c14161e..0000000 --- a/pkg/app/handler/useflags/index.go +++ /dev/null @@ -1,45 +0,0 @@ -// Used to display the landing page of the USE flag section - -package useflags - -import ( - "html/template" - "net/http" - utils2 "soko/pkg/app/utils" - "soko/pkg/models" -) - -// Index renders a template to show the index page of the USE flags -// section containing a bubble chart of popular USE flags -func Index(w http.ResponseWriter, r *http.Request) { - - data := struct { - Header models.Header - Page string - Application models.Application - }{ - Header: models.Header{Title: "Useflags – ", Tab: "useflags"}, - Page: "browse", - Application: utils2.GetApplicationData(), - } - - templates := template.Must( - template.Must( - template.Must( - template.New("Show").ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/useflags/browseuseflagsheader.tmpl")). - ParseGlob("web/templates/useflags/index.tmpl")) - - templates.ExecuteTemplate(w, "index.tmpl", data) -} - -// Index renders a template to show the index page of the USE flags -// section containing a bubble chart of popular USE flags -func Default(w http.ResponseWriter, r *http.Request) { - userPreferences := utils2.GetUserPreferences(r) - if userPreferences.Useflags.Layout == "bubble" { - http.Redirect(w, r, "/useflags/popular", http.StatusSeeOther) - } else { - http.Redirect(w, r, "/useflags/search", http.StatusSeeOther) - } -} diff --git a/pkg/app/handler/useflags/local.go b/pkg/app/handler/useflags/local.go deleted file mode 100644 index 23d1403..0000000 --- a/pkg/app/handler/useflags/local.go +++ /dev/null @@ -1,55 +0,0 @@ -// Used to search for USE flags - -package useflags - -import ( - "github.com/go-pg/pg" - "html/template" - "net/http" - utils2 "soko/pkg/app/utils" - "soko/pkg/database" - "soko/pkg/models" - "sort" -) - -// Search renders a template containing a list of search results -// for a given query of USE flags -func Local(w http.ResponseWriter, r *http.Request) { - - var useflags []models.Useflag - err := database.DBCon.Model(&useflags).Where("scope = 'local'").Select() - if err != nil && err != pg.ErrNoRows { - http.Error(w, http.StatusText(http.StatusInternalServerError), - http.StatusInternalServerError) - return - } - - sort.Slice(useflags, func(i, j int) bool { - if useflags[i].Package != useflags[j].Package { - return useflags[i].Package < useflags[j].Package - } else { - return useflags[i].Name < useflags[j].Name - } - }) - - data := struct { - Header models.Header - Page string - Useflags []models.Useflag - Application models.Application - }{ - Header: models.Header{Title: "Local" + " – ", Tab: "useflags"}, - Page: "local", - Useflags: useflags, - Application: utils2.GetApplicationData(), - } - - templates := template.Must( - template.Must( - template.Must( - template.New("Show").ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/useflags/browseuseflagsheader.tmpl")). - ParseGlob("web/templates/useflags/listlocal.tmpl")) - - templates.ExecuteTemplate(w, "listlocal.tmpl", data) -} diff --git a/pkg/app/handler/useflags/local.templ b/pkg/app/handler/useflags/local.templ new file mode 100644 index 0000000..cdc4a53 --- /dev/null +++ b/pkg/app/handler/useflags/local.templ @@ -0,0 +1,48 @@ +package useflags + +import "net/http" +import "soko/pkg/database" +import "soko/pkg/models" +import "github.com/go-pg/pg/v10" + +templ local(useflags []models.Useflag) { + <div class="container mb-5"> + <div class="row"> + <div class="col-12"> + <div class="card border-0"> + <div class="list-group"> + for i, use := range useflags { + if i == 0 || use.Package != useflags[i-1].Package { + @templ.Raw("</div></div>") + <h3 class={ templ.KV("mt-4", i > 0) }>{ use.Package }</h3> + @templ.Raw(`<div class="card border-0"><div class="list-group">`) + } + <a + class="list-group-item list-group-item-action text-dark" + href={ templ.SafeURL("/useflags/" + use.Name) } + > + <h3 class="kk-search-result-header">{ use.Name }</h3> + { use.Description } + </a> + } + </div> + </div> + </div> + </div> + </div> +} + +func Local(w http.ResponseWriter, r *http.Request) { + var useflags []models.Useflag + err := database.DBCon.Model(&useflags). + Where("scope = 'local'"). + Order("package", "name"). + Column("package", "name", "description"). + Select() + if err != nil && err != pg.ErrNoRows { + http.Error(w, http.StatusText(http.StatusInternalServerError), + http.StatusInternalServerError) + return + } + RenderPage(w, r, "Local", "Local", local(useflags)) +} diff --git a/pkg/app/handler/useflags/popular.go b/pkg/app/handler/useflags/popular.go index 2c1773d..7443bd1 100644 --- a/pkg/app/handler/useflags/popular.go +++ b/pkg/app/handler/useflags/popular.go @@ -8,57 +8,43 @@ import ( "net/http" "soko/pkg/database" "soko/pkg/models" - "sort" - "strings" + + "github.com/go-pg/pg/v10" ) +var excludePopularUseflags = []string{"test", "doc", "debug"} + // Popular shows a json encoded list of popular USE flags func Popular(w http.ResponseWriter, r *http.Request) { + popular := struct { + Name string `json:"name"` + Useflags []struct { + Useflag string `pg:"useflag" json:"name"` + Count int `pg:"count" json:"size"` + Children types.Object `pg:"-" json:"children"` + } `json:"children"` + }{ + Name: "flags", + } - var versions []models.Version - err := database.DBCon.Model(&versions).Column("useflags").Select() + err := database.DBCon.Model((*models.Version)(nil)). + Column("useflag"). + ColumnExpr("COUNT(useflag) AS count"). + TableExpr("jsonb_array_elements_text(useflags) AS raw_useflag"). + TableExpr("REPLACE(raw_useflag,'+','') AS useflag"). + Where(`useflag NOT LIKE '%\_%'`). + Where("useflag NOT IN (?)", pg.In(excludePopularUseflags)). + Group("useflag"). + Order("count DESC"). + Limit(66). + Select(&popular.Useflags) if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } - dict := make(map[string]int) - for _, version := range versions { - for _, useflag := range version.Useflags { - if useflag != "test" && useflag != "doc" && useflag != "debug" && len(strings.Split(useflag, "_")) < 2 { - dict[strings.ReplaceAll(useflag, "+", "")] = dict[strings.ReplaceAll(useflag, "+", "")] + 1 - } - } - } - - type kv struct { - Key string `json:"name"` - Value int `json:"size"` - Children types.Object `json:"children"` - } - - type p struct { - Name string `json:"name"` - Children []kv `json:"children"` - } - - var ss []kv - for k, v := range dict { - ss = append(ss, kv{k, v, nil}) - } - - sort.Slice(ss, func(i, j int) bool { - return ss[i].Value > ss[j].Value - }) - - popular := p{ - Name: "flags", - Children: ss[0:66], - } - b, err := json.Marshal(popular) - if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) diff --git a/pkg/app/handler/useflags/popular.templ b/pkg/app/handler/useflags/popular.templ new file mode 100644 index 0000000..716a73a --- /dev/null +++ b/pkg/app/handler/useflags/popular.templ @@ -0,0 +1,31 @@ +package useflags + +import "net/http" + +templ popular() { + <div class="container mb-5"> + <div class="row"> + <div class="col-12"> + <div class="card" style="background: none;border: none;"> + <noscript> + <div class="panel-body kk-panel-content-sorry"> + This feature requires JavaScript to work. + </div> + </noscript> + <div + class="panel-body kk-useflag-bubble-container" + id="bubble-placeholder" + style="overflow: hidden!important; display: none;" + ></div> + </div> + </div> + </div> + </div> + <script src="/assets/useflags.js"></script> +} + +// PopularPage renders a template to show the index page of the USE flags +// section containing a bubble chart of popular USE flags +func PopularPage(w http.ResponseWriter, r *http.Request) { + RenderPage(w, r, "Useflags", "Widely used", popular()) +} diff --git a/pkg/app/handler/useflags/search.go b/pkg/app/handler/useflags/search.go deleted file mode 100644 index 2523834..0000000 --- a/pkg/app/handler/useflags/search.go +++ /dev/null @@ -1,54 +0,0 @@ -// Used to search for USE flags - -package useflags - -import ( - "github.com/go-pg/pg" - "html/template" - "net/http" - utils2 "soko/pkg/app/utils" - "soko/pkg/database" - "soko/pkg/models" -) - -// Search renders a template containing a list of search results -// for a given query of USE flags -func Search(w http.ResponseWriter, r *http.Request) { - - results, _ := r.URL.Query()["q"] - - param := "" - var useflags []models.Useflag - if len(results) != 0 { - param = results[0] - err := database.DBCon.Model(&useflags).Where("name LIKE ? ", (param + "%")).Select() - if err != nil && err != pg.ErrNoRows { - http.Error(w, http.StatusText(http.StatusInternalServerError), - http.StatusInternalServerError) - return - } - } - - data := struct { - Header models.Header - Page string - Search string - Useflags []models.Useflag - Application models.Application - }{ - Header: models.Header{Title: param + " – ", Tab: "useflags"}, - Page: "search", - Search: param, - Useflags: useflags, - Application: utils2.GetApplicationData(), - } - - templates := template.Must( - template.Must( - template.Must( - template.New("Show").ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/useflags/browseuseflagsheader.tmpl")). - ParseGlob("web/templates/useflags/search.tmpl")) - - templates.ExecuteTemplate(w, "search.tmpl", data) -} diff --git a/pkg/app/handler/useflags/search.templ b/pkg/app/handler/useflags/search.templ new file mode 100644 index 0000000..bcfa88a --- /dev/null +++ b/pkg/app/handler/useflags/search.templ @@ -0,0 +1,92 @@ +package useflags + +import "net/http" +import "soko/pkg/database" +import "soko/pkg/models" +import "github.com/go-pg/pg/v10" + +css searchButton() { + border-top-right-radius: 0.25rem !important; + border-bottom-right-radius: 0.25rem !important; + font-size: 1.1em !important; + height: 2.3em !important; + border-left: 0px; + box-shadow: inset 0 1px 1px rgba(0,0,0,0.075) !important; +} + +templ search(query string, useflags []models.Useflag) { + <div class="container mb-5"> + <div class="row"> + <div class={ "col-12", templ.KV("mt-5", len(useflags) == 0), templ.KV("pt-5", len(useflags) == 0) }> + <div class="col-12 mt-3 text-center"> + <h2>Find USE flags</h2> + </div> + <div class="col-12"> + <form action="/useflags/search" method="get" class="useflag-search mt-3 mb-5 mx-5 px-5"> + <div class="typeahead__container mx-5 px-5"> + <div class="typeahead__field"> + <span class="typeahead__query" style="font-size: 1.1em; height: 2.3em;"> + <input id="q" name="q" class="rounded-left" style="font-size: 1.1em; height: 2.3em;border-right: 0px;" type="search" autocomplete="off" placeholder="Find USE flags"/> + </span> + <span class="typeahead__button" style="font-size: 1.1em!important; height: 2.3em!important;border-left: 0px;"> + <button class={ searchButton() } type="submit"> + <span class="typeahead__search-icon"></span> + </button> + </span> + </div> + </div> + </form> + </div> + if query != "" { + if len(useflags) > 0 { + <h2>USE Flag Search Results <small>{ "for" } { query }</small></h2> + <div class="card border-0"> + <div class="list-group"> + for _, use := range useflags { + <a + class="list-group-item list-group-item-action text-dark" + href={ templ.URL("/useflags/" + use.Name) } + > + <h3 class="kk-search-result-header"> + { use.Name } + if use.Scope == "local" { + <span class="text-secondary">({ use.Package })</span> + } + </h3> + { use.Description } + </a> + } + </div> + </div> + } else { + <h2>No results found <small>{ "for" } { query }</small></h2> + } + } + </div> + </div> + </div> + <script src="/assets/useflags.js"></script> +} + +// Search renders a template containing a list of search results +// for a given query of USE flags +func Search(w http.ResponseWriter, r *http.Request) { + results := r.URL.Query()["q"] + + param := "" + var useflags []models.Useflag + if len(results) != 0 { + param = results[0] + err := database.DBCon.Model(&useflags). + Column("name", "description", "scope", "package"). + Where("name LIKE ?", param+"%"). + OrderExpr("scope, name <-> ?", param). + Select() + if err != nil && err != pg.ErrNoRows { + http.Error(w, http.StatusText(http.StatusInternalServerError), + http.StatusInternalServerError) + return + } + } + RenderPage(w, r, param, "Search", search(param, useflags)) +} diff --git a/pkg/app/handler/useflags/show.go b/pkg/app/handler/useflags/show.go deleted file mode 100644 index bcea074..0000000 --- a/pkg/app/handler/useflags/show.go +++ /dev/null @@ -1,139 +0,0 @@ -// Used to show a specific package - -package useflags - -import ( - "github.com/go-pg/pg/v9" - "html/template" - "net/http" - utils2 "soko/pkg/app/utils" - "soko/pkg/database" - "soko/pkg/models" - "soko/pkg/utils" - "strings" -) - -// Show renders a template to show a given USE flag -func Show(w http.ResponseWriter, r *http.Request) { - - useflagName := r.URL.Path[len("/useflags/"):] - - var useflags []models.Useflag - err := database.DBCon.Model(&useflags).Where("name = ? ", useflagName).Select() - if err != nil || len(useflags) < 1 { - http.NotFound(w, r) - return - } - - useflag := useflags[0] - var localuseflags []models.Useflag - - for _, use := range useflags { - if use.Scope == "global" { - useflag = use - } else if use.Scope == "local" { - localuseflags = append(localuseflags, use) - } else if use.Scope == "use_expand" { - ShowUseExpand(w, r, use) - return - } - } - - var versions []models.Version - err = database.DBCon.Model(&versions).Column("atom").Where("useflags::jsonb @> ?", "\""+useflagName+"\"").Select() - if err != nil && err != pg.ErrNoRows { - http.Error(w, http.StatusText(http.StatusInternalServerError), - http.StatusInternalServerError) - return - } - - var packages []string - for _, version := range versions { - packages = append(packages, version.Atom) - } - - packages = utils.Deduplicate(packages) - - data := struct { - Header models.Header - Page string - Useflag models.Useflag - LocalUseflags []models.Useflag - Packages []string - Application models.Application - }{ - Header: models.Header{Title: useflag.Name + " – ", Tab: "useflags"}, - Page: "show", - Useflag: useflag, - LocalUseflags: localuseflags, - Packages: packages, - Application: utils2.GetApplicationData(), - } - - templates := template.Must( - template.Must( - template.Must( - template.New("Show").Funcs(template.FuncMap{ - "replaceall": strings.ReplaceAll, - }).ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/useflags/useflagsheader.tmpl")). - ParseGlob("web/templates/useflags/show.tmpl")) - - templates.ExecuteTemplate(w, "show.tmpl", data) -} - -// ShowUseExpand renders a template to show a given use_expand -func ShowUseExpand(w http.ResponseWriter, r *http.Request, useExpand models.Useflag) { - - funcMap := template.FuncMap{ - "replaceall": strings.ReplaceAll, - } - - var otheruseexpands []models.Useflag - err := database.DBCon.Model(&otheruseexpands).Where("use_expand = ? ", useExpand.UseExpand).Select() - if err != nil && err != pg.ErrNoRows { - http.Error(w, http.StatusText(http.StatusInternalServerError), - http.StatusInternalServerError) - return - } - - var versions []models.Version - err = database.DBCon.Model(&versions).Column("atom").Where("useflags::jsonb @> ?", "\""+useExpand.Name+"\"").Select() - if err != nil && err != pg.ErrNoRows { - http.Error(w, http.StatusText(http.StatusInternalServerError), - http.StatusInternalServerError) - return - } - - var packages []string - for _, version := range versions { - packages = append(packages, version.Atom) - } - - packages = utils.Deduplicate(packages) - - data := struct { - Header models.Header - Page string - Useflag models.Useflag - OtherUseExpands []models.Useflag - Packages []string - Application models.Application - }{ - Header: models.Header{Title: useExpand.Name + " – ", Tab: "useflags"}, - Page: "show", - Useflag: useExpand, - OtherUseExpands: otheruseexpands, - Packages: packages, - Application: utils2.GetApplicationData(), - } - - templates := template.Must( - template.Must( - template.Must( - template.New("Show").Funcs(funcMap).ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/useflags/useflagsheader.tmpl")). - ParseGlob("web/templates/useflags/showexpand.tmpl")) - - templates.ExecuteTemplate(w, "showexpand.tmpl", data) -} diff --git a/pkg/app/handler/useflags/show.templ b/pkg/app/handler/useflags/show.templ new file mode 100644 index 0000000..2beb499 --- /dev/null +++ b/pkg/app/handler/useflags/show.templ @@ -0,0 +1,175 @@ +package useflags + +import "net/http" +import "strconv" +import "strings" +import "soko/pkg/app/layout" +import "soko/pkg/database" +import "soko/pkg/models" +import "github.com/go-pg/pg/v10" + +templ showUseflagHeader(useflag models.Useflag) { + <div class="kk-header-container"> + <div class="container"> + <div class="row"> + <div class="col-12"> + <div class="row mt-3 pt-2"> + <div class="col-md-5"> + <h1 class="stick-top kk-package-title" id="package-title"> + <small class="kk-package-cat"> + <a href="/useflags" class={ "text-dark", "ml-1", templ.KV("text-capitalize", useflag.UseExpand == "") }> + if useflag.UseExpand != "" { + { useflag.UseExpand } + } else { + { useflag.Scope } USE flag + } + </a> + </small> + <div> + <div class="kk-package-name" style="margin-left: 0px!important;"> + <span class="fa fa-fw fa-sliders"></span> + <span class="ml-2"> + if useflag.UseExpand != "" { + { strings.TrimPrefix(useflag.Name, useflag.UseExpand + "_") } + } else { + { useflag.Name } + } + </span> + </div> + </div> + </h1> + </div> + if useflag.Scope != "local" { + <div class="col-md-7"> + <p class="lead kk-package-maindesc"> + { useflag.Description } + </p> + </div> + } + <div class="col-md-12 pt-4 mt-1"></div> + </div> + </div> + </div> + </div> + </div> +} + +templ show(useflag models.Useflag, localUseflags, otherUseExpands []models.Useflag, Packages []string) { + @showUseflagHeader(useflag) + <div class="tab-content" id="myTabContent"> + <div class="container mb-5"> + <div class="row"> + <div class="col-12"> + if len(otherUseExpands) != 0 { + <h3 class="mb-2">Other “{ useflag.UseExpand }” USE_EXPAND flag values</h3> + <div class="card"> + <div class="table-responsive"> + <table class="table"> + <thead> + <th>Use Flag</th> + <th>Description</th> + </thead> + <tbody> + for _, use := range otherUseExpands { + <tr> + <th class="kk-nobreak-cell"> + <a href={ templ.URL("/useflags/" + use.Name) }>{ use.Name }</a> + </th> + <td>{ use.Description }</td> + </tr> + } + </tbody> + </table> + </div> + </div> + } + if len(localUseflags) != 0 { + <h3 class="mb-2">Packages describing “{ useflag.Name }” as local USE flag</h3> + <div class="card mb-4 border-top-0"> + <div class="table-responsive"> + <table class="table mb-0"> + <thead> + <th>Package</th> + <th>“{ useflag.Name }” Flag Description</th> + </thead> + <tbody> + for _, use := range localUseflags { + <tr> + <th class="kk-nobreak-cell"> + <a href={ templ.URL("/packages/" + use.Package) }>{ use.Package }</a> + </th> + <td>{ use.Description }</td> + </tr> + } + </tbody> + </table> + </div> + </div> + } + if len(Packages) != 0 { + <h3 class="mb-2 pt-2">All packages providing a “{ useflag.Name }” USE flag ({ strconv.Itoa(len(Packages)) })</h3> + <div class="card"> + <div class="card-body"> + <ul class="kk-col-list kk-3col-list kk-useflag-listing mb-0"> + for _, pkg := range Packages { + <li><a href={ templ.URL("/packages/" + pkg) }>{ pkg }</a></li> + } + </ul> + </div> + </div> + } + </div> + </div> + </div> + </div> +} + +// Show renders a template to show a given USE flag +func Show(w http.ResponseWriter, r *http.Request) { + useFlagName := r.PathValue("useflag") + + var useflags []models.Useflag + err := database.DBCon.Model(&useflags). + Where("name = ?", useFlagName). + Order("scope", "package"). + Select() + if err != nil || len(useflags) < 1 { + http.NotFound(w, r) + return + } + + var packages []string + err = database.DBCon.Model((*models.Version)(nil)). + Column("atom").Distinct(). + Where("useflags::jsonb @> ?", "\""+useFlagName+"\""). + Order("atom"). + Select(&packages) + if err != nil && err != pg.ErrNoRows { + http.Error(w, http.StatusText(http.StatusInternalServerError), + http.StatusInternalServerError) + return + } + + useflag := useflags[0] + + var localUseFlags, otherUseExpands []models.Useflag + if use := useflags[len(useflags)-1]; use.Scope == "use_expand" { + err := database.DBCon.Model(&otherUseExpands). + Column("name", "description"). + Where("use_expand = ?", useflag.UseExpand). + Order("name"). + Select() + if err != nil && err != pg.ErrNoRows { + http.Error(w, http.StatusText(http.StatusInternalServerError), + http.StatusInternalServerError) + return + } + } else if useflag.Scope == "global" { + localUseFlags = useflags[1:] + } else { + localUseFlags = useflags + } + + layout.Layout(useFlagName, "useflags", + show(useflag, localUseFlags, otherUseExpands, packages)).Render(r.Context(), w) +} diff --git a/pkg/app/handler/useflags/suggest.go b/pkg/app/handler/useflags/suggest.go index 710ac15..2093a3b 100644 --- a/pkg/app/handler/useflags/suggest.go +++ b/pkg/app/handler/useflags/suggest.go @@ -4,54 +4,43 @@ package useflags import ( "encoding/json" - "github.com/go-pg/pg/v9" "net/http" "soko/pkg/database" "soko/pkg/models" + + "github.com/go-pg/pg/v10" ) // Suggest returns a json encoded suggestions of // USE flags based on the given query func Suggest(w http.ResponseWriter, r *http.Request) { - - results, _ := r.URL.Query()["q"] - + results, found := r.URL.Query()["q"] + if !found || len(results[0]) < 1 { + http.Error(w, http.StatusText(http.StatusBadRequest), + http.StatusBadRequest) + return + } param := results[0] - var useflags []models.Useflag - err := database.DBCon.Model(&useflags).Where("name LIKE ? ", (param + "%")).Select() + var suggestions struct { + Results []struct { + Id string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + } `json:"results"` + } + + err := database.DBCon.Model((*models.Useflag)(nil)). + Column("id", "name", "description"). + Where("name LIKE ?", param+"%"). + Select(&suggestions.Results) if err != nil && err != pg.ErrNoRows { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } - type Suggest struct { - Id string `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - } - - type Suggestions struct { - Results []Suggest `json:"results"` - } - - var suggests []Suggest - - for _, useflag := range useflags { - suggests = append(suggests, Suggest{ - Id: useflag.Id, - Name: useflag.Name, - Description: useflag.Description, - }) - } - - suggestions := Suggestions{ - Results: suggests, - } - jsondata, err := json.Marshal(suggestions) - if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) diff --git a/pkg/app/handler/useflags/utils.go b/pkg/app/handler/useflags/utils.go new file mode 100644 index 0000000..5056792 --- /dev/null +++ b/pkg/app/handler/useflags/utils.go @@ -0,0 +1,20 @@ +package useflags + +import ( + "net/http" + "soko/pkg/app/layout" + + "github.com/a-h/templ" +) + +var tabs = []layout.SubTab{ + {Name: "Widely used", Link: templ.URL("/useflags"), Icon: "fa fa-line-chart mr-1"}, + {Name: "Search", Link: templ.URL("/useflags/search"), Icon: "fa fa-search mr-1"}, + {Name: "Global", Link: templ.URL("/useflags/global"), Icon: "fa fa-globe mr-1"}, + {Name: "Local", Link: templ.URL("/useflags/local"), Icon: "fa fa-map-marker mr-1"}, + {Name: "USE Expand", Link: templ.URL("/useflags/expand"), Icon: "fa fa-list mr-1"}, +} + +func RenderPage(w http.ResponseWriter, r *http.Request, title string, currentTab string, content templ.Component) { + layout.TabbedLayout(title, "useflags", "USE flags", "fa fa-fw fa-sliders", "", tabs, currentTab, content).Render(r.Context(), w) +} diff --git a/pkg/app/handler/user/general.templ b/pkg/app/handler/user/general.templ new file mode 100644 index 0000000..c908295 --- /dev/null +++ b/pkg/app/handler/user/general.templ @@ -0,0 +1,89 @@ +package user + +import "encoding/base64" +import "encoding/json" +import "net/http" +import "time" +import "soko/pkg/app/utils" +import "soko/pkg/models" + +templ general(preferences models.GeneralPreferences) { + <form method="post" action="/user/preferences/general/layout"> + <div class="row"> + <div class="col-5 offset-1 mt-1"> + <div class="card" style="background: transparent;"> + <div class="card-body"> + <img id="img1" alt="Recently Added Packages (default)" src="/assets/pgo3.png" style="width: 100%;cursor: pointer;"/> + </div> + </div> + <div class="text-center mt-2"> + <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;"> + <input + type="radio" + id="classicLandingpageLayout" + name="landingpage-layout" + value="classic" + checked?={ preferences.LandingPageLayout == "classic" } + /> + <label class="form-check-label ml-1" for="classicLandingpageLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Recently Added Packages (default)">Recently Added Packages <i>(default)</i></label> + </div> + </div> + </div> + <div class="col-5 mt-1"> + <div class="card" style="background: transparent;"> + <div class="card-body"> + <img id="img2" alt="Recently Visited Packages" src="/assets/pgo4.png" style="width: 100%;cursor: pointer;"/> + </div> + </div> + <div class="text-center mt-2"> + <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;"> + <input + type="radio" + id="fullLandingpageLayout" + name="landingpage-layout" + value="full" + checked?={ preferences.LandingPageLayout == "full" } + /> + <label class="form-check-label ml-1" for="fullLandingpageLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Recently Visited Packages">Recently Visited Packages</label> + </div> + </div> + </div> + <div class="col-10 offset-1 mt-4"> + <button type="submit" class="float-right btn btn-sm btn-primary">Save</button> + <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/general/reset">Reset to Defaults</a> + </div> + </div> + </form> + <div id="myModal" class="modal"> + <span class="close">×</span> + <img class="modal-content" id="img01"/> + <div id="caption"></div> + </div> +} + +func General(w http.ResponseWriter, r *http.Request) { + userPreferences := utils.GetUserPreferences(r) + r.ParseForm() + // landing page layout + layout := r.Form.Get("landingpage-layout") + if layout == "classic" || layout == "full" { + userPreferences.General.LandingPageLayout = layout + } + // store cookie + encodedUserPreferences, err := json.Marshal(&userPreferences.General) + if err == nil { + sEnc := base64.StdEncoding.EncodeToString(encodedUserPreferences) + addCookie(w, "userpref_general", "/", sEnc, 365*24*time.Hour) + } + http.Redirect(w, r, "/user/preferences/general", http.StatusSeeOther) +} + +func ResetGeneral(w http.ResponseWriter, r *http.Request) { + userPreferences := utils.GetDefaultUserPreferences() + encodedUserPreferences, err := json.Marshal(&userPreferences.General) + if err == nil { + sEnc := base64.StdEncoding.EncodeToString(encodedUserPreferences) + addCookie(w, "userpref_general", "/", sEnc, 365*24*time.Hour) + } + http.Redirect(w, r, "/user/preferences/general", http.StatusSeeOther) +} diff --git a/pkg/app/handler/user/maintainers.templ b/pkg/app/handler/user/maintainers.templ new file mode 100644 index 0000000..a12c913 --- /dev/null +++ b/pkg/app/handler/user/maintainers.templ @@ -0,0 +1,91 @@ +package user + +import "encoding/base64" +import "encoding/json" +import "net/http" +import "time" +import "soko/pkg/app/utils" +import "soko/pkg/models" +import "slices" +import "soko/pkg/database" + +func splitAllProjects() [][]models.Project { + var projects []models.Project + database.DBCon.Model(&projects).Column("name", "email").Select() + split := (3 + len(projects)) / 4 + return [][]models.Project{projects[:split], projects[split : 2*split], projects[2*split : 3*split], projects[3*split:]} +} + +templ maintainers(preferences models.MaintainersPreferences) { + <form method="post" action="/user/preferences/maintainers/edit"> + <div class="row"> + <div class="col-12"> + <h3 class="mt-0" id="qa-report">Include Project Packages</h3> + <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;"> + <input + type="checkbox" + id="include-packages" + name="include-packages" + value="true" + checked?={ preferences.IncludeProjectPackages } + /> + <label class="form-check-label ml-1" for="include-packages" style="overflow:hidden;text-overflow: ellipsis;" title="">Include packages of projects the maintainer is part of</label> + </div> + <i>If this option is enabled, all packages, QA reports, pull requests and bugs of projects a maintainer is part of will be displayed as well on the maintainer page. That is, if <i>Larry</i> is part of the <i>Python</i> project, all packages, QA reports, pull requests and bugs of the Python project will be displayed as well on the maintainer page of <i>Larry</i>.<br/>Below you can furthermore specify projects that will be excluded on the maintainer page. E.g. if Larry is furthermore part of the proxy-maintainers project, and the project is marked below, packages of the proxy maintainers project won't be shown on Larry's maintainer page.</i> + </div> + <div class="col-12"> + <h3 class="mt-4 pt-3" id="qa-report">Excluded Projects</h3> + </div> + for _, projects := range splitAllProjects() { + <div class="col-3"> + for _, project := range projects { + <li class="list-group-item"> + <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;height:21px;"> + <input + type="checkbox" + id={ "excluded-projects-" + project.Email } + name="excluded-projects" + value={ project.Email } + checked?={ slices.Contains(preferences.ExcludedProjects, project.Email) } + /> + <label class="form-check-label ml-1" for={ "excluded-projects-" + project.Email } style="overflow:hidden;text-overflow: ellipsis;height:21px;" title={ project.Name }>{ project.Name }</label> + </div> + </li> + } + </div> + } + <div class="col-12 mt-4"> + <button type="submit" class="float-right btn btn-sm btn-primary">Save</button> + <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/maintainers/reset">Reset to Defaults</a> + </div> + </div> + </form> +} + +func Maintainers(w http.ResponseWriter, r *http.Request) { + userPreferences := utils.GetUserPreferences(r) + r.ParseForm() + // excluded projects + excludedProjects := r.Form["excluded-projects"] + userPreferences.Maintainers.ExcludedProjects = excludedProjects + // include projects? + includePackages := r.Form.Get("include-packages") + userPreferences.Maintainers.IncludeProjectPackages = includePackages == "true" + // store cookie + encodedUserPreferences, err := json.Marshal(&userPreferences.Maintainers) + if err == nil { + sEnc := base64.StdEncoding.EncodeToString(encodedUserPreferences) + addCookie(w, "userpref_maintainers", "/", sEnc, 365*24*time.Hour) + } + http.Redirect(w, r, "/user/preferences/maintainers", http.StatusSeeOther) +} + +func ResetMaintainers(w http.ResponseWriter, r *http.Request) { + userPreferences := utils.GetDefaultUserPreferences() + encodedUserPreferences, err := json.Marshal(&userPreferences.Maintainers) + if err == nil { + sEnc := base64.StdEncoding.EncodeToString(encodedUserPreferences) + addCookie(w, "userpref_maintainers", "/", sEnc, 365*24*time.Hour) + } + http.Redirect(w, r, "/user/preferences/maintainers", http.StatusSeeOther) +} diff --git a/pkg/app/handler/user/packages.templ b/pkg/app/handler/user/packages.templ new file mode 100644 index 0000000..0bf4cbd --- /dev/null +++ b/pkg/app/handler/user/packages.templ @@ -0,0 +1,126 @@ +package user + +import "encoding/base64" +import "encoding/json" +import "net/http" +import "time" +import "soko/pkg/app/utils" +import "soko/pkg/models" + +templ packages(preferences models.PackagesPreferences) { + <div class="row"> + <form method="post" action="/user/preferences/packages/edit"> + <h4 class="mb-1">Layout</h4> + <div class="row"> + <div class="col-6 mt-1"> + <div class="card" style="background: transparent;"> + <div class="card-body"> + <img id="img1" alt="Versions + Metadata (default)" src="/assets/pgo2.png" style="width: 100%;cursor: pointer;"/> + </div> + </div> + <div class="text-center mt-2"> + <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;"> + <input + type="radio" + id="minimalOverviewLayout" + name="overview-layout" + value="minimal" + checked?={ preferences.Overview.Layout == "minimal" } + /> + <label class="form-check-label ml-1" for="minimalOverviewLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Versions + Metadata (default)">Versions + Metadata <i>(default)</i></label> + </div> + </div> + </div> + <div class="col-6 mt-1"> + <div class="card" style="background: transparent;"> + <div class="card-body"> + <img id="img2" alt="Versions + Metadata + Changelog" src="/assets/pgo1.png" onclick="document.getElementById('fullOverviewLayout').checked = true;" style="width: 100%;cursor: pointer;"/> + </div> + </div> + <div class="text-center mt-2"> + <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;"> + <input + type="radio" + id="fullOverviewLayout" + name="overview-layout" + value="full" + checked?={ preferences.Overview.Layout == "full" } + /> + <label class="form-check-label ml-1" for="fullOverviewLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Versions + Metadata + Changelog">Versions + Metadata + Changelog</label> + </div> + </div> + </div> + </div> + <h4 class="mt-4 mb-1">EAPI version</h4> + <div class="card"> + <div class="card-body"> + Show + <select class="form-control form-control-sm ml-2" style="max-width: 100px;display: inline;" name="overview-eapi" id="overview-eapi"> + <option + value="none" + selected?={ preferences.Overview.EAPI == "none" } + >none</option> + <option + value="column" + selected?={ preferences.Overview.EAPI == "column" } + >in column</option> + <option + value="inline" + selected?={ preferences.Overview.EAPI == "inline" } + >inline</option> + </select> + </div> + </div> + <div class="row"> + <div class="col-12 mt-4"> + <button type="submit" class="float-right btn btn-sm btn-primary">Save</button> + <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/packages/reset">Reset to Defaults</a> + </div> + </div> + </form> + </div> + <div id="myModal" class="modal"> + <span class="close">×</span> + <img class="modal-content" id="img01"/> + <div id="caption"></div> + </div> +} + +func EditPackagesPreferences(w http.ResponseWriter, r *http.Request) { + + userPreferences := utils.GetUserPreferences(r) + + r.ParseForm() + + // Overview: Layout + overviewLayout := r.Form.Get("overview-layout") + if overviewLayout == "minimal" || overviewLayout == "full" { + userPreferences.Packages.Overview.Layout = overviewLayout + } + + // EAPI + showEAPI := r.Form.Get("overview-eapi") + if showEAPI == "none" || showEAPI == "column" || showEAPI == "inline" { + userPreferences.Packages.Overview.EAPI = showEAPI + } + + // + // Store cookie + // + encodedUserPreferences, err := json.Marshal(&userPreferences.Packages) + if err == nil { + sEnc := base64.StdEncoding.EncodeToString(encodedUserPreferences) + addCookie(w, "userpref_packages", "/", sEnc, 365*24*time.Hour) + } + http.Redirect(w, r, "/user/preferences/packages", http.StatusSeeOther) +} + +func ResetPackages(w http.ResponseWriter, r *http.Request) { + userPreferences := utils.GetDefaultUserPreferences() + encodedUserPreferences, err := json.Marshal(&userPreferences.Packages) + if err == nil { + sEnc := base64.StdEncoding.EncodeToString(encodedUserPreferences) + addCookie(w, "userpref_packages", "/", sEnc, 365*24*time.Hour) + } + http.Redirect(w, r, "/user/preferences/packages", http.StatusSeeOther) +} diff --git a/pkg/app/handler/user/preferences.go b/pkg/app/handler/user/preferences.go deleted file mode 100644 index 8c5deec..0000000 --- a/pkg/app/handler/user/preferences.go +++ /dev/null @@ -1,245 +0,0 @@ -package user - -import ( - b64 "encoding/base64" - "encoding/json" - "net/http" - "soko/pkg/app/utils" - "soko/pkg/config" - "soko/pkg/database" - "soko/pkg/models" - "strconv" - "strings" - "time" -) - -// Preferences renders a template to show the user preferences page -func Preferences(w http.ResponseWriter, r *http.Request) { - - pageName := "general" - - if strings.HasSuffix(r.URL.Path, "/general") { - pageName = "general" - } else if strings.HasSuffix(r.URL.Path, "/packages") { - pageName = "packages" - } else if strings.HasSuffix(r.URL.Path, "/maintainers") { - pageName = "maintainers" - } else if strings.HasSuffix(r.URL.Path, "/useflags") { - pageName = "useflags" - } else if strings.HasSuffix(r.URL.Path, "/arches") { - pageName = "arches" - } - - var allProjects []*models.Project - database.DBCon.Model(&allProjects).Select() - - renderUserTemplate(w, r, allProjects, pageName, "preferences") -} - -func EditPackagesPreferences(w http.ResponseWriter, r *http.Request) { - - userPreferences := utils.GetUserPreferences(r) - - r.ParseForm() - - // Overview: Layout - overviewLayout := r.Form.Get("overview-layout") - if overviewLayout == "minimal" || overviewLayout == "full" { - userPreferences.Packages.Overview.Layout = overviewLayout - } - - // Overview: Keywords - overviewKeywords := r.Form["overview-keywords"] - userPreferences.Packages.Overview.Keywords = overviewKeywords - - // EAPI - showEAPI := r.Form.Get("overview-eapi") - if showEAPI == "none" || showEAPI == "column" || showEAPI == "inline" { - userPreferences.Packages.Overview.EAPI = showEAPI - } - - // Overview: Show Outdated - userPreferences.Packages.Overview.ShowOutdated = r.Form.Get("overview-showOutdated") == "true" - - // Overview: Metadata fields - overviewMetadataFields := r.Form["overview-metadata-fields"] - userPreferences.Packages.Overview.MetadataFields = overviewMetadataFields - - // Overview: Changelog - changelogSize, err := strconv.Atoi(r.Form.Get("overview-changelog-size")) - if err == nil { - if changelogSize < 100 { - userPreferences.Packages.Overview.ChangelogLength = changelogSize - } else { - userPreferences.Packages.Overview.ChangelogLength = 100 - } - } - - // Dependencies - defaultDependenciesPage := r.Form.Get("dependencies-default-page") - if defaultDependenciesPage == "dependencies" || defaultDependenciesPage == "reverse-dependencies" { - userPreferences.Packages.Dependencies.Default = defaultDependenciesPage - } - - // QA Report - qaReportClasses := r.Form["qareport-classes"] - excludedQAReportClasses := []int{} - for i := 0; i <= 190; i++ { - if !contains(qaReportClasses, strconv.Itoa(i)) { - excludedQAReportClasses = append(excludedQAReportClasses, i) - } - } - userPreferences.Packages.QAReport.ExcludedWarningClasses = excludedQAReportClasses - - // Tabs - visibleTabs := r.Form["visible-tabs"] - userPreferences.Packages.Tabs.Visible = visibleTabs - - // - // Store cookie - // - encodedUserPreferences, err := json.Marshal(&userPreferences.Packages) - if err == nil { - sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences) - addCookie(w, "userpref_packages", "/", sEnc, 365*24*time.Hour) - } - http.Redirect(w, r, "/user/preferences/packages", http.StatusSeeOther) -} - -func ResetPackages(w http.ResponseWriter, r *http.Request) { - userPreferences := utils.GetDefaultUserPreferences() - encodedUserPreferences, err := json.Marshal(&userPreferences.Packages) - if err == nil { - sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences) - addCookie(w, "userpref_packages", "/", sEnc, 365*24*time.Hour) - } - http.Redirect(w, r, "/user/preferences/packages", http.StatusSeeOther) -} - -func General(w http.ResponseWriter, r *http.Request) { - userPreferences := utils.GetUserPreferences(r) - r.ParseForm() - // landing page layout - layout := r.Form.Get("landingpage-layout") - if layout == "classic" || layout == "full" { - userPreferences.General.LandingPageLayout = layout - } - // store cookie - encodedUserPreferences, err := json.Marshal(&userPreferences.General) - if err == nil { - sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences) - addCookie(w, "userpref_general", "/", sEnc, 365*24*time.Hour) - } - http.Redirect(w, r, "/user/preferences/general", http.StatusSeeOther) -} - -func ResetGeneral(w http.ResponseWriter, r *http.Request) { - userPreferences := utils.GetDefaultUserPreferences() - encodedUserPreferences, err := json.Marshal(&userPreferences.General) - if err == nil { - sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences) - addCookie(w, "userpref_general", "/", sEnc, 365*24*time.Hour) - } - http.Redirect(w, r, "/user/preferences/general", http.StatusSeeOther) -} - -func Useflags(w http.ResponseWriter, r *http.Request) { - userPreferences := utils.GetUserPreferences(r) - r.ParseForm() - // default use flag page - layout := r.Form.Get("useflag-default-page") - if layout == "bubble" || layout == "search" { - userPreferences.Useflags.Layout = layout - } - // store cookie - encodedUserPreferences, err := json.Marshal(&userPreferences.Useflags) - if err == nil { - sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences) - addCookie(w, "userpref_useflags", "/", sEnc, 365*24*time.Hour) - } - http.Redirect(w, r, "/user/preferences/useflags", http.StatusSeeOther) -} - -func ResetUseflags(w http.ResponseWriter, r *http.Request) { - userPreferences := utils.GetDefaultUserPreferences() - encodedUserPreferences, err := json.Marshal(&userPreferences.Useflags) - if err == nil { - sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences) - addCookie(w, "userpref_useflags", "/", sEnc, 365*24*time.Hour) - } - http.Redirect(w, r, "/user/preferences/useflags", http.StatusSeeOther) -} - -func Arches(w http.ResponseWriter, r *http.Request) { - userPreferences := utils.GetUserPreferences(r) - r.ParseForm() - // visible arches - visibleArches := r.Form["visible-arches"] - userPreferences.Arches.Visible = visibleArches - // default arch - defaultArch := r.Form.Get("arches-default-arch") - userPreferences.Arches.DefaultArch = defaultArch - // default arches page - defaultPage := r.Form.Get("arches-default-page") - userPreferences.Arches.DefaultPage = defaultPage - // store cookie - encodedUserPreferences, err := json.Marshal(&userPreferences.Arches) - if err == nil { - sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences) - addCookie(w, "userpref_arches", "/", sEnc, 365*24*time.Hour) - } - http.Redirect(w, r, "/user/preferences/arches", http.StatusSeeOther) -} - -func ResetArches(w http.ResponseWriter, r *http.Request) { - userPreferences := utils.GetDefaultUserPreferences() - encodedUserPreferences, err := json.Marshal(&userPreferences.Arches) - if err == nil { - sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences) - addCookie(w, "userpref_arches", "/", sEnc, 365*24*time.Hour) - } - http.Redirect(w, r, "/user/preferences/arches", http.StatusSeeOther) -} - -func Maintainers(w http.ResponseWriter, r *http.Request) { - userPreferences := utils.GetUserPreferences(r) - r.ParseForm() - // excluded projects - excludedProjects := r.Form["excluded-projects"] - userPreferences.Maintainers.ExcludedProjects = excludedProjects - // include projects? - includePackages := r.Form.Get("include-packages") - userPreferences.Maintainers.IncludeProjectPackages = includePackages == "true" - // store cookie - encodedUserPreferences, err := json.Marshal(&userPreferences.Maintainers) - if err == nil { - sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences) - addCookie(w, "userpref_maintainers", "/", sEnc, 365*24*time.Hour) - } - http.Redirect(w, r, "/user/preferences/maintainers", http.StatusSeeOther) -} - -func ResetMaintainers(w http.ResponseWriter, r *http.Request) { - userPreferences := utils.GetDefaultUserPreferences() - encodedUserPreferences, err := json.Marshal(&userPreferences.Maintainers) - if err == nil { - sEnc := b64.StdEncoding.EncodeToString(encodedUserPreferences) - addCookie(w, "userpref_maintainers", "/", sEnc, 365*24*time.Hour) - } - http.Redirect(w, r, "/user/preferences/maintainers", http.StatusSeeOther) -} - -// addCookie will apply a new cookie to the response of a http request -// with the key/value specified. -func addCookie(w http.ResponseWriter, name, path, value string, ttl time.Duration) { - expire := time.Now().Add(ttl) - cookie := http.Cookie{ - Name: name, - Path: path, - Value: value, - Expires: expire, - HttpOnly: true, - Secure: config.DevMode() == "false", - } - http.SetCookie(w, &cookie) -} diff --git a/pkg/app/handler/user/preferences.templ b/pkg/app/handler/user/preferences.templ new file mode 100644 index 0000000..5119635 --- /dev/null +++ b/pkg/app/handler/user/preferences.templ @@ -0,0 +1,80 @@ +package user + +import "net/http" +import "time" +import "soko/pkg/app/layout" +import "soko/pkg/app/utils" +import "soko/pkg/config" +import "soko/pkg/models" + +var viewTabs = []layout.SubTab{ + { + Name: "General", + Link: "/user/preferences/general", + Icon: "fa fa-globe mr-1", + }, + { + Name: "Packages", + Link: "/user/preferences/packages", + Icon: "fa fa-cube mr-1", + }, + { + Name: "Maintainers", + Link: "/user/preferences/maintainers", + Icon: "fa fa-users mr-1", + }, +} + +templ show(currentSubTab string, preferences models.UserPreferences) { + <div class="container mb-5"> + switch currentSubTab { + case "General": + @general(preferences.General) + case "Packages": + @packages(preferences.Packages) + case "Maintainers": + @maintainers(preferences.Maintainers) + } + </div> + <script src="/assets/userpref.js"></script> +} + +templ sortableScript() { + <script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script> + <script> + if(document.getElementById("example1") != null && document.getElementById("example2") != null) { + new Sortable(example1, { + group: 'shared', + animation: 150, + ghostClass: 'bg-info' + }); + new Sortable(example2, { + group: 'shared', + animation: 150, + ghostClass: 'bg-info' + }); + } + </script> +} + +func Preferences(currentSubTab string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + layout.TabbedLayout("User", "preferences", "Preferences", "fa fa-fw fa-cog", "You can customize the page contents to your needs here", viewTabs, + currentSubTab, show(currentSubTab, utils.GetUserPreferences(r))).Render(r.Context(), w) + } +} + +// addCookie will apply a new cookie to the response of a http request +// with the key/value specified. +func addCookie(w http.ResponseWriter, name, path, value string, ttl time.Duration) { + expire := time.Now().Add(ttl) + cookie := http.Cookie{ + Name: name, + Path: path, + Value: value, + Expires: expire, + HttpOnly: true, + Secure: config.DevMode() == "false", + } + http.SetCookie(w, &cookie) +} diff --git a/pkg/app/handler/user/utils.go b/pkg/app/handler/user/utils.go deleted file mode 100644 index 0372ef8..0000000 --- a/pkg/app/handler/user/utils.go +++ /dev/null @@ -1,71 +0,0 @@ -package user - -import ( - "html/template" - "net/http" - "soko/pkg/app/utils" - "soko/pkg/models" - "strings" -) - -// renderAboutTemplate renders a specific about template -func renderUserTemplate(w http.ResponseWriter, r *http.Request, allProjects []*models.Project, pageName, page string) { - templates := template.Must( - template.Must( - template.Must( - template.Must( - template.New(page).Funcs(template.FuncMap{ - "Contains": contains, - "ContainsInt": containsInt, - "CreateSlice": createSlice, - "GetPkgcheckClass": models.GetPkgcheckClass, - "add": func(a, b int) int { - return a + b - }, - }). - ParseGlob("web/templates/layout/*.tmpl")). - ParseGlob("web/templates/user/preferences/*.tmpl")). - ParseGlob("web/templates/user/userheader.tmpl")). - ParseGlob("web/templates/user/" + page + ".tmpl")) - - templates.ExecuteTemplate(w, page+".tmpl", getPageData(pageName, allProjects, utils.GetUserPreferences(r))) -} - -func contains(list []string, item string) bool { - return strings.Contains(" "+strings.Join(list, " ")+" ", " "+item+" ") -} - -func containsInt(list []int, item int) bool { - for _, v := range list { - if v == item { - return true - } - } - return false -} - -func createSlice(n int) []int { - slice := []int{} - for i := 0; i <= n; i++ { - slice = append(slice, i) - } - return slice -} - -// getPageData returns the data used -// in all about templates -func getPageData(pageName string, allProjects []*models.Project, preferences models.UserPreferences) interface{} { - return struct { - Header models.Header - Application models.Application - PageName string - Projects []*models.Project - UserPreferences models.UserPreferences - }{ - Header: models.Header{Title: "User – ", Tab: "user"}, - Application: utils.GetApplicationData(), - PageName: pageName, - Projects: allProjects, - UserPreferences: preferences, - } -} diff --git a/pkg/app/layout/page.templ b/pkg/app/layout/page.templ new file mode 100644 index 0000000..ebfe060 --- /dev/null +++ b/pkg/app/layout/page.templ @@ -0,0 +1,188 @@ +package layout + +import "soko/pkg/config" + +templ head(title string) { + <head> + <title> + if title != "" { + { title } – Gentoo Packages + } else { + Gentoo Packages + } + </title> + <meta charset="utf-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + <meta name="theme-color" content="#54487a"/> + <meta name="description" content="Gentoo Packages Database"/> + <script src="/assets/application.js"></script> + <link rel="icon" href="https://packages.gentoo.org/favicon.ico" type="image/x-icon"/> + <link rel="stylesheet" href="/assets/stylesheets.css"/> + </head> +} + +templ siteTitle() { + <div class="site-title"> + <div class="container"> + <div class="row justify-content-between"> + <div class="logo"> + <a href="/" title="Back to the homepage" class="site-logo"> + <img src="https://assets.gentoo.org/tyrian/site-logo.png" alt="Gentoo" srcset="https://assets.gentoo.org/tyrian/site-logo.svg"/> + </a> + <span class="site-label">Packages</span> + </div> + <div class="site-title-buttons"> + <div class="btn-group btn-group-sm"> + <a href="https://get.gentoo.org/" role="button" class="btn get-gentoo"><span class="fa fa-fw fa-download"></span> <strong>Get Gentoo!</strong></a> + <div class="btn-group btn-group-sm"> + <a class="btn gentoo-org-sites dropdown-toggle" data-toggle="dropdown" data-target="#" href="#"> + <span class="fa fa-fw fa-map-o"></span> <span class="d-none d-sm-inline">gentoo.org sites</span> <span class="caret"></span> + </a> + <div class="dropdown-menu dropdown-menu-right"> + <a class="dropdown-item" href="https://www.gentoo.org/" title="Main Gentoo website"><span class="fa fa-home fa-fw"></span> gentoo.org</a> + <a class="dropdown-item" href="https://wiki.gentoo.org/" title="Find and contribute documentation"><span class="fa fa-file-text-o fa-fw"></span> Wiki</a> + <a class="dropdown-item" href="https://bugs.gentoo.org/" title="Report issues and find common issues"><span class="fa fa-bug fa-fw"></span> Bugs</a> + <a class="dropdown-item" href="https://forums.gentoo.org/" title="Discuss with the community"><span class="fa fa-comments-o fa-fw"></span> Forums</a> + <a class="dropdown-item" href="https://packages.gentoo.org/" title="Find software for your Gentoo"><span class="fa fa-hdd-o fa-fw"></span> Packages</a> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="https://planet.gentoo.org/" title="Find out what's going on in the developer community"><span class="fa fa-rss fa-fw"></span> Planet</a> + <a class="dropdown-item" href="https://archives.gentoo.org/" title="Read up on past discussions"><span class="fa fa-archive fa-fw"></span> Archives</a> + <a class="dropdown-item" href="https://sources.gentoo.org/" title="Browse our source code"><span class="fa fa-code fa-fw"></span> Sources</a> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="https://infra-status.gentoo.org/" title="Get updates on the services provided by Gentoo"><span class="fa fa-server fa-fw"></span> Infra Status</a> + </div> + </div> + </div> + </div> + </div> + </div> + </div> +} + +templ navigationBar(tab string) { + <nav class="tyrian-navbar navbar navbar-dark navbar-expand-lg bg-primary" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar-main-collapse" aria-controls="navbar-main-collapse" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + </div> + <div class="collapse navbar-collapse navbar-main-collapse" id="navbar-main-collapse"> + <ul class="navbar-nav mr-auto"> + <li class={ "nav-item", templ.KV("active", tab == "home") }><a class="nav-link" href="/">Home</a></li> + <li class={ "nav-item", templ.KV("active", tab == "packages") }><a class="nav-link" href="/categories">Packages</a></li> + <li class={ "nav-item", templ.KV("active", tab == "maintainers") }><a class="nav-link" href="/maintainers">Maintainers</a></li> + <li class={ "nav-item", templ.KV("active", tab == "useflags") }><a class="nav-link" href="/useflags">USE flags</a></li> + <li class={ "nav-item", templ.KV("active", tab == "arches") }><a class="nav-link" href="/arches">Architectures</a></li> + <li class={ "nav-item", templ.KV("active", tab == "about") }><a class="nav-link" href="/about">About</a></li> + </ul> + if tab != "home" { + <form class="form-inline inlinesearch" role="search" action="/packages/search" method="get"> + <div class="input-group"> + <div class="input-group-prepend"> + <span class="input-group-text" id="basic-addon1"><i class="fa fa-search" aria-hidden="true"></i></span> + </div> + <input class="form-control" name="q" type="text" placeholder="Find Packages" aria-label="Find Packages"/> + </div> + </form> + } + </div> + </div> + </nav> +} + +templ footer() { + <footer style="background-color: #fafafa; box-shadow:none!important;"> + <div class="container pt-4" style="border-top: 1px solid #dddddd;"> + <div class="row"> + <div class="col-2 col-sm-2 col-md-2"> + <ul class="footerlinks three-icons"> + <li><a href="https://twitter.com/gentoo" title="@Gentoo on Twitter"><span class="fa fa-twitter fa-fw"></span></a></li> + <li><a href="https://www.facebook.com/gentoo.org" title="Gentoo on Facebook"><span class="fa fa-facebook fa-fw"></span></a></li> + <li><a href="https://www.reddit.com/r/Gentoo/" title="Gentoo on Reddit"><span class="fa fa-reddit-alien fa-fw"></span></a></li> + </ul> + </div> + <div class="col-8 col-sm-8 col-md-8"> + <strong>© 2001–2024 Gentoo Authors</strong> + <br/> + <small> + Gentoo is a trademark of the Gentoo Foundation, Inc. and of Förderverein Gentoo e.V. + The contents of this document, unless otherwise expressly stated, are licensed under the + <a href="https://creativecommons.org/licenses/by-sa/4.0/" rel="license">CC-BY-SA-4.0</a> license. + The <a href="https://www.gentoo.org/inside-gentoo/foundation/name-logo-guidelines.html">Gentoo Name and Logo Usage Guidelines</a> apply. + </small> + </div> + <div class="col-2 col-sm-2 col-md-2 text-right"> + <strong><a class="text-dark" href="https://www.gentoo.org/inside-gentoo/contact/">Contact</a></strong> + <br/> + <small>{ config.Version() }</small> + </div> + </div> + </div> + </footer> +} + +templ Layout(title string, tab string, contents templ.Component) { + <!DOCTYPE html> + <html lang="en"> + @head(title) + <body> + <header> + @siteTitle() + @navigationBar(tab) + </header> + @contents + @footer() + </body> + </html> +} + +type SubTab struct { + Name string + Link templ.SafeURL + Icon string + BadgeValue string +} + +templ tabbedHeader(subTitle string, icon string, description string, tabs []SubTab, currentSubTab string, contents templ.Component) { + <div class="kk-header-container"> + <div class="container"> + <div class="row"> + <div class="col-12"> + <div class="row mt-3 pt-2"> + <div class="col-md-5"> + <h1 class="stick-top kk-package-title" id="package-title"> + <div> + <div class="kk-package-name" style="margin-left: 0px!important;"><span class={ icon }></span><span class="ml-2">{ subTitle }</span></div> + </div> + </h1> + </div> + <div class="col-md-7">{ description }</div> + <div class="col-md-12 pt-4 mt-1"> + <nav class="nav kk-package-nav"> + for _, tab := range tabs { + <a class={ "nav-link", templ.KV("active", tab.Name == currentSubTab) } href={ tab.Link }> + if tab.Icon != "" { + <i class={ tab.Icon } aria-hidden="true"></i> + } + { tab.Name } + if tab.BadgeValue != "" { + <span class="ml-1 badge badge-pill kk-misc-badge">{ tab.BadgeValue }</span> + } + </a> + } + </nav> + </div> + </div> + </div> + </div> + </div> + </div> + <div class="tab-content" id="myTabContent"> + @contents + </div> +} + +templ TabbedLayout(title string, tab string, subTitle string, icon string, description string, tabs []SubTab, currentSubTab string, contents templ.Component) { + @Layout(title, tab, tabbedHeader(subTitle, icon, description, tabs, currentSubTab, contents)) +} diff --git a/pkg/app/serve.go b/pkg/app/serve.go index ce4d8bb..b54d4f2 100644 --- a/pkg/app/serve.go +++ b/pkg/app/serve.go @@ -3,11 +3,10 @@ package app import ( - "github.com/99designs/gqlgen/graphql/handler" - "github.com/99designs/gqlgen/graphql/handler/extension" - "log" + "log/slog" "net/http" _ "net/http/pprof" + "os" "soko/pkg/api/graphql/generated" "soko/pkg/api/graphql/graphiql" "soko/pkg/api/graphql/resolvers" @@ -21,75 +20,103 @@ import ( "soko/pkg/app/handler/user" "soko/pkg/config" "soko/pkg/database" - "soko/pkg/logger" + + "github.com/99designs/gqlgen/graphql/handler" + "github.com/99designs/gqlgen/graphql/handler/extension" ) // Serve is used to serve the web application func Serve() { - database.Connect() defer database.DBCon.Close() - setRoute("/categories", categories.Index) - setRoute("/categories.json", categories.JSONCategories) - setRoute("/categories/", categories.Show) - - setRoute("/useflags/popular.json", useflags.Popular) - setRoute("/useflags/suggest.json", useflags.Suggest) - setRoute("/useflags/search", useflags.Search) - setRoute("/useflags/global", useflags.Global) - setRoute("/useflags/local", useflags.Local) - setRoute("/useflags/popular", useflags.Index) - setRoute("/useflags", useflags.Default) - setRoute("/useflags/", useflags.Show) - - setRoute("/arches", arches.Index) - setRoute("/arches/", arches.Show) - - setRoute("/about", about.Index) - setRoute("/about/help", about.Help) - setRoute("/about/feedback", about.Feedback) - setRoute("/about/feeds", about.Feeds) - setRoute("/about/status", about.Status) - - setRoute("/maintainers", maintainer.Browse) - setRoute("/maintainers/", maintainer.Browse) - setRoute("/maintainer/", maintainer.Show) - - setRoute("/packages/search", packages.Search) - setRoute("/packages/suggest.json", packages.Suggest) - setRoute("/packages/resolve.json", packages.Resolve) - setRoute("/packages/added", packages.Added) - setRoute("/packages/updated", packages.Updated) - setRoute("/packages/stable", packages.Stabilized) - setRoute("/packages/keyworded", packages.Keyworded) - setRoute("/packages/", packages.Show) - setRoute("/", index.Show) - - setRoute("/packages/added.atom", packages.AddedFeed) - setRoute("/packages/updated.atom", packages.UpdatedFeed) - setRoute("/packages/keyworded.atom", packages.KeywordedFeed) - setRoute("/packages/stable.atom", packages.StabilizedFeed) - // Added for backwards compability - redirect("/packages/stabilized.atom", "/packages/stable.atom") - setRoute("/packages/search.atom", packages.SearchFeed) - - setRoute("/user", user.Preferences) - setRoute("/user/preferences", user.Preferences) - setRoute("/user/preferences/", user.Preferences) + setRoute("GET /categories", categories.Index) + setRoute("GET /categories.json", categories.JSONCategories) + setRoute("GET /categories/{category}", categories.ShowPackages) + setRoute("GET /categories/{category}/bugs", categories.ShowBugs) + setRoute("GET /categories/{category}/outdated", categories.ShowOutdated) + setRoute("GET /categories/{category}/outdated.atom", categories.OutdatedFeed) + setRoute("GET /categories/{category}/pull-requests", categories.ShowPullRequests) + setRoute("GET /categories/{category}/security", categories.ShowSecurity) + setRoute("GET /categories/{category}/stabilization", categories.ShowStabilizations) + setRoute("GET /categories/{category}/stabilization.atom", categories.StabilizationFeed) + setRoute("GET /categories/{category}/stabilization.json", categories.ShowStabilizationFile) + setRoute("GET /categories/{category}/stabilization.list", categories.ShowStabilizationFile) + setRoute("GET /categories/{category}/stabilization.xml", categories.ShowStabilizationFile) + + redirect("GET /useflags", "/useflags/popular") + setRoute("GET /useflags/popular.json", useflags.Popular) + setRoute("GET /useflags/suggest.json", useflags.Suggest) + setRoute("GET /useflags/search", useflags.Search) + setRoute("GET /useflags/global", useflags.Global) + setRoute("GET /useflags/local", useflags.Local) + setRoute("GET /useflags/expand", useflags.Expand) + setRoute("GET /useflags/popular", useflags.PopularPage) + setRoute("GET /useflags/{useflag}", useflags.Show) + + redirect("GET /arches", "/arches/amd64/keyworded") + setRoute("GET /arches/{arch}/stable", arches.ShowStable) + setRoute("GET /arches/{arch}/stable.atom", arches.ShowStableFeed) + setRoute("GET /arches/{arch}/keyworded", arches.ShowKeyworded) + setRoute("GET /arches/{arch}/keyworded.atom", arches.ShowKeywordedFeed) + setRoute("GET /arches/{arch}/leaf-packages", arches.ShowLeafPackages) + + setRoute("GET /about", about.Index) + setRoute("GET /about/help", about.Help) + setRoute("GET /about/feedback", about.Feedback) + setRoute("GET /about/feeds", about.Feeds) + setRoute("GET /about/status", about.Status) + + setRoute("GET /maintainers", maintainer.BrowseProjects) + redirect("GET /maintainers/gentoo-projects", "/maintainers") + setRoute("GET /maintainers/gentoo-developers", maintainer.BrowseDevs) + setRoute("GET /maintainers/proxied-maintainers", maintainer.BrowseProxyDevs) + setRoute("GET /maintainer/{email}", maintainer.ShowPackages) + setRoute("GET /maintainer/{email}/bugs", maintainer.ShowBugs) + setRoute("GET /maintainer/{email}/changelog", maintainer.ShowChangelog) + setRoute("GET /maintainer/{email}/changelog.atom", maintainer.ShowChangelogFeed) + setRoute("GET /maintainer/{email}/info.json", maintainer.ShowInfoJson) + setRoute("GET /maintainer/{email}/outdated", maintainer.ShowOutdated) + setRoute("GET /maintainer/{email}/outdated.atom", maintainer.ShowOutdatedFeed) + setRoute("GET /maintainer/{email}/pull-requests", maintainer.ShowPullRequests) + setRoute("GET /maintainer/{email}/security", maintainer.ShowSecurity) + setRoute("GET /maintainer/{email}/stabilization", maintainer.ShowStabilization) + setRoute("GET /maintainer/{email}/stabilization.json", maintainer.ShowStabilizationFile) + setRoute("GET /maintainer/{email}/stabilization.list", maintainer.ShowStabilizationFile) + setRoute("GET /maintainer/{email}/stabilization.xml", maintainer.ShowStabilizationFile) + setRoute("GET /maintainer/{email}/stabilization.atom", maintainer.ShowStabilizationFeed) + + setRoute("GET /packages/search", packages.Search) + setRoute("GET /packages/suggest.json", packages.Suggest) + setRoute("GET /packages/resolve.json", packages.Resolve) + setRoute("GET /packages/added", packages.Added) + setRoute("GET /packages/updated", packages.Updated) + setRoute("GET /packages/stable", packages.Stabilized) + setRoute("GET /packages/keyworded", packages.Keyworded) + setRoute("GET /packages/{category}/{package}", packages.Show) + setRoute("GET /packages/{category}/{package}/{pageName}", packages.Show) + setRoute("GET /{$}", index.Show) + + setRoute("GET /packages/added.atom", packages.AddedFeed) + setRoute("GET /packages/updated.atom", packages.UpdatedFeed) + setRoute("GET /packages/keyworded.atom", packages.KeywordedFeed) + setRoute("GET /packages/stable.atom", packages.StabilizedFeed) + // Added for backwards compatibility + redirect("GET /packages/stabilized.atom", "/packages/stable.atom") + setRoute("GET /packages/search.atom", packages.SearchFeed) + + redirect("GET /user", "/user/preferences/general") + redirect("GET /user/preferences", "/user/preferences/general") + setRoute("GET /user/preferences/general", user.Preferences("General")) + setRoute("GET /user/preferences/packages", user.Preferences("Packages")) + setRoute("GET /user/preferences/maintainers", user.Preferences("Maintainers")) setRoute("/user/preferences/general/layout", user.General) setRoute("/user/preferences/general/reset", user.ResetGeneral) - setRoute("/user/preferences/arches/visible", user.Arches) - setRoute("/user/preferences/arches/reset", user.ResetArches) - setRoute("/user/preferences/packages/edit", user.EditPackagesPreferences) setRoute("/user/preferences/packages/reset", user.ResetPackages) - setRoute("/user/preferences/useflags/edit", user.Useflags) - setRoute("/user/preferences/useflags/reset", user.ResetUseflags) - setRoute("/user/preferences/maintainers/edit", user.Maintainers) setRoute("/user/preferences/maintainers/reset", user.ResetMaintainers) @@ -109,9 +136,11 @@ func Serve() { // graphiql: api explorer setRoute("/api/explore/", graphiql.Show) - logger.Info.Println("Serving on port: " + config.Port()) - log.Fatal(http.ListenAndServe(":"+config.Port(), nil)) - + address := ":" + config.Port() + slog.Info("Serving HTTP", "address", address) + err := http.ListenAndServe(address, nil) + slog.Error("exited server", "err", err) + os.Exit(1) } // define a route using the default middleware and the given handler @@ -121,7 +150,7 @@ func setRoute(path string, handler http.HandlerFunc) { func redirect(from, to string) { http.HandleFunc(from, func(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, to, 301) + http.Redirect(w, r, to, http.StatusMovedPermanently) }) } diff --git a/pkg/app/utils/applicationdata.go b/pkg/app/utils/applicationdata.go index d22e5c9..db27f63 100644 --- a/pkg/app/utils/applicationdata.go +++ b/pkg/app/utils/applicationdata.go @@ -3,8 +3,8 @@ package utils import ( + "log/slog" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" "time" ) @@ -14,9 +14,9 @@ import ( func GetApplicationData() models.Application { // Select user by primary key. applicationData := &models.Application{Id: "latest"} - err := database.DBCon.Select(applicationData) + err := database.DBCon.Model(applicationData).WherePK().Select() if err != nil { - logger.Error.Println("Error fetching application data") + slog.Error("Failed fetching application data", slog.Any("err", err)) return models.Application{ Id: "latest", LastUpdate: time.Now(), diff --git a/pkg/app/utils/bugs.go b/pkg/app/utils/bugs.go new file mode 100644 index 0000000..d840541 --- /dev/null +++ b/pkg/app/utils/bugs.go @@ -0,0 +1,21 @@ +package utils + +import ( + "soko/pkg/models" +) + +func CountBugsCategories(bugs []*models.Bug) (generalCount, stabilizationCount, keywordingCount int) { + for _, bug := range bugs { + switch bug.Component { + case "Current packages": + generalCount++ + case "Stabilization": + stabilizationCount++ + case "Keywording": + keywordingCount++ + default: + continue + } + } + return +} diff --git a/pkg/app/utils/changedVersion.templ b/pkg/app/utils/changedVersion.templ new file mode 100644 index 0000000..b23269d --- /dev/null +++ b/pkg/app/utils/changedVersion.templ @@ -0,0 +1,130 @@ +package utils + +import "slices" +import "soko/pkg/models" +import "strings" +import "time" + +templ ChangedVersionsTable(versions []*models.Version) { + for _, version := range versions { + <li class="list-group-item kk-package-detailed"> + <div class="row"> + <div class="col-xs-12 col-md-6"> + <h4 class="stick-top"><a href={ templ.URL("/packages/" + version.Atom) }>{ version.Atom }</a></h4> + <div class="kk-package-detailed-toolbox"> + <button type="button" class="kk-btn-xs btn btn-outline-secondary" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + <span class="fa fa-fw fa-navicon"></span> + </button> + <div class="dropdown-menu dropdown-menu-right"> + <a + class="dropdown-item" + target="_blank" + href={ templ.URL("https://bugs.gentoo.org/buglist.cgi?quicksearch=" + version.Atom) } + > + <span class="fa fa-fw fa-bug"></span> + Related bugs + </a> + <a + class="dropdown-item" + target="_blank" + href={ templ.URL("https://wiki.gentoo.org/index.php?title=Special:Search&fulltext=Search&search=" + version.Package) } + > + <span class="fa fa-fw fa-book"></span> + Documentation + </a> + <a + class="dropdown-item" + target="_blank" + href={ templ.URL("https://forums.gentoo.org/search.php?search_terms=all&show_results=topics&search_keywords=" + version.Package + "&mode=results") } + > + <span class="fa fa-fw fa-comments-o"></span> + Forums posts + </a> + <div class="dropdown-divider"></div> + <a + class="dropdown-item" + target="_blank" + href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/tree/" + version.Atom) } + > + <span class="fa fa-fw fa-code-fork"></span> + Git repository browser + </a> + <a + class="dropdown-item" + target="_blank" + href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/log/" + version.Atom + "?showmsg=1") } + > + <span class="fa fa-fw fa-history"></span> + Git log + </a> + <a + class="dropdown-item" + target="_blank" + href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/atom/" + version.Atom + "?h=master") } + > + <span class="fa fa-fw fa-rss"></span> + Changes feed + </a> + </div> + </div> + { version.Description } + <br/> + <small class="text-muted"></small> + if len(version.Commits) > 0 { + <div class="kk-inline-changelog-entry"> + <a + href={ templ.URL("https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=" + version.Commits[0].Id) } + title="Git commit" + > + <span class="octicon octicon-git-pull-request"></span> + <span class="kk-commit-message">{ version.Commits[0].Message }</span> + </a> + </div> + } + </div> + <div class="col-xs-12 col-md-6"> + <small class="text-muted pull-right"> + if len(version.Commits) > 0 { + <span title={ version.Commits[0].CommitterDate.Format(time.DateTime) + " UTC" }> + { version.Commits[0].CommitterDate.Format(time.DateTime) } UTC + </span> + } else { + <span title="unknown">unknown</span> + } + </small> + <div class="kk-version-card"> + <p class="mb-2"> + <strong>{ version.Version }</strong> + <span class="kk-slot"> : { version.Slot }</span> + if len(version.Restricts) > 0 { + <span + class="badge badge-danger kk-restrict-label" + title={ "The following features are restricted: " + strings.Join(version.Restricts, " ") } + > + { FormatRestricts(version.Restricts) } + </span> + } + </p> + <p> + for _, arch := range models.ArchesToShow { + if slices.Contains(strings.Fields(version.Keywords), arch) { + <span style="margin-right: 4px;" class="label kk-keyword-stable" title={ version.Version + " is stable on " + arch }> + { arch } + </span> + } else if slices.Contains(strings.Fields(version.Keywords), "~"+arch) { + <span style="margin-right: 4px;" class="label kk-keyword-testing" title={ version.Version + " is testing on " + arch }> + ~{ arch } + </span> + } else { + <span style="margin-right: 4px;" class="label kk-keyword-unknown" title={ version.Version + " is unknown on " + arch }> + ?{ arch } + </span> + } + } + </p> + </div> + </div> + </div> + </li> + } +} diff --git a/pkg/app/utils/outdated.go b/pkg/app/utils/outdated.go new file mode 100644 index 0000000..317c82b --- /dev/null +++ b/pkg/app/utils/outdated.go @@ -0,0 +1,29 @@ +package utils + +import ( + "net/http" + "time" + + "github.com/gorilla/feeds" + + "soko/pkg/models" +) + +func OutdatedFeed(w http.ResponseWriter, link, title string, outdated []models.OutdatedPackages) { + feed := &feeds.Feed{ + Title: "Outdated Packages for " + title, + Author: &feeds.Author{Name: "Gentoo Packages Database"}, + Created: time.Now(), + Link: &feeds.Link{Href: link}, + } + + for _, entry := range outdated { + feed.Add(&feeds.Item{ + Id: entry.Atom, + Title: entry.Atom, + Description: "Version " + entry.NewestVersion + " is available, while the latest version in the Gentoo tree is " + entry.GentooVersion + ".", + Link: &feeds.Link{Href: "https://packages.gentoo.org/packages/" + entry.Atom, Type: "text/html", Rel: "alternate"}, + }) + } + feed.WriteAtom(w) +} diff --git a/pkg/app/utils/stabilization.go b/pkg/app/utils/stabilization.go new file mode 100644 index 0000000..8757440 --- /dev/null +++ b/pkg/app/utils/stabilization.go @@ -0,0 +1,86 @@ +package utils + +import ( + "encoding/json" + "encoding/xml" + "html" + "net/http" + "soko/pkg/models" + "strings" + "time" + + "github.com/gorilla/feeds" +) + +type stabilization struct { + XMLName xml.Name `xml:"stabilization" json:"-"` + Category string `xml:"category" json:"category"` + Package string `xml:"package" json:"package"` + Version string `xml:"version" json:"version"` + Message string `xml:"message" json:"message"` +} + +func (s stabilization) String() string { + return s.Category + "/" + s.Package + "-" + s.Version + " # " + s.Message +} + +func StabilizationExport(w http.ResponseWriter, pageUrl string, results []*models.PkgCheckResult) { + result := make([]stabilization, len(results)) + for i, pkgcheck := range results { + result[i] = stabilization{ + Category: pkgcheck.Category, + Package: pkgcheck.Package, + Version: pkgcheck.Version, + Message: pkgcheck.Message, + } + } + + _, extension, _ := strings.Cut(pageUrl, ".") + switch extension { + case "json": + b, err := json.Marshal(result) + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write(b) + case "xml": + b, err := xml.Marshal(struct { + XMLName xml.Name `xml:"xml"` + Packages []stabilization + }{Packages: result}) + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/xml") + w.Write(b) + case "list": + var lines string + for _, pkg := range result { + lines += pkg.String() + "\n" + } + w.Header().Set("Content-Type", "text/plain") + w.Write([]byte(lines)) + } +} + +func StabilizationFeed(w http.ResponseWriter, link, title string, results []*models.PkgCheckResult) { + feed := &feeds.Feed{ + Title: "Stabilization candidates for " + title, + Author: &feeds.Author{Name: "Gentoo Packages Database"}, + Created: time.Now(), + Link: &feeds.Link{Href: link}, + } + + for _, pkgcheck := range results { + feed.Add(&feeds.Item{ + Title: pkgcheck.CPV, + Description: html.EscapeString(pkgcheck.Message), + Link: &feeds.Link{Href: "https://packages.gentoo.org/packages/" + pkgcheck.Atom, Type: "text/html", Rel: "alternate"}, + Id: pkgcheck.CPV, + }) + } + feed.WriteAtom(w) +} diff --git a/pkg/app/utils/userdata.go b/pkg/app/utils/userdata.go index baaba7f..dc4258b 100644 --- a/pkg/app/utils/userdata.go +++ b/pkg/app/utils/userdata.go @@ -38,21 +38,8 @@ func GetUserPreferences(r *http.Request) models.UserPreferences { } } - cookie, err = r.Cookie("userpref_useflags") - if err == nil { - cookieValue, err := b64.StdEncoding.DecodeString(cookie.Value) - if err == nil { - json.Unmarshal(cookieValue, &userPreferences.Useflags) - } - } - - cookie, err = r.Cookie("userpref_arches") - if err == nil { - cookieValue, err := b64.StdEncoding.DecodeString(cookie.Value) - if err == nil { - json.Unmarshal(cookieValue, &userPreferences.Arches) - } - } + // old cookie: userpref_useflags + // old cookie: userpref_arches userPreferences.Sanitize() diff --git a/pkg/app/utils/version.go b/pkg/app/utils/version.go new file mode 100644 index 0000000..5609404 --- /dev/null +++ b/pkg/app/utils/version.go @@ -0,0 +1,19 @@ +package utils + +import ( + "soko/pkg/utils" + "strings" +) + +// FormatRestricts returns a string containing a comma separated +// list of capitalized first letters of the package restricts +func FormatRestricts(restricts []string) string { + var result []string + for _, restrict := range restricts { + if restrict != "" && restrict != "(" && restrict != ")" && !strings.HasSuffix(restrict, "?") { + result = append(result, strings.ToUpper(string(restrict[0]))) + } + } + result = utils.Deduplicate(result) + return strings.Join(result, ", ") +} diff --git a/pkg/config/config.go b/pkg/config/config.go index b291555..3bd651f 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1,6 +1,9 @@ package config -import "os" +import ( + "fmt" + "os" +) func PortDir() string { return getEnv("SOKO_PORT_DIR", "/mnt/packages-tree/gentoo") @@ -34,12 +37,12 @@ func DevMode() string { return getEnv("SOKO_DEVMODE", "false") } -func Debug() string { - return getEnv("SOKO_DEBUG", "false") +func Debug() bool { + return getEnv("SOKO_DEBUG", "false") == "true" } -func Quiet() string { - return getEnv("SOKO_QUIET", "false") +func Quiet() bool { + return getEnv("SOKO_QUIET", "false") == "true" } func LogFile() string { @@ -47,7 +50,7 @@ func LogFile() string { } func Version() string { - return getEnv("SOKO_VERSION", "v1.0.0") + return getEnv("SOKO_VERSION", "v1.0.3") } func Port() string { @@ -66,6 +69,10 @@ func CacheControl() string { return getEnv("SOKO_CACHE_CONTROL", "max-age=300") } +func UserAgent() string { + return fmt.Sprintf("Gentoo Soko %s/packages.gentoo.org/gpackages@gentoo.org", Version()) +} + func getEnv(key string, fallback string) string { if os.Getenv(key) != "" { return os.Getenv(key) diff --git a/pkg/database/connection.go b/pkg/database/connection.go index 33325e6..77a6b50 100644 --- a/pkg/database/connection.go +++ b/pkg/database/connection.go @@ -4,11 +4,14 @@ package database import ( "context" - "github.com/go-pg/pg/v9" - "github.com/go-pg/pg/v9/orm" - "log" + "log/slog" + "os" + "time" + + "github.com/go-pg/pg/v10" + "github.com/go-pg/pg/v10/orm" + "soko/pkg/config" - "soko/pkg/logger" "soko/pkg/models" ) @@ -19,39 +22,50 @@ var ( ) // CreateSchema creates the tables in the database -// in case they don't alreay exist +// in case they don't already exist func CreateSchema() error { - for _, model := range []interface{}{(*models.Package)(nil), + for _, model := range []interface{}{ + (*models.CommitToPackage)(nil), + (*models.CommitToVersion)(nil), + (*models.PackageToBug)(nil), + (*models.VersionToBug)(nil), + (*models.PackageToGithubPullRequest)(nil), + (*models.MaskToVersion)(nil), + (*models.DeprecatedToVersion)(nil), + (*models.Package)(nil), + (*models.CategoryPackagesInformation)(nil), (*models.Category)(nil), (*models.Version)(nil), (*models.Commit)(nil), (*models.KeywordChange)(nil), - (*models.CommitToPackage)(nil), - (*models.CommitToVersion)(nil), (*models.Useflag)(nil), (*models.Mask)(nil), - (*models.MaskToVersion)(nil), + (*models.DeprecatedPackage)(nil), (*models.OutdatedPackages)(nil), (*models.Project)(nil), (*models.MaintainerToProject)(nil), (*models.PkgCheckResult)(nil), (*models.GithubPullRequest)(nil), - (*models.PackageToGithubPullRequest)(nil), (*models.Bug)(nil), - (*models.PackageToBug)(nil), - (*models.VersionToBug)(nil), (*models.ReverseDependency)(nil), (*models.Maintainer)(nil), - (*models.Application)(nil)} { - - err := DBCon.CreateTable(model, &orm.CreateTableOptions{ + (*models.Application)(nil), + } { + err := DBCon.Model(model).CreateTable(&orm.CreateTableOptions{ IfNotExists: true, }) if err != nil { + tableName := string(DBCon.Model(model).TableModel().Table().TypeName) + slog.Error("Failed creating table", slog.String("table", tableName), slog.Any("err", err)) return err } - } + _, err := DBCon.Exec("CREATE EXTENSION IF NOT EXISTS pg_trgm") + if err != nil { + slog.Error("Failed creating extension 'pg_trgm'", slog.Any("err", err)) + return err + } + return nil } @@ -63,7 +77,10 @@ func (d dbLogger) BeforeQuery(c context.Context, q *pg.QueryEvent) (context.Cont // AfterQuery is used to log SQL queries func (d dbLogger) AfterQuery(c context.Context, q *pg.QueryEvent) error { - logger.Debug.Println(q.FormattedQuery()) + query, err := q.FormattedQuery() + if err == nil { + slog.Debug(string(query), slog.Duration("duration", time.Since(q.StartTime))) + } return nil } @@ -71,19 +88,30 @@ func (d dbLogger) AfterQuery(c context.Context, q *pg.QueryEvent) error { // and turn on logging if desired func Connect() { DBCon = pg.Connect(&pg.Options{ - User: config.PostgresUser(), - Password: config.PostgresPass(), - Database: config.PostgresDb(), - Addr: config.PostgresHost() + ":" + config.PostgresPort(), + User: config.PostgresUser(), + Password: config.PostgresPass(), + Database: config.PostgresDb(), + Addr: config.PostgresHost() + ":" + config.PostgresPort(), + DialTimeout: 10 * time.Second, }) - DBCon.AddQueryHook(dbLogger{}) + if !config.Quiet() { + DBCon.AddQueryHook(dbLogger{}) + } - err := CreateSchema() - if err != nil { - logger.Error.Println("ERROR: Could not create database schema") - logger.Error.Println(err) - log.Fatalln(err) + if err := CreateSchema(); err != nil { + slog.Error("Failed creating database schema", slog.Any("err", err)) + os.Exit(1) } +} +func TruncateTable(model any) { + query := DBCon.Model(model) + tableName := string(query.TableModel().Table().TypeName) + _, err := query.Exec("TRUNCATE TABLE ?TableName") + if err != nil { + slog.Error("Failed truncating table", slog.String("table", tableName), slog.Any("err", err)) + } else { + slog.Info("Truncated table", slog.String("table", tableName)) + } } diff --git a/pkg/logger/loggers.go b/pkg/logger/loggers.go deleted file mode 100644 index 0ef51e9..0000000 --- a/pkg/logger/loggers.go +++ /dev/null @@ -1,39 +0,0 @@ -package logger - -import ( - "io" - "log" - "os" -) - -var ( - Debug *log.Logger - Info *log.Logger - Error *log.Logger -) - -func Init( - debugHandle io.Writer, - infoHandle io.Writer, - errorHandle io.Writer) { - - Debug = log.New(debugHandle, - "DEBUG: ", - log.Ldate|log.Ltime|log.Lshortfile) - - Info = log.New(infoHandle, - "INFO: ", - log.Ldate|log.Ltime|log.Lshortfile) - - Error = log.New(errorHandle, - "ERROR: ", - log.Ldate|log.Ltime|log.Lshortfile) -} - -func CreateLogFile(path string) *os.File { - f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - log.Println(err) - } - return f -} diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index 9e48a02..2d6a878 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -1,44 +1,45 @@ package metrics import ( - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" "soko/pkg/app/utils" "soko/pkg/database" "soko/pkg/models" "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" ) var ( - UpdateAges = map[string]prometheus.Gauge { + UpdateAges = map[string]prometheus.Gauge{ "dependencies": promauto.NewGauge(prometheus.GaugeOpts{ - Name: "pgo_update_age", - Help: "The age of the last update", + Name: "pgo_update_age", + Help: "The age of the last update", ConstLabels: prometheus.Labels{"type": "dependencies"}, }), "pkgcheck": promauto.NewGauge(prometheus.GaugeOpts{ - Name: "pgo_update_age", - Help: "The age of the last update", + Name: "pgo_update_age", + Help: "The age of the last update", ConstLabels: prometheus.Labels{"type": "pkgcheck"}, }), "pullrequests": promauto.NewGauge(prometheus.GaugeOpts{ - Name: "pgo_update_age", - Help: "The age of the last update", + Name: "pgo_update_age", + Help: "The age of the last update", ConstLabels: prometheus.Labels{"type": "pullrequests"}, }), "bugs": promauto.NewGauge(prometheus.GaugeOpts{ - Name: "pgo_update_age", - Help: "The age of the last update", + Name: "pgo_update_age", + Help: "The age of the last update", ConstLabels: prometheus.Labels{"type": "bugs"}, }), "projects": promauto.NewGauge(prometheus.GaugeOpts{ - Name: "pgo_update_age", - Help: "The age of the last update", + Name: "pgo_update_age", + Help: "The age of the last update", ConstLabels: prometheus.Labels{"type": "projects"}, }), "maintainers": promauto.NewGauge(prometheus.GaugeOpts{ - Name: "pgo_update_age", - Help: "The age of the last update", + Name: "pgo_update_age", + Help: "The age of the last update", ConstLabels: prometheus.Labels{"type": "maintainers"}, }), } @@ -49,8 +50,7 @@ var ( }) ) - -func Update(){ +func Update() { database.Connect() defer database.DBCon.Close() @@ -65,10 +65,9 @@ func Update(){ } lastCommit := &models.Commit{Id: utils.GetApplicationData().LastCommit} - err := database.DBCon.Select(lastCommit) + err := database.DBCon.Model(lastCommit).WherePK().Select() if err == nil { LastCommitAge.Set(time.Since(lastCommit.CommitterDate).Seconds()) } - } diff --git a/pkg/models/category.go b/pkg/models/category.go index a1a073c..fcf13b0 100644 --- a/pkg/models/category.go +++ b/pkg/models/category.go @@ -3,7 +3,17 @@ package models type Category struct { - Name string `pg:",pk"` - Description string - Packages []*Package `pg:",fk:category"` + Name string `pg:",pk"` + Description string + Packages []*Package `pg:",fk:category"` + PackagesInformation CategoryPackagesInformation `pg:",fk:name,rel:has-one"` +} + +type CategoryPackagesInformation struct { + Name string `pg:",pk"` + Outdated int + PullRequests int + Bugs int + SecurityBugs int + StableRequests int } diff --git a/pkg/models/commit.go b/pkg/models/commit.go index d6fa710..7e6cd07 100644 --- a/pkg/models/commit.go +++ b/pkg/models/commit.go @@ -15,8 +15,8 @@ type Commit struct { CommitterDate time.Time Message string ChangedFiles *ChangedFiles - ChangedPackages []*Package `pg:"many2many:commit_to_packages,joinFK:package_atom"` - ChangedVersions []*Version `pg:"many2many:commit_to_versions,joinFK:version_id"` + ChangedPackages []*Package `pg:"many2many:commit_to_packages,join_fk:package_atom"` + ChangedVersions []*Version `pg:"many2many:commit_to_versions,join_fk:version_id"` KeywordChanges []*KeywordChange `pg:",fk:commit_id"` } @@ -34,11 +34,11 @@ type ChangedFile struct { type KeywordChange struct { Id string `pg:",pk"` CommitId string - Commit *Commit `pg:",fk:commit_id"` + Commit *Commit `pg:",fk:commit_id,rel:has-one"` VersionId string - Version *Version `pg:",fk:version_id"` + Version *Version `pg:",fk:version_id,rel:has-one"` PackageId string - Package *Package `pg:",fk:package_id"` + Package *Package `pg:",fk:package_id,rel:has-one"` Added []string Stabilized []string All []string diff --git a/pkg/models/deprecated.go b/pkg/models/deprecated.go new file mode 100644 index 0000000..1c1b1cb --- /dev/null +++ b/pkg/models/deprecated.go @@ -0,0 +1,19 @@ +// Contains the model of a package deprecated entry + +package models + +import "time" + +type DeprecatedPackage struct { + Versions string `pg:",pk"` + Author string + AuthorEmail string + Date time.Time + Reason string +} + +type DeprecatedToVersion struct { + Id string `pg:",pk"` + DeprecatedVersions string + VersionId string +} diff --git a/pkg/models/github.go b/pkg/models/github.go index bbd9dd5..aca52e9 100644 --- a/pkg/models/github.go +++ b/pkg/models/github.go @@ -31,62 +31,59 @@ type GitHubPullRequestQueryResult struct { Data GitHubPullRequestQueryResultData `json:"data"` } -func (res GitHubPullRequestQueryResult) HasNextPage() bool { +func (res *GitHubPullRequestQueryResult) HasNextPage() bool { return res.Data.Search.PageInfo.HasNextPage } -func (res GitHubPullRequestQueryResult) CreatePullRequest() []GithubPullRequest { - var pullrequests []GithubPullRequest +func (res *GitHubPullRequestQueryResult) EndCursor() string { + return res.Data.Search.PageInfo.EndCursor +} + +func (res *GitHubPullRequestQueryResult) AppendPullRequest(pullRequests map[int]*GithubPullRequest) { for _, rawObject := range res.Data.Search.Edges { - pullrequest := rawObject.Node - cistate := "" - cistatelink := "" - if pullrequest.Commits.Nodes != nil && len(pullrequest.Commits.Nodes) > 0 { - cistate = pullrequest.Commits.Nodes[0].Commit.Status.State - - if pullrequest.Commits.Nodes[0].Commit.Status.Contexts != nil && len(pullrequest.Commits.Nodes[0].Commit.Status.Contexts) > 0 { - cistatelink = pullrequest.Commits.Nodes[0].Commit.Status.Contexts[0].TargetUrl + pullRequest := rawObject.Node + var ciState, ciStateLink string + if pullRequest.Commits.Nodes != nil && len(pullRequest.Commits.Nodes) > 0 { + ciState = pullRequest.Commits.Nodes[0].Commit.Status.State + + if pullRequest.Commits.Nodes[0].Commit.Status.Contexts != nil && len(pullRequest.Commits.Nodes[0].Commit.Status.Contexts) > 0 { + ciStateLink = pullRequest.Commits.Nodes[0].Commit.Status.Contexts[0].TargetUrl } } - pullrequests = append(pullrequests, GithubPullRequest{ - Id: strconv.Itoa(pullrequest.Number), - Closed: pullrequest.Closed, - Url: pullrequest.Url, - Title: pullrequest.Title, - CreatedAt: pullrequest.CreatedAt, - UpdatedAt: pullrequest.UpdatedAt, - CiState: cistate, - CiStateLink: cistatelink, - Labels: pullrequest.CreateLabelsArray(), - Comments: pullrequest.Comments.TotalCount, - Files: pullrequest.CreateFilesArray(), - Author: pullrequest.Author.Login, - }) + pullRequests[pullRequest.Number] = &GithubPullRequest{ + Id: strconv.Itoa(pullRequest.Number), + Closed: pullRequest.Closed, + Url: pullRequest.Url, + Title: pullRequest.Title, + CreatedAt: pullRequest.CreatedAt, + UpdatedAt: pullRequest.UpdatedAt, + CiState: ciState, + CiStateLink: ciStateLink, + Labels: pullRequest.CreateLabelsArray(), + Comments: pullRequest.Comments.TotalCount, + Files: pullRequest.CreateFilesArray(), + Author: pullRequest.Author.Login, + } } - return pullrequests } -func (node GitHubPullRequestSearchNode) CreateLabelsArray() []GitHubPullRequestLabelNode { - var labels []GitHubPullRequestLabelNode - for _, label := range node.Labels.Edges { - labels = append(labels, label.Node) +func (node *GitHubPullRequestSearchNode) CreateLabelsArray() []GitHubPullRequestLabelNode { + labels := make([]GitHubPullRequestLabelNode, len(node.Labels.Edges)) + for i, label := range node.Labels.Edges { + labels[i] = label.Node } return labels } -func (node GitHubPullRequestSearchNode) CreateFilesArray() []GitHubPullRequestFileNode { - var labels []GitHubPullRequestFileNode - for _, label := range node.Files.Edges { - labels = append(labels, label.Node) +func (node *GitHubPullRequestSearchNode) CreateFilesArray() []GitHubPullRequestFileNode { + labels := make([]GitHubPullRequestFileNode, len(node.Files.Edges)) + for i, label := range node.Files.Edges { + labels[i] = label.Node } return labels } -func (res GitHubPullRequestQueryResult) EndCursor() string { - return res.Data.Search.PageInfo.EndCursor -} - type GitHubPullRequestQueryResultData struct { Search GitHubPullRequestSearchResult `json:"search"` } diff --git a/pkg/models/package.go b/pkg/models/package.go index 439480a..f543891 100644 --- a/pkg/models/package.go +++ b/pkg/models/package.go @@ -2,23 +2,26 @@ package models -import "sort" +import ( + "sort" + "strings" +) type Package struct { Atom string `pg:",pk"` Category string Name string - Versions []*Version `pg:",fk:atom"` + Versions []*Version `pg:",fk:atom,rel:has-many"` Longdescription string Maintainers []*Maintainer Upstream Upstream - Commits []*Commit `pg:"many2many:commit_to_packages,joinFK:commit_id"` + Commits []*Commit `pg:"many2many:commit_to_packages,join_fk:commit_id"` PrecedingCommits int `pg:",use_zero"` - PkgCheckResults []*PkgCheckResult `pg:",fk:atom"` - Outdated []*OutdatedPackages `pg:",fk:atom"` - Bugs []*Bug `pg:"many2many:package_to_bugs,joinFK:bug_id"` - PullRequests []*GithubPullRequest `pg:"many2many:package_to_github_pull_requests,joinFK:github_pull_request_id"` - ReverseDependencies []*ReverseDependency `pg:",fk:atom"` + PkgCheckResults []*PkgCheckResult `pg:",fk:atom,rel:has-many"` + Outdated []*OutdatedPackages `pg:",fk:atom,rel:has-many"` + Bugs []*Bug `pg:"many2many:package_to_bugs,join_fk:bug_id"` + PullRequests []*GithubPullRequest `pg:"many2many:package_to_github_pull_requests,join_fk:github_pull_request_id"` + ReverseDependencies []*ReverseDependency `pg:",fk:atom,rel:has-many"` } type Maintainer struct { @@ -28,9 +31,16 @@ type Maintainer struct { Restrict string PackagesInformation MaintainerPackagesInformation // In case the maintainer type is "project", Project will point to the project - Project Project `pg:",fk:email"` + Project Project `pg:",fk:email,rel:has-one"` // In case the maintainer type is not "project", Projects will point to the projects the maintainer is member of - Projects []*Project `pg:"many2many:maintainer_to_projects,joinFK:project_email"` + Projects []*Project `pg:"many2many:maintainer_to_projects,join_fk:project_email"` +} + +func (m *Maintainer) PrintName() string { + if m.Name != "" { + return m.Name + } + return m.Email } type MaintainerPackagesInformation struct { @@ -53,18 +63,36 @@ type RemoteId struct { Id string } -func (p Package) BuildRevDepMap() map[string]map[string]string { - var data = map[string]map[string]string{} +type packageDepMap struct { + Version string + Atom string + Map map[string]struct{} +} + +func (p Package) BuildRevDepMap() []packageDepMap { + var data = map[string]packageDepMap{} for _, dep := range p.ReverseDependencies { - if data[dep.ReverseDependencyVersion] == nil { - data[dep.ReverseDependencyVersion] = map[string]string{} - data[dep.ReverseDependencyVersion]["Atom"] = dep.ReverseDependencyAtom + if _, found := data[dep.ReverseDependencyVersion]; !found { + data[dep.ReverseDependencyVersion] = packageDepMap{ + Version: dep.ReverseDependencyVersion, + Atom: strings.ReplaceAll(dep.ReverseDependencyAtom, "[B]", ""), + Map: map[string]struct{}{}, + } } - data[dep.ReverseDependencyVersion][dep.Type] = "true" + data[dep.ReverseDependencyVersion].Map[dep.Type] = struct{}{} } - return data + result := make([]packageDepMap, 0, len(data)) + for _, v := range data { + result = append(result, v) + } + + sort.Slice(result, func(i, j int) bool { + return result[i].Version < result[j].Version + }) + + return result } func (p Package) Description() string { @@ -76,6 +104,15 @@ func (p Package) Description() string { return p.Longdescription } +func (p *Package) HasVersion(version string) bool { + for _, v := range p.Versions { + if v.Version == version { + return true + } + } + return false +} + func (p Package) AllBugs() []*Bug { allBugs := make(map[string]*Bug) @@ -101,3 +138,18 @@ func (p Package) AllBugs() []*Bug { return allBugsList } + +func (p *Package) AllUseflags() []string { + useflags := make(map[string]struct{}) + for _, version := range p.Versions { + for _, useflag := range version.Useflags { + useflags[strings.TrimPrefix(useflag, "+")] = struct{}{} + } + } + + useflagsList := make([]string, 0, len(useflags)) + for useflag := range useflags { + useflagsList = append(useflagsList, useflag) + } + return useflagsList +} diff --git a/pkg/models/userpreferences.go b/pkg/models/userpreferences.go index 0e6cd19..91d95ee 100644 --- a/pkg/models/userpreferences.go +++ b/pkg/models/userpreferences.go @@ -2,14 +2,10 @@ package models -import "strings" - type UserPreferences struct { General GeneralPreferences Packages PackagesPreferences Maintainers MaintainersPreferences - Useflags UseflagsPreferences - Arches ArchesPreferences } type GeneralPreferences struct { @@ -17,55 +13,12 @@ type GeneralPreferences struct { } type PackagesPreferences struct { - Overview PackagesOverviewPreferences - Dependencies PackagesDependenciesPreferences - QAReport PackagesQAReportPreferences - PullRequests PackagesPullRequestsPreferences - Bugs PackagesBugsPreferences - Security PackagesSecurityPreferences - Changelog PackagesChangelogPreferences - Tabs PackagesTabsPreferences + Overview PackagesOverviewPreferences } type PackagesOverviewPreferences struct { - Layout string - Keywords []string - EAPI string - ShowOutdated bool - MetadataFields []string - ChangelogType string - ChangelogLength int -} - -type PackagesDependenciesPreferences struct { - Default string -} - -type PackagesQAReportPreferences struct { - ExcludedWarningClasses []int - ShowAll bool -} - -type PackagesPullRequestsPreferences struct { - Layout string -} - -type PackagesBugsPreferences struct { Layout string -} - -type PackagesSecurityPreferences struct { - Layout string - ShowGLSAs bool -} - -type PackagesChangelogPreferences struct { - Layout string - Size int -} - -type PackagesTabsPreferences struct { - Visible []string + EAPI string } type MaintainersPreferences struct { @@ -73,64 +26,20 @@ type MaintainersPreferences struct { ExcludedProjects []string } -type UseflagsPreferences struct { - Layout string -} - -type ArchesPreferences struct { - Visible []string - DefaultArch string - DefaultPage string -} +var ArchesToShow = [...]string{"amd64", "x86", "alpha", "arm", "arm64", "hppa", "ia64", "ppc", "ppc64", "riscv", "sparc"} +var AllArches = [...]string{"alpha", "amd64", "arm", "arm64", "hppa", "ia64", "mips", "ppc", "ppc64", "riscv", "s390", "sparc", "x86"} func GetDefaultUserPreferences() UserPreferences { userPreferences := UserPreferences{} userPreferences.General = GeneralPreferences{} userPreferences.Packages = PackagesPreferences{} userPreferences.Packages.Overview = PackagesOverviewPreferences{} - userPreferences.Packages.Dependencies = PackagesDependenciesPreferences{} - userPreferences.Packages.QAReport = PackagesQAReportPreferences{} - userPreferences.Packages.PullRequests = PackagesPullRequestsPreferences{} - userPreferences.Packages.Bugs = PackagesBugsPreferences{} - userPreferences.Packages.Security = PackagesSecurityPreferences{} - userPreferences.Packages.Changelog = PackagesChangelogPreferences{} - userPreferences.Packages.Tabs = PackagesTabsPreferences{} userPreferences.Maintainers = MaintainersPreferences{} - userPreferences.Useflags = UseflagsPreferences{} - userPreferences.Arches = ArchesPreferences{} userPreferences.General.LandingPageLayout = "classic" userPreferences.Packages.Overview.Layout = "minimal" - userPreferences.Packages.Overview.Keywords = []string{"amd64", "x86", "alpha", "arm", "arm64", "hppa", "ia64", "ppc", "ppc64", "sparc"} userPreferences.Packages.Overview.EAPI = "none" - userPreferences.Packages.Overview.ShowOutdated = true - userPreferences.Packages.Overview.MetadataFields = []string{"homepage", "upstream", "longdescription", "useflags", "license", "maintainers"} - userPreferences.Packages.Overview.ChangelogType = "compact" - userPreferences.Packages.Overview.ChangelogLength = 5 - - userPreferences.Packages.Dependencies.Default = "dependencies" - - userPreferences.Packages.QAReport.ExcludedWarningClasses = []int{} - userPreferences.Packages.QAReport.ShowAll = true - - userPreferences.Packages.PullRequests.Layout = "default" - - userPreferences.Packages.Bugs.Layout = "default" - - userPreferences.Packages.Security.Layout = "default" - userPreferences.Packages.Security.ShowGLSAs = false - - userPreferences.Packages.Changelog.Layout = "compact" - userPreferences.Packages.Changelog.Size = 15 - - userPreferences.Packages.Tabs.Visible = []string{"Overview", "Dependencies", "QA report", "Pull requests", "Bugs", "Security", "Changelog"} - - userPreferences.Arches.Visible = []string{"amd64", "x86", "alpha", "arm", "arm64", "hppa", "ia64", "ppc", "ppc64", "sparc"} - userPreferences.Arches.DefaultArch = "amd64" - userPreferences.Arches.DefaultPage = "keyworded" - - userPreferences.Useflags.Layout = "bubble" userPreferences.Maintainers.IncludeProjectPackages = false userPreferences.Maintainers.ExcludedProjects = []string{} @@ -141,127 +50,15 @@ func GetDefaultUserPreferences() UserPreferences { func (u *UserPreferences) Sanitize() { defaultUserPreferences := GetDefaultUserPreferences() - if !(u.General.LandingPageLayout == "classic" || u.General.LandingPageLayout == "full"){ + if !(u.General.LandingPageLayout == "classic" || u.General.LandingPageLayout == "full") { u.General.LandingPageLayout = defaultUserPreferences.General.LandingPageLayout } - if !(u.Packages.Overview.Layout == "minimal" || u.Packages.Overview.Layout == "full"){ + if !(u.Packages.Overview.Layout == "minimal" || u.Packages.Overview.Layout == "full") { u.Packages.Overview.Layout = defaultUserPreferences.Packages.Overview.Layout } - sanitizedKeywords := []string{} - for _, keyword := range u.Packages.Overview.Keywords { - if strings.Contains(strings.Join(u.GetAllKeywords(), ","), keyword){ - sanitizedKeywords = append(sanitizedKeywords, keyword) - } - } - u.Packages.Overview.Keywords = sanitizedKeywords - - if !(u.Packages.Overview.EAPI == "none" || u.Packages.Overview.EAPI == "column" || u.Packages.Overview.EAPI == "inline"){ + if !(u.Packages.Overview.EAPI == "none" || u.Packages.Overview.EAPI == "column" || u.Packages.Overview.EAPI == "inline") { u.Packages.Overview.EAPI = defaultUserPreferences.Packages.Overview.EAPI } - - sanitizedMetadataFields := []string{} - for _, metadataField := range u.Packages.Overview.MetadataFields { - if strings.Contains(strings.Join(defaultUserPreferences.Packages.Overview.MetadataFields, ","), metadataField){ - sanitizedMetadataFields = append(sanitizedMetadataFields, metadataField) - } - } - u.Packages.Overview.MetadataFields = sanitizedMetadataFields - - if !(u.Packages.Overview.ChangelogType == "compact"){ - u.Packages.Overview.ChangelogType = defaultUserPreferences.Packages.Overview.ChangelogType - } - - if !(u.Packages.Overview.ChangelogLength >= 100){ - u.Packages.Overview.ChangelogLength = 100 - } - - if !(u.Packages.Dependencies.Default == "dependencies" || u.Packages.Dependencies.Default == "reverse-dependencies"){ - u.Packages.Dependencies.Default = defaultUserPreferences.Packages.Dependencies.Default - } - - if !(u.Packages.PullRequests.Layout == "default"){ - u.Packages.PullRequests.Layout = defaultUserPreferences.Packages.PullRequests.Layout - } - - if !(u.Packages.Bugs.Layout == "default"){ - u.Packages.Bugs.Layout = defaultUserPreferences.Packages.Bugs.Layout - } - - if !(u.Packages.Security.Layout == "default"){ - u.Packages.Security.Layout = defaultUserPreferences.Packages.Security.Layout - } - - if !(u.Packages.Changelog.Layout == "default"){ - u.Packages.Changelog.Layout = defaultUserPreferences.Packages.Changelog.Layout - } - - if !(u.Packages.Changelog.Size >= 100){ - u.Packages.Changelog.Size = 100 - } - - sanitizedTabs := []string{} - for _, tab := range u.Packages.Tabs.Visible { - if strings.Contains(strings.Join(defaultUserPreferences.Packages.Tabs.Visible, ","), tab){ - sanitizedTabs = append(sanitizedTabs, tab) - } - } - u.Packages.Tabs.Visible = sanitizedTabs - - sanitizedVisibleArches := []string{} - for _, keyword := range u.Arches.Visible { - if strings.Contains(strings.Join(u.GetAllKeywords(), ","), keyword){ - sanitizedVisibleArches = append(sanitizedVisibleArches, keyword) - } - } - u.Arches.Visible = sanitizedVisibleArches - - if !strings.Contains(strings.Join(u.GetAllKeywords(), ","), u.Arches.DefaultArch){ - u.Arches.DefaultArch = defaultUserPreferences.Arches.DefaultArch - } - - if !(u.Arches.DefaultPage == "keyworded" || u.Arches.DefaultPage == "stable"){ - u.Arches.DefaultPage = defaultUserPreferences.Arches.DefaultPage - } - - if !(u.Useflags.Layout == "bubble" || u.Useflags.Layout == "search"){ - u.Useflags.Layout = defaultUserPreferences.Useflags.Layout - } -} - -func (u UserPreferences) ContainsPkgcheckClass(class string) bool { - for _, v := range u.Packages.QAReport.ExcludedWarningClasses { - if GetPkgcheckClass(v) == class { - return false - } - } - return true -} - -func (u UserPreferences) GetAllKeywords() []string { - return []string{"alpha", "amd64", "arm", "arm64", "hppa", "ia64", "m68k", "mips", "ppc", "ppc64", "riscv", "s390", "sparc", "x86", "ppc-aix", "amd64-linux", "arm-linux", "arm64-linux", "ppc64-linux", "x86-linux", "ppc-macos", "x86-macos", "x64-macos", "m68k-mint", "sparc-solaris", "sparc64-solaris", "x64-solaris", "x86-solaris", "x64-winnt", "x86-winnt", "x64-cygwin", "x86-cygwin"} -} - -func GetPkgcheckClass(number int) string { - pkgcheckClasses := []string{"AbsoluteSymlink", "ArchesWithoutProfiles", "BadCommitSummary", "BadDependency", "BadDescription", "BadFilename", "BadHomepage", "BadKeywords", "BadPackageUpdate", "BadProtocol", "BadWhitespaceCharacter", "BannedCharacter", "BannedEapi", "BannedEapiCommand", "BinaryFile", "CatBadlyFormedXml", "CatInvalidXml", "CatMetadataXmlEmptyElement", "CatMetadataXmlIndentation", "CatMetadataXmlInvalidCatRef", "CatMetadataXmlInvalidPkgRef", "CatMissingMetadataXml", "ConflictingAccountIdentifiers", "ConflictingChksums", "DeadUrl", "DeprecatedChksum", "DeprecatedDep", "DeprecatedEapi", "DeprecatedEapiCommand", "DeprecatedEclass", "DeprecatedInsinto", "DirectNoMaintainer", "DirectStableKeywords", "DoubleEmptyLine", "DoublePrefixInPath", "DroppedKeywords", "DroppedStableKeywords", "DroppedUnstableKeywords", "DuplicateEclassInherits", "DuplicateFiles", "DuplicateKeywords", "EbuildIncorrectCopyright", "EbuildInvalidCopyright", "EbuildInvalidLicenseHeader", "EbuildNonGentooAuthorsCopyright", "EbuildOldGentooCopyright", "EclassBashSyntaxError", "EclassIncorrectCopyright", "EclassInvalidCopyright", "EclassInvalidLicenseHeader", "EclassNonGentooAuthorsCopyright", "EclassOldGentooCopyright", "EmptyCategoryDir", "EmptyFile", "EmptyMaintainer", "EmptyPackageDir", "EmptyProject", "EqualVersions", "ExecutableFile", "HomepageInSrcUri", "HttpsUrlAvailable", "IncorrectCopyright", "InvalidBdepend", "InvalidCommitMessage", "InvalidCommitTag", "InvalidCopyright", "InvalidDepend", "InvalidEapi", "InvalidLicense", "InvalidLicenseHeader", "InvalidPN", "InvalidPdepend", "InvalidProperties", "InvalidRdepend", "InvalidRequiredUse", "InvalidRestrict", "InvalidSlot", "InvalidSrcUri", "InvalidUTF8", "InvalidUseFlags", "LaggingProfileEapi", "LaggingStable", "MaintainerWithoutProxy", "MatchingChksums", "MatchingGlobalUse", "MismatchedPN", "MismatchedPerlVersion", "MissingAccountIdentifier", "MissingChksum", "MissingLicense", "MissingLicenseFile", "MissingLicenseRestricts", "MissingManifest", "MissingPackageRevision", "MissingPythonEclass", "MissingSignOff", "MissingSlash", "MissingSlotDep", "MissingTestRestrict", "MissingUnpackerDep", "MissingUri", "MissingUseDepDefault", "MissingVirtualKeywords", "MovedPackageUpdate", "MultiMovePackageUpdate", "NoFinalNewline", "NonGentooAuthorsCopyright", "NonexistentBlocker", "NonexistentDeps", "NonexistentProfilePath", "NonexistentProjectMaintainer", "NonsolvableDepsInDev", "NonsolvableDepsInExp", "NonsolvableDepsInStable", "ObsoleteUri", "OldGentooCopyright", "OldMultiMovePackageUpdate", "OldPackageUpdate", "OutdatedBlocker", "OutsideRangeAccountIdentifier", "OverlappingKeywords", "PkgBadlyFormedXml", "PkgInvalidXml", "PkgMetadataXmlEmptyElement", "PkgMetadataXmlIndentation", "PkgMetadataXmlInvalidCatRef", "PkgMetadataXmlInvalidPkgRef", "PkgMissingMetadataXml", "PotentialGlobalUse", "PotentialLocalUse", "PotentialStable", "ProbableGlobalUse", "ProbableUseExpand", "ProfileError", "ProfileWarning", "PythonEclassError", "PythonMissingDeps", "PythonMissingRequiredUse", "PythonRuntimeDepInAnyR1", "RdependChange", "RedirectedUrl", "RedundantDodir", "RedundantLongDescription", "RedundantUriRename", "RedundantVersion", "RequiredUseDefaults", "SSLCertificateError", "SizeViolation", "SourcingError", "StableRequest", "StaleProxyMaintProject", "StaticSrcUri", "TarballAvailable", "TrailingEmptyLine", "UncheckableDep", "UnderscoreInUseFlag", "UnknownCategories", "UnknownKeywords", "UnknownLicenses", "UnknownManifest", "UnknownMirror", "UnknownPkgDirEntry", "UnknownProfilePackageKeywords", "UnknownProfilePackageUse", "UnknownProfilePackages", "UnknownProfileUse", "UnknownProperties", "UnknownRestrict", "UnknownUseFlags", "UnnecessaryLicense", "UnnecessaryManifest", "UnnecessarySlashStrip", "UnsortedKeywords", "UnstableOnly", "UnstatedIuse", "UnusedEclasses", "UnusedGlobalUse", "UnusedInMastersEclasses", "UnusedInMastersGlobalUse", "UnusedInMastersLicenses", "UnusedInMastersMirrors", "UnusedLicenses", "UnusedLocalUse", "UnusedMirrors", "UnusedProfileDirs", "VariableInHomepage", "VisibleVcsPkg", "VulnerablePackage", "WhitespaceFound", "WrongIndentFound", "WrongMaintainerType"} - return pkgcheckClasses[number] -} - -func GetPkgcheckClassIndex(class string) int { - pkgcheckClasses := []string{"AbsoluteSymlink", "ArchesWithoutProfiles", "BadCommitSummary", "BadDependency", "BadDescription", "BadFilename", "BadHomepage", "BadKeywords", "BadPackageUpdate", "BadProtocol", "BadWhitespaceCharacter", "BannedCharacter", "BannedEapi", "BannedEapiCommand", "BinaryFile", "CatBadlyFormedXml", "CatInvalidXml", "CatMetadataXmlEmptyElement", "CatMetadataXmlIndentation", "CatMetadataXmlInvalidCatRef", "CatMetadataXmlInvalidPkgRef", "CatMissingMetadataXml", "ConflictingAccountIdentifiers", "ConflictingChksums", "DeadUrl", "DeprecatedChksum", "DeprecatedDep", "DeprecatedEapi", "DeprecatedEapiCommand", "DeprecatedEclass", "DeprecatedInsinto", "DirectNoMaintainer", "DirectStableKeywords", "DoubleEmptyLine", "DoublePrefixInPath", "DroppedKeywords", "DroppedStableKeywords", "DroppedUnstableKeywords", "DuplicateEclassInherits", "DuplicateFiles", "DuplicateKeywords", "EbuildIncorrectCopyright", "EbuildInvalidCopyright", "EbuildInvalidLicenseHeader", "EbuildNonGentooAuthorsCopyright", "EbuildOldGentooCopyright", "EclassBashSyntaxError", "EclassIncorrectCopyright", "EclassInvalidCopyright", "EclassInvalidLicenseHeader", "EclassNonGentooAuthorsCopyright", "EclassOldGentooCopyright", "EmptyCategoryDir", "EmptyFile", "EmptyMaintainer", "EmptyPackageDir", "EmptyProject", "EqualVersions", "ExecutableFile", "HomepageInSrcUri", "HttpsUrlAvailable", "IncorrectCopyright", "InvalidBdepend", "InvalidCommitMessage", "InvalidCommitTag", "InvalidCopyright", "InvalidDepend", "InvalidEapi", "InvalidLicense", "InvalidLicenseHeader", "InvalidPN", "InvalidPdepend", "InvalidProperties", "InvalidRdepend", "InvalidRequiredUse", "InvalidRestrict", "InvalidSlot", "InvalidSrcUri", "InvalidUTF8", "InvalidUseFlags", "LaggingProfileEapi", "LaggingStable", "MaintainerWithoutProxy", "MatchingChksums", "MatchingGlobalUse", "MismatchedPN", "MismatchedPerlVersion", "MissingAccountIdentifier", "MissingChksum", "MissingLicense", "MissingLicenseFile", "MissingLicenseRestricts", "MissingManifest", "MissingPackageRevision", "MissingPythonEclass", "MissingSignOff", "MissingSlash", "MissingSlotDep", "MissingTestRestrict", "MissingUnpackerDep", "MissingUri", "MissingUseDepDefault", "MissingVirtualKeywords", "MovedPackageUpdate", "MultiMovePackageUpdate", "NoFinalNewline", "NonGentooAuthorsCopyright", "NonexistentBlocker", "NonexistentDeps", "NonexistentProfilePath", "NonexistentProjectMaintainer", "NonsolvableDepsInDev", "NonsolvableDepsInExp", "NonsolvableDepsInStable", "ObsoleteUri", "OldGentooCopyright", "OldMultiMovePackageUpdate", "OldPackageUpdate", "OutdatedBlocker", "OutsideRangeAccountIdentifier", "OverlappingKeywords", "PkgBadlyFormedXml", "PkgInvalidXml", "PkgMetadataXmlEmptyElement", "PkgMetadataXmlIndentation", "PkgMetadataXmlInvalidCatRef", "PkgMetadataXmlInvalidPkgRef", "PkgMissingMetadataXml", "PotentialGlobalUse", "PotentialLocalUse", "PotentialStable", "ProbableGlobalUse", "ProbableUseExpand", "ProfileError", "ProfileWarning", "PythonEclassError", "PythonMissingDeps", "PythonMissingRequiredUse", "PythonRuntimeDepInAnyR1", "RdependChange", "RedirectedUrl", "RedundantDodir", "RedundantLongDescription", "RedundantUriRename", "RedundantVersion", "RequiredUseDefaults", "SSLCertificateError", "SizeViolation", "SourcingError", "StableRequest", "StaleProxyMaintProject", "StaticSrcUri", "TarballAvailable", "TrailingEmptyLine", "UncheckableDep", "UnderscoreInUseFlag", "UnknownCategories", "UnknownKeywords", "UnknownLicenses", "UnknownManifest", "UnknownMirror", "UnknownPkgDirEntry", "UnknownProfilePackageKeywords", "UnknownProfilePackageUse", "UnknownProfilePackages", "UnknownProfileUse", "UnknownProperties", "UnknownRestrict", "UnknownUseFlags", "UnnecessaryLicense", "UnnecessaryManifest", "UnnecessarySlashStrip", "UnsortedKeywords", "UnstableOnly", "UnstatedIuse", "UnusedEclasses", "UnusedGlobalUse", "UnusedInMastersEclasses", "UnusedInMastersGlobalUse", "UnusedInMastersLicenses", "UnusedInMastersMirrors", "UnusedLicenses", "UnusedLocalUse", "UnusedMirrors", "UnusedProfileDirs", "VariableInHomepage", "VisibleVcsPkg", "VulnerablePackage", "WhitespaceFound", "WrongIndentFound", "WrongMaintainerType"} - for k, v := range pkgcheckClasses { - if v == class { - return k - } - } - return -1 -} - -func createSlice(n int) []int { - slice := []int{} - for i := 0; i <= n; i++ { - slice = append(slice, i) - } - return slice } diff --git a/pkg/models/version.go b/pkg/models/version.go index eb40a59..f36eb52 100644 --- a/pkg/models/version.go +++ b/pkg/models/version.go @@ -6,6 +6,7 @@ import ( "fmt" "math/big" "regexp" + "sort" "strconv" "strings" "unicode" @@ -27,25 +28,39 @@ type Version struct { Homepage []string License string Description string - Commits []*Commit `pg:"many2many:commit_to_versions,joinFK:commit_id"` - Masks []*Mask `pg:"many2many:mask_to_versions,joinFK:mask_versions"` + Commits []*Commit `pg:"many2many:commit_to_versions,join_fk:commit_id"` + Masks []*Mask `pg:"many2many:mask_to_versions,join_fk:mask_versions"` + Deprecates []*DeprecatedPackage `pg:"many2many:deprecated_to_versions,join_fk:deprecated_versions"` PkgCheckResults []*PkgCheckResult `pg:",fk:cpv"` Dependencies []*ReverseDependency `pg:",fk:reverse_dependency_version"` - Bugs []*Bug `pg:"many2many:version_to_bugs,joinFK:bug_id"` + Bugs []*Bug `pg:"many2many:version_to_bugs,join_fk:bug_id"` } -func (v Version) BuildDepMap() map[string]map[string]string { - var data = map[string]map[string]string{} +type versionDepMap struct { + Atom string + Map map[string]struct{} +} + +func (v Version) BuildDepMap() []versionDepMap { + var data = map[string]map[string]struct{}{} for _, dep := range v.Dependencies { if data[dep.Atom] == nil { - data[dep.Atom] = map[string]string{} - data[dep.Atom]["Atom"] = dep.Atom + data[dep.Atom] = map[string]struct{}{} } - data[dep.Atom][dep.Type] = "true" + data[dep.Atom][dep.Type] = struct{}{} + } + + result := make([]versionDepMap, 0, len(data)) + for k, v := range data { + result = append(result, versionDepMap{k, v}) } - return data + sort.Slice(result, func(i, j int) bool { + return result[i].Atom < result[j].Atom + }) + + return result } // GreaterThan returns true if the version is greater than the given version @@ -54,15 +69,13 @@ func (v *Version) GreaterThan(other Version) bool { versionIdentifierA := v.computeVersionIdentifier() versionIdentifierB := other.computeVersionIdentifier() - if(v.Version == "0.7.8_p0-r100"){ + if v.Version == "0.7.8_p0-r100" { fmt.Println("versionIdentifierA") fmt.Println(versionIdentifierA) fmt.Println("versionIdentifierB") fmt.Println(versionIdentifierB) } - - // compare the numeric part numericPartsA := strings.Split(versionIdentifierA.NumericPart, ".") numericPartsB := strings.Split(versionIdentifierB.NumericPart, ".") @@ -214,9 +227,13 @@ func (v *Version) computeVersionIdentifier() VersionIdentifier { } // getNumericPart returns the numeric part of the version, that is: -// version, letter +// +// version, letter +// // i.e. 10.3.18a becomes -// 10.3.18, a +// +// 10.3.18, a +// // The first returned string is the version and the second if the (optional) letter func getNumericPart(str string) (string, string) { if unicode.IsLetter(rune(str[len(str)-1])) { @@ -227,14 +244,23 @@ func getNumericPart(str string) (string, string) { // getSuffix creates a VersionSuffix based on the given string. // The given string is expected to be look like -// pre20190518 +// +// pre20190518 +// // for instance. The suffix named as well as the following number // will be parsed and returned as VersionSuffix func getSuffix(str string) *VersionSuffix { allowedSuffixes := []string{"alpha", "beta", "pre", "rc", "p"} for _, allowedSuffix := range allowedSuffixes { - if regexp.MustCompile(allowedSuffix + `\d+`).MatchString(str) { - parsedSuffix, err := strconv.Atoi(strings.ReplaceAll(str, allowedSuffix, "")) + if regexp.MustCompile(allowedSuffix + `\d*`).MatchString(str) { + trimmed := strings.TrimPrefix(str, allowedSuffix) + if len(trimmed) == 0 { + return &VersionSuffix{ + Name: allowedSuffix, + Number: 0, + } + } + parsedSuffix, err := strconv.Atoi(trimmed) if err == nil { return &VersionSuffix{ Name: allowedSuffix, @@ -255,7 +281,9 @@ func isRevision(str string) bool { // getSuffixOrder returns an int for the given suffix, // based on the following: -// _alpha < _beta < _pre < _rc < _p < none +// +// _alpha < _beta < _pre < _rc < _p < none +// // as defined in the Package Manager Specification (PMS) func getSuffixOrder(suffix string) int { if suffix == "p" { diff --git a/pkg/portage/bugs/bugs.go b/pkg/portage/bugs/bugs.go new file mode 100644 index 0000000..3e803b8 --- /dev/null +++ b/pkg/portage/bugs/bugs.go @@ -0,0 +1,334 @@ +package bugs + +import ( + "encoding/json" + "log/slog" + "net/http" + "net/url" + "regexp" + "soko/pkg/config" + "soko/pkg/database" + "soko/pkg/models" + "soko/pkg/portage/utils" + "strconv" + "strings" + "time" + + "github.com/go-pg/pg/v10" +) + +type restAPIBug struct { + Id int `json:"id"` + Product string `json:"product"` + Status string `json:"status"` + Summary string `json:"summary"` + Component string `json:"component"` + StabilizationAtoms string `json:"cf_stabilisation_atoms"` + AssigneeDetails struct { + RealName string `json:"real_name"` + } `json:"assigned_to_detail"` +} + +func (b *restAPIBug) BugId() string { + return strconv.Itoa(b.Id) +} + +func (b *restAPIBug) ToDBType() *models.Bug { + return &models.Bug{ + Id: b.BugId(), + Product: b.Product, + Status: b.Status, + Summary: b.Summary, + Component: b.Component, + Assignee: b.AssigneeDetails.RealName, + } +} + +func UpdateBugs() { + database.Connect() + defer database.DBCon.Close() + + update := models.Application{ + Id: "bugs", + } + err := database.DBCon.Model(&update).WherePK().Select() + if err != nil && err != pg.ErrNoRows { + slog.Error("Failed to fetch last update time for bugs", slog.Any("err", err)) + return + } + if update.LastCommit != "" { + importAllOpenBugs() + } else { + lastUpdate := update.LastUpdate + if err != nil { + importAllOpenBugs() + } else { + if time.Now().Before(lastUpdate) { + lastUpdate = time.Now() + } + changedSince := lastUpdate.AddDate(0, 0, -2) + updateChangedBugs(changedSince) + } + } + + updateCategoriesInfo() + + updateStatus() +} + +func fetchBugs(changedSince *time.Time, bugStatus []string) (bugs []restAPIBug, err error) { + const limit = 5000 + + params := url.Values{ + "include_fields": []string{"id,product,status,summary,component,assigned_to,cf_stabilisation_atoms"}, + "bug_status": bugStatus, + "order": []string{"changeddate DESC"}, + "product": []string{"Gentoo Linux", "Gentoo Security"}, + "limit": []string{strconv.Itoa(limit)}, + } + + if changedSince != nil { + params.Set("chfieldfrom", changedSince.Format("2006-01-02")) + } + + for offset := 0; ; offset += limit { + slog.Info("Importing bugs from bugs.gentoo.org", slog.Int("start", offset), slog.Int("end", offset+limit)) + params.Set("offset", strconv.Itoa(offset)) + resp, err := http.Get("https://bugs.gentoo.org/rest/bug?" + params.Encode()) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + slog.Error("Failed to fetch bugs", slog.Int("status", resp.StatusCode)) + return bugs, nil + } + + var response struct { + Bugs []restAPIBug `json:"bugs"` + } + err = json.NewDecoder(resp.Body).Decode(&response) + if err != nil { + slog.Error("Failed to decode bugs", slog.Any("err", err)) + return bugs, nil + } + + bugs = append(bugs, response.Bugs...) + + if len(response.Bugs) < limit { + break + } + } + slog.Info("Collected bugs", slog.Int("count", len(bugs))) + return +} + +func importAllOpenBugs() { + bugs, err := fetchBugs(nil, []string{"UNCONFIRMED", "CONFIRMED", "IN_PROGRESS"}) + if err != nil { + slog.Error("Failed to fetch bugs", + slog.String("status", "UNCONFIRMED, CONFIRMED, IN_PROGRESS"), + slog.Any("err", err)) + return + } + + database.TruncateTable((*models.Bug)(nil)) + database.TruncateTable((*models.PackageToBug)(nil)) + database.TruncateTable((*models.VersionToBug)(nil)) + + processApiBugs(bugs) +} + +func updateChangedBugs(changedSince time.Time) { + bugs, err := fetchBugs(&changedSince, []string{"UNCONFIRMED", "CONFIRMED", "IN_PROGRESS", "RESOLVED"}) + if err != nil { + slog.Error("Failed to fetch bugs", + slog.String("status", "UNCONFIRMED, CONFIRMED, IN_PROGRESS, RESOLVED"), + slog.Time("changed_since", changedSince), + slog.Any("err", err)) + return + } + processApiBugs(bugs) +} + +func processApiBugs(bugs []restAPIBug) { + var resolvedBugs []string + var dbBugs []*models.Bug + var verBugs []*models.VersionToBug + var pkgsBugs []*models.PackageToBug + processedBugs := make(map[int]struct{}, len(bugs)) + + for _, bug := range bugs { + if bug.Status == "RESOLVED" { + resolvedBugs = append(resolvedBugs, bug.BugId()) + } else if _, found := processedBugs[bug.Id]; !found { + dbBugs = append(dbBugs, bug.ToDBType()) + processedBugs[bug.Id] = struct{}{} + bugId := bug.BugId() + if strings.TrimSpace(bug.StabilizationAtoms) != "" { + versions := make(map[string]struct{}) + for _, gpackage := range strings.Split(bug.StabilizationAtoms, "\n") { + affectedVersions, _, _ := strings.Cut(strings.TrimSpace(gpackage), " ") + if strings.TrimSpace(affectedVersions) != "" { + for _, version := range calculateAffectedVersions(affectedVersions) { + versions[version.Id] = struct{}{} + } + } + } + for version := range versions { + verBugs = append(verBugs, &models.VersionToBug{ + Id: version + "-" + bugId, + VersionId: version, + BugId: bugId, + }) + } + } else { + summary, _, _ := strings.Cut(strings.TrimSpace(bug.Summary), " ") + affectedPackage := versionSpecifierToPackageAtom(summary) + + pkgsBugs = append(pkgsBugs, &models.PackageToBug{ + Id: affectedPackage + "-" + bugId, + PackageAtom: affectedPackage, + BugId: bugId, + }) + } + } + } + + res1, err := database.DBCon.Model(&dbBugs).OnConflict("(id) DO UPDATE").Insert() + if err != nil { + slog.Error("Failed to insert bugs", slog.Any("err", err)) + return + } + + res2, err := database.DBCon.Model(&verBugs).OnConflict("(id) DO UPDATE").Insert() + if err != nil { + slog.Error("Failed to insert version bugs", slog.Any("err", err)) + return + } + + res3, err := database.DBCon.Model(&pkgsBugs).OnConflict("(id) DO UPDATE").Insert() + if err != nil { + slog.Error("Failed to insert package bugs", slog.Any("err", err)) + return + } + + slog.Info("Inserted", + slog.Int("bugs", res1.RowsAffected()), + slog.Int("version_bugs", res2.RowsAffected()), + slog.Int("package_bugs", res3.RowsAffected())) + + if len(resolvedBugs) > 0 { + res1, err := database.DBCon.Model((*models.Bug)(nil)).WhereIn("id IN (?)", resolvedBugs).Delete() + if err != nil { + slog.Error("Failed to delete bugs", slog.Any("err", err)) + return + } + + res2, err := database.DBCon.Model((*models.PackageToBug)(nil)).WhereIn("bug_id IN (?)", resolvedBugs).Delete() + if err != nil { + slog.Error("Failed to delete package bugs", slog.Any("err", err)) + return + } + + res3, err := database.DBCon.Model((*models.VersionToBug)(nil)).WhereIn("bug_id IN (?)", resolvedBugs).Delete() + if err != nil { + slog.Error("Failed to delete version bugs", slog.Any("err", err)) + return + } + + slog.Info("Deleted", + slog.Int("bugs", res1.RowsAffected()), + slog.Int("package_bugs", res2.RowsAffected()), + slog.Int("version_bugs", res3.RowsAffected())) + } +} + +func calculateAffectedVersions(versionSpecifier string) []*models.Version { + packageAtom := versionSpecifierToPackageAtom(versionSpecifier) + return utils.CalculateAffectedVersions(versionSpecifier, packageAtom) +} + +var versionNumber = regexp.MustCompile(`-[0-9]`) + +// versionSpecifierToPackageAtom returns the package atom from a given version specifier +func versionSpecifierToPackageAtom(versionSpecifier string) string { + gpackage := strings.ReplaceAll(versionSpecifier, ">", "") + gpackage = strings.ReplaceAll(gpackage, "<", "") + gpackage = strings.ReplaceAll(gpackage, "=", "") + gpackage = strings.ReplaceAll(gpackage, "~", "") + + gpackage, _, _ = strings.Cut(gpackage, ":") + + gpackage = versionNumber.Split(gpackage, 2)[0] + + return gpackage +} + +func updateCategoriesInfo() { + var categoriesInfoArr []*models.CategoryPackagesInformation + err := database.DBCon.Model((*models.PackageToBug)(nil)). + ColumnExpr("SPLIT_PART(package_atom, '/', 1) as name"). + ColumnExpr("COUNT(DISTINCT bug_id) as bugs"). + ColumnExpr("COUNT(DISTINCT bug_id) FILTER(WHERE component = ?) as security_bugs", "Vulnerabilities"). + Join("JOIN bugs").JoinOn("package_to_bug.bug_id = bugs.id"). + Where("NULLIF(package_atom, '') IS NOT NULL"). + Where(`package_atom LIKE '%/%'`). + GroupExpr("SPLIT_PART(package_atom, '/', 1)"). + Select(&categoriesInfoArr) + if err != nil { + slog.Error("Failed collecting bugs stats", slog.Any("err", err)) + return + } + categoriesInfo := make(map[string]*models.CategoryPackagesInformation, len(categoriesInfoArr)) + for _, categoryInfo := range categoriesInfoArr { + if categoryInfo.Name != "" { + categoriesInfo[categoryInfo.Name] = categoryInfo + } + } + + var categories []*models.CategoryPackagesInformation + err = database.DBCon.Model(&categories).Column("name").Select() + if err != nil { + slog.Error("Failed fetching categories packages information", slog.Any("err", err)) + return + } else if len(categories) > 0 { + for _, category := range categories { + if info, found := categoriesInfo[category.Name]; found { + category.Bugs = info.Bugs + category.SecurityBugs = info.SecurityBugs + } else { + category.Bugs = 0 + category.SecurityBugs = 0 + } + delete(categoriesInfo, category.Name) + } + _, err = database.DBCon.Model(&categories). + Set("bugs = ?bugs"). + Set("security_bugs = ?security_bugs"). + Update() + if err != nil { + slog.Error("Failed updating categories packages information", slog.Any("err", err)) + } + categories = make([]*models.CategoryPackagesInformation, 0, len(categoriesInfo)) + } + + for _, catInfo := range categoriesInfo { + categories = append(categories, catInfo) + } + if len(categories) > 0 { + _, err = database.DBCon.Model(&categories).Insert() + if err != nil { + slog.Error("Failed inserting categories packages information", slog.Any("err", err)) + } + } +} + +func updateStatus() { + database.DBCon.Model(&models.Application{ + Id: "bugs", + LastUpdate: time.Now(), + Version: config.Version(), + }).OnConflict("(id) DO UPDATE").Insert() +} diff --git a/pkg/portage/bugs/security.go b/pkg/portage/bugs/security.go deleted file mode 100644 index 5b4c053..0000000 --- a/pkg/portage/bugs/security.go +++ /dev/null @@ -1,332 +0,0 @@ -package bugs - -import ( - "encoding/csv" - "net/http" - "regexp" - "soko/pkg/config" - "soko/pkg/database" - "soko/pkg/logger" - "soko/pkg/models" - "strings" - "time" -) - -func UpdateBugs(init bool) { - UpdateSecurityBugs() - UpdatePackagesBugs(init) - - UpdateClosedBugs() - - updateStatus() -} - -func UpdateSecurityBugs() { - importBugs("https://bugs.gentoo.org/buglist.cgi?columnlist=bug_id,product,component,assigned_to,bug_status,resolution,short_desc,changeddate,cf_stabilisation_atoms&component=Vulnerabilities&list_id=4688108&product=Gentoo%20Security&query_format=advanced&resolution=---&ctype=csv&human=1") -} - -func UpdatePackagesBugs(init bool) { - // - // Keywording - // - importBugs("https://bugs.gentoo.org/buglist.cgi?columnlist=bug_id,product,component,assigned_to,bug_status,resolution,short_desc,changeddate,cf_stabilisation_atoms&bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=IN_PROGRESS&component=Keywording&limit=0&list_id=4688124&product=Gentoo%20Linux&query_format=advanced&resolution=---&ctype=csv&human=1") - - // - // Stabilization - // - importBugs("https://bugs.gentoo.org/buglist.cgi?columnlist=bug_id,product,component,assigned_to,bug_status,resolution,short_desc,changeddate,cf_stabilisation_atoms&bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=IN_PROGRESS&component=Stabilization&limit=0&list_id=4688124&product=Gentoo%20Linux&query_format=advanced&resolution=---&ctype=csv&human=1") - - // - // Current Packages - // - if init { - importBugs("https://bugs.gentoo.org/buglist.cgi?columnlist=bug_id,product,component,assigned_to,bug_status,resolution,short_desc,changeddate,cf_stabilisation_atoms&bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=IN_PROGRESS&chfield=%5BBug%20creation%5D&chfieldfrom=2000-01-01&chfieldto=2020-01-01&component=Current%20packages&limit=0&list_id=4688124&product=Gentoo%20Linux&query_format=advanced&resolution=---&ctype=csv&human=1") - } - importBugs("https://bugs.gentoo.org/buglist.cgi?columnlist=bug_id,product,component,assigned_to,bug_status,resolution,short_desc,changeddate,cf_stabilisation_atoms&bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=IN_PROGRESS&chfield=%5BBug%20creation%5D&chfieldfrom=2020-01-01&chfieldto=2021-01-01&component=Current%20packages&limit=0&list_id=4688124&product=Gentoo%20Linux&query_format=advanced&resolution=---&ctype=csv&human=1") -} - -func UpdateClosedBugs() { - logger.Error.Println("UpdateClosedBugs") - // - // Security - // - deleteBugs("https://bugs.gentoo.org/buglist.cgi?bug_status=RESOLVED&component=Vulnerabilities&list_id=4694466&order=changeddate%20DESC%2Cbug_status%2Cpriority%2Cassigned_to%2Cbug_id&product=Gentoo%20Security&query_format=advanced&resolution=FIXED&resolution=INVALID&resolution=WONTFIX&resolution=LATER&resolution=REMIND&resolution=DUPLICATE&resolution=WORKSFORME&resolution=CANTFIX&resolution=NEEDINFO&resolution=TEST-REQUEST&resolution=UPSTREAM&ctype=csv&human=1") - - // - // Keywording - // - deleteBugs("https://bugs.gentoo.org/buglist.cgi?bug_status=RESOLVED&component=Keywording&list_id=4694472&order=changeddate%20DESC%2Cbug_status%2Cpriority%2Cassigned_to%2Cbug_id&product=Gentoo%20Linux&query_format=advanced&resolution=FIXED&resolution=INVALID&resolution=WONTFIX&resolution=LATER&resolution=REMIND&resolution=DUPLICATE&resolution=WORKSFORME&resolution=CANTFIX&resolution=NEEDINFO&resolution=TEST-REQUEST&resolution=UPSTREAM&resolution=OBSOLETE&ctype=csv&human=1") - - // - // Stabilization - // - deleteBugs("https://bugs.gentoo.org/buglist.cgi?bug_status=RESOLVED&component=Stabilization&list_id=4694456&order=changeddate%20DESC%2Cbug_status%2Cpriority%2Cassigned_to%2Cbug_id&product=Gentoo%20Linux&query_format=advanced&resolution=FIXED&resolution=INVALID&resolution=WONTFIX&resolution=LATER&resolution=REMIND&resolution=DUPLICATE&resolution=WORKSFORME&resolution=CANTFIX&resolution=NEEDINFO&resolution=TEST-REQUEST&resolution=UPSTREAM&resolution=OBSOLETE&ctype=csv&human=1") - - // - // Current Packages - // - deleteBugs("https://bugs.gentoo.org/buglist.cgi?bug_status=RESOLVED&component=Current%20packages&list_id=4773158&order=changeddate%20DESC%2Cbug_status%2Cpriority%2Cassigned_to%2Cbug_id&product=Gentoo%20Linux&query_format=advanced&resolution=FIXED&resolution=INVALID&resolution=WONTFIX&resolution=LATER&resolution=REMIND&resolution=DUPLICATE&resolution=WORKSFORME&resolution=CANTFIX&resolution=NEEDINFO&resolution=TEST-REQUEST&resolution=UPSTREAM&resolution=OBSOLETE&ctype=csv&human=1") -} - -func deleteBugs(source string) { - database.Connect() - defer database.DBCon.Close() - - data, err := readCSVFromUrl(source) - if err != nil { - logger.Error.Println(err) - } - - for idx, row := range data { - // skip header - if idx == 0 || len(row) < 7 { - continue - } - - bug := models.Bug{ - Id: row[0], - } - - // - // Delete bug - // - _, err = database.DBCon.Model(&bug).WherePK().Delete() - if err != nil { - logger.Error.Println(err) - } - - // - // Delete Package To Bug - // - bugId := row[0] - summary := row[6] - summary = strings.Split(summary, " ")[0] - affectedPackage := versionSpecifierToPackageAtom(summary) - - _, err = database.DBCon.Model(&models.PackageToBug{ - Id: affectedPackage + "-" + bugId, - PackageAtom: affectedPackage, - BugId: bugId, - }).Where("bug_id = ?bug_id").Delete() - if err != nil { - logger.Error.Println(err) - } - } -} - -func importBugs(source string) { - - database.Connect() - defer database.DBCon.Close() - - data, err := readCSVFromUrl(source) - if err != nil { - logger.Error.Println(err) - } - - for idx, row := range data { - // skip header - if idx == 0 || len(row) < 7 { - continue - } - - bug := models.Bug{ - Id: row[0], - Product: row[1], - Component: row[2], - Assignee: row[3], - Status: row[4], - Summary: row[6], - } - - database.DBCon.Model(&bug).WherePK().OnConflict("(id) DO UPDATE").Insert() - - // - // Insert Package To Bug - // - bugId := row[0] - summary := row[6] - if strings.TrimSpace(row[8]) != "" { - for _, gpackage := range strings.Split(row[8], "\n") { - affectedVersions := strings.Split(gpackage, " ")[0] - if strings.TrimSpace(affectedVersions) != "" { - CalculateAffectedVersions(bugId, affectedVersions) - } - } - } else { - summary = strings.Split(summary, " ")[0] - affectedPackage := versionSpecifierToPackageAtom(summary) - - database.DBCon.Model(&models.PackageToBug{ - Id: affectedPackage + "-" + bugId, - PackageAtom: affectedPackage, - BugId: bugId, - }).WherePK().OnConflict("(id) DO UPDATE").Insert() - } - - } - -} - -func CalculateAffectedVersions(bugId, versionSpecifier string) { - - packageAtom := versionSpecifierToPackageAtom(versionSpecifier) - var versions []*models.Version - - if strings.HasPrefix(versionSpecifier, "=") { - versions = exaktVersion(versionSpecifier, packageAtom) - } else if strings.HasPrefix(versionSpecifier, "<=") { - versions = comparedVersions("<=", versionSpecifier, packageAtom) - } else if strings.HasPrefix(versionSpecifier, "<") { - versions = comparedVersions("<", versionSpecifier, packageAtom) - } else if strings.HasPrefix(versionSpecifier, ">=") { - versions = comparedVersions(">=", versionSpecifier, packageAtom) - } else if strings.HasPrefix(versionSpecifier, ">") { - versions = comparedVersions(">", versionSpecifier, packageAtom) - } else if strings.HasPrefix(versionSpecifier, "~") { - versions = allRevisions(versionSpecifier, packageAtom) - } else if strings.Contains(versionSpecifier, ":") { - versions = versionsWithSlot(versionSpecifier, packageAtom) - } else { - versions = allVersions(versionSpecifier, packageAtom) - } - - for _, version := range versions { - versionToBug := &models.VersionToBug{ - Id: version.Id + "-" + bugId, - VersionId: version.Id, - BugId: bugId, - } - - _, err := database.DBCon.Model(versionToBug).OnConflict("(id) DO UPDATE").Insert() - - if err != nil { - logger.Error.Printf("Error while inserting version to bug entry: %v", err) - } - } -} - -// comparedVersions computes and returns all versions that are >=, >, <= or < than then given version -func comparedVersions(operator string, versionSpecifier string, packageAtom string) []*models.Version { - var results []*models.Version - var versions []*models.Version - versionSpecifier = strings.ReplaceAll(versionSpecifier, operator, "") - versionSpecifier = strings.ReplaceAll(versionSpecifier, packageAtom+"-", "") - versionSpecifier = strings.Split(versionSpecifier, ":")[0] - - database.DBCon.Model(&versions). - Where("atom = ?", packageAtom). - Select() - - for _, v := range versions { - givenVersion := models.Version{Version: versionSpecifier} - if operator == ">" { - if v.GreaterThan(givenVersion) { - results = append(results, v) - } - } else if operator == ">=" { - if v.GreaterThan(givenVersion) || v.EqualTo(givenVersion) { - results = append(results, v) - } - } else if operator == "<" { - if v.SmallerThan(givenVersion) { - results = append(results, v) - } - } else if operator == "<=" { - if v.SmallerThan(givenVersion) || v.EqualTo(givenVersion) { - results = append(results, v) - } - } - } - return results -} - -// allRevisions returns all revisions of the given version -func allRevisions(versionSpecifier string, packageAtom string) []*models.Version { - var versions []*models.Version - revision := regexp.MustCompile(`-r[0-9]*$`) - versionWithoutRevision := revision.Split(versionSpecifier, 1)[0] - versionWithoutRevision = strings.ReplaceAll(versionWithoutRevision, "~", "") - database.DBCon.Model(&versions). - Where("id LIKE ?", versionWithoutRevision+"%"). - Select() - - return versions -} - -// exaktVersion returns the exact version specified in the versionSpecifier -func exaktVersion(versionSpecifier string, packageAtom string) []*models.Version { - var versions []*models.Version - database.DBCon.Model(&versions). - Where("id = ?", versionSpecifier). - Select() - - return versions -} - -// TODO include subslot -// versionsWithSlot returns all versions with the given slot -func versionsWithSlot(versionSpecifier string, packageAtom string) []*models.Version { - var versions []*models.Version - slot := strings.Split(versionSpecifier, ":")[1] - - database.DBCon.Model(&versions). - Where("atom = ?", packageAtom). - Where("slot = ?", slot). - Select() - - return versions -} - -// allVersions returns all versions of the given package -func allVersions(versionSpecifier string, packageAtom string) []*models.Version { - var versions []*models.Version - database.DBCon.Model(&versions). - Where("atom = ?", packageAtom). - Select() - return versions -} - -func readCSVFromUrl(url string) ([][]string, error) { - resp, err := http.Get(url) - if err != nil { - return nil, err - } - - defer resp.Body.Close() - reader := csv.NewReader(resp.Body) - reader.Comma = ',' - data, err := reader.ReadAll() - if err != nil { - return nil, err - } - - return data, nil -} - -// versionSpecifierToPackageAtom returns the package atom from a given version specifier -func versionSpecifierToPackageAtom(versionSpecifier string) string { - gpackage := strings.ReplaceAll(versionSpecifier, ">", "") - gpackage = strings.ReplaceAll(gpackage, "<", "") - gpackage = strings.ReplaceAll(gpackage, "=", "") - gpackage = strings.ReplaceAll(gpackage, "~", "") - - gpackage = strings.Split(gpackage, ":")[0] - - versionnumber := regexp.MustCompile(`-[0-9]`) - gpackage = versionnumber.Split(gpackage, 2)[0] - - return gpackage -} - -func updateStatus() { - - database.Connect() - defer database.DBCon.Close() - - database.DBCon.Model(&models.Application{ - Id: "bugs", - LastUpdate: time.Now(), - Version: config.Version(), - }).OnConflict("(id) DO UPDATE").Insert() -} diff --git a/pkg/portage/dependencies/dependency.go b/pkg/portage/dependencies/dependency.go index 3ded5eb..e6e4358 100644 --- a/pkg/portage/dependencies/dependency.go +++ b/pkg/portage/dependencies/dependency.go @@ -1,158 +1,99 @@ package dependencies import ( + "archive/tar" "fmt" - "io/ioutil" + "io" + "log/slog" "net/http" "regexp" "soko/pkg/config" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" - "strconv" "strings" - "sync" "time" -) - -// TODO -var WaitGroup sync.WaitGroup - -var Dependencies []*models.ReverseDependency - -var PackageCounter int -var DependencyCounter int -var ErrCounter int -var NewCounter int -var ( - mu sync.RWMutex + "github.com/ulikunitz/xz" ) -func AddDependency(dependency *models.ReverseDependency) { - mu.Lock() - defer mu.Unlock() - Dependencies = append(Dependencies, dependency) -} - -func AddtoErrorCounter(amount int) { - mu.Lock() - defer mu.Unlock() - ErrCounter = ErrCounter + amount -} - -func GetErrorCounter() int { - mu.RLock() // readers lock - defer mu.RUnlock() - return ErrCounter -} +var Dependencies []*models.ReverseDependency func FullPackageDependenciesUpdate() { - database.Connect() defer database.DBCon.Close() - var packages []models.Package - database.DBCon.Model(&packages).Select() - - PackageCounter = 0 - NewCounter = 0 - - cc := 0 - - for _, gpackage := range packages { - - if cc%100 == 0 { - logger.Info.Println(time.Now().Format(time.Kitchen) + ": " + strconv.Itoa(cc)) - WaitGroup.Wait() - } - - WaitGroup.Add(1) - go UpdatePackageDependencies(gpackage.Atom) - - cc++ + dependencyCounter, err := UpdateDependencies() + if err != nil { + return } - logger.Info.Println("Waiting for go routines to finish") - - WaitGroup.Wait() - - logger.Info.Println() - logger.Info.Println("Processed " + strconv.Itoa(PackageCounter) + " packages.") - logger.Info.Println("Got " + strconv.Itoa(DependencyCounter) + " dependencies.") - logger.Info.Println("Start inserting dependencies into the database") - logger.Info.Println("Errors: " + strconv.Itoa(GetErrorCounter())) + slog.Info("collected dependencies", slog.Int("count", dependencyCounter)) - logger.Info.Println("---") - - // finally delete all outdated dependencies - // TODO in future we want a better incremental update here - deleteAllDependencies() - - counter := 0 - length := len(Dependencies) - for _, dependency := range Dependencies { - - if counter%1000 == 0 { - logger.Info.Println(time.Now().Format(time.Kitchen) + ": " + strconv.Itoa(counter) + " / " + strconv.Itoa(length)) - } - - database.DBCon.Model(dependency).WherePK().OnConflict("(id) DO UPDATE").Insert() - counter++ + database.TruncateTable((*models.ReverseDependency)(nil)) + // because we removed all previous rows in table, we aren't concerned about + // duplicates, so we can use bulk insert + res, err := database.DBCon.Model(&Dependencies).Insert() + if err != nil { + slog.Error("Error during inserting dependencies", slog.Any("err", err)) + } else { + slog.Info("Inserted dependencies", slog.Int("rows", res.RowsAffected())) } updateStatus() } -func UpdatePackageDependencies(atom string) { - - // reverse dependeny urls - rdepend := "https://qa-reports.gentoo.org/output/genrdeps/rindex/" + atom - parseDependencies(atom, rdepend, "rdepend") - - depend := "https://qa-reports.gentoo.org/output/genrdeps/dindex/" + atom - parseDependencies(atom, depend, "depend") - - pdepend := "https://qa-reports.gentoo.org/output/genrdeps/pindex/" + atom - parseDependencies(atom, pdepend, "pdepend") - - bdepend := "https://qa-reports.gentoo.org/output/genrdeps/bindex/" + atom - parseDependencies(atom, bdepend, "bdepend") - - WaitGroup.Done() -} - -func parseDependencies(atom, url, kind string) { - +func UpdateDependencies() (int, error) { client := http.Client{ Timeout: 600 * time.Second, } - resp, err := client.Get(url) - + resp, err := client.Get("https://qa-reports.gentoo.org/output/genrdeps/rdeps.tar.xz") if err != nil { - logger.Error.Println(err) - return + slog.Error("Failed fetching dependencies", slog.Any("err", err)) + return 0, err } - defer resp.Body.Close() if resp.StatusCode != 200 { - return + slog.Error("Got bad status code", slog.Int("code", resp.StatusCode)) + return 0, fmt.Errorf("status code: %d", resp.StatusCode) } - PackageCounter++ - - rawResponse, err := ioutil.ReadAll(resp.Body) - + xz, err := xz.NewReader(resp.Body) if err != nil { - return + slog.Error("Failed decompressing dependencies", slog.Any("err", err)) + return 0, err } - rawDependencies := strings.Split(string(rawResponse), "\n") - - for _, rawDependency := range rawDependencies { + var dependencyCounter int + tr := tar.NewReader(xz) + for { + hdr, err := tr.Next() + if err == io.EOF { + break // end of tar archive + } + if err != nil { + slog.Error("Failed reading dependencies tar", slog.Any("err", err)) + return 0, err + } + switch hdr.Typeflag { + case tar.TypeReg: + nameParts := strings.SplitN(hdr.Name, "/", 2) + + rawResponse, err := io.ReadAll(tr) + if err != nil { + slog.Error("Failed reading file from tar", slog.Any("err", err)) + return 0, err + } + parseDependencies(string(rawResponse), nameParts[1], nameParts[0]) + dependencyCounter++ + } + } + return dependencyCounter, nil +} +func parseDependencies(rawResponse, atom, kind string) { + for _, rawDependency := range strings.Split(rawResponse, "\n") { dependencyParts := strings.Split(rawDependency, ":") if strings.TrimSpace(dependencyParts[0]) == "" { @@ -164,7 +105,7 @@ func parseDependencies(atom, url, kind string) { condition = dependencyParts[1] } - AddDependency(&models.ReverseDependency{ + Dependencies = append(Dependencies, &models.ReverseDependency{ Id: atom + "-" + kind + "-" + rawDependency, Atom: atom, Type: kind, @@ -172,9 +113,7 @@ func parseDependencies(atom, url, kind string) { ReverseDependencyVersion: dependencyParts[0], Condition: condition, }) - } - } func versionSpecifierToPackageAtom(versionSpecifier string) string { @@ -191,40 +130,6 @@ func versionSpecifierToPackageAtom(versionSpecifier string) string { return gpackage } -// deleteAllPullrequests deletes all entries in the pullrequests and package to pull request table -func deleteAllDependencies() { - var reverseDependencies []*models.ReverseDependency - database.DBCon.Model(&reverseDependencies).Select() - for _, reverseDependency := range reverseDependencies { - database.DBCon.Model(reverseDependency).WherePK().Delete() - } -} - -func deleteOutdatedDependencies(newDependencies []*models.ReverseDependency) { - var oldDependencies []*models.ReverseDependency - database.DBCon.Model(&oldDependencies).Select() - - for index, oldDependency := range oldDependencies { - - if index%10000 == 0 { - fmt.Println(time.Now().Format(time.Kitchen) + ": " + strconv.Itoa(index) + " / " + strconv.Itoa(len(oldDependencies))) - } - - found := false - for _, newDependency := range newDependencies { - if oldDependency.Id == newDependency.Id { - found = true - } - } - - if !found { - database.DBCon.Model(oldDependency).WherePK().Delete() - } - - } - -} - func updateStatus() { database.DBCon.Model(&models.Application{ Id: "dependencies", diff --git a/pkg/portage/github/pullrequests.go b/pkg/portage/github/pullrequests.go index ea70cd0..9399a06 100644 --- a/pkg/portage/github/pullrequests.go +++ b/pkg/portage/github/pullrequests.go @@ -3,32 +3,28 @@ package github import ( "bytes" "encoding/json" - "io/ioutil" + "log/slog" "net/http" - appUtils "soko/pkg/app/utils" "soko/pkg/config" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" - "soko/pkg/utils" "strconv" "strings" "time" ) func buildQuery(limit int, isOpen bool, lastUpdated, after string) map[string]string { - - lastUpdatedQuery := "" + var lastUpdatedQuery string if lastUpdated != "" { lastUpdatedQuery = `updated:>` + lastUpdated } - afterQuery := "" + var afterQuery string if after != "" { afterQuery = `after: "` + after + `",` } - isOpenQuery := "" + var isOpenQuery string if isOpen { isOpenQuery = `is:open` } @@ -109,102 +105,139 @@ func buildQuery(limit int, isOpen bool, lastUpdated, after string) map[string]st } func FullUpdatePullRequests() { - database.Connect() defer database.DBCon.Close() - deleteAllPullrequests() + database.TruncateTable((*models.GithubPullRequest)(nil)) + database.TruncateTable((*models.PackageToGithubPullRequest)(nil)) // year of the git migration - UpdatePullRequestsAfter(true, "2015-01-01", "") + updatePullRequestsAfter(true, "2015-01-01", "") updateStatus() } -func IncrementalUpdatePullRequests() { - - database.Connect() - defer database.DBCon.Close() +func updatePullRequestsAfter(isOpen bool, lastUpdated, after string) { + pullRequests := make(map[int]*models.GithubPullRequest) + client := &http.Client{Timeout: time.Second * 30} - lastUpdate := appUtils.GetApplicationData().LastUpdate.UTC().Format(time.RFC3339) - lastUpdate = strings.Split(lastUpdate, "Z")[0] + "Z" - UpdatePullRequestsAfter(false, lastUpdate, "") - // TODO --> we need to update old ent - // TODO --> delete closed pull requests + for { + slog.Info("Requesting pull requests", slog.Int("index", len(pullRequests))) + jsonData := buildQuery(100, isOpen, lastUpdated, after) + jsonValue, _ := json.Marshal(jsonData) - updateStatus() -} + request, err := http.NewRequest(http.MethodPost, "https://api.github.com/graphql", bytes.NewBuffer(jsonValue)) + if err != nil { + slog.Error("Failed querying github graphql", slog.Any("err", err)) + return + } -func UpdatePullRequestsAfter(isOpen bool, lastUpdated, after string) { - jsonData := buildQuery(100, isOpen, lastUpdated, after) + request.Header.Set("Authorization", "bearer "+config.GithubAPIToken()) + response, err := client.Do(request) + if err != nil { + slog.Error("The HTTP request failed", slog.Any("err", err)) + return + } + defer response.Body.Close() - jsonValue, _ := json.Marshal(jsonData) - request, err := http.NewRequest("POST", "https://api.github.com/graphql", bytes.NewBuffer(jsonValue)) - request.Header.Set("Authorization", "bearer "+config.GithubAPIToken()) - client := &http.Client{Timeout: time.Second * 30} - response, err := client.Do(request) - if err != nil { - logger.Error.Println("The HTTP request failed with error") - logger.Error.Println(err) + var prData models.GitHubPullRequestQueryResult + err = json.NewDecoder(response.Body).Decode(&prData) + if err != nil { + slog.Error("Failed to parse JSON", slog.Any("err", err)) + return + } + prData.AppendPullRequest(pullRequests) + + // If there is a next page, import it as well + if prData.HasNextPage() { + time.Sleep(2 * time.Second) + after = prData.EndCursor() + } else { + break + } } - defer response.Body.Close() - data, _ := ioutil.ReadAll(response.Body) - var prData models.GitHubPullRequestQueryResult - err = json.Unmarshal([]byte(data), &prData) - - pullrequests := prData.CreatePullRequest() - - for _, pullrequest := range pullrequests { - // - // Create Pullrequest - // - database.DBCon.Model(&pullrequest).WherePK().OnConflict("(id) DO UPDATE").Insert() + if len(pullRequests) == 0 { + slog.Info("No pull requests to insert") + return + } - // - // Create Package To Pullrequest - // - var affectedPackages []string + categoriesPullRequests := make(map[string]map[string]struct{}) + var pkgsPullRequests []*models.PackageToGithubPullRequest + for _, pullrequest := range pullRequests { + affectedPackages := make(map[string]struct{}) for _, file := range pullrequest.Files { pathParts := strings.Split(file.Path, "/") if len(pathParts) >= 2 && strings.Contains(pathParts[0], "-") { - affectedPackages = append(affectedPackages, pathParts[0]+"/"+pathParts[1]) + affectedPackages[pathParts[0]+"/"+pathParts[1]] = struct{}{} + + prs, ok := categoriesPullRequests[pathParts[0]] + if !ok { + prs = make(map[string]struct{}) + } + prs[pullrequest.Id] = struct{}{} + categoriesPullRequests[pathParts[0]] = prs } } - affectedPackages = utils.Deduplicate(affectedPackages) - for _, affectedPackage := range affectedPackages { - database.DBCon.Model(&models.PackageToGithubPullRequest{ + for affectedPackage := range affectedPackages { + pkgsPullRequests = append(pkgsPullRequests, &models.PackageToGithubPullRequest{ Id: affectedPackage + "-" + pullrequest.Id, PackageAtom: affectedPackage, GithubPullRequestId: pullrequest.Id, - }).WherePK().OnConflict("(id) DO UPDATE").Insert() + }) } } - // - // If there is a next page, import it as well - // + rows := make([]*models.GithubPullRequest, 0, len(pullRequests)) + for _, row := range pullRequests { + rows = append(rows, row) + } + result, err := database.DBCon.Model(&rows).OnConflict("(id) DO UPDATE").Insert() + if err != nil { + slog.Error("Failed to insert pull requests", slog.Any("err", err)) + return + } + slog.Info("Inserted pull requests", slog.Int("rows", result.RowsAffected())) - if prData.HasNextPage() { - // Wait for some time, as Github will block the request otherwise - time.Sleep(2 * time.Second) - UpdatePullRequestsAfter(isOpen, lastUpdated, prData.EndCursor()) + result, err = database.DBCon.Model(&pkgsPullRequests).OnConflict("(id) DO UPDATE").Insert() + if err != nil { + slog.Error("Failed to insert packages to pull requests", slog.Any("err", err)) + return } + slog.Info("Inserted packages to pull requests", slog.Int("rows", result.RowsAffected())) + updateCategoriesPullRequests(categoriesPullRequests) } -// deleteAllPullrequests deletes all entries in the pullrequests and package to pull request table -func deleteAllPullrequests() { - var pullrequests []*models.GithubPullRequest - database.DBCon.Model(&pullrequests).Select() - for _, pullrequest := range pullrequests { - database.DBCon.Model(pullrequest).WherePK().Delete() +func updateCategoriesPullRequests(categoriesPullRequests map[string]map[string]struct{}) { + var categories []*models.CategoryPackagesInformation + err := database.DBCon.Model(&categories).Column("name").Select() + if err != nil { + slog.Error("Failed fetching categories packages information", slog.Any("err", err)) + return + } else if len(categories) > 0 { + for _, category := range categories { + category.PullRequests = len(categoriesPullRequests[category.Name]) + delete(categoriesPullRequests, category.Name) + } + _, err = database.DBCon.Model(&categories).Set("pull_requests = ?pull_requests").Update() + if err != nil { + slog.Error("Failed updating categories packages information", slog.Any("err", err)) + } + categories = make([]*models.CategoryPackagesInformation, 0, len(categoriesPullRequests)) } - var packagesToGithubPullRequest []*models.PackageToGithubPullRequest - database.DBCon.Model(&packagesToGithubPullRequest).Select() - for _, packageToGithubPullRequest := range packagesToGithubPullRequest { - database.DBCon.Model(packageToGithubPullRequest).WherePK().Delete() + for category, prs := range categoriesPullRequests { + categories = append(categories, &models.CategoryPackagesInformation{ + Name: category, + PullRequests: len(prs), + }) + } + if len(categories) > 0 { + _, err = database.DBCon.Model(&categories).Insert() + if err != nil { + slog.Error("Failed inserting categories packages information", slog.Any("err", err)) + } } } diff --git a/pkg/portage/maintainers/update.go b/pkg/portage/maintainers/update.go index e42a8e6..306d9d8 100644 --- a/pkg/portage/maintainers/update.go +++ b/pkg/portage/maintainers/update.go @@ -1,24 +1,30 @@ package maintainers import ( + "log/slog" "soko/pkg/config" "soko/pkg/database" "soko/pkg/models" - "soko/pkg/utils" - "sort" "strings" "time" ) +const maintainerNeededEmail = "maintainer-needed@gentoo.org" + func FullImport() { database.Connect() defer database.DBCon.Close() + slog.Info("Loading all raw maintainers from the database") var allMaintainerInformation []*models.Maintainer database.DBCon.Model((*models.Package)(nil)).ColumnExpr("jsonb_array_elements(maintainers)->>'Name' as name, jsonb_array_elements(maintainers) ->> 'Email' as email, jsonb_array_elements(maintainers) ->> 'Type' as type").Select(&allMaintainerInformation) - maintainers := map[string]*models.Maintainer{} + maintainers := map[string]*models.Maintainer{ + maintainerNeededEmail: { + Email: maintainerNeededEmail, + }, + } for _, rawMaintainer := range allMaintainerInformation { _, ok := maintainers[rawMaintainer.Email] @@ -31,6 +37,7 @@ func FullImport() { } } + slog.Info("Loading all packages from the database") var gpackages []*models.Package database.DBCon.Model(&gpackages). Relation("Outdated"). @@ -41,24 +48,20 @@ func FullImport() { Relation("Versions.PkgCheckResults"). Select() - // TODO in future we want an incremental update here - // but for now we delete everything and insert it again - // this is currently acceptable as it takes less than 2 seconds - deleteAllMaintainers() - for _, maintainer := range maintainers { - outdated := 0 - securityBugs := 0 - pullrequestIds := []string{} - nonSecurityBugs := 0 - stableRequests := 0 + var outdated, stableRequests int + pullRequestIds := make(map[string]struct{}) maintainerPackages := []*models.Package{} for _, gpackage := range gpackages { found := false - for _, packageMaintainer := range gpackage.Maintainers { - if packageMaintainer.Email == maintainer.Email { - found = true + if len(gpackage.Maintainers) == 0 && maintainer.Email == maintainerNeededEmail { + found = true + } else { + for _, packageMaintainer := range gpackage.Maintainers { + if packageMaintainer.Email == maintainer.Email { + found = true + } } } @@ -68,7 +71,7 @@ func FullImport() { outdated = outdated + len(gpackage.Outdated) for _, pullRequest := range gpackage.PullRequests { - pullrequestIds = append(pullrequestIds, string(pullRequest.Id)) + pullRequestIds[pullRequest.Id] = struct{}{} } // Find Stable Requests @@ -82,31 +85,26 @@ func FullImport() { } } - for _, bug := range getAllBugs(maintainerPackages) { - if bug.Component == "Vulnerabilities" { - securityBugs++ - } else { - nonSecurityBugs++ - } - } + securityBugs, nonSecurityBugs := countBugs(maintainerPackages) maintainer.PackagesInformation = models.MaintainerPackagesInformation{ Outdated: outdated, - PullRequests: len(utils.Deduplicate(pullrequestIds)), + PullRequests: len(pullRequestIds), Bugs: nonSecurityBugs, SecurityBugs: securityBugs, StableRequests: stableRequests, } + maintainer.Name = strings.TrimSpace(maintainer.Name) + if maintainer.Name == "" { - maintainer.Name = strings.Title(strings.Split(maintainer.Email, "@")[0]) + name, _, _ := strings.Cut(maintainer.Email, "@") + maintainer.Name = strings.Title(name) } if maintainer.Type == "project" && strings.HasPrefix(maintainer.Name, "Gentoo ") { - maintainer.Name = strings.Replace(maintainer.Name, "Gentoo ", "", 1) - } - - if maintainer.Type == "person" { + maintainer.Name = strings.TrimPrefix(maintainer.Name, "Gentoo ") + } else if maintainer.Type == "person" { if strings.HasSuffix(maintainer.Email, "@gentoo.org") { maintainer.Type = "gentoo-developer" } else { @@ -114,49 +112,44 @@ func FullImport() { } } - database.DBCon.Model(maintainer).WherePK().OnConflict("(email) DO UPDATE").Insert() } + // TODO in future we want an incremental update here + // but for now we delete everything and insert it again + // this is currently acceptable as it takes less than 2 seconds + database.TruncateTable((*models.Maintainer)(nil)) + + rows := make([]*models.Maintainer, 0, len(maintainers)) + for _, row := range maintainers { + rows = append(rows, row) + } + res, err := database.DBCon.Model(&rows).OnConflict("(email) DO NOTHING").Insert() + if err != nil { + slog.Error("Failed inserting maintainers", slog.Any("err", err)) + return + } + slog.Info("Inserted maintainers", slog.Int("rows", res.RowsAffected())) + updateStatus() } -func getAllBugs(packages []*models.Package) []*models.Bug { +func countBugs(packages []*models.Package) (securityBugs, nonSecurityBugs int) { allBugs := make(map[string]*models.Bug) - for _, gpackage := range packages { for _, bug := range gpackage.AllBugs() { allBugs[bug.Id] = bug } } - var allBugsList []*models.Bug for _, bug := range allBugs { - allBugsList = append(allBugsList, bug) - } - - sort.Slice(allBugsList, func(i, j int) bool { - return allBugsList[i].Id < allBugsList[j].Id - }) - - return allBugsList -} - -// deleteAllMaintainers deletes all entries in the maintainers table -func deleteAllMaintainers() { - var maintainers []*models.Maintainer - database.DBCon.Model(&maintainers).Select() - for _, maintainer := range maintainers { - database.DBCon.Model(maintainer).WherePK().Delete() - } -} - -func contains(element string, elements []string) bool { - for _, el := range elements { - if element == el { - return true + if bug.Component == "Vulnerabilities" { + securityBugs++ + } else { + nonSecurityBugs++ } } - return false + + return } func updateStatus() { diff --git a/pkg/portage/pkgcheck/parse.go b/pkg/portage/pkgcheck/parse.go index 36e80ad..6eab781 100644 --- a/pkg/portage/pkgcheck/parse.go +++ b/pkg/portage/pkgcheck/parse.go @@ -2,12 +2,10 @@ package pkgcheck import ( "encoding/xml" - "io/ioutil" - "log" + "log/slog" "net/http" "soko/pkg/config" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" "time" ) @@ -30,62 +28,111 @@ type PkgCheckResult struct { // UpdatePkgCheckResults will update the database table that contains all pkgcheck results func UpdatePkgCheckResults() { - database.Connect() defer database.DBCon.Close() - if config.Quiet() == "true" { - log.SetOutput(ioutil.Discard) - } - // get the pkg check results from qa-reports.gentoo.org pkgCheckResults, err := parseQAReport() if err != nil { - logger.Error.Println("Error while parsing qa-reports data. Aborting...") + slog.Error("Failed parsing qa-reports data", slog.Any("err", err)) + return } - // clean up the database - deleteAllPkgCheckResults() - - // update the database with the new results - for _, pkgCheckResult := range pkgCheckResults.Results { - database.DBCon.Insert(&models.PkgCheckResult{ - Id: pkgCheckResult.Category + "/" + pkgCheckResult.Package + "-" + pkgCheckResult.Version + "-" + pkgCheckResult.Class + "-" + pkgCheckResult.Message, - Atom: pkgCheckResult.Category + "/" + pkgCheckResult.Package, + collected := make(map[string]*models.PkgCheckResult, len(pkgCheckResults)) + for _, pkgCheckResult := range pkgCheckResults { + catpkg := pkgCheckResult.Category + "/" + pkgCheckResult.Package + catpkgver := catpkg + "-" + pkgCheckResult.Version + id := catpkgver + "-" + pkgCheckResult.Class + "-" + pkgCheckResult.Message + collected[id] = &models.PkgCheckResult{ + Id: id, + Atom: catpkg, Category: pkgCheckResult.Category, Package: pkgCheckResult.Package, Version: pkgCheckResult.Version, - CPV: pkgCheckResult.Category + "/" + pkgCheckResult.Package + "-" + pkgCheckResult.Version, + CPV: catpkgver, Class: pkgCheckResult.Class, Message: pkgCheckResult.Message, - }) + } + } + + // clean up the database + database.TruncateTable((*models.PkgCheckResult)(nil)) + + // update the database with the new results + rows := make([]*models.PkgCheckResult, 0, len(collected)) + for _, row := range collected { + rows = append(rows, row) + } + res, err := database.DBCon.Model(&rows).OnConflict("(id) DO NOTHING").Insert() + if err != nil { + slog.Error("Failed inserting pkgcheck results", slog.Any("err", err)) + return } + slog.Info("Inserted pkgcheck results", slog.Int("rows", res.RowsAffected())) + + updateCategoriesInfo() updateStatus() } // parseQAReport gets the xml from qa-reports.gentoo.org and parses it -func parseQAReport() (PkgCheckResults, error) { +func parseQAReport() ([]PkgCheckResult, error) { resp, err := http.Get("https://qa-reports.gentoo.org/output/gentoo-ci/output.xml") if err != nil { - return PkgCheckResults{}, err + return nil, err } defer resp.Body.Close() - xmlData, err := ioutil.ReadAll(resp.Body) - if err != nil { - return PkgCheckResults{}, err - } var pkgCheckResults PkgCheckResults - xml.Unmarshal(xmlData, &pkgCheckResults) - return pkgCheckResults, err + err = xml.NewDecoder(resp.Body).Decode(&pkgCheckResults) + return pkgCheckResults.Results, err } -// deleteAllOutdated deletes all entries in the outdated table -func deleteAllPkgCheckResults() { - var allPkgCheckResults []*models.PkgCheckResult - database.DBCon.Model(&allPkgCheckResults).Select() - for _, pkgCheckResult := range allPkgCheckResults { - database.DBCon.Model(pkgCheckResult).WherePK().Delete() +func updateCategoriesInfo() { + var categoriesInfoArr []*models.CategoryPackagesInformation + err := database.DBCon.Model((*models.PkgCheckResult)(nil)). + ColumnExpr("SPLIT_PART(atom, '/', 1) as name"). + ColumnExpr("COUNT(id) as stable_requests"). + Where("NULLIF(atom, '') IS NOT NULL"). + Where("class = 'StableRequest'"). + GroupExpr("SPLIT_PART(atom, '/', 1)"). + Select(&categoriesInfoArr) + if err != nil { + slog.Error("Failed collecting pkgcheck results stats", slog.Any("err", err)) + return + } + categoriesInfo := make(map[string]int, len(categoriesInfoArr)) + for _, categoryInfo := range categoriesInfoArr { + categoriesInfo[categoryInfo.Name] = categoryInfo.StableRequests + } + + var categories []*models.CategoryPackagesInformation + err = database.DBCon.Model(&categories).Column("name").Select() + if err != nil { + slog.Error("Failed fetching categories packages information", slog.Any("err", err)) + return + } else if len(categories) > 0 { + for _, category := range categories { + category.StableRequests = categoriesInfo[category.Name] + delete(categoriesInfo, category.Name) + } + _, err = database.DBCon.Model(&categories).Set("stable_requests = ?stable_requests").Update() + if err != nil { + slog.Error("Failed updating categories packages information", slog.Any("err", err)) + } + categories = make([]*models.CategoryPackagesInformation, 0, len(categoriesInfo)) + } + + for category, stableRequests := range categoriesInfo { + categories = append(categories, &models.CategoryPackagesInformation{ + Name: category, + StableRequests: stableRequests, + }) + } + if len(categories) > 0 { + _, err = database.DBCon.Model(&categories).Insert() + if err != nil { + slog.Error("Error while inserting categories packages information", slog.Any("err", err)) + } } } diff --git a/pkg/portage/projects/update.go b/pkg/portage/projects/update.go index d9a47a0..d463862 100644 --- a/pkg/portage/projects/update.go +++ b/pkg/portage/projects/update.go @@ -2,40 +2,36 @@ package projects import ( "encoding/xml" - "io/ioutil" - "log" + "log/slog" "net/http" "soko/pkg/config" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" "time" ) -// UpdatePkgCheckResults will update the database table that contains all pkgcheck results +// UpdateProjects will update the database table that contains all projects func UpdateProjects() { - database.Connect() defer database.DBCon.Close() - if config.Quiet() == "true" { - log.SetOutput(ioutil.Discard) - } - - // get the pkg check results from qa-reports.gentoo.org + // get projects from api.gentoo.org projectList, err := parseProjectList() if err != nil { - logger.Error.Println("Error while parsing project list. Aborting...") + slog.Error("Error while parsing project list", slog.Any("err", err)) + return } - // clean up the database - deleteAllProjects() - - // insert new project list - for _, project := range projectList.Projects { - database.DBCon.Insert(&project) + var members []*models.MaintainerToProject + membersMap := make(map[string]struct{}) + for _, project := range projectList { for _, member := range project.Members { - database.DBCon.Insert(&models.MaintainerToProject{ + id := member.Email + "|" + project.Email + if _, ok := membersMap[id]; ok { + continue + } + membersMap[id] = struct{}{} + members = append(members, &models.MaintainerToProject{ Id: member.Email + "-" + project.Email, MaintainerEmail: member.Email, ProjectEmail: project.Email, @@ -43,38 +39,48 @@ func UpdateProjects() { } } + // clean up the database + database.TruncateTable((*models.Project)(nil)) + database.TruncateTable((*models.MaintainerToProject)(nil)) + + // insert new project list + _, err = database.DBCon.Model(&projectList).Insert() + if err != nil { + slog.Error("Error while inserting project list", slog.Any("err", err)) + return + } + _, err = database.DBCon.Model(&members).Insert() + if err != nil { + slog.Error("Error while inserting project members", slog.Any("err", err)) + return + } + updateStatus() } -// parseQAReport gets the xml from qa-reports.gentoo.org and parses it -func parseProjectList() (models.ProjectList, error) { +// parseProjectList gets the xml from api.gentoo.org and parses it +func parseProjectList() ([]models.Project, error) { resp, err := http.Get("https://api.gentoo.org/metastructure/projects.xml") if err != nil { - return models.ProjectList{}, err + return nil, err } defer resp.Body.Close() - xmlData, err := ioutil.ReadAll(resp.Body) - if err != nil { - return models.ProjectList{}, err - } - var projectList models.ProjectList - xml.Unmarshal(xmlData, &projectList) - return projectList, err -} -// deleteAllOutdated deletes all entries in the outdated table -func deleteAllProjects() { - var allProjects []*models.Project - database.DBCon.Model(&allProjects).Select() - for _, project := range allProjects { - database.DBCon.Model(project).WherePK().Delete() + var projectList models.ProjectList + err = xml.NewDecoder(resp.Body).Decode(&projectList) + if err != nil { + return nil, err } - var allMaintainerToProjects []*models.MaintainerToProject - database.DBCon.Model(&allMaintainerToProjects).Select() - for _, maintainerToProject := range allMaintainerToProjects { - database.DBCon.Model(maintainerToProject).WherePK().Delete() + uniqueProjects := make([]models.Project, 0, len(projectList.Projects)) + seen := make(map[string]struct{}, len(projectList.Projects)) + for _, project := range projectList.Projects { + if _, ok := seen[project.Email]; !ok { + seen[project.Email] = struct{}{} + uniqueProjects = append(uniqueProjects, project) + } } + return uniqueProjects, nil } func updateStatus() { diff --git a/pkg/portage/repology/outdated.go b/pkg/portage/repology/outdated.go index e836ab0..93f9008 100644 --- a/pkg/portage/repology/outdated.go +++ b/pkg/portage/repology/outdated.go @@ -1,17 +1,20 @@ package repology import ( - "bytes" + "bufio" + "context" "encoding/json" - "io/ioutil" - "log" + "fmt" + "log/slog" "net/http" + "regexp" "soko/pkg/config" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" "strings" "time" + + "golang.org/x/time/rate" ) type Package struct { @@ -22,158 +25,298 @@ type Package struct { Status string `json:"status"` } -type Packages map[string][]Package +type Packages = map[string][]Package + +var client = http.Client{Timeout: 1 * time.Minute} +var clientRateLimiter = rate.NewLimiter(rate.Every(2*time.Second), 1) // UpdateOutdated will update the database table that contains all outdated gentoo versions func UpdateOutdated() { - database.Connect() defer database.DBCon.Close() - if config.Quiet() == "true" { - log.SetOutput(ioutil.Discard) + // Get all outdated Versions + outdated := newOutdatedCheck() + for letter := 'a'; letter <= 'z'; letter++ { + outdated.getOutdatedStartingWith(letter) } - // Get all outdated Versions - var outdatedVersions []*models.OutdatedPackages - letters := "abcdefghijklmnopqrstuvwxyz" - for _, letter := range letters { - outdatedVersions = append(outdatedVersions, getOutdatedStartingWith(letter)...) + // Update the database + if len(outdated.outdatedVersions) > 0 { + database.TruncateTable((*models.OutdatedPackages)(nil)) + + res, err := database.DBCon.Model(&outdated.outdatedVersions).Insert() + if err != nil { + slog.Error("Error while inserting outdated packages", slog.Any("err", err)) + } else { + slog.Info("Inserted outdated packages", slog.Int("res", res.RowsAffected())) + } } - // Clean up the database - deleteAllOutdated() + // Updated the outdated status of categories + var categories []*models.CategoryPackagesInformation + err := database.DBCon.Model(&categories).Column("name").Select() + if err != nil { + slog.Error("Failed fetching categories packages information", slog.Any("err", err)) + return + } else if len(categories) > 0 { + for _, category := range categories { + category.Outdated = outdated.outdatedCategories[category.Name] + delete(outdated.outdatedCategories, category.Name) + } + _, err = database.DBCon.Model(&categories).Set("outdated = ?outdated").Update() + if err != nil { + slog.Error("Failed updating categories packages information", slog.Any("err", err)) + } + categories = make([]*models.CategoryPackagesInformation, 0, len(outdated.outdatedCategories)) + } - // Update the database - for _, outdated := range outdatedVersions { - database.DBCon.Insert(outdated) + for category, count := range outdated.outdatedCategories { + categories = append(categories, &models.CategoryPackagesInformation{ + Name: category, + Outdated: count, + }) + } + if len(categories) > 0 { + _, err = database.DBCon.Model(&categories).Insert() + if err != nil { + slog.Error("Error while inserting categories packages information", slog.Any("err", err)) + } } updateStatus() } -// getOutdatedStartingWith gets all outdated packages starting with the given letter -func getOutdatedStartingWith(letter rune) []*models.OutdatedPackages { - repoPackages, err := parseRepologyData("https://repology.org/api/v1/projects/" + string(letter) + "/?inrepo=gentoo&outdated=1") +type atomOutdatedRules struct { + ignore bool + ignoreVersions []string + ignoreRepos []string + selectedRepos []string +} + +func (a *atomOutdatedRules) isIgnored(version string, repo string) bool { + if a == nil { + return false + } else if a.ignore { + return true + } + + for _, v := range a.ignoreVersions { + if strings.HasPrefix(version, v) { + return true + } + } + for _, r := range a.ignoreRepos { + if strings.HasPrefix(repo, r) { + return true + } + } + if len(a.selectedRepos) > 0 { + found := false + for _, r := range a.selectedRepos { + if strings.HasPrefix(repo, r) { + found = true + break + } + } + if !found { + return true + } + } + return false +} + +type outdatedCheck struct { + blockedRepos map[string]struct{} + blockedCategories map[string]struct{} + atomRules map[string]*atomOutdatedRules + + outdatedCategories map[string]int + outdatedVersions []*models.OutdatedPackages +} + +func newOutdatedCheck() outdatedCheck { + return outdatedCheck{ + blockedRepos: readBlockList("ignored-repositories"), + blockedCategories: readBlockList("ignored-categories"), + atomRules: buildAtomRules(), + + outdatedCategories: make(map[string]int), + } +} +// getOutdatedStartingWith gets all outdated packages starting with the given letter +func (o *outdatedCheck) getOutdatedStartingWith(letter rune) { + repoPackages, err := parseRepologyData(letter) if err != nil { - logger.Error.Println("Error while fetching repology data") - return []*models.OutdatedPackages{} + slog.Error("Error while fetching repology data", slog.String("letter", string(letter)), slog.Any("err", err)) } - blockedRepos := readBlocklist("ignored-repositories") - blockedCategories := readBlocklist("ignored-categories") - blockedPackages := readBlocklist("ignored-packages") + for packagename := range repoPackages { + outdated := make(map[string]bool) + currentVersion := make(map[string]string) + var newestVersion string - var outdatedVersions []*models.OutdatedPackages - for packagename, _ := range repoPackages { - atom := "" - newest := "" - version := "" - outdated := false // get the gentoo atom name first + gentooPackages := make(map[string]struct{}) for _, v := range repoPackages[packagename] { if v.Repo == "gentoo" { - atom = v.VisibleName + gentooPackages[v.VisibleName] = struct{}{} } } + mainLoop: for _, v := range repoPackages[packagename] { - if v.Status == "newest" && - !contains(blockedRepos, v.Repo) && - !contains(blockedPackages, atom+"::"+v.Repo) { - newest = v.Version - } - if v.Repo == "gentoo" && v.Status == "newest" { - outdated = false - break - } - if v.Repo == "gentoo" && - v.Status == "outdated" && - !containsPrefix(blockedCategories, strings.Split(v.VisibleName, "/")[0]) && - !containsPrefix(blockedPackages, v.VisibleName) { - - atom = v.VisibleName - outdated = true - version = v.Version + category, _, _ := strings.Cut(v.VisibleName, "/") + if v.Repo == "gentoo" { + if v.Status == "newest" { + outdated[v.VisibleName] = false + } else if v.Status == "outdated" { + if contains(o.blockedCategories, category) || o.atomRules[v.VisibleName].isIgnored(v.Version, v.Repo) { + continue + } + if _, found := outdated[v.VisibleName]; !found { + outdated[v.VisibleName] = true + } + if latest, found := currentVersion[v.VisibleName]; found { + current := models.Version{Version: v.Version} + if current.GreaterThan(models.Version{Version: latest}) { + currentVersion[v.VisibleName] = v.Version + } + } else { + currentVersion[v.VisibleName] = v.Version + } + } + } else if len(newestVersion) == 0 && v.Status == "newest" && !contains(o.blockedRepos, v.Repo) { + for atom := range gentooPackages { + if o.atomRules[atom].isIgnored(v.Version, v.Repo) { + continue mainLoop + } + } + newestVersion = v.Version } } - if outdated && newest != "" && strings.HasPrefix(packagename, string(letter)) { - outdatedVersions = append(outdatedVersions, &models.OutdatedPackages{ - Atom: atom, - GentooVersion: version, - NewestVersion: newest, - }) + if len(newestVersion) == 0 { + continue } - } - return outdatedVersions + for atom, outdated := range outdated { + if outdated && packagename[0] == byte(letter) { + o.outdatedVersions = append(o.outdatedVersions, &models.OutdatedPackages{ + Atom: atom, + GentooVersion: currentVersion[atom], + NewestVersion: newestVersion, + }) + + category, _, found := strings.Cut(atom, "/") + if found { + o.outdatedCategories[category]++ + } + } + } + } } // parseRepologyData gets the json from given url and parses it -func parseRepologyData(url string) (Packages, error) { - resp, err := http.Get(url) +func parseRepologyData(letter rune) (Packages, error) { + err := clientRateLimiter.Wait(context.Background()) + if err != nil { + return Packages{}, fmt.Errorf("rate limiter failed: %w", err) + } + + url := "https://repology.org/api/v1/projects/" + string(letter) + "/?inrepo=gentoo&outdated=1" + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return Packages{}, fmt.Errorf("new request: %w", err) + } + req.Header.Set("User-Agent", config.UserAgent()) + + resp, err := client.Do(req) if err != nil { - return Packages{}, err + return Packages{}, fmt.Errorf("do http: %w", err) } defer resp.Body.Close() - var repoPackages Packages - dec := json.NewDecoder(resp.Body) - err = dec.Decode(&repoPackages) - return repoPackages, err -} -// deleteAllOutdated deletes all entries in the outdated table -func deleteAllOutdated() { - var allOutdated []*models.OutdatedPackages - database.DBCon.Model(&allOutdated).Select() - for _, outdated := range allOutdated { - database.DBCon.Model(outdated).WherePK().Delete() + if resp.StatusCode != http.StatusOK { + return Packages{}, fmt.Errorf("error while fetching repology data: %s", resp.Status) } + + var repoPackages Packages + err = json.NewDecoder(resp.Body).Decode(&repoPackages) + return repoPackages, err } -// readBlocklist parses a block list and returns a list of +// readBlockList parses a block list and returns a list of // lines whereas comments as well as empty lines are ignored -func readBlocklist(file string) []string { - var blocklist []string - resp, err := http.Get("https://gitweb.gentoo.org/sites/soko-metadata.git/plain/repology/" + file) +func readBlockList(file string) map[string]struct{} { + blocklist := make(map[string]struct{}) + resp, err := client.Get("https://gitweb.gentoo.org/sites/soko-metadata.git/plain/repology/" + file) if err != nil { - return []string{} + slog.Error("Failed to fetch blacklist", slog.String("file", file), slog.Any("err", err)) + return blocklist } defer resp.Body.Close() - buf := new(bytes.Buffer) - buf.ReadFrom(resp.Body) - rawBlocklist := buf.String() + if resp.StatusCode != http.StatusOK { + slog.Error("Failed to fetch blacklist", slog.String("file", file), slog.String("status", resp.Status)) + return blocklist + } - for _, line := range strings.Split(rawBlocklist, "\n") { + scanner := bufio.NewScanner(resp.Body) + for scanner.Scan() { + line := scanner.Text() if !strings.HasPrefix(line, "#") && strings.TrimSpace(line) != "" { - blocklist = append(blocklist, line) + blocklist[line] = struct{}{} } } return blocklist } -// contains returns true if the given list includes -// the given string. Otherwise false is returned. -func contains(list []string, item string) bool { - for _, i := range list { - if i == item { - return true +func buildAtomRules() map[string]*atomOutdatedRules { + var versionNumber = regexp.MustCompile(`-[0-9]`) + + blacklist := readBlockList("ignored-packages") + whitelist := readBlockList("selected-packages") + + atomRules := make(map[string]*atomOutdatedRules, len(blacklist)+len(whitelist)) + for line := range blacklist { + cpv, repo, hasRepo := strings.Cut(line, "::") + atom := versionNumber.Split(cpv, 2)[0] + rule, found := atomRules[atom] + if !found { + rule = &atomOutdatedRules{} + atomRules[atom] = rule + } + if hasRepo && repo != "" { + rule.ignoreRepos = append(rule.ignoreRepos, repo) + } else if atom != cpv { + rule.ignoreVersions = append(rule.ignoreVersions, strings.TrimPrefix(cpv, atom+"-")) + } else { + rule.ignore = true } } - return false -} -// contains returns true if the given string is a prefix -// of an item in the given list. Otherwise false is returned. -func containsPrefix(list []string, item string) bool { - for _, i := range list { - if strings.HasPrefix(i, item) { - return true + for line := range whitelist { + cpv, repo, hasRepo := strings.Cut(line, "::") + atom := versionNumber.Split(cpv, 2)[0] + rule, found := atomRules[atom] + if !found { + rule = &atomOutdatedRules{} + atomRules[atom] = rule + } + if hasRepo && repo != "" { + rule.selectedRepos = append(rule.selectedRepos, repo) } } - return false + + return atomRules +} + +// contains returns true if the given list includes +// the given string. Otherwise false is returned. +func contains(list map[string]struct{}, item string) bool { + _, found := list[item] + return found } func updateStatus() { diff --git a/pkg/portage/repository/category.go b/pkg/portage/repository/category.go index 8ea9413..b0dfe18 100644 --- a/pkg/portage/repository/category.go +++ b/pkg/portage/repository/category.go @@ -4,12 +4,11 @@ package repository import ( "encoding/xml" - "io/ioutil" + "log/slog" "os" "regexp" "soko/pkg/config" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" "strings" ) @@ -17,99 +16,116 @@ import ( // isCategory checks whether the path points to a category // descriptions that is an metadata.xml file func isCategory(path string) bool { - isCategory, _ := regexp.MatchString(`[^/]*\/metadata\.xml`, path) + isCategory, _ := regexp.MatchString(`^[^/]*\/metadata\.xml$`, path) return isCategory } -// UpdateCategory updates the category in the database in case -// the given path points to a category description -func UpdateCategory(path string) { - - splittedLine := strings.Split(path, "\t") +// UpdateCategories updates the categories in the database for each +// given path that points to a category description +func UpdateCategories(paths []string) { + deleted := map[string]*models.Category{} + modified := map[string]*models.Category{} + + for _, path := range paths { + splittedLine := strings.Split(path, "\t") + + if len(splittedLine) != 2 { + if len(splittedLine) == 1 && isCategory(path) { + if cat := updateModifiedCategory(path); cat != nil { + modified[cat.Name] = cat + } + } + continue + } - if len(splittedLine) != 2 { - if len(splittedLine) == 1 && isCategory(path) { - updateModifiedCategory(path) + status := splittedLine[0] + changedFile := splittedLine[1] + + if !isCategory(changedFile) { + continue + } else if status == "D" { + cat := updateDeletedCategory(changedFile) + deleted[cat.Name] = cat + } else if status == "A" || status == "M" { + if cat := updateModifiedCategory(changedFile); cat != nil { + modified[cat.Name] = cat + } } - return } - status := splittedLine[0] - changedFile := splittedLine[1] + if len(deleted) > 0 { + rows := make([]*models.Category, 0, len(deleted)) + for _, row := range deleted { + rows = append(rows, row) + } + res, err := database.DBCon.Model(&rows).Delete() + if err != nil { + slog.Error("Failed deleting categories", slog.Any("err", err)) + } else { + slog.Info("Deleted categories", slog.Int("rows", res.RowsAffected())) + } + } - if isCategory(changedFile) && status == "D" { - updateDeletedCategory(changedFile) - } else if isCategory(changedFile) && (status == "A" || status == "M") { - updateModifiedCategory(changedFile) + if len(modified) > 0 { + rows := make([]*models.Category, 0, len(modified)) + for _, row := range modified { + rows = append(rows, row) + } + res, err := database.DBCon.Model(&rows).OnConflict("(name) DO UPDATE").Insert() + if err != nil { + slog.Error("Failed updating categories", slog.Any("err", err)) + } else { + slog.Info("Updated categories", slog.Int("rows", res.RowsAffected())) + } } } // updateDeletedCategory deletes a category from the database -func updateDeletedCategory(changedFile string) { - splitted := strings.Split(changedFile, "/") - id := splitted[0] - - category := &models.Category{Name: id} - _, err := database.DBCon.Model(category).WherePK().Delete() - - if err != nil { - logger.Error.Println("Error during deleting category " + id) - logger.Error.Println(err) - } - +func updateDeletedCategory(changedFile string) *models.Category { + name, _, _ := strings.Cut(changedFile, "/") + return &models.Category{Name: name} } // updateModifiedCategory adds a category to the database or // updates it. To do so, it parses the metadata from metadata.xml -func updateModifiedCategory(changedFile string) { - splitted := strings.Split(changedFile, "/") - id := splitted[0] - - catmetadata := GetCatMetadata(config.PortDir() + "/" + changedFile) - description := "" +func updateModifiedCategory(changedFile string) *models.Category { + name, _, _ := strings.Cut(changedFile, "/") - for _, longdescription := range catmetadata.Longdescriptions { - if longdescription.Lang == "en" { - description = strings.TrimSpace(longdescription.Content) - } + xmlFile, err := os.Open(config.PortDir() + "/" + changedFile) + if err != nil { + slog.Error("Failed reading category metadata", slog.String("category", changedFile), slog.Any("err", err)) + return nil } + defer xmlFile.Close() - category := &models.Category{ - Name: id, - Description: description, + var catMetadata CatMetadata + err = xml.NewDecoder(xmlFile).Decode(&catMetadata) + if err != nil { + slog.Error("Error decoding category", slog.String("category", changedFile), slog.Any("err", err)) + return nil } - _, err := database.DBCon.Model(category).OnConflict("(name) DO UPDATE").Insert() - - if err != nil { - logger.Error.Println("Error during updating category " + id) - logger.Error.Println(err) + var description string + for _, longDescription := range catMetadata.LongDescriptions { + if longDescription.Lang == "en" || longDescription.Lang == "" { + description = strings.TrimSpace(longDescription.Content) + } } -} -// GetCatMetadata reads and parses the category -// metadata from the metadata.xml file -func GetCatMetadata(path string) Catmetadata { - xmlFile, err := os.Open(path) - if err != nil { - logger.Error.Println("Error during reading category metadata") - logger.Error.Println(err) + return &models.Category{ + Name: name, + Description: description, } - defer xmlFile.Close() - byteValue, _ := ioutil.ReadAll(xmlFile) - var catmetadata Catmetadata - xml.Unmarshal(byteValue, &catmetadata) - return catmetadata } // Descriptions of the category metadata.xml format -type Catmetadata struct { +type CatMetadata struct { XMLName xml.Name `xml:"catmetadata"` - Longdescriptions []Longdescription `xml:"longdescription"` + LongDescriptions []LongDescription `xml:"longdescription"` } -type Longdescription struct { +type LongDescription struct { XMLName xml.Name `xml:"longdescription"` Lang string `xml:"lang,attr"` Content string `xml:",chardata"` diff --git a/pkg/portage/repository/commit.go b/pkg/portage/repository/commit.go index f9ccc7f..17a3371 100644 --- a/pkg/portage/repository/commit.go +++ b/pkg/portage/repository/commit.go @@ -3,44 +3,57 @@ package repository import ( + "log/slog" "os/exec" + "slices" "soko/pkg/config" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" "soko/pkg/portage/utils" - "strconv" "strings" "time" ) +var ( + // arrays for collecting date for batch dump into database + commits []*models.Commit + packages []*models.Package + keywordChanges = map[string]*models.KeywordChange{} + packagesCommit []*models.CommitToPackage + versionsCommits []*models.CommitToVersion +) + // UpdateCommits incrementally imports all new commits. New commits are // determined by retrieving the last commit in the database (if present) // and parsing all following commits. In case no last commit is present // a full import starting with the first commit in the tree is done. func UpdateCommits() string { - logger.Info.Println("Start updating commits") + slog.Info("Start updating commits") - latestCommit, PrecedingCommitsOffset := utils.GetLatestCommitAndPreceeding() + latestCommit, precedingCommitsOffset := utils.GetLatestCommitAndPreceding() - for PrecedingCommits, rawCommit := range utils.GetCommits(latestCommit, "HEAD") { - latestCommit = processCommit(PrecedingCommits, PrecedingCommitsOffset, rawCommit) + for precedingCommits, rawCommit := range utils.GetCommits(latestCommit, "HEAD") { + latestCommit = processCommit(precedingCommits, precedingCommitsOffset, rawCommit) + + if len(commits) > 10000 { + dumpToDatabase() + } } - logger.Info.Println("Finished updating commits") + dumpToDatabase() + slog.Info("Finished updating commits") return latestCommit } // processCommit parses a single commit log output and updates it into the database -func processCommit(PrecedingCommits int, PrecedingCommitsOffset int, rawCommit string) string { - +func processCommit(PrecedingCommits, PrecedingCommitsOffset int, rawCommit string) string { commitLines := strings.Split(rawCommit, "\n") if len(commitLines) < 8 { return "" } - logProgess(PrecedingCommits) + logProgress(PrecedingCommits) id := strings.TrimSpace(strings.ReplaceAll(commitLines[0], "commit ", "")) authorName := strings.TrimSpace(strings.Split(strings.ReplaceAll(commitLines[1], "Author: ", ""), "<")[0]) @@ -59,7 +72,7 @@ func processCommit(PrecedingCommits int, PrecedingCommitsOffset int, rawCommit s changedFiles := processChangedFiles(PrecedingCommits, PrecedingCommitsOffset, commitLines, id) - commit := &models.Commit{ + commits = append(commits, &models.Commit{ Id: id, PrecedingCommits: PrecedingCommitsOffset + PrecedingCommits + 1, AuthorName: authorName, @@ -70,26 +83,16 @@ func processCommit(PrecedingCommits int, PrecedingCommitsOffset int, rawCommit s CommitterDate: committerDate, Message: message, ChangedFiles: changedFiles, - } - - _, err := database.DBCon.Model(commit).OnConflict("(id) DO UPDATE").Insert() - - if err != nil { - logger.Error.Println("Error during updating commit: " + id) - logger.Error.Println(err) - } + }) return id } // processChangedFiles parses files that have changed in the commit and links the // commit to packages and package versions -func processChangedFiles(PrecedingCommits int, PrecedingCommitsOffset int, commitLines []string, id string) *models.ChangedFiles { - var addedFiles []*models.ChangedFile - var modifiedFiles []*models.ChangedFile - var deletedFiles []*models.ChangedFile +func processChangedFiles(PrecedingCommits, PrecedingCommitsOffset int, commitLines []string, id string) *models.ChangedFiles { + var addedFiles, modifiedFiles, deletedFiles []*models.ChangedFile for _, commitLine := range commitLines { - line := strings.Split(commitLine, "\t") if len(line) < 2 { continue @@ -99,25 +102,18 @@ func processChangedFiles(PrecedingCommits int, PrecedingCommitsOffset int, commi path := strings.TrimSpace(line[1]) if strings.HasPrefix(status, "M") { - - modifiedFiles = addChangedFile(modifiedFiles, path, "M") + modifiedFiles = append(modifiedFiles, &models.ChangedFile{Path: path, ChangeType: "M"}) createKeywordChange(id, path, commitLine) - } else if strings.HasPrefix(commitLine, "D") { - - deletedFiles = addChangedFile(deletedFiles, path, "D") - + deletedFiles = append(deletedFiles, &models.ChangedFile{Path: path, ChangeType: "D"}) } else if strings.HasPrefix(commitLine, "A") { - - addedFiles = addChangedFile(addedFiles, path, "A") + addedFiles = append(addedFiles, &models.ChangedFile{Path: path, ChangeType: "A"}) updateFirstCommitOfPackage(path, commitLine, PrecedingCommitsOffset+PrecedingCommits+1) createAddedKeywords(id, path, commitLine) - } linkCommitToPackage(commitLine, path, id) linkCommitToVersion(commitLine, path, id) - } return &models.ChangedFiles{ @@ -127,116 +123,91 @@ func processChangedFiles(PrecedingCommits int, PrecedingCommitsOffset int, commi } } -// logProgess logs the progress of a loop -func logProgess(counter int) { +// logProgress logs the progress of a loop +func logProgress(counter int) { if counter%1000 == 0 { - logger.Info.Println("Processed commits: " + strconv.Itoa(counter)) + slog.Info("Processed commits", slog.Int("commits", counter)) } else if counter == 1 { // The initial commit is *huge* that's why we log it as well - logger.Info.Println("Processed first commit.") + slog.Info("Processed first commit.") } } -func linkCommitToPackage(commitLine string, path string, id string) { - var commitToPackage *models.CommitToPackage +func linkCommitToPackage(commitLine, path, id string) { if (len(strings.Split(commitLine, "/")) >= 3) && (strings.HasPrefix(commitLine, "M") || strings.HasPrefix(commitLine, "D") || strings.HasPrefix(commitLine, "A")) { - pathParts := strings.Split(strings.ReplaceAll(path, ".ebuild", ""), "/") + pathParts := strings.Split(strings.TrimSuffix(path, ".ebuild"), "/") - commitToPackageId := id + "-" + pathParts[0] + "/" + strings.Split(commitLine, "/")[1] - commitToPackage = &models.CommitToPackage{ - Id: commitToPackageId, + packageAtom := pathParts[0] + "/" + strings.Split(commitLine, "/")[1] + packagesCommit = append(packagesCommit, &models.CommitToPackage{ + Id: id + "-" + packageAtom, CommitId: id, - PackageAtom: pathParts[0] + "/" + strings.Split(commitLine, "/")[1], - } - - _, err := database.DBCon.Model(commitToPackage).OnConflict("(id) DO NOTHING").Insert() - - if err != nil { - logger.Error.Println("Error during updating CommitToPackage: " + commitToPackageId) - logger.Error.Println(err) - } - + PackageAtom: packageAtom, + }) } } -func linkCommitToVersion(commitLine string, path string, id string) { - var commitToVersion *models.CommitToVersion +func linkCommitToVersion(commitLine, path, id string) { if (strings.HasPrefix(commitLine, "M") || strings.HasPrefix(commitLine, "D") || strings.HasPrefix(commitLine, "A")) && - len(strings.Split(strings.ReplaceAll(path, ".ebuild", ""), "/")) == 3 && + len(strings.Split(strings.TrimSuffix(path, ".ebuild"), "/")) == 3 && strings.HasSuffix(strings.TrimSpace(strings.Split(commitLine, "\t")[1]), ".ebuild") { - pathParts := strings.Split(strings.ReplaceAll(path, ".ebuild", ""), "/") + pathParts := strings.Split(strings.TrimSuffix(path, ".ebuild"), "/") - commitToVersionId := id + "-" + pathParts[0] + "/" + pathParts[2] - commitToVersion = &models.CommitToVersion{ - Id: commitToVersionId, + versionId := pathParts[0] + "/" + pathParts[2] + versionsCommits = append(versionsCommits, &models.CommitToVersion{ + Id: id + "-" + versionId, CommitId: id, - VersionId: pathParts[0] + "/" + pathParts[2], - } - - _, err := database.DBCon.Model(commitToVersion).OnConflict("(id) DO NOTHING").Insert() - - if err != nil { - logger.Error.Println("Error during updating CommitToVersion: " + commitToVersionId) - logger.Error.Println(err) - } - + VersionId: versionId, + }) } } -func createKeywordChange(id string, path string, commitLine string) { - - if !strings.HasSuffix(path, ".ebuild") || !(len(strings.Split(commitLine, "/")) >= 3) { +func createKeywordChange(id, path, commitLine string) { + if !strings.HasSuffix(path, ".ebuild") || !(strings.Count(commitLine, "/") >= 2) { return } - var change *models.KeywordChange - raw_lines, err := utils.Exec(config.PortDir(), "git", "show", id, "--", path) if err != nil { if exitError, ok := err.(*exec.ExitError); !ok || exitError.ExitCode() != 1 { - logger.Error.Println("Problem parsing file") + slog.Error("Failed running git show", slog.String("id", id), slog.String("path", path), slog.Any("err", err)) return } } - var keywords_old []string - var keywords_new []string + var keywords_old, keywords_new []string for _, line := range raw_lines { if strings.HasPrefix(line, "-KEYWORDS=") { - keywords_old = strings.Split(strings.ReplaceAll(strings.ReplaceAll(line, "-KEYWORDS=", ""), "\"", ""), " ") - + keywords_old = strings.Split(strings.ReplaceAll(strings.TrimPrefix(line, "-KEYWORDS="), "\"", ""), " ") } else if strings.HasPrefix(line, "+KEYWORDS") { - keywords_new = strings.Split(strings.ReplaceAll(strings.ReplaceAll(line, "+KEYWORDS=", ""), "\"", ""), " ") + keywords_new = strings.Split(strings.ReplaceAll(strings.TrimPrefix(line, "+KEYWORDS="), "\"", ""), " ") } } - var added_keywords []string - var stabilized_keywords []string + var added_keywords, stabilized_keywords []string if keywords_old != nil && keywords_new != nil { - for _, keyword := range keywords_new { - if !utils.Contains(keywords_old, keyword) { + if !slices.Contains(keywords_old, keyword) { added_keywords = append(added_keywords, keyword) } - if !strings.HasPrefix(keyword, "~") && utils.Contains(keywords_old, ("~"+keyword)) { + if !strings.HasPrefix(keyword, "~") && slices.Contains(keywords_old, "~"+keyword) { stabilized_keywords = append(stabilized_keywords, keyword) } } - pathParts := strings.Split(strings.ReplaceAll(path, ".ebuild", ""), "/") + pathParts := strings.Split(strings.TrimSuffix(path, ".ebuild"), "/") keywordChangeId := id + "-" + strings.TrimSpace(strings.Split(commitLine, "\t")[1]) - change = &models.KeywordChange{ + keywordChanges[keywordChangeId] = &models.KeywordChange{ Id: keywordChangeId, CommitId: id, VersionId: pathParts[0] + "/" + pathParts[2], @@ -245,39 +216,28 @@ func createKeywordChange(id string, path string, commitLine string) { Stabilized: stabilized_keywords, All: keywords_new, } - - _, err := database.DBCon.Model(change).OnConflict("(id) DO UPDATE").Insert() - - if err != nil { - logger.Error.Println("Error updating Keyword change: " + keywordChangeId) - logger.Error.Println(err) - } - } } func createAddedKeywords(id string, path string, commitLine string) { - var change *models.KeywordChange if strings.HasSuffix(strings.TrimSpace(strings.Split(commitLine, "\t")[1]), ".ebuild") && - (len(strings.Split(commitLine, "/")) >= 3) { + (strings.Count(commitLine, "/") >= 2) { raw_lines, err := utils.Exec(config.PortDir(), "git", "show", id, "--", path) if err != nil { if exitError, ok := err.(*exec.ExitError); !ok || exitError.ExitCode() != 1 { - logger.Error.Println("Problem parsing file") - logger.Error.Println(exitError) + slog.Error("Failed running git show", slog.String("id", id), slog.String("path", path), slog.Any("err", err)) return } } for _, line := range raw_lines { if strings.HasPrefix(line, "+KEYWORDS=") { - - pathParts := strings.Split(strings.ReplaceAll(path, ".ebuild", ""), "/") - keywords := strings.Split(strings.ReplaceAll(strings.ReplaceAll(line, "+KEYWORDS=", ""), "\"", ""), " ") + pathParts := strings.Split(strings.TrimSuffix(path, ".ebuild"), "/") + keywords := strings.Split(strings.ReplaceAll(strings.TrimPrefix(line, "+KEYWORDS="), "\"", ""), " ") keywordChangeId := id + "-" + strings.TrimSpace(strings.Split(commitLine, "\t")[1]) - change = &models.KeywordChange{ + keywordChanges[keywordChangeId] = &models.KeywordChange{ Id: keywordChangeId, CommitId: id, VersionId: pathParts[0] + "/" + pathParts[2], @@ -285,14 +245,6 @@ func createAddedKeywords(id string, path string, commitLine string) { Added: keywords, All: keywords, } - - _, err := database.DBCon.Model(change).OnConflict("(id) DO UPDATE").Insert() - - if err != nil { - logger.Error.Println("Error updating Keyword change: " + keywordChangeId) - logger.Error.Println(err) - } - } } @@ -301,26 +253,64 @@ func createAddedKeywords(id string, path string, commitLine string) { func updateFirstCommitOfPackage(path string, commitLine string, precedingCommits int) { // Added Package - if strings.HasSuffix(path, "metadata.xml") && len(strings.Split(path, "/")) == 3 { - + if strings.HasSuffix(path, "metadata.xml") && strings.Count(commitLine, "/") == 2 { atom := strings.Split(path, "/")[0] + "/" + strings.Split(path, "/")[1] - addedpackage := &models.Package{ + packages = append(packages, &models.Package{ Atom: atom, PrecedingCommits: precedingCommits, + }) + } +} + +func dumpToDatabase() { + slog.Info("Writing to database", + slog.Int("KeywordChange", len(keywordChanges)), + slog.Int("Package", len(packages)), + slog.Int("CommitToPackage", len(packagesCommit)), + slog.Int("CommitToVersion", len(versionsCommits)), + slog.Int("Commit", len(commits))) + + if len(keywordChanges) > 0 { + rows := make([]*models.KeywordChange, 0, len(keywordChanges)) + for _, keywordChange := range keywordChanges { + rows = append(rows, keywordChange) + } + _, err := database.DBCon.Model(&rows).OnConflict("(id) DO UPDATE").Insert() + if err != nil { + slog.Error("Failed inserting KeywordChange", slog.Any("err", err)) } + clear(keywordChanges) + } - _, err := database.DBCon.Model(addedpackage).Column("preceding_commits").WherePK().Update() + if len(packages) > 0 { + _, err := database.DBCon.Model(&packages).Column("preceding_commits").Update() if err != nil { - logger.Error.Println("Error updating precedingCommits (" + strconv.Itoa(precedingCommits) + ") of package: " + atom) - logger.Error.Println(err) + slog.Error("Failed inserting Package", slog.Any("err", err)) } + packages = packages[:0] + } + if len(packagesCommit) > 0 { + _, err := database.DBCon.Model(&packagesCommit).OnConflict("(id) DO NOTHING").Insert() + if err != nil { + slog.Error("Failed inserting CommitToPackage", slog.Any("err", err)) + } + packagesCommit = packagesCommit[:0] } -} -func addChangedFile(changedFiles []*models.ChangedFile, path string, status string) []*models.ChangedFile { - return append(changedFiles, &models.ChangedFile{ - Path: path, - ChangeType: status, - }) + if len(versionsCommits) > 0 { + _, err := database.DBCon.Model(&versionsCommits).OnConflict("(id) DO NOTHING").Insert() + if err != nil { + slog.Error("Failed inserting CommitToVersion", slog.Any("err", err)) + } + versionsCommits = versionsCommits[:0] + } + + if len(commits) > 0 { + _, err := database.DBCon.Model(&commits).OnConflict("(id) DO UPDATE").Insert() + if err != nil { + slog.Error("Failed inserting Commit", slog.Any("err", err)) + } + commits = commits[:0] + } } diff --git a/pkg/portage/repository/deprecated.go b/pkg/portage/repository/deprecated.go new file mode 100644 index 0000000..594c553 --- /dev/null +++ b/pkg/portage/repository/deprecated.go @@ -0,0 +1,154 @@ +// Contains functions to import package deprecated entries into the database +// +// Example +// +// ## # Dev E. Loper <developer@gentoo.org> (2019-07-01) +// ## # Deprecated upstream, see HOMEPAGE +// ## dev-perl/Mail-Sender +// + +package repository + +import ( + "log/slog" + "soko/pkg/config" + "soko/pkg/database" + "soko/pkg/models" + "soko/pkg/portage/utils" + "strings" + + "github.com/a-h/templ" + "github.com/go-pg/pg/v10" +) + +// isPackagesDeprecated checks whether the path +// points to a package.mask file +func isPackagesDeprecated(path string) bool { + return path == "profiles/package.deprecated" +} + +// UpdatePackagesDeprecated updates all entries in +// the Deprecated table in the database +func UpdatePackagesDeprecated(path string) { + + splittedLine := strings.Split(path, "\t") + + var status, changedFile string + switch len(splittedLine) { + case 2: + status = splittedLine[0] + changedFile = splittedLine[1] + case 1: + // This happens in case of a full update + status = "A" + changedFile = splittedLine[0] + default: + // should not happen + return + } + + if status != "D" && isPackagesDeprecated(changedFile) { + slog.Info("Updating package.deprecated") + + // delete all existing entries before parsing the file again + // in future we might implement a incremental version here + database.TruncateTable((*models.DeprecatedPackage)(nil)) + + for _, entry := range getDeprecatedPackages(changedFile) { + parsePackagesDeprecated(entry) + } + } +} + +// parse the package.mask entries and +// update the DeprecatedPackage table in the database +func parsePackagesDeprecated(entry string) { + packageLines := strings.Split(entry, "\n") + if len(packageLines) >= 3 { + packageLine, packageLines := packageLines[0], packageLines[1:] + author, authorEmail, date := parseAuthorLine(packageLine) + + var reason string + packageLine, packageLines = packageLines[0], packageLines[1:] + for strings.HasPrefix(packageLine, "#") { + if packageLine == "#" { + reason += "<br />" + } else { + reason = reason + " " + templ.EscapeString(strings.TrimPrefix(packageLine, "# ")) + } + packageLine, packageLines = packageLines[0], packageLines[1:] + } + + reason = bugListMatcher.ReplaceAllStringFunc(reason, func(bugList string) string { + return bugReplacer.ReplaceAllString(bugList, `<a href="https://bugs.gentoo.org/$1">$0</a>`) + }) + + packageLines = append(packageLines, packageLine) + + for _, version := range packageLines { + entry := &models.DeprecatedPackage{ + Author: strings.TrimSpace(author), + AuthorEmail: strings.TrimSpace(authorEmail), + Date: date, + Reason: strings.TrimSpace(reason), + Versions: version, + } + + _, err := database.DBCon.Model(entry).OnConflict("(versions) DO UPDATE").Insert() + if err != nil { + slog.Error("Failed inserting/updating package deprecated entry", slog.Any("err", err)) + } + } + } + +} + +// get all entries from the package.deprecated file +func getDeprecatedPackages(path string) []string { + var deprecates []string + lines, err := utils.ReadLines(config.PortDir() + "/" + path) + if err != nil { + slog.Error("Could not read package.deprecated file. Abort deprecated import", slog.Any("err", err)) + return deprecates + } + + line, lines := lines[0], lines[1:] + for !strings.Contains(line, "#--- END OF EXAMPLES ---") { + line, lines = lines[0], lines[1:] + } + lines = lines[1:] + + return strings.Split(strings.Join(lines, "\n"), "\n\n") +} + +// Calculate all versions that are currently +// deprecated and update the DeprecatedToVersion Table +func CalculateDeprecatedToVersion() { + database.TruncateTable((*models.DeprecatedToVersion)(nil)) + + var deprecates []*models.DeprecatedPackage + err := database.DBCon.Model(&deprecates).Select() + if err != nil && err != pg.ErrNoRows { + slog.Error("Failed to retrieve package masks. Aborting update", slog.Any("err", err)) + return + } + + for _, deprecate := range deprecates { + versionSpecifier := deprecate.Versions + packageAtom := versionSpecifierToPackageAtom(versionSpecifier) + versions := utils.CalculateAffectedVersions(versionSpecifier, packageAtom) + + for _, version := range versions { + depToVersion := &models.DeprecatedToVersion{ + Id: versionSpecifier + "-" + version.Id, + DeprecatedVersions: versionSpecifier, + VersionId: version.Id, + } + + _, err := database.DBCon.Model(depToVersion).OnConflict("(id) DO UPDATE").Insert() + if err != nil { + slog.Error("Failed inserting/updating deprecated to version entry", slog.Any("err", err)) + } + } + } +} diff --git a/pkg/portage/repository/mask.go b/pkg/portage/repository/mask.go index 8a480b9..c6b500c 100644 --- a/pkg/portage/repository/mask.go +++ b/pkg/portage/repository/mask.go @@ -12,14 +12,17 @@ package repository import ( - "github.com/go-pg/pg/v9" + "log/slog" "regexp" + "soko/pkg/config" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" "soko/pkg/portage/utils" "strings" "time" + + "github.com/a-h/templ" + "github.com/go-pg/pg/v10" ) // isMask checks whether the path @@ -35,25 +38,25 @@ func UpdateMask(path string) { splittedLine := strings.Split(path, "\t") var status, changedFile string - if len(splittedLine) == 2 { + switch len(splittedLine) { + case 2: status = splittedLine[0] changedFile = splittedLine[1] - } else if len(splittedLine) == 1 { + case 1: // This happens in case of a full update status = "A" changedFile = splittedLine[0] - } else { + default: // should not happen return } if status != "D" && isMask(changedFile) { - - logger.Info.Println("Updating Masks") + slog.Info("Updating Masks") // delete all existing masks before parsing the file again // in future we might implement a incremental version here - deleteAllMasks() + database.TruncateTable((*models.Mask)(nil)) for _, packageMask := range getMasks(changedFile) { parsePackageMask(packageMask) @@ -61,6 +64,8 @@ func UpdateMask(path string) { } } +var versionNumber = regexp.MustCompile(`-[0-9]`) + // versionSpecifierToPackageAtom returns the package atom from a given version specifier func versionSpecifierToPackageAtom(versionSpecifier string) string { gpackage := strings.ReplaceAll(versionSpecifier, ">", "") @@ -69,9 +74,7 @@ func versionSpecifierToPackageAtom(versionSpecifier string) string { gpackage = strings.ReplaceAll(gpackage, "~", "") gpackage = strings.Split(gpackage, ":")[0] - - versionnumber := regexp.MustCompile(`-[0-9]`) - gpackage = versionnumber.Split(gpackage, 2)[0] + gpackage = versionNumber.Split(gpackage, 2)[0] return gpackage } @@ -79,10 +82,8 @@ func versionSpecifierToPackageAtom(versionSpecifier string) string { // parseAuthorLine parses the first line in the package.mask file // and returns the author name, author email and the date func parseAuthorLine(authorLine string) (string, string, time.Time) { - if !(strings.Contains(authorLine, "<") && strings.Contains(authorLine, ">")) { - logger.Error.Println("Error while parsing the author line in mask entry:") - logger.Error.Println(authorLine) + slog.Error("Error while parsing the author line in mask entry", slog.String("authorLine", authorLine)) return "", "", time.Now() } @@ -94,12 +95,15 @@ func parseAuthorLine(authorLine string) (string, string, time.Time) { date = strings.ReplaceAll(date, ")", "") parsedDate, err := time.Parse("2006-01-02", date) if err != nil { - logger.Error.Println("Error while parsing package mask date: " + date) - logger.Error.Println(err) + slog.Error("Failed parsing package mask date", slog.String("date", date), slog.Any("err", err)) } return author, authorEmail, parsedDate } +// based on regex from GLEP-0084 +var bugListMatcher = regexp.MustCompile(`[Bb]ugs? +#\d+(,? +#\d+)*`) +var bugReplacer = regexp.MustCompile(`#(\d+)`) + // parse the package.mask entries and // update the Mask table in the database func parsePackageMask(packageMask string) { @@ -108,29 +112,35 @@ func parsePackageMask(packageMask string) { packageMaskLine, packageMaskLines := packageMaskLines[0], packageMaskLines[1:] author, authorEmail, date := parseAuthorLine(packageMaskLine) - reason := "" + var reason string packageMaskLine, packageMaskLines = packageMaskLines[0], packageMaskLines[1:] for strings.HasPrefix(packageMaskLine, "#") { - reason = reason + " " + strings.Replace(packageMaskLine, "# ", "", 1) + if packageMaskLine == "#" { + reason += "<br />" + } else { + reason = reason + " " + templ.EscapeString(strings.TrimPrefix(packageMaskLine, "# ")) + } packageMaskLine, packageMaskLines = packageMaskLines[0], packageMaskLines[1:] } + reason = bugListMatcher.ReplaceAllStringFunc(reason, func(bugList string) string { + return bugReplacer.ReplaceAllString(bugList, `<a href="https://bugs.gentoo.org/$1">$0</a>`) + }) + packageMaskLines = append(packageMaskLines, packageMaskLine) for _, version := range packageMaskLines { - useflag := &models.Mask{ - Author: author, - AuthorEmail: authorEmail, + mask := &models.Mask{ + Author: strings.TrimSpace(author), + AuthorEmail: strings.TrimSpace(authorEmail), Date: date, - Reason: reason, + Reason: strings.TrimSpace(reason), Versions: version, } - _, err := database.DBCon.Model(useflag).OnConflict("(versions) DO UPDATE").Insert() - + _, err := database.DBCon.Model(mask).OnConflict("(versions) DO UPDATE").Insert() if err != nil { - logger.Error.Println("Error while inserting/updating package mask entry") - logger.Error.Println(err) + slog.Error("Failed inserting/updating package mask entry", slog.Any("err", err)) } } } @@ -140,11 +150,10 @@ func parsePackageMask(packageMask string) { // get all mask entries from the package.mask file func getMasks(path string) []string { var masks []string - lines, err := utils.ReadLines(path) + lines, err := utils.ReadLines(config.PortDir() + "/" + path) if err != nil { - logger.Error.Println("Could not read Masks file. Abort masks import") - logger.Error.Println(err) + slog.Error("Could not read Masks file. Abort masks import", slog.Any("err", err)) return masks } @@ -160,128 +169,26 @@ func getMasks(path string) []string { // Calculate all versions that are currently // masked and update the MaskToVersion Table func CalculateMaskedVersions() { - // clean up all masked versions before recalculating them - deleteAllMasksToVersion() + database.TruncateTable((*models.MaskToVersion)(nil)) var masks []*models.Mask err := database.DBCon.Model(&masks).Select() if err != nil && err != pg.ErrNoRows { - logger.Error.Println("Failed to retrieve package masks. Aborting update") - logger.Error.Println(err) + slog.Error("Failed to retrieve package masks. Aborting update", slog.Any("err", err)) + return } for _, mask := range masks { versionSpecifier := mask.Versions packageAtom := versionSpecifierToPackageAtom(versionSpecifier) - var versions []*models.Version - - if strings.HasPrefix(versionSpecifier, "=") { - versions = exaktVersion(versionSpecifier, packageAtom) - } else if strings.HasPrefix(versionSpecifier, "<=") { - versions = comparedVersions("<=", versionSpecifier, packageAtom) - } else if strings.HasPrefix(versionSpecifier, "<") { - versions = comparedVersions("<", versionSpecifier, packageAtom) - } else if strings.HasPrefix(versionSpecifier, ">=") { - versions = comparedVersions(">=", versionSpecifier, packageAtom) - } else if strings.HasPrefix(versionSpecifier, ">") { - versions = comparedVersions(">", versionSpecifier, packageAtom) - } else if strings.HasPrefix(versionSpecifier, "~") { - versions = allRevisions(versionSpecifier, packageAtom) - } else if strings.Contains(versionSpecifier, ":") { - versions = versionsWithSlot(versionSpecifier, packageAtom) - } else { - versions = allVersions(versionSpecifier, packageAtom) - } - + versions := utils.CalculateAffectedVersions(versionSpecifier, packageAtom) maskVersions(versionSpecifier, versions) } } -// comparedVersions computes and returns all versions that are >=, >, <= or < than then given version -func comparedVersions(operator string, versionSpecifier string, packageAtom string) []*models.Version { - var results []*models.Version - var versions []*models.Version - versionSpecifier = strings.ReplaceAll(versionSpecifier, operator, "") - versionSpecifier = strings.ReplaceAll(versionSpecifier, packageAtom+"-", "") - versionSpecifier = strings.Split(versionSpecifier, ":")[0] - - database.DBCon.Model(&versions). - Where("atom = ?", packageAtom). - Select() - - for _, v := range versions { - givenVersion := models.Version{Version: versionSpecifier} - if operator == ">" { - if v.GreaterThan(givenVersion) { - results = append(results, v) - } - } else if operator == ">=" { - if v.GreaterThan(givenVersion) || v.EqualTo(givenVersion) { - results = append(results, v) - } - } else if operator == "<" { - if v.SmallerThan(givenVersion) { - results = append(results, v) - } - } else if operator == "<=" { - if v.SmallerThan(givenVersion) || v.EqualTo(givenVersion) { - results = append(results, v) - } - } - } - return results -} - -// allRevisions returns all revisions of the given version -func allRevisions(versionSpecifier string, packageAtom string) []*models.Version { - var versions []*models.Version - revision := regexp.MustCompile(`-r[0-9]*$`) - versionWithoutRevision := revision.Split(versionSpecifier, 1)[0] - versionWithoutRevision = strings.ReplaceAll(versionWithoutRevision, "~", "") - database.DBCon.Model(&versions). - Where("id LIKE ?", versionWithoutRevision+"%"). - Select() - - return versions -} - -// exaktVersion returns the exact version specified in the versionSpecifier -func exaktVersion(versionSpecifier string, packageAtom string) []*models.Version { - var versions []*models.Version - database.DBCon.Model(&versions). - Where("id = ?", strings.Replace(versionSpecifier, "=", "", 1)). - Select() - - return versions -} - -// TODO include subslot -// versionsWithSlot returns all versions with the given slot -func versionsWithSlot(versionSpecifier string, packageAtom string) []*models.Version { - var versions []*models.Version - slot := strings.Split(versionSpecifier, ":")[1] - - database.DBCon.Model(&versions). - Where("atom = ?", packageAtom). - Where("slot = ?", slot). - Select() - - return versions -} - -// allVersions returns all versions of the given package -func allVersions(versionSpecifier string, packageAtom string) []*models.Version { - var versions []*models.Version - database.DBCon.Model(&versions). - Where("atom = ?", packageAtom). - Select() - return versions -} - // maskVersions updates the MaskToVersion table using the given versions func maskVersions(versionSpecifier string, versions []*models.Version) { - for _, version := range versions { maskToVersion := &models.MaskToVersion{ Id: versionSpecifier + "-" + version.Id, @@ -291,27 +198,8 @@ func maskVersions(versionSpecifier string, versions []*models.Version) { _, err := database.DBCon.Model(maskToVersion).OnConflict("(id) DO UPDATE").Insert() - if err != nil{ - logger.Error.Println("Error while inserting mask to version entry") - logger.Error.Println(err) + if err != nil { + slog.Error("Error while inserting mask to version entry", slog.Any("err", err)) } } } - -// deleteAllMasks deletes all entries in the mask table -func deleteAllMasksToVersion() { - var masks []*models.MaskToVersion - database.DBCon.Model(&masks).Select() - for _, mask := range masks { - database.DBCon.Model(mask).WherePK().Delete() - } -} - -// deleteAllMasks deletes all entries in the mask table -func deleteAllMasks() { - var masks []*models.Mask - database.DBCon.Model(&masks).Select() - for _, mask := range masks { - database.DBCon.Model(mask).WherePK().Delete() - } -} diff --git a/pkg/portage/repository/package.go b/pkg/portage/repository/package.go index b67888e..09c060e 100644 --- a/pkg/portage/repository/package.go +++ b/pkg/portage/repository/package.go @@ -4,12 +4,11 @@ package repository import ( "encoding/xml" - "io/ioutil" + "log/slog" "os" "regexp" "soko/pkg/config" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" "strings" ) @@ -17,93 +16,141 @@ import ( // isPackage checks whether the path points to a package // descriptions that is an metadata.xml file func isPackage(path string) bool { - isPackage, _ := regexp.MatchString(`[^/]*\/[^/]*\/metadata\.xml`, path) + isPackage, _ := regexp.MatchString(`^[^/]*\/[^/]*\/metadata\.xml$`, path) return isPackage } -// UpdatePackage updates the package in the database in case -// the given path points to a package description -func UpdatePackage(path string) { - - splittedLine := strings.Split(path, "\t") +// UpdatePackages updates the packages in the database for each +// given path that points to a package description +func UpdatePackages(paths []string) { + deleted := map[string]*models.Package{} + modified := map[string]*models.Package{} + + for _, path := range paths { + splittedLine := strings.Split(path, "\t") + + if len(splittedLine) != 2 { + if len(splittedLine) == 1 && isPackage(path) { + if pkg := updateModifiedPackage(path); pkg != nil { + modified[pkg.Atom] = pkg + } + } + continue + } - if len(splittedLine) != 2 { - if len(splittedLine) == 1 && isPackage(path) { - updateModifiedPackage(path) + status := splittedLine[0] + changedFile := splittedLine[1] + + if !isPackage(changedFile) { + continue + } else if status == "D" { + pkg := updateDeletedPackage(changedFile) + deleted[pkg.Atom] = pkg + } else if status == "A" || status == "M" { + if pkg := updateModifiedPackage(changedFile); pkg != nil { + modified[pkg.Atom] = pkg + } } - return } - status := splittedLine[0] - changedFile := splittedLine[1] + if len(deleted) > 0 { + rows := make([]*models.Package, 0, len(deleted)) + for _, row := range deleted { + rows = append(rows, row) + } + res, err := database.DBCon.Model(&rows).Delete() + if err != nil { + slog.Error("Failed deleting packages", slog.Any("err", err)) + } else { + slog.Info("Deleted packages", slog.Int("rows", res.RowsAffected())) + } + } - if isPackage(changedFile) && status == "D" { - updateDeletedPackage(changedFile) - } else if isPackage(changedFile) && (status == "A" || status == "M") { - updateModifiedPackage(changedFile) + if len(modified) > 0 { + rows := make([]*models.Package, 0, len(modified)) + for _, row := range modified { + rows = append(rows, row) + } + res, err := database.DBCon.Model(&rows).OnConflict("(atom) DO UPDATE"). + Set("atom = EXCLUDED.atom"). + Set("category = EXCLUDED.category"). + Set("name = EXCLUDED.name"). + Set("longdescription = EXCLUDED.longdescription"). + Set("maintainers = EXCLUDED.maintainers"). + Set("upstream = EXCLUDED.upstream"). + Insert() + if err != nil { + slog.Error("Failed updating packages", slog.Any("err", err)) + } else { + slog.Info("Updated packages", slog.Int("rows", res.RowsAffected())) + } } } // updateDeletedPackage deletes a package from the database -func updateDeletedPackage(changedFile string) { +func updateDeletedPackage(changedFile string) *models.Package { splitted := strings.Split(changedFile, "/") category := splitted[0] packagename := splitted[1] atom := category + "/" + packagename - gpackage := &models.Package{Atom: atom} - _, err := database.DBCon.Model(gpackage).WherePK().Delete() - - if err != nil { - logger.Error.Println("Error during deleting package " + atom) - logger.Error.Println(err) - } + return &models.Package{Atom: atom} } // updateModifiedPackage adds a package to the database or // updates it. To do so, it parses the metadata from metadata.xml -func updateModifiedPackage(changedFile string) { +func updateModifiedPackage(changedFile string) *models.Package { splitted := strings.Split(changedFile, "/") category := splitted[0] packagename := splitted[1] atom := category + "/" + packagename - pkgmetadata := GetPkgMetadata(config.PortDir() + "/" + atom + "/metadata.xml") - var maintainers []*models.Maintainer + xmlFile, err := os.Open(config.PortDir() + "/" + atom + "/metadata.xml") + if err != nil { + slog.Error("Failed reading package metadata", slog.String("atom", atom), slog.Any("err", err)) + return nil + } + defer xmlFile.Close() + var pkgMetadata PkgMetadata + err = xml.NewDecoder(xmlFile).Decode(&pkgMetadata) + if err != nil { + slog.Error("Failed decoding package metadata", slog.String("atom", atom), slog.Any("err", err)) + return nil + } - for _, maintainer := range pkgmetadata.MaintainerList { - maintainer := &models.Maintainer{ - Name: maintainer.Name, - Type: maintainer.Type, - Email: maintainer.Email, + maintainers := make([]*models.Maintainer, len(pkgMetadata.MaintainerList)) + for i, maintainer := range pkgMetadata.MaintainerList { + maintainers[i] = &models.Maintainer{ + Name: strings.TrimSpace(maintainer.Name), + Type: strings.TrimSpace(maintainer.Type), + Email: strings.TrimSpace(maintainer.Email), Restrict: maintainer.Restrict, } - maintainers = append(maintainers, maintainer) } - longDescription := "" - for _, l := range pkgmetadata.LongdescriptionList { - if l.Language == "" { + var longDescription string + for _, l := range pkgMetadata.LongDescriptionList { + if l.Language == "" || l.Language == "en" { longDescription = l.Content } } - remoteIds := []models.RemoteId{} - for _, r := range pkgmetadata.Upstream.RemoteIds { - remoteIds = append(remoteIds, models.RemoteId{ + remoteIds := make([]models.RemoteId, len(pkgMetadata.Upstream.RemoteIds)) + for i, r := range pkgMetadata.Upstream.RemoteIds { + remoteIds[i] = models.RemoteId{ Type: r.Type, Id: r.Content, - }) + } } upstream := models.Upstream{ RemoteIds: remoteIds, - Doc: pkgmetadata.Upstream.Doc, - BugsTo: pkgmetadata.Upstream.BugsTo, - Changelog: pkgmetadata.Upstream.Changelog, + Doc: pkgMetadata.Upstream.Doc, + BugsTo: pkgMetadata.Upstream.BugsTo, + Changelog: pkgMetadata.Upstream.Changelog, } - gpackage := &models.Package{ + return &models.Package{ Atom: atom, Category: category, Name: packagename, @@ -111,42 +158,14 @@ func updateModifiedPackage(changedFile string) { Maintainers: maintainers, Upstream: upstream, } - - _, err := database.DBCon.Model(gpackage).OnConflict("(atom) DO UPDATE"). - Set("atom = EXCLUDED.atom"). - Set("category = EXCLUDED.category"). - Set("name = EXCLUDED.name"). - Set("longdescription = EXCLUDED.longdescription"). - Set("maintainers = EXCLUDED.maintainers"). - Insert() - - if err != nil { - logger.Error.Println("Error during updating package " + atom) - logger.Error.Println(err) - } -} - -// GetPkgMetadata reads and parses the package -// metadata from the metadata.xml file -func GetPkgMetadata(path string) Pkgmetadata { - xmlFile, err := os.Open(path) - if err != nil { - logger.Error.Println("Error during reading package metadata") - logger.Error.Println(err) - } - defer xmlFile.Close() - byteValue, _ := ioutil.ReadAll(xmlFile) - var pkgmetadata Pkgmetadata - xml.Unmarshal(byteValue, &pkgmetadata) - return pkgmetadata } // Descriptions of the package metadata.xml format -type Pkgmetadata struct { +type PkgMetadata struct { XMLName xml.Name `xml:"pkgmetadata"` MaintainerList []Maintainer `xml:"maintainer"` - LongdescriptionList []LongdescriptionItem `xml:"longdescription"` + LongDescriptionList []LongDescriptionItem `xml:"longdescription"` Upstream Upstream `xml:"upstream"` } @@ -158,7 +177,7 @@ type Maintainer struct { Name string `xml:"name"` } -type LongdescriptionItem struct { +type LongDescriptionItem struct { XMLName xml.Name `xml:"longdescription"` Content string `xml:",chardata"` Language string `xml:"lang,attr"` diff --git a/pkg/portage/repository/use.go b/pkg/portage/repository/use.go index 5aa2798..a05e589 100644 --- a/pkg/portage/repository/use.go +++ b/pkg/portage/repository/use.go @@ -3,9 +3,9 @@ package repository import ( + "log/slog" "soko/pkg/config" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" "soko/pkg/portage/utils" "strings" @@ -15,18 +15,18 @@ import ( // case the given file contains USE flags descriptions and imports // each USE flag into the database func UpdateUse(path string) { - splittedLine := strings.Split(path, "\t") var status, changedFile string - if len(splittedLine) == 2 { + switch len(splittedLine) { + case 2: status = splittedLine[0] changedFile = splittedLine[1] - } else if len(splittedLine) == 1 { + case 1: // This happens in case of a full update status = "A" changedFile = splittedLine[0] - } else { + default: // should not happen return } @@ -34,28 +34,35 @@ func UpdateUse(path string) { if status != "D" && (isLocalUseflag(changedFile) || isGlobalUseflag(changedFile) || isUseExpand(changedFile)) { rawFlags, _ := utils.ReadLines(config.PortDir() + "/" + changedFile) + scope := getScope(changedFile) + useFlags := make(map[string]*models.Useflag, len(rawFlags)) for _, rawFlag := range rawFlags { - - if strings.TrimSpace(rawFlag) == "" || rawFlag[0:1] == "#" { + if strings.TrimSpace(rawFlag) == "" || rawFlag[0] == '#' { continue } - - scope := getScope(changedFile) - - var err error - if scope == "local" || scope == "global" { - err = createUseflag(rawFlag, scope) - } else if scope == "use_expand" { + switch scope { + case "local", "global": + if flag := createUseflag(rawFlag, scope); flag != nil { + useFlags[flag.Id] = flag + } + case "use_expand": file := strings.Split(changedFile, "/")[2] - err = createUseExpand(rawFlag, file) + flag := createUseExpand(rawFlag, file) + useFlags[flag.Id] = flag } + } + if len(useFlags) > 0 { + rows := make([]*models.Useflag, 0, len(useFlags)) + for _, row := range useFlags { + rows = append(rows, row) + } + res, err := database.DBCon.Model(&rows).OnConflict("(id) DO UPDATE").Insert() if err != nil { - logger.Info.Println("Error during updating useflag " + rawFlag) - logger.Info.Println(err) - logger.Error.Println("Error during updating useflag " + rawFlag) - logger.Error.Println(err) + slog.Error("Failed updating use flags", slog.Any("err", err)) + } else { + slog.Info("Updated use flags", slog.Int("rows", res.RowsAffected())) } } } @@ -64,46 +71,42 @@ func UpdateUse(path string) { // createUseflag parses the description from the file, // creates a USE flag and imports it into the database -func createUseflag(rawFlag string, scope string) error { - line := strings.Split(rawFlag, " - ") - splitted := strings.Split(line[0], ":") - gpackage := "" +func createUseflag(rawFlag string, scope string) *models.Useflag { + pkguse, description, found := strings.Cut(rawFlag, " - ") + if !found { + return nil + } - if scope == "local" { - gpackage = splitted[0] + pkg, use, found := strings.Cut(pkguse, ":") + if found != (scope == "local") { + return nil + } else if !found { + use = pkguse } - useflag := &models.Useflag{ - Id: line[0] + "-" + scope, - Package: gpackage, - Name: splitted[len(splitted)-1], + return &models.Useflag{ + Id: pkguse + "-" + scope, + Package: pkg, + Name: use, Scope: scope, - Description: strings.Join(line[1:], ""), + Description: description, } - - _, err := database.DBCon.Model(useflag).OnConflict("(id) DO UPDATE").Insert() - - return err } // createUseExpand parses the description from the file, // creates a USE expand flag and imports it into the database -func createUseExpand(rawFlag string, file string) error { - name := strings.ReplaceAll(file, ".desc", "") - line := strings.Split(rawFlag, " - ") - id := name + "_" + line[0] +func createUseExpand(rawFlag string, file string) *models.Useflag { + group := strings.TrimSuffix(file, ".desc") + unexpanded, description, _ := strings.Cut(rawFlag, " - ") + id := group + "_" + unexpanded - useExpand := &models.Useflag{ + return &models.Useflag{ Id: id, - Name: name + "_" + line[0], + Name: id, Scope: "use_expand", - Description: strings.Join(line[1:], ""), - UseExpand: name, + Description: description, + UseExpand: group, } - - _, err := database.DBCon.Model(useExpand).OnConflict("(id) DO UPDATE").Insert() - - return err } // getScope returns either "local", "global", "use_expand" diff --git a/pkg/portage/repository/version.go b/pkg/portage/repository/version.go index 4fbe33d..178a9d2 100644 --- a/pkg/portage/repository/version.go +++ b/pkg/portage/repository/version.go @@ -3,10 +3,10 @@ package repository import ( + "log/slog" "regexp" "soko/pkg/config" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" "soko/pkg/portage/utils" "strings" @@ -15,36 +15,71 @@ import ( // isVersion checks whether the path points to a package version // that is an .ebuild file func isVersion(path string) bool { - isVersion, _ := regexp.MatchString(`[^/]*\/[^/]*\/.*\.ebuild`, path) + isVersion, _ := regexp.MatchString(`^[^/]*\/[^/]*\/.*\.ebuild$`, path) return isVersion } -// UpdateVersion updates the version in the database in case -// the given path points to a package version -func UpdateVersion(path string) { +// UpdateVersions updates the versions in the database for each +// given path that points to a package version +func UpdateVersions(paths []string) { + deleted := map[string]*models.Version{} + modified := map[string]*models.Version{} - line := strings.Split(path, "\t") + for _, path := range paths { + line := strings.Split(path, "\t") - if len(line) != 2 { - if len(line) == 1 && isVersion(path) { - updateModifiedVersion(path) + if len(line) != 2 { + if len(line) == 1 && isVersion(path) { + ver := updateModifiedVersion(path) + modified[ver.Id] = ver + } + continue + } + + status := line[0] + changedFile := line[1] + + if !isVersion(changedFile) { + continue + } else if status == "D" { + ver := updateDeletedVersion(changedFile) + deleted[ver.Id] = ver + } else if status == "A" || status == "M" { + ver := updateModifiedVersion(changedFile) + modified[ver.Id] = ver } - return } - status := line[0] - changedFile := line[1] + if len(deleted) > 0 { + rows := make([]*models.Version, 0, len(deleted)) + for _, row := range deleted { + rows = append(rows, row) + } + res, err := database.DBCon.Model(&rows).Delete() + if err != nil { + slog.Error("Failed deleting versions", slog.Any("err", err)) + } else { + slog.Info("Deleted versions", slog.Int("rows", res.RowsAffected())) + } + } - if isVersion(changedFile) && status == "D" { - updateDeletedVersion(changedFile) - } else if isVersion(changedFile) && (status == "A" || status == "M") { - updateModifiedVersion(changedFile) + if len(modified) > 0 { + rows := make([]*models.Version, 0, len(modified)) + for _, row := range modified { + rows = append(rows, row) + } + res, err := database.DBCon.Model(&rows).OnConflict("(id) DO UPDATE").Insert() + if err != nil { + slog.Error("Failed updating versions", slog.Any("err", err)) + } else { + slog.Info("Updated versions", slog.Int("rows", res.RowsAffected())) + } } } // updateDeletedVersion deletes a package version from the database -func updateDeletedVersion(changedFile string) { - splitted := strings.Split(strings.ReplaceAll(changedFile, ".ebuild", ""), "/") +func updateDeletedVersion(changedFile string) *models.Version { + splitted := strings.Split(strings.TrimSuffix(changedFile, ".ebuild"), "/") category := splitted[0] packagename := splitted[1] version := strings.ReplaceAll(splitted[2], packagename+"-", "") @@ -52,19 +87,13 @@ func updateDeletedVersion(changedFile string) { atom := category + "/" + packagename id := atom + "-" + version - versionObject := &models.Version{Id: id} - _, err := database.DBCon.Model(versionObject).WherePK().Delete() - - if err != nil { - logger.Error.Println("Error during deleting version " + id) - logger.Error.Println(err) - } + return &models.Version{Id: id} } // updateModifiedVersion adds a package version to the database or // updates it. To do so, it parses the metadata from the md5-cache -func updateModifiedVersion(changedFile string) { - splitted := strings.Split(strings.ReplaceAll(changedFile, ".ebuild", ""), "/") +func updateModifiedVersion(changedFile string) *models.Version { + splitted := strings.Split(strings.TrimSuffix(changedFile, ".ebuild"), "/") category := splitted[0] packagename := splitted[1] version := strings.ReplaceAll(splitted[2], packagename+"-", "") @@ -76,56 +105,45 @@ func updateModifiedVersion(changedFile string) { slot := "0" subslot := "0" - eapi := "" - keywords := "" - var useflags []string - var restricts []string - var properties []string - var homepages []string - license := "" - description := "" + var eapi, keywords, license, description string + var useflags, restricts, properties, homepages []string for _, metadata := range version_metadata { - switch { case strings.HasPrefix(metadata, "EAPI="): - eapi = strings.ReplaceAll(metadata, "EAPI=", "") + eapi = strings.TrimPrefix(metadata, "EAPI=") case strings.HasPrefix(metadata, "KEYWORDS="): - keywords = strings.ReplaceAll(metadata, "KEYWORDS=", "") + keywords = strings.TrimPrefix(metadata, "KEYWORDS=") case strings.HasPrefix(metadata, "IUSE="): - useflags = strings.Split(strings.ReplaceAll(metadata, "IUSE=", ""), " ") + useflags = strings.Split(strings.TrimPrefix(metadata, "IUSE="), " ") case strings.HasPrefix(metadata, "RESTRICT="): - restricts = strings.Split(strings.ReplaceAll(strings.ReplaceAll(metadata, "RESTRICT=", ""), "!test? ( test )", ""), " ") + restricts = strings.Split(strings.ReplaceAll(strings.TrimPrefix(metadata, "RESTRICT="), "!test? ( test )", ""), " ") if len(restricts) == 1 && restricts[0] == "" { restricts = []string{} } case strings.HasPrefix(metadata, "PROPERTIES="): - properties = strings.Split(strings.ReplaceAll(metadata, "PROPERTIES=", ""), " ") + properties = strings.Split(strings.TrimPrefix(metadata, "PROPERTIES="), " ") case strings.HasPrefix(metadata, "HOMEPAGE="): - homepages = strings.Split(strings.ReplaceAll(metadata, "HOMEPAGE=", ""), " ") + homepages = strings.Split(strings.TrimPrefix(metadata, "HOMEPAGE="), " ") case strings.HasPrefix(metadata, "LICENSE="): - license = strings.ReplaceAll(metadata, "LICENSE=", "") + license = strings.TrimPrefix(metadata, "LICENSE=") case strings.HasPrefix(metadata, "DESCRIPTION="): - description = strings.ReplaceAll(metadata, "DESCRIPTION=", "") + description = strings.TrimPrefix(metadata, "DESCRIPTION=") case strings.HasPrefix(metadata, "SLOT="): - rawslot := strings.ReplaceAll(metadata, "SLOT=", "") - slot = strings.Split(rawslot, "/")[0] - if len(strings.Split(rawslot, "/")) > 1 { - subslot = strings.Split(rawslot, "/")[1] - } + rawSlot := strings.TrimPrefix(metadata, "SLOT=") + slot, subslot, _ = strings.Cut(rawSlot, "/") } - } - ebuildVersion := &models.Version{ + return &models.Version{ Id: id, Category: category, Package: packagename, @@ -142,11 +160,4 @@ func updateModifiedVersion(changedFile string) { License: license, Description: description, } - - _, err := database.DBCon.Model(ebuildVersion).OnConflict("(id) DO UPDATE").Insert() - - if err != nil { - logger.Error.Println("Error during updating version " + id) - logger.Error.Println(err) - } } diff --git a/pkg/portage/update.go b/pkg/portage/update.go index 551c5e8..8ad9187 100644 --- a/pkg/portage/update.go +++ b/pkg/portage/update.go @@ -3,11 +3,10 @@ package portage import ( - "io/ioutil" - "log" + "log/slog" + "os" "soko/pkg/config" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" "soko/pkg/portage/repository" "soko/pkg/portage/utils" @@ -20,73 +19,65 @@ import ( // this is the first update that is there is no last update a full import // starting with the first commit in the tree is done. func Update() { - database.Connect() defer database.DBCon.Close() - if config.Quiet() == "true" { - log.SetOutput(ioutil.Discard) - } - - logger.Info.Println("Start update...") + slog.Info("Start update...") // update the local useflags repository.UpdateUse("profiles/use.local.desc") - updateMetadata() - updatePackageData() + latestCommit := utils.GetLatestCommit() + changed := utils.ChangedFiles(latestCommit, "HEAD") + + updateMetadata(changed) + updatePackageData(changed) updateHistory() repository.CalculateMaskedVersions() - + repository.CalculateDeprecatedToVersion() } // updateMetadata updates all USE flags, package masks and arches in the database // by parsing: -// - profiles/use.desc -// - profiles/use.local.desc -// - profiles/use.local.desc -// - profiles/desc/* -// - profiles/package.mask -// - profiles/arch.list +// - profiles/use.desc +// - profiles/use.local.desc +// - profiles/use.local.desc +// - profiles/desc/* +// - profiles/package.mask +// - profiles/package.deprecated +// - profiles/arch.list // // It works incrementally so that files are only parsed and updated whenever the // file has been modified within the new commits. New commits are determined by // retrieving the last commit in the database (if present) and parsing all // following commits. In case no last commit is present a full import // starting with the first commit in the tree is done. -func updateMetadata() { - - logger.Info.Println("Start updating changed metadata") - - latestCommit := utils.GetLatestCommit() - - for _, path := range utils.ChangedFiles(latestCommit, "HEAD") { +func updateMetadata(changed []string) { + slog.Info("Start updating changed metadata") + slog.Info("Iterating changed files", slog.Int("count", len(changed))) + for _, path := range changed { repository.UpdateUse(path) repository.UpdateMask(path) + repository.UpdatePackagesDeprecated(path) repository.UpdateArch(path) } - } // updatePackageData incrementally updates all package data in the database, that has // been changed since the last update. That is: -// - categories -// - packages -// - versions +// - categories +// - packages +// - versions +// // changed data is determined by parsing all commits since the last update. -func updatePackageData() { - - logger.Info.Println("Start updating changed package data") - - latestCommit := utils.GetLatestCommit() - - for _, path := range utils.ChangedFiles(latestCommit, "HEAD") { - repository.UpdateVersion(path) - repository.UpdatePackage(path) - repository.UpdateCategory(path) - } +func updatePackageData(changed []string) { + slog.Info("Start updating changed package data") + slog.Info("Iterating changed files", slog.Int("count", len(changed))) + repository.UpdateVersions(changed) + repository.UpdatePackages(changed) + repository.UpdateCategories(changed) } // updateHistory incrementally imports all new commits. New commits are @@ -94,8 +85,7 @@ func updatePackageData() { // and parsing all following commits. In case no last commit is present // a full import starting with the first commit in the tree is done. func updateHistory() { - - logger.Info.Println("Start updating the history") + slog.Info("Start updating the history") latestCommit := repository.UpdateCommits() @@ -111,13 +101,9 @@ func updateHistory() { LastCommit: latestCommit, } - _, err := database.DBCon.Model(application). - OnConflict("(id) DO UPDATE"). - Insert() - + _, err := database.DBCon.Model(application).OnConflict("(id) DO UPDATE").Insert() if err != nil { - logger.Error.Println("Updating application data failed") - logger.Error.Println(err) + slog.Error("Failed updating application data", slog.Any("err", err)) } } @@ -132,108 +118,125 @@ func updateHistory() { // Once there is no outdated data found anymore this method may become // obsolete. func FullUpdate() { - database.Connect() defer database.DBCon.Close() - if config.Quiet() == "true" { - log.SetOutput(ioutil.Discard) - } - - logger.Info.Println("Full update up...") + slog.Info("Full update up...") // Add new entries & update existing - logger.Info.Println("Update all present files") + slog.Info("Update all present files") - // update the local useflags + // update useflags + database.TruncateTable((*models.Useflag)(nil)) + repository.UpdateUse("profiles/use.desc") repository.UpdateUse("profiles/use.local.desc") - - for _, path := range utils.AllFiles() { - repository.UpdateVersion(path) - repository.UpdatePackage(path) - repository.UpdateCategory(path) + if entries, err := os.ReadDir(config.PortDir() + "/profiles/desc"); err != nil { + slog.Error("Error reading profiles/desc", slog.Any("err", err)) + } else { + for _, entry := range entries { + repository.UpdateUse("profiles/desc/" + entry.Name()) + } } + allFiles := utils.AllFiles() + updateMetadata(allFiles) + repository.UpdateVersions(allFiles) + repository.UpdatePackages(allFiles) + repository.UpdateCategories(allFiles) + // Delete removed entries - logger.Info.Println("Delete removed files from the database") + slog.Info("Delete removed files from the database") deleteRemovedVersions() deleteRemovedPackages() deleteRemovedCategories() fixPrecedingCommitsOfPackages() - logger.Info.Println("Finished update up...") + repository.CalculateMaskedVersions() + repository.CalculateDeprecatedToVersion() + + slog.Info("Finished update up...") } // deleteRemovedVersions removes all versions from the database // that are present in the database but not in the main tree. func deleteRemovedVersions() { - var versions []*models.Version - database.DBCon.Model(&versions).Select() + var versions, toDelete []*models.Version + err := database.DBCon.Model(&versions).Column("id", "atom", "package", "version").Select() + if err != nil { + slog.Error("Failed fetching versions", slog.Any("err", err)) + return + } for _, version := range versions { path := config.PortDir() + "/" + version.Atom + "/" + version.Package + "-" + version.Version + ".ebuild" if !utils.FileExists(path) { - - logger.Error.Println("Found ebuild version in the database that does not exist at:") - logger.Error.Println(path) - - _, err := database.DBCon.Model(version).WherePK().Delete() - - if err != nil { - logger.Error.Println("Error deleting version " + version.Atom + " - " + version.Version) - logger.Error.Println(err) - } + slog.Error("Found ebuild version in the database that does not exist", slog.String("version", version.Id)) + toDelete = append(toDelete, version) } + } + if len(toDelete) > 0 { + res, err := database.DBCon.Model(&toDelete).Delete() + if err != nil { + slog.Error("Failed deleting versions", slog.Any("err", err)) + } else { + slog.Info("Deleted versions", slog.Int("rows", res.RowsAffected())) + } } } // deleteRemovedPackages removes all packages from the database // that are present in the database but not in the main tree. func deleteRemovedPackages() { - var packages []*models.Package - database.DBCon.Model(&packages).Select() - - for _, gpackage := range packages { - path := config.PortDir() + "/" + gpackage.Atom - if !utils.FileExists(path) { - - logger.Error.Println("Found package in the database that does not exist at:") - logger.Error.Println(path) - - _, err := database.DBCon.Model(gpackage).WherePK().Delete() + var packages, toDelete []*models.Package + err := database.DBCon.Model(&packages).Column("atom").Select() + if err != nil { + slog.Error("Failed fetching packages", slog.Any("err", err)) + return + } - if err != nil { - logger.Error.Println("Error deleting package " + gpackage.Atom) - logger.Error.Println(err) - } + for _, pkg := range packages { + if !utils.FileExists(config.PortDir() + "/" + pkg.Atom) { + slog.Error("Found package in the database that does not exist", slog.String("atom", pkg.Atom)) + toDelete = append(toDelete, pkg) } + } + if len(toDelete) > 0 { + res, err := database.DBCon.Model(&toDelete).Delete() + if err != nil { + slog.Error("Failed deleting packages", slog.Any("err", err)) + } else { + slog.Info("Deleted packages", slog.Int("rows", res.RowsAffected())) + } } } // deleteRemovedCategories removes all categories from the database // that are present in the database but not in the main tree. func deleteRemovedCategories() { - var categories []*models.Category - database.DBCon.Model(&categories).Select() + var categories, toDelete []*models.Category + err := database.DBCon.Model(&categories).Column("name").Select() + if err != nil { + slog.Error("Failed fetching categories", slog.Any("err", err)) + return + } for _, category := range categories { - path := config.PortDir() + "/" + category.Name - if !utils.FileExists(path) { - - logger.Error.Println("Found category in the database that does not exist at:") - logger.Error.Println(path) - - _, err := database.DBCon.Model(category).WherePK().Delete() - - if err != nil { - logger.Error.Println("Error deleting category " + category.Name) - logger.Error.Println(err) - } + if !utils.FileExists(config.PortDir() + "/" + category.Name) { + slog.Error("Found category in the database that does not exist", slog.String("name", category.Name)) + toDelete = append(toDelete, category) } + } + if len(toDelete) > 0 { + res, err := database.DBCon.Model(&toDelete).Delete() + if err != nil { + slog.Error("Failed deleting categories", slog.Any("err", err)) + } else { + slog.Info("Deleted categories", slog.Int("rows", res.RowsAffected())) + } } } @@ -245,15 +248,16 @@ func deleteRemovedCategories() { // packages' section. func fixPrecedingCommitsOfPackages() { var packages []*models.Package - database.DBCon.Model(&packages).Select() - for _, gpackage := range packages { - if gpackage.PrecedingCommits == 0 { - logger.Error.Println("Preceding Commits of package " + gpackage.Atom + " is null.") - logger.Error.Println("This should not happen. Preceding Commits will be set to 1") - gpackage.PrecedingCommits = 1 - database.DBCon.Model(gpackage).WherePK().Update() - } + database.DBCon.Model(&packages).Where("preceding_commits = 0").Select() + if len(packages) == 0 { + return + } + + slog.Error("Found packages with preceding commits == 0. This should not happen. Fixing...", slog.Int("count", len(packages))) + for _, pkg := range packages { + pkg.PrecedingCommits = 1 } + database.DBCon.Model(&packages).Update() } // GetApplicationData is used to retrieve the @@ -261,9 +265,9 @@ func fixPrecedingCommitsOfPackages() { func getApplicationData() models.Application { // Select user by primary key. applicationData := &models.Application{Id: "latest"} - err := database.DBCon.Select(applicationData) + err := database.DBCon.Model(applicationData).WherePK().Select() if err != nil { - logger.Error.Println("Error fetching application data") + slog.Error("Failed fetching application data", slog.Any("err", err)) return models.Application{ Id: "latest", LastUpdate: time.Now(), diff --git a/pkg/portage/utils/files.go b/pkg/portage/utils/files.go index c328cec..a0d0065 100644 --- a/pkg/portage/utils/files.go +++ b/pkg/portage/utils/files.go @@ -27,9 +27,6 @@ func ReadLines(path string) ([]string, error) { // FileExists checks whether the file // at the given path does exist func FileExists(path string) bool { - if _, err := os.Stat(path); err == nil { - return true - } else { - return false - } + _, err := os.Stat(path) + return err == nil } diff --git a/pkg/portage/utils/git.go b/pkg/portage/utils/git.go index 2f67c01..c576105 100644 --- a/pkg/portage/utils/git.go +++ b/pkg/portage/utils/git.go @@ -3,10 +3,10 @@ package utils import ( + "log/slog" "os/exec" "soko/pkg/config" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" "strings" ) @@ -23,8 +23,7 @@ func AllFiles() []string { cmd.Dir = config.PortDir() out, err := cmd.CombinedOutput() if err != nil { - logger.Error.Println("ERROR: cmd.Run() failed with:") - logger.Error.Println(err) + slog.Error("cmd.Run() failed", slog.Any("err", err)) return allFiles } @@ -45,7 +44,7 @@ func ChangedFiles(startCommit string, endCommit string) []string { cmd.Dir = config.PortDir() out, err := cmd.CombinedOutput() if err != nil { - logger.Error.Println("ERROR: cmd.Run() failed with %s\n", err) + slog.Error("cmd.Run() failed", slog.Any("err", err)) return changedFiles } @@ -56,10 +55,11 @@ func ChangedFiles(startCommit string, endCommit string) []string { // GetCommits returns the log message of all commits after // the given startCommit and before the given endCommit. The // log message: -// - uses '%Y-%m-%dT%H:%M:%S%z' as date format -// - doesn't include merges -// - doesn't include renames -// - includes the status of the changed files +// - uses '%Y-%m-%dT%H:%M:%S%z' as date format +// - doesn't include merges +// - doesn't include renames +// - includes the status of the changed files +// // Furthermore the commits are in reverse order. func GetCommits(startCommit string, endCommit string) []string { var commits []string @@ -76,7 +76,7 @@ func GetCommits(startCommit string, endCommit string) []string { cmd.Dir = config.PortDir() out, err := cmd.CombinedOutput() if err != nil { - logger.Error.Println("cmd.Run() failed with %s\n", err) + slog.Error("cmd.Run() failed", slog.Any("err", err)) return commits } @@ -87,14 +87,14 @@ func GetCommits(startCommit string, endCommit string) []string { // GetLatestCommit retrieves the latest commit in // the database and returns the hash of the commit func GetLatestCommit() string { - latestCommit, _ := GetLatestCommitAndPreceeding() + latestCommit, _ := GetLatestCommitAndPreceding() return latestCommit } -// GetLatestCommitAndPreceeding retrieves the latest +// GetLatestCommitAndPreceding retrieves the latest // commit in the database. The hash of the latest commit // as well as the number of preceding commits is returned -func GetLatestCommitAndPreceeding() (string, int) { +func GetLatestCommitAndPreceding() (string, int) { latestCommit := EmptyTree() PrecedingCommitsOffset := 0 diff --git a/pkg/portage/utils/misc.go b/pkg/portage/utils/misc.go deleted file mode 100644 index 3e4e79c..0000000 --- a/pkg/portage/utils/misc.go +++ /dev/null @@ -1,13 +0,0 @@ -// Contains miscellaneous utility functions - -package utils - -// Contains tells whether string a contains string x. -func Contains(a []string, x string) bool { - for _, n := range a { - if x == n { - return true - } - } - return false -} diff --git a/pkg/portage/utils/version.go b/pkg/portage/utils/version.go new file mode 100644 index 0000000..942bd53 --- /dev/null +++ b/pkg/portage/utils/version.go @@ -0,0 +1,145 @@ +package utils + +import ( + "regexp" + "soko/pkg/database" + "soko/pkg/models" + "strings" +) + +var ( + revision = regexp.MustCompile(`-r[0-9]*$`) +) + +func CalculateAffectedVersions(versionSpecifier, packageAtom string) []*models.Version { + if strings.HasPrefix(versionSpecifier, "=") { + return exactVersion(versionSpecifier, packageAtom) + } else if strings.HasPrefix(versionSpecifier, "<=") { + return comparedVersions("<=", versionSpecifier, packageAtom) + } else if strings.HasPrefix(versionSpecifier, "<") { + return comparedVersions("<", versionSpecifier, packageAtom) + } else if strings.HasPrefix(versionSpecifier, ">=") { + return comparedVersions(">=", versionSpecifier, packageAtom) + } else if strings.HasPrefix(versionSpecifier, ">") { + return comparedVersions(">", versionSpecifier, packageAtom) + } else if strings.HasPrefix(versionSpecifier, "~") { + return allRevisions(versionSpecifier, packageAtom) + } else if strings.Contains(versionSpecifier, ":") { + return versionsWithSlot(versionSpecifier, packageAtom) + } else { + return allVersions(versionSpecifier, packageAtom) + } +} + +// extract slot and subslot name from versionSpecifier +func slotAndSubslot(versionSpecifier string) (string, []string) { + version, fullslot, found := strings.Cut(versionSpecifier, ":") + if found { + return version, strings.SplitN(fullslot, "/", 2) + } else { + return version, nil + } +} + +// comparedVersions computes and returns all versions that are >=, >, <= or < than then given version +func comparedVersions(operator string, versionSpecifier string, packageAtom string) []*models.Version { + var results, versions []*models.Version + versionSpecifier = strings.ReplaceAll(versionSpecifier, operator, "") + versionSpecifier = strings.ReplaceAll(versionSpecifier, packageAtom+"-", "") + versionSpecifier, slots := slotAndSubslot(versionSpecifier) + + q := database.DBCon.Model(&versions). + Where("atom = ?", packageAtom) + if len(slots) >= 1 { + q = q.Where("slot = ?", slots[0]) + } + if len(slots) == 2 { + q = q.Where("subslot = ?", slots[1]) + } + q.Select() + + for _, v := range versions { + givenVersion := models.Version{Version: versionSpecifier} + if operator == ">" { + if v.GreaterThan(givenVersion) { + results = append(results, v) + } + } else if operator == ">=" { + if v.GreaterThan(givenVersion) || v.EqualTo(givenVersion) { + results = append(results, v) + } + } else if operator == "<" { + if v.SmallerThan(givenVersion) { + results = append(results, v) + } + } else if operator == "<=" { + if v.SmallerThan(givenVersion) || v.EqualTo(givenVersion) { + results = append(results, v) + } + } + } + return results +} + +// allRevisions returns all revisions of the given version +func allRevisions(versionSpecifier string, packageAtom string) []*models.Version { + var versions []*models.Version + versionSpecifier, slots := slotAndSubslot(versionSpecifier) + versionWithoutRevision := revision.Split(versionSpecifier, 1)[0] + versionWithoutRevision = strings.ReplaceAll(versionWithoutRevision, "~", "") + + q := database.DBCon.Model(&versions). + Where("id LIKE ?", versionWithoutRevision+"%") + if len(slots) >= 1 { + q = q.Where("slot = ?", slots[0]) + } + if len(slots) == 2 { + q = q.Where("subslot = ?", slots[1]) + } + q.Select() + + return versions +} + +// exactVersion returns the exact version specified in the versionSpecifier +func exactVersion(versionSpecifier string, packageAtom string) []*models.Version { + var versions []*models.Version + versionSpecifier, slots := slotAndSubslot(versionSpecifier) + + q := database.DBCon.Model(&versions). + Where("id = ?", strings.Replace(versionSpecifier, "=", "", 1)) + if len(slots) >= 1 { + q = q.Where("slot = ?", slots[0]) + } + if len(slots) == 2 { + q = q.Where("subslot = ?", slots[1]) + } + q.Select() + + return versions +} + +// versionsWithSlot returns all versions with the given slot +func versionsWithSlot(versionSpecifier string, packageAtom string) []*models.Version { + var versions []*models.Version + _, slots := slotAndSubslot(versionSpecifier) + + q := database.DBCon.Model(&versions). + Where("atom = ?", packageAtom). + Where("slot = ?", slots[0]) + if len(slots) == 2 { + q = q.Where("subslot = ?", slots[1]) + } + q.Select() + + return versions +} + +// allVersions returns all versions of the given package +func allVersions(versionSpecifier string, packageAtom string) []*models.Version { + var versions []*models.Version + database.DBCon.Model(&versions). + Where("atom = ?", packageAtom). + Select() + return versions +} diff --git a/pkg/selfcheck/check.go b/pkg/selfcheck/check.go index b3634b9..6d02548 100644 --- a/pkg/selfcheck/check.go +++ b/pkg/selfcheck/check.go @@ -1,34 +1,35 @@ package selfcheck import ( - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" + "log/slog" "soko/pkg/database" - "soko/pkg/logger" "soko/pkg/models" "soko/pkg/selfcheck/metrics" "soko/pkg/selfcheck/repository" "soko/pkg/selfcheck/storage" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" ) -func AllPackages(){ - logger.Info.Println("selfcheck: Preparing new check...") - logger.Info.Println("selfcheck: Updating selfcheck repository") +func AllPackages() { + slog.Info("selfcheck: Preparing new check...") + slog.Info("selfcheck: Updating selfcheck repository") repository.UpdateRepo() - logger.Info.Println("selfcheck: Importing data") + slog.Info("selfcheck: Importing data") repository.Import() - logger.Info.Println("selfcheck: Resetting metrics") + slog.Info("selfcheck: Resetting metrics") resetMetrics() - logger.Info.Println("selfcheck: Start check") + slog.Info("selfcheck: Start check") for _, category := range storage.Categories { - //logger.Info.Println("Checking " + category.Name) + //slog.Info("Checking " + category.Name) checkCategory(category) } - logger.Info.Println("selfcheck: Finished check") + slog.Info("selfcheck: Finished check") } -func resetMetrics(){ +func resetMetrics() { for _, metric := range metrics.MissingPackages { prometheus.Unregister(metric) } @@ -39,8 +40,7 @@ func resetMetrics(){ metrics.MissingVersions = map[string]prometheus.Gauge{} } - -func checkCategory(category *models.Category){ +func checkCategory(category *models.Category) { // create a client (safe to share across requests) database.Connect() @@ -53,9 +53,8 @@ func checkCategory(category *models.Category){ Relation("Packages.Versions"). Select() - if err != nil { - logger.Error.Println(err) + slog.Error("Failed fetching category", slog.Any("err", err), slog.Any("category", category.Name)) return } @@ -75,8 +74,8 @@ func checkCategory(category *models.Category){ metric.Set(1) } else { metrics.MissingPackages[localPackage.Atom] = promauto.NewGauge(prometheus.GaugeOpts{ - Name: "pgo_missing_package", - Help: "A package that is missing on packages.g.o although it's present in the tree", + Name: "pgo_missing_package", + Help: "A package that is missing on packages.g.o although it's present in the tree", ConstLabels: prometheus.Labels{"atom": localPackage.Atom}, }) metrics.MissingPackages[localPackage.Atom].Set(1) @@ -89,8 +88,7 @@ func checkCategory(category *models.Category){ } -func checkVersions(remotePackage *models.Package){ - +func checkVersions(remotePackage *models.Package) { for _, localVersion := range storage.Versions { @@ -99,7 +97,7 @@ func checkVersions(remotePackage *models.Package){ // search for local version in remote versions versionFound := false for _, remoteVersion := range remotePackage.Versions { - if localVersion.Id == remoteVersion.Id && localVersion.Id == remoteVersion.Id { + if localVersion.Id == remoteVersion.Id { versionFound = true break } @@ -110,8 +108,8 @@ func checkVersions(remotePackage *models.Package){ metric.Set(1) } else { metrics.MissingVersions[localVersion.Id] = promauto.NewGauge(prometheus.GaugeOpts{ - Name: "pgo_missing_version", - Help: "A version that is missing on packages.g.o although it's present in the tree", + Name: "pgo_missing_version", + Help: "A version that is missing on packages.g.o although it's present in the tree", ConstLabels: prometheus.Labels{"id": localVersion.Id}, }) metrics.MissingVersions[localVersion.Id].Set(1) @@ -123,4 +121,3 @@ func checkVersions(remotePackage *models.Package){ } } } - diff --git a/pkg/selfcheck/portage/category.go b/pkg/selfcheck/portage/category.go index 62ef93d..c9b49db 100644 --- a/pkg/selfcheck/portage/category.go +++ b/pkg/selfcheck/portage/category.go @@ -4,11 +4,11 @@ package repository import ( "encoding/xml" - "io/ioutil" + "io" + "log/slog" "os" "regexp" "soko/pkg/config" - "soko/pkg/logger" "soko/pkg/models" "soko/pkg/selfcheck/storage" "strings" @@ -29,14 +29,13 @@ func UpdateCategory(path string) { } } - // updateModifiedCategory adds a category to the database or // updates it. To do so, it parses the metadata from metadata.xml func updateModifiedCategory(changedFile string) { splitted := strings.Split(changedFile, "/") id := splitted[0] - catmetadata := GetCatMetadata(config.PortDir() + "/" + changedFile) + catmetadata := GetCatMetadata(config.SelfCheckPortDir() + "/" + changedFile) description := "" for _, longdescription := range catmetadata.Longdescriptions { @@ -51,7 +50,7 @@ func updateModifiedCategory(changedFile string) { }) } -func addCategory(category *models.Category){ +func addCategory(category *models.Category) { found := false for _, cat := range storage.Categories { if cat.Name == category.Name { @@ -69,11 +68,11 @@ func addCategory(category *models.Category){ func GetCatMetadata(path string) Catmetadata { xmlFile, err := os.Open(path) if err != nil { - logger.Error.Println("Error during reading category metadata") - logger.Error.Println(err) + slog.Error("Failed reading category metadata", slog.String("path", path), slog.Any("err", err)) + return Catmetadata{} } defer xmlFile.Close() - byteValue, _ := ioutil.ReadAll(xmlFile) + byteValue, _ := io.ReadAll(xmlFile) var catmetadata Catmetadata xml.Unmarshal(byteValue, &catmetadata) return catmetadata diff --git a/pkg/selfcheck/portage/mask.go b/pkg/selfcheck/portage/mask.go index 12e2f86..1d8fc53 100644 --- a/pkg/selfcheck/portage/mask.go +++ b/pkg/selfcheck/portage/mask.go @@ -12,8 +12,8 @@ package repository import ( + "log/slog" "regexp" - "soko/pkg/logger" "soko/pkg/models" "soko/pkg/portage/utils" "soko/pkg/selfcheck/storage" @@ -57,8 +57,7 @@ func versionSpecifierToPackageAtom(versionSpecifier string) string { func parseAuthorLine(authorLine string) (string, string, time.Time) { if !(strings.Contains(authorLine, "<") && strings.Contains(authorLine, ">")) { - logger.Error.Println("Error while parsing the author line in mask entry:") - logger.Error.Println(authorLine) + slog.Error("Error while parsing the author line in mask entry", slog.String("authorLine", authorLine)) return "", "", time.Now() } @@ -70,8 +69,7 @@ func parseAuthorLine(authorLine string) (string, string, time.Time) { date = strings.ReplaceAll(date, ")", "") parsedDate, err := time.Parse("2006-01-02", date) if err != nil { - logger.Error.Println("Error while parsing package mask date: " + date) - logger.Error.Println(err) + slog.Error("Failed parsing package mask date", slog.String("date", date), slog.Any("err", err)) } return author, authorEmail, parsedDate } @@ -115,8 +113,7 @@ func getMasks(path string) []string { lines, err := utils.ReadLines(path) if err != nil { - logger.Error.Println("Could not read Masks file. Abort masks import") - logger.Error.Println(err) + slog.Error("Could not read Masks file. Abort masks import", slog.Any("err", err)) return masks } @@ -171,7 +168,7 @@ func comparedVersions(operator string, versionSpecifier string, packageAtom stri versionSpecifier = strings.Split(versionSpecifier, ":")[0] for _, version := range storage.Versions { - if version.Atom == packageAtom { + if version.Atom == packageAtom { versions = append(versions, version) } } @@ -207,7 +204,7 @@ func allRevisions(versionSpecifier string, packageAtom string) []*models.Version versionWithoutRevision = strings.ReplaceAll(versionWithoutRevision, "~", "") for _, version := range storage.Versions { - if strings.HasPrefix(version.Id, versionWithoutRevision) { + if strings.HasPrefix(version.Id, versionWithoutRevision) { versions = append(versions, version) } } @@ -268,4 +265,4 @@ func maskVersions(mask *models.Mask, versions []*models.Version) { } } -}
\ No newline at end of file +} diff --git a/pkg/selfcheck/portage/package.go b/pkg/selfcheck/portage/package.go index 4e03724..ad011ff 100644 --- a/pkg/selfcheck/portage/package.go +++ b/pkg/selfcheck/portage/package.go @@ -4,11 +4,11 @@ package repository import ( "encoding/xml" - "io/ioutil" + "io" + "log/slog" "os" "regexp" "soko/pkg/config" - "soko/pkg/logger" "soko/pkg/models" "soko/pkg/selfcheck/storage" "strings" @@ -37,7 +37,7 @@ func updateModifiedPackage(changedFile string) { packagename := splitted[1] atom := category + "/" + packagename - pkgmetadata := GetPkgMetadata(config.PortDir() + "/" + atom + "/metadata.xml") + pkgmetadata := GetPkgMetadata(config.SelfCheckPortDir() + "/" + atom + "/metadata.xml") var maintainers []*models.Maintainer for _, maintainer := range pkgmetadata.MaintainerList { @@ -52,7 +52,7 @@ func updateModifiedPackage(changedFile string) { longDescription := "" for _, l := range pkgmetadata.LongdescriptionList { - if l.Language == "" { + if l.Language == "" || l.Language == "en" { longDescription = l.Content } } @@ -83,8 +83,7 @@ func updateModifiedPackage(changedFile string) { } - -func addPackage(newPackage *models.Package){ +func addPackage(newPackage *models.Package) { found := false for _, p := range storage.Packages { if p.Atom == newPackage.Atom { @@ -102,11 +101,11 @@ func addPackage(newPackage *models.Package){ func GetPkgMetadata(path string) Pkgmetadata { xmlFile, err := os.Open(path) if err != nil { - logger.Error.Println("Error during reading package metadata") - logger.Error.Println(err) + slog.Error("Failed reading package metadata", slog.String("path", path), slog.Any("err", err)) + return Pkgmetadata{} } defer xmlFile.Close() - byteValue, _ := ioutil.ReadAll(xmlFile) + byteValue, _ := io.ReadAll(xmlFile) var pkgmetadata Pkgmetadata xml.Unmarshal(byteValue, &pkgmetadata) return pkgmetadata diff --git a/pkg/selfcheck/portage/use.go b/pkg/selfcheck/portage/use.go index a47f543..21ea283 100644 --- a/pkg/selfcheck/portage/use.go +++ b/pkg/selfcheck/portage/use.go @@ -3,8 +3,8 @@ package repository import ( + "log/slog" "soko/pkg/config" - "soko/pkg/logger" "soko/pkg/models" "soko/pkg/portage/utils" "soko/pkg/selfcheck/storage" @@ -18,7 +18,7 @@ func UpdateUse(path string) { if isLocalUseflag(path) || isGlobalUseflag(path) || isUseExpand(path) { - rawFlags, _ := utils.ReadLines(config.PortDir() + "/" + path) + rawFlags, _ := utils.ReadLines(config.SelfCheckPortDir() + "/" + path) for _, rawFlag := range rawFlags { @@ -37,10 +37,7 @@ func UpdateUse(path string) { } if err != nil { - logger.Info.Println("Error during updating useflag " + rawFlag) - logger.Info.Println(err) - logger.Error.Println("Error during updating useflag " + rawFlag) - logger.Error.Println(err) + slog.Error("Failed updating useflag", slog.String("useflag", rawFlag), slog.Any("err", err)) } } } diff --git a/pkg/selfcheck/portage/version.go b/pkg/selfcheck/portage/version.go index 7018593..f71612f 100644 --- a/pkg/selfcheck/portage/version.go +++ b/pkg/selfcheck/portage/version.go @@ -40,7 +40,7 @@ func updateModifiedVersion(changedFile string) { atom := category + "/" + packagename id := atom + "-" + version - version_metadata, _ := utils.ReadLines(config.PortDir() + "/metadata/md5-cache/" + id) + version_metadata, _ := utils.ReadLines(config.SelfCheckPortDir() + "/metadata/md5-cache/" + id) slot := "0" subslot := "0" @@ -113,7 +113,7 @@ func updateModifiedVersion(changedFile string) { } -func addVersion(newVersion *models.Version){ +func addVersion(newVersion *models.Version) { found := false for _, v := range storage.Versions { if v.Id == newVersion.Id { diff --git a/pkg/selfcheck/serve.go b/pkg/selfcheck/serve.go index 857e6f6..7d5498b 100644 --- a/pkg/selfcheck/serve.go +++ b/pkg/selfcheck/serve.go @@ -1,29 +1,32 @@ package selfcheck import ( - "github.com/prometheus/client_golang/prometheus/promhttp" - "log" + "log/slog" "net/http" + "os" + + "github.com/prometheus/client_golang/prometheus/promhttp" + "soko/pkg/config" - "soko/pkg/logger" "soko/pkg/metrics" ) // Serve is used to serve the web application func Serve() { - // prometheus metrics http.Handle("/metrics", metricsHandler()) - logger.Info.Println("Serving on port: " + config.Port()) - log.Fatal(http.ListenAndServe(":"+config.Port(), nil)) - + address := ":" + config.Port() + slog.Info("Serving self-check", slog.String("address", address)) + err := http.ListenAndServe(address, nil) + slog.Error("exited server", "err", err) + os.Exit(1) } // metricsHandler is used as default middleware to update the metrics func metricsHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { metrics.Update() - promhttp.Handler().ServeHTTP(w,r) + promhttp.Handler().ServeHTTP(w, r) }) } @@ -2,13 +2,17 @@ package main import ( "flag" - "github.com/jasonlvhit/gocron" - "io" - "io/ioutil" + "log" + "log/slog" "os" + "time" + + "github.com/jasonlvhit/gocron" + "github.com/lmittmann/tint" + slogmulti "github.com/samber/slog-multi" + "soko/pkg/app" "soko/pkg/config" - "soko/pkg/logger" "soko/pkg/portage" "soko/pkg/portage/bugs" "soko/pkg/portage/dependencies" @@ -18,16 +22,10 @@ import ( "soko/pkg/portage/projects" "soko/pkg/portage/repology" "soko/pkg/selfcheck" - "time" ) func main() { - - waitForPostgres() - - errorLogFile := logger.CreateLogFile(config.LogFile()) - defer errorLogFile.Close() - initLoggers(os.Stdout, errorLogFile) + initLoggers() serve := flag.Bool("serve", false, "Start serving the application") selfchecks := flag.Bool("enable-selfchecks", false, "Perform selfchecks periodicals to monitor the consistency of the data") @@ -36,7 +34,7 @@ func main() { updateOutdatedPackages := flag.Bool("update-outdated-packages", false, "Update the repology.org data of outdated packages") updatePkgcheckResults := flag.Bool("update-pkgcheck-results", false, "Update the qa-reports that is the pkgcheck results") updatePullrequests := flag.Bool("update-pullrequests", false, "Update the pull requests") - initBugs := flag.Bool("init-bugs", false, "Import all bugs, including the old ones. This is usually just done once.") + flag.Bool("init-bugs", false, "Import all bugs, including the old ones. This is usually just done once.") updateBugs := flag.Bool("update-bugs", false, "Update the bugs belonging to the packages") updateDependencies := flag.Bool("update-dependencies", false, "Update the dependencies and reverse dependencies of the packages") updateProjects := flag.Bool("update-projects", false, "Update the project information") @@ -47,39 +45,36 @@ func main() { flag.Parse() if *selfchecks { - logger.Info.Println("Enabling periodical selfcheck") + slog.Info("Enabling periodical selfcheck") go runSelfChecks() selfcheck.Serve() } if *update { - logger.Info.Println("Updating package data") + slog.Info("Updating package data") portage.Update() } if *fullupdate { - logger.Info.Println("Performing full update of the package data") + slog.Info("Performing full update of the package data") portage.FullUpdate() } if *updateOutdatedPackages { - logger.Info.Println("Updating the repology data") + slog.Info("Updating the repology data") repology.UpdateOutdated() } if *updatePkgcheckResults { - logger.Info.Println("Updating the qa-reports that is the pkgcheck data") + slog.Info("Updating the qa-reports that is the pkgcheck data") pkgcheck.UpdatePkgCheckResults() } if *updatePullrequests { - logger.Info.Println("Updating the pull requests data") + slog.Info("Updating the pull requests data") github.FullUpdatePullRequests() } - if *initBugs { - bugs.UpdateBugs(true) - } if *updateBugs { - logger.Info.Println("Updating the bugs data") - bugs.UpdateBugs(false) + slog.Info("Updating the bugs data") + bugs.UpdateBugs() } if *updateDependencies { - logger.Info.Println("Updating the dependencies data") + slog.Info("Updating the dependencies data") dependencies.FullPackageDependenciesUpdate() } if *updateProjects { @@ -88,7 +83,7 @@ func main() { // updateMaintainers should always be executed last, as it is using // the updated bugs, pullrequests and and outdated packages if *updateMaintainers { - logger.Info.Println("Updating the maintainers data") + slog.Info("Updating the maintainers data") maintainers.FullImport() } @@ -99,26 +94,45 @@ func main() { if *help { flag.PrintDefaults() } - } // initialize the loggers depending on whether // config.debug is set to true -func initLoggers(infoHandler io.Writer, errorHandler io.Writer) { - if config.Debug() == "true" { - logger.Init(os.Stdout, infoHandler, errorHandler) - } else { - logger.Init(ioutil.Discard, infoHandler, errorHandler) +func initLoggers() { + errorHandler, err := os.OpenFile(config.LogFile(), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Println("failed to open error log file", config.LogFile(), "error:", err) + errorHandler = os.Stderr } -} -// TODO this has to be solved differently -// wait for postgres to come up -func waitForPostgres() { - time.Sleep(5 * time.Second) + var handler slog.Handler + if config.Debug() { + handler = tint.NewHandler(os.Stdout, &tint.Options{ + Level: slog.LevelDebug, + AddSource: true, + TimeFormat: time.DateTime, + }) + } else { + handler = slogmulti.Fanout( + tint.NewHandler(os.Stdout, &tint.Options{ + Level: slog.LevelInfo, + AddSource: true, + TimeFormat: time.DateTime, + NoColor: true, + }), + tint.NewHandler(errorHandler, &tint.Options{ + Level: slog.LevelError, + AddSource: true, + TimeFormat: time.DateTime, + NoColor: true, + }), + ) + } + slog.SetLogLoggerLevel(slog.LevelInfo) + slog.SetDefault(slog.New(handler)) } func runSelfChecks() { gocron.Every(1).Hour().From(gocron.NextTick()).Do(selfcheck.AllPackages) - <- gocron.Start() + <-gocron.Start() } diff --git a/web/packs/application.js b/web/packs/application.js index b4479bc..87bc08e 100644 --- a/web/packs/application.js +++ b/web/packs/application.js @@ -3,9 +3,7 @@ import "regenerator-runtime/runtime"; require("turbolinks").start(); import {} from 'jquery-ujs'; -import './src/vendor/javascripts/moment.min'; -import './src/javascript/arches'; import './src/javascript/kkuleomi'; import 'bootstrap'; diff --git a/web/packs/index.js b/web/packs/index.js index 3790f16..2064302 100644 --- a/web/packs/index.js +++ b/web/packs/index.js @@ -1,3 +1,3 @@ -import './src/vendor/javascripts/jquery.typeahead.min' +import 'jquery-typeahead/dist/jquery.typeahead.min.js' import './src/javascript/index/typeahead' import './src/javascript/index/query_generator' diff --git a/web/packs/packages.js b/web/packs/packages.js deleted file mode 100644 index cfdbfe1..0000000 --- a/web/packs/packages.js +++ /dev/null @@ -1 +0,0 @@ -import './src/javascript/packages/show'
\ No newline at end of file diff --git a/web/packs/src/javascript/arches.js b/web/packs/src/javascript/arches.js deleted file mode 100644 index dee720f..0000000 --- a/web/packs/src/javascript/arches.js +++ /dev/null @@ -1,2 +0,0 @@ -// Place all the behaviors and hooks related to the matching controller here. -// All this logic will automatically be available in application.js. diff --git a/web/packs/src/javascript/kkuleomi.js b/web/packs/src/javascript/kkuleomi.js index 3a01529..73e1bce 100644 --- a/web/packs/src/javascript/kkuleomi.js +++ b/web/packs/src/javascript/kkuleomi.js @@ -1,9 +1,3 @@ -$(document).on('ready page:load kkuleomi:ajax', function(event) { +$(document).on('ready page:load kkuleomi:ajax', function() { $('[data-toggle="tooltip"]').tooltip(); - - $('.kk-i18n-date').each(function(idx) { - // TODO: Support different date formats - var me = $(this); - me.text(moment.unix(me.data('utcts')).local().format('ddd, D MMM YYYY HH:mm')); - }); }); diff --git a/web/packs/src/javascript/packages/show.js b/web/packs/src/javascript/packages/show.js deleted file mode 100644 index 9f25fd5..0000000 --- a/web/packs/src/javascript/packages/show.js +++ /dev/null @@ -1,12 +0,0 @@ -// $(function() { -// var atom = $('#package-title').data('atom'); -// -// $.ajax({ -// url: '/packages/' + atom + '/changelog.html' -// }).done(function(data) { -// $('#changelog-container').html(data); -// $(document).trigger('kkuleomi:ajax'); -// }).fail(function() { -// $('#changelog-container > li').html('<span class="fa fa-fw fa-3x fa-ban text-danger"></span><br><br>Changelog currently not available. Please check back later.'); -// }); -// }); diff --git a/web/packs/src/stylesheets/application.scss b/web/packs/src/stylesheets/application.scss index 135491d..dd8228a 100644 --- a/web/packs/src/stylesheets/application.scss +++ b/web/packs/src/stylesheets/application.scss @@ -11,4 +11,4 @@ @import "sprockets-octicons"; @import "useflags"; -@import "../vendor/stylesheets/jquery.typeahead.min"; +@import "~jquery-typeahead/dist/jquery.typeahead.min" diff --git a/web/packs/src/stylesheets/misc.scss b/web/packs/src/stylesheets/misc.scss index 17c9f2e..df35790 100644 --- a/web/packs/src/stylesheets/misc.scss +++ b/web/packs/src/stylesheets/misc.scss @@ -146,7 +146,7 @@ td .alert { } } -body.kk .typeahead-list > li > a { +body.kk .typeahead__list > li > a { // Firefox workaround again white-space: normal; } @@ -304,4 +304,4 @@ input[type="checkbox"].user-pref-checkbox:checked + label, input[type="checkbox" .modal-content { width: 100%; } -}
\ No newline at end of file +} diff --git a/web/packs/src/vendor/javascripts/.keep b/web/packs/src/vendor/javascripts/.keep deleted file mode 100644 index e69de29..0000000 --- a/web/packs/src/vendor/javascripts/.keep +++ /dev/null diff --git a/web/packs/src/vendor/javascripts/d3.min.js b/web/packs/src/vendor/javascripts/d3.min.js deleted file mode 100644 index 6733ae4..0000000 --- a/web/packs/src/vendor/javascripts/d3.min.js +++ /dev/null @@ -1,5 +0,0 @@ -!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function r(n){return null===n?0/0:+n}function u(n){return!isNaN(n)}function i(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function c(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function l(){this._=Object.create(null)}function s(n){return(n+="")===pa||n[0]===va?va+n:n}function f(n){return(n+="")[0]===va?n.slice(1):n}function h(n){return s(n)in this._}function g(n){return(n=s(n))in this._&&delete this._[n]}function p(){var n=[];for(var t in this._)n.push(f(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function m(){this._=Object.create(null)}function y(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=da.length;r>e;++e){var u=da[e]+t;if(u in n)return u}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new l;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function S(){ta.event.preventDefault()}function k(){for(var n,t=ta.event;n=t.sourceEvent;)t=n;return t}function E(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=ta.event;u.target=n,ta.event=u,t[u.type].apply(e,r)}finally{ta.event=i}}},t}function A(n){return ya(n,_a),n}function N(n){return"function"==typeof n?n:function(){return Ma(n,this)}}function C(n){return"function"==typeof n?n:function(){return xa(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ta.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function q(n){return n.trim().replace(/\s+/g," ")}function L(n){return new RegExp("(?:^|\\s+)"+ta.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=T(n).map(D);var u=n.length;return"function"==typeof t?r:e}function D(n){var t=L(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",q(u+" "+n))):e.setAttribute("class",q(u.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e?t.createElementNS(e,n):t.createElement(n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ta.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return ba(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function Z(n){return ya(n,Sa),n}function V(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,ra(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+ta.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=$;a>0&&(n=n.slice(0,a));var l=ka.get(n);return l&&(n=l,c=B),a?t?u:r:t?b:i}function $(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Aa,u="click"+r,i=ta.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ea&&(Ea="onselectstart"in e?!1:x(e.style,"userSelect")),Ea){var o=n(e).style,a=o[Ea];o[Ea]="none"}return function(n){if(i.on(r,null),Ea&&(o[Ea]=a),n){var t=function(){i.on(u,null)};i.on(u,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var u=r.createSVGPoint();if(0>Na){var i=t(n);if(i.scrollX||i.scrollY){r=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Na=!(o.f||o.e),r.remove()}}return Na?(u.x=e.pageX,u.y=e.pageY):(u.x=e.clientX,u.y=e.clientY),u=u.matrixTransform(n.getScreenCTM().inverse()),[u.x,u.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ta.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nt(n){return n>1?0:-1>n?qa:Math.acos(n)}function tt(n){return n>1?Ra:-1>n?-Ra:Math.asin(n)}function et(n){return((n=Math.exp(n))-1/n)/2}function rt(n){return((n=Math.exp(n))+1/n)/2}function ut(n){return((n=Math.exp(2*n))-1)/(n+1)}function it(n){return(n=Math.sin(n/2))*n}function ot(){}function at(n,t,e){return this instanceof at?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof at?new at(n.h,n.s,n.l):bt(""+n,_t,at):new at(n,t,e)}function ct(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new mt(u(n+120),u(n),u(n-120))}function lt(n,t,e){return this instanceof lt?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof lt?new lt(n.h,n.c,n.l):n instanceof ft?gt(n.l,n.a,n.b):gt((n=wt((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new lt(n,t,e)}function st(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new ft(e,Math.cos(n*=Da)*t,Math.sin(n)*t)}function ft(n,t,e){return this instanceof ft?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof ft?new ft(n.l,n.a,n.b):n instanceof lt?st(n.h,n.c,n.l):wt((n=mt(n)).r,n.g,n.b):new ft(n,t,e)}function ht(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=pt(u)*Xa,r=pt(r)*$a,i=pt(i)*Ba,new mt(dt(3.2404542*u-1.5371385*r-.4985314*i),dt(-.969266*u+1.8760108*r+.041556*i),dt(.0556434*u-.2040259*r+1.0572252*i))}function gt(n,t,e){return n>0?new lt(Math.atan2(e,t)*Pa,Math.sqrt(t*t+e*e),n):new lt(0/0,0/0,n)}function pt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function vt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function dt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mt(n,t,e){return this instanceof mt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mt?new mt(n.r,n.g,n.b):bt(""+n,mt,ct):new mt(n,t,e)}function yt(n){return new mt(n>>16,n>>8&255,255&n)}function Mt(n){return yt(n)+""}function xt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function bt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(kt(u[0]),kt(u[1]),kt(u[2]))}return(i=Ga.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function _t(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new at(r,u,c)}function wt(n,t,e){n=St(n),t=St(t),e=St(e);var r=vt((.4124564*n+.3575761*t+.1804375*e)/Xa),u=vt((.2126729*n+.7151522*t+.072175*e)/$a),i=vt((.0193339*n+.119192*t+.9503041*e)/Ba);return ft(116*u-16,500*(r-u),200*(u-i))}function St(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function kt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function Et(n){return"function"==typeof n?n:function(){return n}}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return void o.error.call(i,r)}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!this.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(tc),tc=setTimeout(qt,t)),nc=0):(nc=1,rc(qt))}function Lt(){var n=Date.now();for(ec=Ka;ec;)n>=ec.t&&(ec.f=ec.c(n-ec.t)),ec=ec.n;return n}function Tt(){for(var n,t=Ka,e=1/0;t;)t.f?t=n?n.n=t.n:Ka=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Qa=n,e}function Rt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Dt(n,t){var e=Math.pow(10,3*ga(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:y;return function(n){var e=ic.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=oc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new cc(e-1)),1),e}function i(n,e){return t(n=new cc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{cc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{cc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{cc=jt;var r=new jt;return r._=t,n(r,e)._}finally{cc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(c,a)),null!=(u=sc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=N[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.slice(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&cc!==jt,o=new(i?jt:cc);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,l=e.length;c>a;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in sc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{cc=jt;var t=new cc;return t._=n,r(t)}finally{cc=Date}}var r=t(n);return e.parse=function(n){try{cc=jt;var t=r.parse(n);return t&&t._}finally{cc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=Yt(v),b=Zt(v),_=Yt(d),w=Zt(d),S=Yt(m),k=Zt(m),E=Yt(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return It(n.getDate(),t,2)},e:function(n,t){return It(n.getDate(),t,2)},H:function(n,t){return It(n.getHours(),t,2)},I:function(n,t){return It(n.getHours()%12||12,t,2)},j:function(n,t){return It(1+ac.dayOfYear(n),t,3)},L:function(n,t){return It(n.getMilliseconds(),t,3)},m:function(n,t){return It(n.getMonth()+1,t,2)},M:function(n,t){return It(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return It(n.getSeconds(),t,2)},U:function(n,t){return It(ac.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return It(ac.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return It(n.getFullYear()%100,t,2)},Y:function(n,t){return It(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function It(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Yt(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new l,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Vt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Xt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function $t(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Bt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Wt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.y=Gt(+r[0]),e+r[0].length):-1}function Jt(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Gt(n){return n+(n>68?1900:2e3)}function Kt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=ga(t)/60|0,u=ga(t)%60;return e+It(r,"0",2)+It(u,"0",2)}function oe(n,t,e){hc.lastIndex=0;var r=hc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ce(){}function le(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function se(n,t){n&&dc.hasOwnProperty(n.type)&&dc[n.type](n,t)}function fe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function he(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)fe(n[e],t,1);t.polygonEnd()}function ge(){function n(n,t){n*=Da,t=t*Da/2+qa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);yc.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;Mc.point=function(o,a){Mc.point=n,r=(t=o)*Da,u=Math.cos(a=(e=a)*Da/2+qa/4),i=Math.sin(a)},Mc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function xe(n){return[Math.atan2(n[1],n[0]),tt(n[2])]}function be(n,t){return ga(n[0]-t[0])<Ca&&ga(n[1]-t[1])<Ca}function _e(n,t){n*=Da;var e=Math.cos(t*=Da);we(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function we(n,t,e){++xc,_c+=(n-_c)/xc,wc+=(t-wc)/xc,Sc+=(e-Sc)/xc}function Se(){function n(n,u){n*=Da;var i=Math.cos(u*=Da),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),l=Math.atan2(Math.sqrt((l=e*c-r*a)*l+(l=r*o-t*c)*l+(l=t*a-e*o)*l),t*o+e*a+r*c);bc+=l,kc+=l*(t+(t=o)),Ec+=l*(e+(e=a)),Ac+=l*(r+(r=c)),we(t,e,r)}var t,e,r;qc.point=function(u,i){u*=Da;var o=Math.cos(i*=Da);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),qc.point=n,we(t,e,r)}}function ke(){qc.point=_e}function Ee(){function n(n,t){n*=Da;var e=Math.cos(t*=Da),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),l=u*c-i*a,s=i*o-r*c,f=r*a-u*o,h=Math.sqrt(l*l+s*s+f*f),g=r*o+u*a+i*c,p=h&&-nt(g)/h,v=Math.atan2(h,g);Nc+=p*l,Cc+=p*s,zc+=p*f,bc+=v,kc+=v*(r+(r=o)),Ec+=v*(u+(u=a)),Ac+=v*(i+(i=c)),we(r,u,i)}var t,e,r,u,i;qc.point=function(o,a){t=o,e=a,qc.point=n,o*=Da;var c=Math.cos(a*=Da);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),we(r,u,i)},qc.lineEnd=function(){n(t,e),qc.lineEnd=ke,qc.point=_e}}function Ae(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function Ne(){return!0}function Ce(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(be(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return void u.lineEnd()}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function qe(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Le(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function l(){y.point=o,d.lineEnd()}function s(n,t){v.push([n,t]);var e=u(n,t);x.point(e[0],e[1])}function f(){x.lineStart(),v=[]}function h(){s(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r)if(1&t){n=e[0];var u,r=n.length-1,o=-1;if(r>0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-Ra-Ca:Ra-n[1])-((t=t.x)[0]<0?t[1]-Ra-Ca:Ra-t[1])}function Pe(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?qa:-qa,c=ga(i-e);ga(c-qa)<Ca?(n.point(e,r=(r+o)/2>0?Ra:-Ra),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=qa&&(ga(e-u)<Ca&&(e-=u*Ca),ga(i-a)<Ca&&(i-=a*Ca),r=Ue(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function Ue(n,t,e,r){var u,i,o=Math.sin(n-e);return ga(o)>Ca?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function je(n,t,e,r){var u;if(null==n)u=e*Ra,r.point(-qa,u),r.point(0,u),r.point(qa,u),r.point(qa,0),r.point(qa,-u),r.point(0,-u),r.point(-qa,-u),r.point(-qa,0),r.point(-qa,u);else if(ga(n[0]-t[0])>Ca){var i=n[0]<t[0]?qa:-qa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Fe(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;yc.reset();for(var a=0,c=t.length;c>a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+qa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+qa/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>qa,k=p*M;if(yc.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*La:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*tt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ca>i||Ca>i&&0>yc)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?qa:-qa),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ca,p[1]+=Ca,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=ga(A-qa)<Ca,C=N||Ca>A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(ga(b[0]-w)<Ca?k:E):k<=b[1]&&b[1]<=E:A>qa^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:qa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ga(i)>Ca,c=gr(n,6*Da);return Le(t,e,c,o?[0,-n]:[-qa,n-qa])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ie(n,t,e,r){function u(r,u){return ga(r[0]-n)<Ca?u>0?0:3:ga(r[0]-e)<Ca?u>0?2:1:ga(r[1]-t)<Ca?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&Q(l,i,n)>0&&++t:i[1]<=r&&Q(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Tc,Math.min(Tc,n)),t=Math.max(-Tc,Math.min(Tc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ye(n){var t=0,e=qa/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*qa/180,e=n[1]*qa/180):[t/qa*180,e/qa*180]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,tt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Dc+=u*n-r*t,r=n,u=t}var t,e,r,u;Hc.point=function(i,o){Hc.point=n,t=r=i,e=u=o},Hc.lineEnd=function(){n(t,e)}}function Xe(n,t){Pc>n&&(Pc=n),n>jc&&(jc=n),Uc>t&&(Uc=t),t>Fc&&(Fc=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){_c+=n,wc+=t,++Sc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);kc+=o*(t+n)/2,Ec+=o*(e+r)/2,Ac+=o,We(t=n,e=r)}var t,e;Ic.point=function(r,u){Ic.point=n,We(t=r,e=u)}}function Ge(){Ic.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);kc+=o*(r+n)/2,Ec+=o*(u+t)/2,Ac+=o,o=u*n-r*t,Nc+=o*(r+n),Cc+=o*(u+t),zc+=3*o,We(r=n,u=t)}var t,e,r,u;Ic.point=function(i,o){Ic.point=n,We(t=r=i,e=u=o)},Ic.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,La)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c -},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=ga(ga(w)-1)<Ca||ga(r-h)<Ca?(r+h)/2:Math.atan2(_,b),A=n(E,k),N=A[0],C=A[1],z=N-t,q=C-e,L=M*z-y*q;(L*L/x>i||ga((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Da),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Pa,e*Pa])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Da,n[1]*Da),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Pa,n[1]*Pa]}function r(){a=Ae(o=lr(m,M,x),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,M=0,x=0,b=Lc,_=y,w=null,S=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(b(o,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Lc):He((w=+n)*Da),u()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Ie(n[0][0],n[0][1],n[1][0],n[1][1]):y,u()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Da,d=n[1]%360*Da,r()):[v*Pa,d*Pa]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Da,M=n[1]%360*Da,x=n.length>2?n[2]%360*Da:0,r()):[m*Pa,M*Pa,x*Pa]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Da,e*Da)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>qa?n-La:-qa>n?n+La:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>qa?t-La:-qa>t?t+La:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),tt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),tt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*La)):(u=n+o*La,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=nt(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ca)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(it(r-t)+u*o*it(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Pa,Math.atan2(o,Math.sqrt(r*r+u*u))*Pa]}:function(){return[n*Pa,t*Pa]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Da),o=Math.cos(u),a=ga((n*=Da)-t),c=Math.cos(a);Yc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Zc.point=function(u,i){t=u*Da,e=Math.sin(i*=Da),r=Math.cos(i),Zc.point=n},Zc.lineEnd=function(){Zc.point=Zc.lineEnd=b}}function br(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function _r(n,t){function e(n,t){o>0?-Ra+Ca>t&&(t=-Ra+Ca):t>Ra-Ca&&(t=Ra-Ca);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(qa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=K(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ra]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ga(u)<Ca?ar:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-K(u)*Math.sqrt(n*n+e*e)]},e)}function Sr(n,t){return[n,Math.log(Math.tan(qa/4+t/2))]}function kr(n){var t,e=ur(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=qa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Er(n,t){return[Math.log(Math.tan(qa/4+t/2)),-n]}function Ar(n){return n[0]}function Nr(n){return n[1]}function Cr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=el.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),Qc.remove(n),el.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&ga(e-c.circle.x)<Ca&&ga(r-c.circle.cy)<Ca;)i=c.P,a.unshift(c),Pr(c),c=i;a.unshift(c),Xr(c);for(var l=o;l.circle&&ga(e-l.circle.x)<Ca&&ga(r-l.circle.cy)<Ca;)o=l.N,a.push(l),Pr(l),l=o;a.push(l),Xr(l);var s,f=a.length;for(s=1;f>s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Qc._;a;)if(r=Fr(a,o)-i,r>Ca)a=a.L;else{if(u=i-Hr(a,o),!(u>Ca)){r>-Ca?(t=a.P,e=a):u>-Ca?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(Qc.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),Qc.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),void Vr(e);if(!e)return void(c.edge=Jr(t.site,c.site));Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Ir(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Kc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(ga(r-t)>Ca||ga(u-e)>Ca)&&(a.splice(o,0,new Qr(Gr(i.site,s,ga(r-f)<Ca&&p-u>Ca?{x:f,y:ga(t-f)<Ca?e:p}:ga(u-p)<Ca&&h-r>Ca?{x:ga(e-p)<Ca?t:h,y:p}:ga(r-h)<Ca&&u-g>Ca?{x:h,y:ga(t-h)<Ca?e:g}:ga(u-g)<Ca&&r-f>Ca?{x:ga(e-g)<Ca?t:f,y:g}:null),i.site,null)),++c)}function Yr(n,t){return t.angle-n.angle}function Zr(){tu(this),this.x=this.y=this.arc=this.site=this.cy=null}function Vr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,l=r.y-a,s=i.x-o,f=i.y-a,h=2*(c*f-l*s);if(!(h>=-za)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=rl.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=tl._;M;)if(m.y<M.y||m.y===M.y&&m.x<=M.x){if(!M.L){y=M.P;break}M=M.L}else{if(!M.R){y=M;break}M=M.R}tl.insert(y,m),y||(nl=m)}}}}function Xr(n){var t=n.circle;t&&(t.P||(nl=t.N),tl.remove(t),rl.push(t),tu(t),n.circle=null)}function $r(n){for(var t,e=Gc,r=Oe(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Br(t,n)||!r(t)||ga(t.a.x-t.b.x)<Ca&&ga(t.a.y-t.b.y)<Ca)&&(t.a=t.b=null,e.splice(u,1))}function Br(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],l=t[1][1],s=n.l,f=n.r,h=s.x,g=s.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.y<c)return}else i={x:d,y:l};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.y<c)return}else i={x:(l-u)/r,y:l};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Wr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Jr(n,t,e,r){var u=new Wr(n,t);return Gc.push(u),e&&Kr(u,n,t,e),r&&Kr(u,t,n,r),Kc[n.i].edges.push(new Qr(u,n,t)),Kc[t.i].edges.push(new Qr(u,t,n)),u}function Gr(n,t,e){var r=new Wr(n,null);return r.a=t,r.b=e,Gc.push(r),r}function Kr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Qr(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function nu(){this._=null}function tu(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function eu(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ru(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function uu(n){for(;n.L;)n=n.L;return n}function iu(n,t){var e,r,u,i=n.sort(ou).pop();for(Gc=[],Kc=new Array(n.length),Qc=new nu,tl=new nu;;)if(u=nl,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Kc[i.i]=new Or(i),jr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;Ur(u.arc)}t&&($r(t),Ir(t));var o={cells:Kc,edges:Gc};return Qc=tl=Gc=Kc=null,o}function ou(n,t){return t.y-n.y||t.x-n.x}function au(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function cu(n){return n.x}function lu(n){return n.y}function su(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function fu(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&fu(n,c[0],e,r,o,a),c[1]&&fu(n,c[1],o,r,u,a),c[2]&&fu(n,c[2],e,a,o,i),c[3]&&fu(n,c[3],o,a,u,i)}}function hu(n,t,e,r,u,i,o){var a,c=1/0;return function l(n,s,f,h,g){if(!(s>i||f>o||r>h||u>g)){if(p=n.point){var p,v=t-n.x,d=e-n.y,m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+xt(Math.round(e+i*n))+xt(Math.round(r+o*n))+xt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=il.lastIndex=ol.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=il.exec(n))&&(r=ol.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:vu(e,r)})),i=ol.lastIndex;return i<t.length&&(u=t.slice(i),a[o]?a[o]+=u:a[++o]=u),a.length<2?c[0]?(t=c[0].x,function(n){return t(n)+""}):function(){return t}:(t=c.length,function(n){for(var e,r=0;t>r;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(mu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*Ra)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/La*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*La/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=ta.hcl(n),t=ta.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return st(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ht(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Pa,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*Pa:0}function Uu(n,t){return n[0]*t[0]+n[1]*t[1]}function ju(n){var t=Math.sqrt(Uu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Fu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Hu(n,t){var e,r=[],u=[],i=ta.transform(n),o=ta.transform(t),a=i.translate,c=o.translate,l=i.rotate,s=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:vu(a[0],c[0])},{i:3,x:vu(a[1],c[1])})):r.push(c[0]||c[1]?"translate("+c+")":""),l!=s?(l-s>180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:vu(g[0],p[0])},{i:e-2,x:vu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Ou(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Iu(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Yu(n){for(var t=n.source,e=n.target,r=Vu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function Zu(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Vu(n,t){if(n===t)return n;for(var e=Zu(n),r=Zu(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Xu(n){n.fixed|=2}function $u(n){n.fixed&=-7}function Bu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Wu(n){n.fixed&=-5}function Ju(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Ju(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var l=t*e[n.point.index];n.charge+=n.pointCharge=l,r+=l*n.point.x,u+=l*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Gu(n,t){return ta.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=ri,n}function Ku(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(u=n.children)&&(r=u.length))for(var r,u;--r>=0;)e.push(u[r])}function Qu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++o<u;)e.push(i[o]);for(;null!=(n=r.pop());)t(n)}function ni(n){return n.children}function ti(n){return n.value}function ei(n,t){return t.value-n.value}function ri(n){return ta.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function ui(n){return n.x}function ii(n){return n.y}function oi(n,t,e){n.y0=t,n.y=e}function ai(n){return ta.range(n.length)}function ci(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function li(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Mi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?mi(r,u=a):mi(r=c,u),o--):(di(r,i),u=i,t(i))}var m=(s+f)/2,y=(h+g)/2,M=0;for(o=0;l>o;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)_i(u[i],t,e,r)}function wi(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),l=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+l*i,e.y=n.y+c*i-l*u}else e.x=n.x+r,e.y=n.y}function Si(n,t){return n.parent==t.parent?1:2}function ki(n){var t=n.children;return t.length?t[0]:n.t}function Ei(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ai(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Ni(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Fi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ml}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=ta.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Ii(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?Oi:ji,c=r?Iu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Du)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Ii(n,t,e,r)},u()}function Yi(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=ic.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(ga(r[0]),ga(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in yl?Math.abs(e-Bi(Math.max(ga(t[0]),ga(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Fi(r.map(u),e?Math:xl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++<s;)for(var h=f-1;h>0;h--)o.push(i(l)*h);for(l=0;o[l]<a;l++);for(s=o.length;o[s-1]>c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return Ml;arguments.length<2?t=Ml:"function"!=typeof t&&(t=ta.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Ji(n.copy(),t,e,r)},Yi(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Yi(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new l;for(var i,o=-1,a=r.length;++o<a;)u.has(i=r[o])||u.set(i,n.push(i));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(i=n,o=0,t={t:"range",a:arguments},e):i},e.rangePoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=(c+l)/2,0):(l-c)/(n.length-1+a);return i=r(c+s*a/2,s),o=0,t={t:"rangePoints",a:arguments},e},e.rangeRoundPoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=l=Math.round((c+l)/2),0):(l-c)/(n.length-1+a)|0;return i=r(c+Math.round(s*a/2+(l-c-(n.length-1+a)*s)/2),s),o=0,t={t:"rangeRoundPoints",a:arguments},e},e.rangeBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=(f-s)/(n.length-a+2*c);return i=r(s+h*c,h),l&&i.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=Math.floor((f-s)/(n.length-a+2*c));return i=r(s+Math.round((f-s-(n.length-a)*h)/2),h),l&&i.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Pi(t.a[0])},e.copy=function(){return Qi(n,t)},e.domain(n)}function no(n,t){function i(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=ta.quantile(n,e/r);return o}function o(n){return isNaN(n=+n)?void 0:t[ta.bisect(a,n)]}var a;return o.domain=function(t){return arguments.length?(n=t.map(r).filter(u).sort(e),i()):n},o.range=function(n){return arguments.length?(t=n,i()):t},o.quantiles=function(){return a},o.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?a[e-1]:n[0],e<a.length?a[e]:n[n.length-1]]},o.copy=function(){return no(n,t)},i()}function to(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return eo(n,t)},e}function ro(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=Et(e),p=Et(r);++f<h;)u.call(this,c=t[f],f)?s.push([+g.call(this,c,f),+p.call(this,c,f)]):s.length&&(o(),s=[]);return s.length&&o(),l.length?l.join(""):null}var e=Ar,r=Nr,u=Ne,i=go,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=El.get(n)||go).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function go(n){return n.join("L")}function po(n){return go(n)+"Z"}function vo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function mo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function yo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function Mo(n,t){return n.length<4?go(n):n[1]+_o(n.slice(1,-1),wo(n,t))}function xo(n,t){return n.length<3?go(n):n[0]+_o((n.push(n[0]),n),wo([n[n.length-2]].concat(n,[n[1]]),t))}function bo(n,t){return n.length<3?go(n):n[0]+_o(n,wo(n,t))}function _o(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return go(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l<t.length;l++,c++)i=n[c],a=t[l],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var s=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+s[0]+","+s[1]}return r}function wo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function So(n){if(n.length<3)return go(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",No(Cl,o),",",No(Cl,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Co(c,o,a);return n.pop(),c.push("L",r),c.join("")}function ko(n){if(n.length<4)return go(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(No(Cl,i)+","+No(Cl,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),Co(e,i,o);return e.join("")}function Eo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[No(Cl,o),",",No(Cl,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Co(t,o,a);return t.join("")}function Ao(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,l=-1;++l<=e;)r=n[l],u=l/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return So(n)}function No(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Co(n,t,e){n.push("C",No(Al,t),",",No(Al,e),",",No(Nl,t),",",No(Nl,e),",",No(Cl,t),",",No(Cl,e))}function zo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function qo(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=zo(u,i);++t<e;)r[t]=(o+(o=zo(u=i,i=n[t+1])))/2;return r[t]=o,r}function Lo(n){for(var t,e,r,u,i=[],o=qo(n),a=-1,c=n.length-1;++a<c;)t=zo(n[a],n[a+1]),ga(t)<Ca?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]-Ra,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Do(n){function t(t){function c(){v.push("M",a(n(m),f),s,l(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,M=t.length,x=Et(e),b=Et(u),_=e===r?function(){return g}:Et(r),w=u===i?function(){return p}:Et(i);++y<M;)o.call(this,h=t[y],y)?(d.push([g=+x.call(this,h,y),p=+b.call(this,h,y)]),m.push([+_.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=Ar,r=Ar,u=0,i=Nr,o=Ne,a=go,c=a.key,l=a,s="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r -},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=El.get(n)||go).key,l=a.reverse||a,s=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function Po(n){return n.radius}function Uo(n){return[n.x,n.y]}function jo(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]-Ra;return[e*Math.cos(r),e*Math.sin(r)]}}function Fo(){return 64}function Ho(){return"circle"}function Oo(n){var t=Math.sqrt(n/qa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Io(n){return function(){var t,e;(t=this[n])&&(e=t[t.active])&&(--t.count?delete t[t.active]:delete this[n],t.active+=.5,e.event&&e.event.interrupt.call(this,this.__data__,e.index))}}function Yo(n,t,e){return ya(n,Pl),n.namespace=t,n.id=e,n}function Zo(n,t,e,r){var u=n.id,i=n.namespace;return Y(n,"function"==typeof e?function(n,o,a){n[i][u].tween.set(t,r(e.call(n,n.__data__,o,a)))}:(e=r(e),function(n){n[i][u].tween.set(t,e)}))}function Vo(n){return null==n&&(n=""),function(){this.textContent=n}}function Xo(n){return null==n?"__transition__":"__transition_"+n+"__"}function $o(n,t,e,r,u){var i=n[e]||(n[e]={active:0,count:0}),o=i[r];if(!o){var a=u.time;o=i[r]={tween:new l,time:a,delay:u.delay,duration:u.duration,ease:u.ease,index:t},u=null,++i.count,ta.timer(function(u){function c(e){if(i.active>r)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,a)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=ec,v=[];return p.t=g+a,u>=g?c(u-g):void(p.c=c)},0,a)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Vl,u);return i==Vl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Vl[i-1]<Vl[i]/u?i-1:i]:[Bl,Vi(n,e)[2]]}return r.invert=function(t){return Ko(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Ko)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Ko(+e+1),t).length}var i=r.domain(),o=Pi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Fi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Yi(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.6"},ea=[].slice,ra=function(n){return ea.call(n)},ua=this.document;if(ua)try{ra(ua.documentElement.childNodes)[0].nodeType}catch(ia){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),ua)try{ua.createElement("DIV").style.setProperty("opacity",0,"")}catch(oa){var aa=this.Element.prototype,ca=aa.setAttribute,la=aa.setAttributeNS,sa=this.CSSStyleDeclaration.prototype,fa=sa.setProperty;aa.setAttribute=function(n,t){ca.call(this,n,t+"")},aa.setAttributeNS=function(n,t,e){la.call(this,n,t,e+"")},sa.setProperty=function(n,t,e){fa.call(this,n,t+"",e)}}ta.ascending=e,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o;)if(null!=(r=n[i])&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var e,r=0,i=n.length,o=-1;if(1===arguments.length)for(;++o<i;)u(e=+n[o])&&(r+=e);else for(;++o<i;)u(e=+t.call(n,n[o],o))&&(r+=e);return r},ta.mean=function(n,t){var e,i=0,o=n.length,a=-1,c=o;if(1===arguments.length)for(;++a<o;)u(e=r(n[a]))?i+=e:--c;else for(;++a<o;)u(e=r(t.call(n,n[a],a)))?i+=e:--c;return c?i/c:void 0},ta.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},ta.median=function(n,t){var i,o=[],a=n.length,c=-1;if(1===arguments.length)for(;++c<a;)u(i=r(n[c]))&&o.push(i);else for(;++c<a;)u(i=r(t.call(n,n[c],c)))&&o.push(i);return o.length?ta.quantile(o.sort(e),.5):void 0},ta.variance=function(n,t){var e,i,o=n.length,a=0,c=0,l=-1,s=0;if(1===arguments.length)for(;++l<o;)u(e=r(n[l]))&&(i=e-a,a+=i/++s,c+=i*(e-a));else for(;++l<o;)u(e=r(t.call(n,n[l],l)))&&(i=e-a,a+=i/++s,c+=i*(e-a));return s>1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var ha=i(e);ta.bisectLeft=ha.left,ta.bisect=ta.bisectRight=ha.right,ta.bisector=function(n){return i(1===n.length?function(t,r){return e(n(t),r)}:n)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=Math.random()*i--|0,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,o),e=new Array(t);++n<t;)for(var r,u=-1,i=e[n]=new Array(r);++u<r;)i[u]=arguments[u][n];return e},ta.transpose=function(n){return ta.zip.apply(ta,n)},ta.keys=function(n){var t=[];for(var e in n)t.push(e);return t},ta.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},ta.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},ta.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ga=Math.abs;ta.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,u=[],i=a(ga(e)),o=-1;if(n*=i,t*=i,e*=i,0>e)for(;(r=n+e*++o)>t;)u.push(r/i);else for(;(r=n+e*++o)<t;)u.push(r/i);return u},ta.map=function(n,t){var e=new l;if(n instanceof l)n.forEach(function(n,t){e.set(n,t)});else if(Array.isArray(n)){var r,u=-1,i=n.length;if(1===arguments.length)for(;++u<i;)e.set(u,n[u]);else for(;++u<i;)e.set(t.call(n,r=n[u],u),r)}else for(var o in n)e.set(o,n[o]);return e};var pa="__proto__",va="\x00";c(l,{has:h,get:function(n){return this._[s(n)]},set:function(n,t){return this._[s(n)]=t},remove:g,keys:p,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:f(t),value:this._[t]});return n},size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t),this._[t])}}),ta.nest=function(){function n(t,o,a){if(a>=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var c,s,f,h,g=-1,p=o.length,v=i[a++],d=new l;++g<p;)(h=d.get(c=v(s=o[g])))?h.push(s):d.set(c,[s]);return t?(s=t(),f=function(e,r){s.set(e,n(t,r,a))}):(s={},f=function(e,r){s[e]=n(t,r,a)}),d.forEach(f),s}function t(n,e){if(e>=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new m;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},c(m,{has:h,add:function(n){return this._[s(n+="")]=!0,n},remove:g,values:p,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=M(n,t,t[e]);return n};var da=["webkit","ms","moz","Moz","o","O"];ta.dispatch=function(){for(var n=new _,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=w(n);return n},_.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ta.event=null,ta.requote=function(n){return n.replace(ma,"\\$&")};var ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ya={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},Ma=function(n,t){return t.querySelector(n)},xa=function(n,t){return t.querySelectorAll(n)},ba=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(ba=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(Ma=function(n,t){return Sizzle(n,t)[0]||null},xa=Sizzle,ba=Sizzle.matchesSelector),ta.selection=function(){return ta.select(ua.documentElement)};var _a=ta.selection.prototype=[];_a.select=function(n){var t,e,r,u,i=[];n=N(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,l=r.length;++c<l;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return A(i)},_a.selectAll=function(n){var t,e,r=[];n=C(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=ra(n.call(e,e.__data__,a,u))),t.parentNode=e);return A(r)};var wa={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};ta.ns={prefix:wa,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.slice(0,t),n=n.slice(t+1)),wa.hasOwnProperty(e)?{space:wa[e],local:n}:n}},_a.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},_a.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!L(n[u]).test(t))return!1;return!0}for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},_a.style=function(n,e,r){var u=arguments.length;if(3>u){if("string"!=typeof n){2>u&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>u){var i=this.node();return t(i).getComputedStyle(i,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},_a.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},_a.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},_a.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},_a.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},_a.insert=function(n,t){return n=j(n),t=N(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},_a.remove=function(){return this.each(F)},_a.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new l,y=new Array(o);for(r=-1;++r<o;)m.has(d=t.call(u=n[r],u.__data__,r))?v[r]=u:m.set(d,u),y[r]=d;for(r=-1;++r<f;)(u=m.get(d=t.call(e,i=e[r],r)))?u!==!0&&(g[r]=u,u.__data__=i):p[r]=H(i),m.set(d,!0);for(r=-1;++r<o;)m.get(y[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],i=e[r],u?(u.__data__=i,g[r]=u):p[r]=H(i);for(;f>r;++r)p[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,a.push(p),c.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++i<o;)(u=r[i])&&(n[i]=u.__data__);return n}var a=Z([]),c=A([]),s=A([]);if("function"==typeof n)for(;++i<o;)e(r=this[i],n.call(r,r.parentNode.__data__,i));else for(;++i<o;)e(r=this[i],n);return c.enter=function(){return a},c.exit=function(){return s},c},_a.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},_a.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return A(u)},_a.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},_a.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},_a.each=function(n){return Y(this,function(t,e,r){n.call(t,t.__data__,e,r)})},_a.call=function(n){var t=ra(arguments);return n.apply(t[0]=this,t),this},_a.empty=function(){return!this.node()},_a.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},_a.size=function(){var n=0;return Y(this,function(){++n}),n};var Sa=[];ta.selection.enter=Z,ta.selection.enter.prototype=Sa,Sa.append=_a.append,Sa.empty=_a.empty,Sa.node=_a.node,Sa.call=_a.call,Sa.size=_a.size,Sa.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var l=-1,s=u.length;++l<s;)(i=u[l])?(t.push(r[l]=e=n.call(u.parentNode,i.__data__,l,a)),e.__data__=i.__data__):t.push(null)}return A(o)},Sa.insert=function(n,t){return arguments.length<2&&(t=V(this)),_a.insert.call(this,n,t)},ta.select=function(t){var e;return"string"==typeof t?(e=[Ma(t,ua)],e.parentNode=ua.documentElement):(e=[t],e.parentNode=n(t)),A([e])},ta.selectAll=function(n){var t;return"string"==typeof n?(t=ra(xa(n,ua)),t.parentNode=ua.documentElement):(t=n,t.parentNode=null),A([t])},_a.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var ka=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});ua&&ka.forEach(function(n){"on"+n in ua&&ka.remove(n)});var Ea,Aa=0;ta.mouse=function(n){return J(n,k())};var Na=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return J(n,r)},ta.behavior.drag=function(){function n(){this.on("mousedown.drag",i).on("touchstart.drag",o)}function e(n,t,e,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=r.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(e(f)).on(i+d,a).on(o+d,c),y=W(f),M=t(h,v);u?(l=u.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var r=E(n,"drag","dragstart","dragend"),u=null,i=e(b,ta.mouse,t,"mousemove","mouseup"),o=e(G,ta.touch,y,"touchmove","touchend");return n.origin=function(t){return arguments.length?(u=t,n):u},ta.rebind(n,r,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?ra(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Ca=1e-6,za=Ca*Ca,qa=Math.PI,La=2*qa,Ta=La-Ca,Ra=qa/2,Da=qa/180,Pa=180/qa,Ua=Math.SQRT2,ja=2,Fa=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=rt(v),o=i/(ja*h)*(e*ut(Ua*t+v)-et(v));return[r+o*l,u+o*s,i*e/rt(Ua*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Ua*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Fa*f)/(2*i*ja*h),p=(c*c-i*i-Fa*f)/(2*c*ja*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ua;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(q,f).on(Oa+".zoom",g).on("dblclick.zoom",p).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function u(n){k.k=Math.max(N[0],Math.min(N[1],n))}function i(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},u(Math.pow(2,o)),i(d=e,r),t=ta.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function c(n){z++||n({type:"zoomstart"})}function l(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function s(n){--z||(n({type:"zoomend"}),d=null)}function f(){function n(){f=1,i(ta.mouse(u),g),l(a)}function r(){h.on(L,null).on(T,null),p(f&&ta.event.target===o),s(a)}var u=this,o=ta.event.target,a=D.of(u,arguments),f=0,h=ta.select(t(u)).on(L,n).on(T,r),g=e(ta.mouse(u)),p=W(u);Dl.call(u),c(a)}function h(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ta.event.target;ta.select(t).on(x,r).on(b,a),_.push(t);for(var e=ta.event.changedTouches,u=0,i=e.length;i>u;++u)d[e[u].identifier]=null;var c=n(),l=Date.now();if(1===c.length){if(500>l-M){var s=c[0];o(p,s,d[s.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=l}else if(c.length>1){var s=c[0],f=c[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function r(){var n,t,e,r,o=ta.touches(p);Dl.call(p);for(var a=0,c=o.length;c>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],u(f*g)}M=null,i(n,t),l(v)}function a(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(_).on(y,null),w.on(q,f).on(R,h),E(),s(v)}var g,p=this,v=D.of(p,arguments),d={},m=0,y=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+y,b="touchend"+y,_=[],w=ta.select(p),E=W(p);t(),c(v),w.on(q,null).on(R,t)}function g(){var n=D.of(this,arguments);y?clearTimeout(y):(Dl.call(this),v=e(d=m||ta.mouse(this)),c(n)),y=setTimeout(function(){y=null,s(n)},50),S(),u(Math.pow(2,.002*Ha())*k.k),i(d,v),l(n)}function p(){var n=ta.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ta.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,m,y,M,x,b,_,w,k={x:0,y:0,k:1},A=[960,500],N=Ia,C=250,z=0,q="mousedown.zoom",L="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=E(n,"zoomstart","zoom","zoomend");return Oa||(Oa="onwheel"in ua?(Ha=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Ha=function(){return ta.event.wheelDelta},"mousewheel"):(Ha=function(){return-ta.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Tl?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},c(n)}).tween("zoom:zoom",function(){var e=A[0],r=A[1],u=d?d[0]:e/2,i=d?d[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},l(n)}}).each("interrupt.zoom",function(){s(n)}).each("end.zoom",function(){s(n)}):(this.__chart__=k,c(n),l(n),s(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(N=null==t?Ia:[+t[0],+t[1]],n):N},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(A=t&&[+t[0],+t[1]],n):A},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ta.rebind(n,D,"on")};var Ha,Oa,Ia=[0,1/0];ta.color=ot,ot.prototype.toString=function(){return this.rgb()+""},ta.hsl=at;var Ya=at.prototype=new ot;Ya.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,this.l/n)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,n*this.l)},Ya.rgb=function(){return ct(this.h,this.s,this.l)},ta.hcl=lt;var Za=lt.prototype=new ot;Za.brighter=function(n){return new lt(this.h,this.c,Math.min(100,this.l+Va*(arguments.length?n:1)))},Za.darker=function(n){return new lt(this.h,this.c,Math.max(0,this.l-Va*(arguments.length?n:1)))},Za.rgb=function(){return st(this.h,this.c,this.l).rgb()},ta.lab=ft;var Va=18,Xa=.95047,$a=1,Ba=1.08883,Wa=ft.prototype=new ot;Wa.brighter=function(n){return new ft(Math.min(100,this.l+Va*(arguments.length?n:1)),this.a,this.b)},Wa.darker=function(n){return new ft(Math.max(0,this.l-Va*(arguments.length?n:1)),this.a,this.b)},Wa.rgb=function(){return ht(this.l,this.a,this.b)},ta.rgb=mt;var Ja=mt.prototype=new ot;Ja.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new mt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mt(u,u,u)},Ja.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mt(n*this.r,n*this.g,n*this.b)},Ja.hsl=function(){return _t(this.r,this.g,this.b)},Ja.toString=function(){return"#"+xt(this.r)+xt(this.g)+xt(this.b)};var Ga=ta.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ga.forEach(function(n,t){Ga.set(n,yt(t))}),ta.functor=Et,ta.xhr=At(y),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++<l;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}s=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++s):10===r&&(u=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;l>s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new m,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv(" ","text/tab-separated-values");var Ka,Qa,nc,tc,ec,rc=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Qa?Qa.n=i:Ka=i,Qa=i,nc||(tc=clearTimeout(tc),nc=1,rc(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var uc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),uc[8+e/3]};var ic=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,oc=ta.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),ac=ta.time={},cc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){lc.setUTCDate.apply(this._,arguments)},setDay:function(){lc.setUTCDay.apply(this._,arguments)},setFullYear:function(){lc.setUTCFullYear.apply(this._,arguments)},setHours:function(){lc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){lc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){lc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){lc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){lc.setUTCSeconds.apply(this._,arguments)},setTime:function(){lc.setTime.apply(this._,arguments)}};var lc=Date.prototype;ac.year=Ft(function(n){return n=ac.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ac.years=ac.year.range,ac.years.utc=ac.year.utc.range,ac.day=Ft(function(n){var t=new cc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ac.days=ac.day.range,ac.days.utc=ac.day.utc.range,ac.dayOfYear=function(n){var t=ac.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ac[n]=Ft(function(n){return(n=ac.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ac[n+"s"]=e.range,ac[n+"s"].utc=e.utc.range,ac[n+"OfYear"]=function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)}}),ac.week=ac.sunday,ac.weeks=ac.sunday.range,ac.weeks.utc=ac.sunday.utc.range,ac.weekOfYear=ac.sundayOfYear;var sc={"-":"",_:" ",0:"0"},fc=/^\s*\d+/,hc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var gc=ta.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ta.format=gc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,pc),le(pc.s,this.s,this),this.s?this.t+=pc.t:this.s=pc.t -},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var pc=new ce;ta.geo.stream=function(n,t){n&&vc.hasOwnProperty(n.type)?vc[n.type](n,t):se(n,t)};var vc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)se(e[r].geometry,t)}},dc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){fe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)fe(e[r],t,0)},Polygon:function(n,t){he(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)he(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)se(e[r],t)}};ta.geo.area=function(n){return mc=0,ta.geo.stream(n,Mc),mc};var mc,yc=new ce,Mc={sphere:function(){mc+=4*qa},point:b,lineStart:b,lineEnd:b,polygonStart:function(){yc.reset(),Mc.lineStart=ge},polygonEnd:function(){var n=2*yc;mc+=0>n?4*qa+n:n,Mc.lineStart=Mc.lineEnd=Mc.point=b}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Da,e*Da]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Pa*l,d=ga(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Pa;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Pa;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ga(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Mc.point(n,e),t(n,e)}function i(){Mc.lineStart()}function o(){u(v,d),Mc.lineEnd(),ga(y)>Ca&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var s,f,h,g,p,v,d,m,y,M,x,b={point:n,lineStart:e,lineEnd:r,polygonStart:function(){b.point=u,b.lineStart=i,b.lineEnd=o,y=0,Mc.polygonStart()},polygonEnd:function(){Mc.polygonEnd(),b.point=n,b.lineStart=e,b.lineEnd=r,0>yc?(s=-(h=180),f=-(g=90)):y>Ca?g=90:-Ca>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){xc=bc=_c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,qc);var t=Nc,e=Cc,r=zc,u=t*t+e*e+r*r;return za>u&&(t=kc,e=Ec,r=Ac,Ca>bc&&(t=_c,e=wc,r=Sc),u=t*t+e*e+r*r,za>u)?[0/0,0/0]:[Math.atan2(e,t)*Pa,tt(r/Math.sqrt(u))*Pa]};var xc,bc,_c,wc,Sc,kc,Ec,Ac,Nc,Cc,zc,qc={sphere:b,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){qc.lineStart=Ee},polygonEnd:function(){qc.lineStart=Se}},Lc=Le(Ne,Pe,je,[-qa,-qa/2]),Tc=1e9;ta.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ie(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ta.geo.conicEqualArea=function(){return Ye(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ca,f+.12*l+Ca],[s-.214*l-Ca,f+.234*l-Ca]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ca,f+.166*l+Ca],[s-.115*l-Ca,f+.234*l-Ca]]).stream(c).point,n},n.scale(1070)};var Rc,Dc,Pc,Uc,jc,Fc,Hc={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Dc=0,Hc.lineStart=Ve},polygonEnd:function(){Hc.lineStart=Hc.lineEnd=Hc.point=b,Rc+=ga(Dc/2)}},Oc={point:Xe,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Ic={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Ic.lineStart=Ke},polygonEnd:function(){Ic.point=We,Ic.lineStart=Je,Ic.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Rc=0,ta.geo.stream(n,u(Hc)),Rc},n.centroid=function(n){return _c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,u(Ic)),zc?[Nc/zc,Cc/zc]:Ac?[kc/Ac,Ec/Ac]:Sc?[_c/Sc,wc/Sc]:[0/0,0/0]},n.bounds=function(n){return jc=Fc=-(Pc=Uc=1/0),ta.geo.stream(n,u(Oc)),[[Pc,Uc],[jc,Fc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):y,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t}return n=lr(n[0]%360*Da,n[1]*Da,n.length>2?n[2]*Da:0),t.invert=function(t){return t=n.invert(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Da,-n[1]*Da,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Pa,n[1]*=Pa}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*Da,u*Da),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Da,(u=+r)*Da),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Da,u=n[1]*Da,i=t[1]*Da,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ga(n%d)>Ca}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ga(n%m)>Ca}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ca],[180,90-Ca]]).minorExtent([[-180,-80-Ca],[180,80+Ca]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},ta.geo.interpolate=function(n,t){return Mr(n[0]*Da,n[1]*Da,t[0]*Da,t[1]*Da)},ta.geo.length=function(n){return Yc=0,ta.geo.stream(n,Zc),Yc};var Yc,Zc={sphere:b,point:b,lineStart:xr,lineEnd:b,polygonStart:b,polygonEnd:b},Vc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Vc)}).raw=Vc;var Xc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},y);(ta.geo.azimuthalEquidistant=function(){return ur(Xc)}).raw=Xc,(ta.geo.conicConformal=function(){return Ye(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ye(wr)}).raw=wr;var $c=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur($c)}).raw=$c,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ra]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Bc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Bc)}).raw=Bc;var Wc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Wc)}).raw=Wc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ra]},(ta.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=Et(e),i=Et(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t<s.length-h;++t)g.push(n[a[s[t]][2]]);return g}var e=Ar,r=Nr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ta.geom.polygon=function(n){return ya(n,Jc),n};var Jc=ta.geom.polygon.prototype=[];Jc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Jc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Jc.clip=function(n){for(var t,e,r,u,i,o,a=Tr(n),c=-1,l=this.length-Tr(this),s=this[l-1];++c<l;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],qr(o,s,u)?(qr(i,s,u)||n.push(Lr(i,o,s,u)),n.push(o)):qr(i,s,u)&&n.push(Lr(i,o,s,u)),i=o;a&&n.push(n[0]),s=u}return n};var Gc,Kc,Qc,nl,tl,el=[],rl=[];Or.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Yr),t.length},Qr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},nu.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=uu(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(eu(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ru(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(ru(this,e),n=e,e=n.U),e.C=!1,r.C=!0,eu(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?uu(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return void(n.C=!1);do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,eu(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ru(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,eu(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,ru(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,eu(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,ru(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},ta.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return iu(e(n),a).cells.forEach(function(e,a){var c=e.edges,l=e.site,s=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):l.x>=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ca)*Ca,y:Math.round(o(n,t)/Ca)*Ca,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=ul;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Yr),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c<l;)u=s,i=f,s=a[c].edge,f=s.l===o?s.r:s.l,r<i.i&&r<f.i&&au(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=Et(r=n),t):r},t.y=function(n){return arguments.length?(o=Et(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?ul:n,t):a===ul?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===ul?null:a&&a[1]},t)};var ul=[[-1e6,-1e6],[1e6,1e6]];ta.geom.delaunay=function(n){return ta.geom.voronoi().triangles(n)},ta.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,s=n.y;if(null!=c)if(ga(c-e)+ga(s-r)<.01)l(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,l(n,f,c,s,u,i,o,a),l(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else l(n,t,e,r,u,i,o,a)}function l(n,t,e,r,u,o,a,c){var l=.5*(u+a),s=.5*(o+c),f=e>=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=Et(a),x=Et(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.x<v&&(v=s.x),s.y<d&&(d=s.y),s.x>m&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=s=null,k}var o,a=Ar,c=Nr;return(o=arguments.length)?(a=cu,c=lu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},ta.interpolateRgb=gu,ta.interpolateObject=pu,ta.interpolateNumber=vu,ta.interpolateString=du;var il=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,ol=new RegExp(il.source,"g");ta.interpolate=mu,ta.interpolators=[function(n,t){var e=typeof t;return("string"===e?Ga.has(t.toLowerCase())||/^(#|rgb\(|hsl\()/i.test(t)?gu:du:t instanceof ot?gu:Array.isArray(t)?yu:"object"===e&&isNaN(t)?pu:vu)(n,t)}],ta.interpolateArray=yu;var al=function(){return y},cl=ta.map({linear:al,poly:ku,quad:function(){return _u},cubic:function(){return wu},sin:function(){return Eu},exp:function(){return Au},circle:function(){return Nu},elastic:Cu,back:zu,bounce:function(){return qu}}),ll=ta.map({"in":y,out:xu,"in-out":bu,"out-in":function(n){return bu(xu(n))}});ta.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=cl.get(e)||al,r=ll.get(r)||y,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:sl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var sl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Yu(n[e]));return t}},ta.layout.chord=function(){function n(){var n,l,f,h,g,p={},v=[],d=ta.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(l=0,g=-1;++g<i;)l+=u[h][g];v.push(l),m.push(ta.range(i)),n+=l}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(La-s*i)/n,l=0,h=-1;++h<i;){for(f=l,g=-1;++g<i;){var y=d[h],M=m[y][g],x=u[y][M],b=l,_=l+=x*n;p[y+"-"+M]={index:y,subindex:M,startAngle:b,endAngle:_,value:x}}r[y]={index:y,startAngle:f,endAngle:l,value:(l-f)/n},l+=s}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,l={},s=0;return l.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,l):u},l.padding=function(n){return arguments.length?(s=n,e=r=null,l):s},l.sortGroups=function(n){return arguments.length?(o=n,e=r=null,l):o},l.sortSubgroups=function(n){return arguments.length?(a=n,e=null,l):a},l.sortChords=function(n){return arguments.length?(c=n,e&&t(),l):c},l.chords=function(){return e||n(),e},l.groups=function(){return r||n(),r},l},ta.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=fl,h=hl,g=-30,p=gl,v=.1,d=.64,m=[],M=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,y,x,b=m.length,_=M.length;for(e=0;_>e;++e)a=M[e],f=a.source,h=a.target,y=h.x-f.x,x=h.y-f.y,(p=y*y+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,y*=p,x*=p,h.x-=y*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=y*(d=1-d),f.y+=x*d);if((d=r*v)&&(y=l[0]/2,x=l[1]/2,e=-1,d))for(;++e<b;)a=m[e],a.x+=(y-a.x)*d,a.y+=(x-a.y)*d;if(g)for(Ju(t=ta.geom.quadtree(m),r,o),e=-1;++e<b;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<b;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*s,a.y-=(a.py-(a.py=a.y))*s);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(M=n,a):M},a.size=function(n){return arguments.length?(l=n,a):l},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(s=+n,a):s},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=M[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++a<l;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,s=M.length,p=l[0],v=l[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=M[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,M[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,M[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=ta.behavior.drag().origin(y).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?void this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e):e},ta.rebind(a,c,"on")};var fl=20,hl=1,gl=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ta.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++l<o;)n(a=i[l],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=ta.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Gu(e,r)},ta.layout.pie=function(){function n(o){var a,c=o.length,l=o.map(function(e,r){return+t.call(n,e,r)}),s=+("function"==typeof r?r.apply(this,arguments):r),f=("function"==typeof u?u.apply(this,arguments):u)-s,h=Math.min(Math.abs(f)/c,+("function"==typeof i?i.apply(this,arguments):i)),g=h*(0>f?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===pl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=pl,r=0,u=La,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var pl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=y,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:vl.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:dl.get(t)||ci,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var vl=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),dl=ta.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=l[i],a>=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=Et(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:Et(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(f,function(n){n.x<g.x&&(g=n),n.x>p.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ni(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=ta.layout.hierarchy().sort(null).value(null),e=Si,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Gu(n,t)},ta.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++i<o;)u=n[i],u.x=a,u.y=l,u.dy=s,a+=u.dx=Math.min(e.x+e.dx-a,s?c(u.area/s):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=s,e.dy-=s}else{for((r||s>e.dx)&&(s=e.dx);++i<o;)u=n[i],u.x=a,u.y=l,u.dx=s,l+=u.dy=Math.min(e.y+e.dy-l,s?c(u.area/s):0);u.z=!1,u.dy+=e.y+e.dy-l,e.x+=s,e.dx-=s}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=l[0],i.dy=l[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=ta.layout.hierarchy(),c=Math.round,l=[1,1],s=null,f=Ri,h=!1,g="squarify",p=.5*(1+Math.sqrt(5)); -return i.size=function(n){return arguments.length?(l=n,i):l},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ri(t):Di(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Di(t,n)}if(!arguments.length)return s;var r;return f=null==(s=n)?Ri:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Gu(i,a)},ta.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ta.scale={};var ml={floor:y,ceil:y};ta.scale.linear=function(){return Ii([0,1],[0,1],mu,!1)};var yl={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var Ml=ta.format(".0e"),xl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(bl)},ta.scale.category20=function(){return ta.scale.ordinal().range(_l)},ta.scale.category20b=function(){return ta.scale.ordinal().range(wl)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Sl)};var bl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(Mt),_l=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(Mt),wl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(Mt),Sl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(Mt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-Ra,f=a.apply(this,arguments)-Ra,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ta)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===kl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=tt(d/l*Math.sin(m))),n&&(E=tt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=qa?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=qa?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),I=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],I[1][0],I[1][1]),",",g," ",I[1],"A",H,",",H," 0 0,",v," ",I[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",I[0])}else N.push("M",y,",",M);if(null!=S){var Y=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-Y,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-Y,g);p===Y?N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",Y,",",Y," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=kl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=Et(t),n):e},n.outerRadius=function(t){return arguments.length?(r=Et(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=Et(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==kl?kl:Et(t),n):i},n.startAngle=function(t){return arguments.length?(o=Et(t),n):o},n.endAngle=function(t){return arguments.length?(a=Et(t),n):a},n.padAngle=function(t){return arguments.length?(c=Et(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Ra;return[Math.cos(t)*n,Math.sin(t)*n]},n};var kl="auto";ta.svg.line=function(){return ho(y)};var El=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});El.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Al=[0,2/3,1/3,0],Nl=[0,1/3,2/3,0],Cl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(y)},ta.svg.area.radial=function(){var n=Do(Ro);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)-Ra,s=l.call(n,u,r)-Ra;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>qa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=Et(t),n):a},n.source=function(t){return arguments.length?(i=Et(t),n):i},n.target=function(t){return arguments.length?(o=Et(t),n):o},n.startAngle=function(t){return arguments.length?(c=Et(t),n):c},n.endAngle=function(t){return arguments.length?(l=Et(t),n):l},n},ta.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=Et(e),n):t},n.target=function(t){return arguments.length?(e=Et(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(zl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=Et(e),n):t},n.size=function(t){return arguments.length?(e=Et(t),n):e},n};var zl=ta.map({circle:Oo,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ll)),e=t*Ll;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=zl.keys();var ql=Math.sqrt(3),Ll=Math.tan(30*Da);_a.transition=function(n){for(var t,e,r=Tl||++Ul,u=Xo(n),i=[],o=Rl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++a<c;){i.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(e=l[s])&&$o(e,s,u,r,o),t.push(e)}return Yo(i,u,r)},_a.interrupt=function(n){return this.each(null==n?Dl:Io(Xo(n)))};var Tl,Rl,Dl=Io(Xo()),Pl=[],Ul=0;Pl.call=_a.call,Pl.empty=_a.empty,Pl.node=_a.node,Pl.size=_a.size,ta.transition=function(n,t){return n&&n.transition?Tl?n.transition(t):n:ta.selection().transition(n)},ta.transition.prototype=Pl,Pl.select=function(n){var t,e,r,u=this.id,i=this.namespace,o=[];n=N(n);for(var a=-1,c=this.length;++a<c;){o.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(r=l[s])&&(e=n.call(r,r.__data__,s,a))?("__data__"in r&&(e.__data__=r.__data__),$o(e,s,i,u,r[i][u]),t.push(e)):t.push(null)}return Yo(o,i,u)},Pl.selectAll=function(n){var t,e,r,u,i,o=this.id,a=this.namespace,c=[];n=C(n);for(var l=-1,s=this.length;++l<s;)for(var f=this[l],h=-1,g=f.length;++h<g;)if(r=f[h]){i=r[a][o],e=n.call(r,r.__data__,h,l),c.push(t=[]);for(var p=-1,v=e.length;++p<v;)(u=e[p])&&$o(u,p,a,o,i),t.push(u)}return Yo(c,a,o)},Pl.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Yo(u,this.namespace,this.id)},Pl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Pl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Pl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Pl.style=function(n,e,r){function u(){this.style.removeProperty(n)}function i(e){return null==e?u:(e+="",function(){var u,i=t(this).getComputedStyle(this,null).getPropertyValue(n);return i!==e&&(u=mu(i,e),function(t){this.style.setProperty(n,u(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Zo(this,"style."+n,e,i)},Pl.styleTween=function(n,e,r){function u(u,i){var o=e.call(this,u,i,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,u)},Pl.text=function(n){return Zo(this,"text",n,Vo)},Pl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Pl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),Y(this,function(r){r[e][t].ease=n}))},Pl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Pl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Pl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=Rl,i=Tl;try{Tl=e,Y(this,function(t,u,i){Rl=t[r][e],n.call(t,t.__data__,u,i)})}finally{Rl=u,Tl=i}}else Y(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Pl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ul,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Yo(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):y:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ca),d=ta.transition(p.exit()).style("opacity",Ca).remove(),m=ta.transition(p.order()).style("opacity",1),M=Math.max(u,0)+o,x=Ui(f),b=l.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ta.transition(b));v.append("line"),v.append("text");var w,S,k,E,A=v.select("line"),N=m.select("line"),C=p.select("text").text(g),z=v.select("text"),q=m.select("text"),L="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,w="x",k="y",S="x2",E="y2",C.attr("dy",0>L?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+L*i+"V0H"+x[1]+"V"+L*i)):(n=Wo,w="y",k="x",S="y2",E="x2",C.attr("dy",".32em").style("text-anchor",0>L?"end":"start"),_.attr("d","M"+L*i+","+x[0]+"H0V"+x[1]+"H"+L*i)),A.attr(E,L*u),z.attr(k,L*M),N.attr(S,0).attr(E,L*u),q.attr(w,0).attr(k,L*M),f.rangeBand){var T=f,R=T.rangeBand()/2;s=f=function(n){return T(n)+R}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=jl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Fl?t+"":jl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var jl="bottom",Fl={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(t){t.each(function(){var t=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",i).on("touchstart.brush",i),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,y);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Hl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var c,f=ta.transition(t),h=ta.transition(o);l&&(c=Ui(l),h.attr("x",c[0]).attr("width",c[1]-c[0]),r(f)),s&&(c=Ui(s),h.attr("y",c[0]).attr("height",c[1]-c[0]),u(f)),e(f)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+f[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",f[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1]-f[0])}function u(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function i(){function i(){32==ta.event.keyCode&&(C||(M=null,q[0]-=f[1],q[1]-=h[1],C=2),S())}function v(){32==ta.event.keyCode&&2==C&&(q[0]+=f[1],q[1]+=h[1],C=0,S())}function d(){var n=ta.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ta.event.altKey?(M||(M=[(f[0]+f[1])/2,(h[0]+h[1])/2]),q[0]=f[+(n[0]<M[0])],q[1]=h[+(n[1]<M[1])]):M=null),A&&m(n,l,0)&&(r(k),t=!0),N&&m(n,s,1)&&(u(k),t=!0),t&&(e(k),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,i=Ui(t),c=i[0],l=i[1],s=q[e],v=e?h:f,d=v[1]-v[0];return C&&(c-=s,l-=d+s),r=(e?p:g)?Math.max(c,Math.min(l,n[e])):n[e],C?u=(r+=s)+d:(M&&(s=Math.max(c,Math.min(l,2*M[e]-r))),r>s?(u=r,r=s):u=s),v[0]!=r||v[1]!=u?(e?a=null:o=null,v[0]=r,v[1]=u,!0):void 0}function y(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ta.select(ta.event.target),w=c.of(b,arguments),k=ta.select(b),E=_.datum(),A=!/^(n|s)$/.test(E)&&l,N=!/^(e|w)$/.test(E)&&s,C=_.classed("extent"),z=W(b),q=ta.mouse(b),L=ta.select(t(b)).on("keydown.brush",i).on("keyup.brush",v);if(ta.event.changedTouches?L.on("touchmove.brush",d).on("touchend.brush",y):L.on("mousemove.brush",d).on("mouseup.brush",y),k.interrupt().selectAll("*").interrupt(),C)q[0]=f[0]-q[0],q[1]=h[0]-q[1];else if(E){var T=+/w$/.test(E),R=+/^n/.test(E);x=[f[1-T]-q[0],h[1-R]-q[1]],q[0]=f[T],q[1]=h[R]}else ta.event.altKey&&(M=q.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,c=E(n,"brushstart","brush","brushend"),l=null,s=null,f=[0,0],h=[0,0],g=!0,p=!0,v=Ol[0];return n.event=function(n){n.each(function(){var n=c.of(this,arguments),t={x:f,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Tl?ta.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,f=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(f,t.x),r=yu(h,t.y);return o=a=null,function(u){f=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(l=t,v=Ol[!l<<1|!s],n):l},n.y=function(t){return arguments.length?(s=t,v=Ol[!l<<1|!s],n):s},n.clamp=function(t){return arguments.length?(l&&s?(g=!!t[0],p=!!t[1]):l?g=!!t:s&&(p=!!t),n):l&&s?[g,p]:l?g:s?p:null},n.extent=function(t){var e,r,u,i,c;return arguments.length?(l&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),o=[e,r],l.invert&&(e=l(e),r=l(r)),e>r&&(c=e,e=r,r=c),(e!=f[0]||r!=f[1])&&(f=[e,r])),s&&(u=t[0],i=t[1],l&&(u=u[1],i=i[1]),a=[u,i],s.invert&&(u=s(u),i=s(i)),u>i&&(c=u,u=i,i=c),(u!=h[0]||i!=h[1])&&(h=[u,i])),n):(l&&(o?(e=o[0],r=o[1]):(e=f[0],r=f[1],l.invert&&(e=l.invert(e),r=l.invert(r)),e>r&&(c=e,e=r,r=c))),s&&(a?(u=a[0],i=a[1]):(u=h[0],i=h[1],s.invert&&(u=s.invert(u),i=s.invert(i)),u>i&&(c=u,u=i,i=c))),l&&s?[[e,u],[r,i]]:l?[e,r]:s&&[u,i])},n.clear=function(){return n.empty()||(f=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!l&&f[0]==f[1]||!!s&&h[0]==h[1]},ta.rebind(n,c,"on")};var Hl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ol=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Il=ac.format=gc.timeFormat,Yl=Il.utc,Zl=Yl("%Y-%m-%dT%H:%M:%S.%LZ");Il.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Zl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Zl.toString,ac.second=Ft(function(n){return new cc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ac.seconds=ac.second.range,ac.seconds.utc=ac.second.utc.range,ac.minute=Ft(function(n){return new cc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ac.minutes=ac.minute.range,ac.minutes.utc=ac.minute.utc.range,ac.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new cc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ac.hours=ac.hour.range,ac.hours.utc=ac.hour.utc.range,ac.month=Ft(function(n){return n=ac.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ac.months=ac.month.range,ac.months.utc=ac.month.utc.range;var Vl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Xl=[[ac.second,1],[ac.second,5],[ac.second,15],[ac.second,30],[ac.minute,1],[ac.minute,5],[ac.minute,15],[ac.minute,30],[ac.hour,1],[ac.hour,3],[ac.hour,6],[ac.hour,12],[ac.day,1],[ac.day,2],[ac.week,1],[ac.month,1],[ac.month,3],[ac.year,1]],$l=Il.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ne]]),Bl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:y,ceil:y};Xl.year=ac.year,ac.scale=function(){return Go(ta.scale.linear(),Xl,$l)};var Wl=Xl.map(function(n){return[n[0].utc,n[1]]}),Jl=Yl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ne]]);Wl.year=ac.year.utc,ac.scale.utc=function(){return Go(ta.scale.linear(),Wl,Jl)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}(); diff --git a/web/packs/src/vendor/javascripts/jquery.typeahead.min.js b/web/packs/src/vendor/javascripts/jquery.typeahead.min.js deleted file mode 100644 index 402bdd6..0000000 --- a/web/packs/src/vendor/javascripts/jquery.typeahead.min.js +++ /dev/null @@ -1,10 +0,0 @@ -/*! - * jQuery Typeahead - * Copyright (C) 2015 RunningCoder.org - * Licensed under the MIT license - * - * @author Tom Bertrand - * @version 2.1.2 (2015-09-28) - * @link http://www.runningcoder.org/jquerytypeahead/ -*/ -!function(a,b,c,d){a.Typeahead={version:"2.1.2"};var e={input:null,minLength:2,maxItem:8,dynamic:!1,delay:300,order:null,offset:!1,hint:!1,accent:!1,highlight:!0,group:!1,maxItemPerGroup:null,dropdownFilter:!1,dynamicFilter:null,backdrop:!1,cache:!1,ttl:36e5,compression:!1,suggestion:!1,searchOnFocus:!1,resultContainer:null,generateOnLoad:null,mustSelectItem:!1,href:null,display:["display"],template:null,correlativeTemplate:!1,emptyTemplate:!1,source:null,callback:{onInit:null,onReady:null,onSearch:null,onResult:null,onLayoutBuiltBefore:null,onLayoutBuiltAfter:null,onNavigate:null,onMouseEnter:null,onMouseLeave:null,onClickBefore:null,onClickAfter:null,onSendRequest:null,onReceiveRequest:null,onSubmit:null},selector:{container:"typeahead-container",group:"typeahead-group",result:"typeahead-result",list:"typeahead-list",display:"typeahead-display",query:"typeahead-query",filter:"typeahead-filter",filterButton:"typeahead-filter-button",filterValue:"typeahead-filter-value",dropdown:"typeahead-dropdown",dropdownCarret:"typeahead-caret",button:"typeahead-button",backdrop:"typeahead-backdrop",hint:"typeahead-hint"},debug:!1},f=".typeahead",g={from:"ãàáäâẽèéëêìíïîõòóöôùúüûñç",to:"aaaaaeeeeeiiiiooooouuuunc"},h=~navigator.appVersion.indexOf("MSIE 9."),i=function(a,b){this.rawQuery="",this.query="",this.source={},this.isGenerated=null,this.generatedGroupCount=0,this.groupCount=0,this.groupBy="group",this.result=[],this.resultCount=0,this.options=b,this.node=a,this.container=null,this.resultContainer=null,this.item=null,this.xhr={},this.hintIndex=null,this.filters={dropdown:{},dynamic:{}},this.requests={},this.backdrop={},this.hint={},this.__construct()};i.prototype={extendOptions:function(){this.options.dynamic&&(this.options.cache=!1,this.options.compression=!1),this.options.cache&&(this.options.cache=function(){var b="undefined"!=typeof a.localStorage;if(b)try{a.localStorage.setItem("typeahead","typeahead"),a.localStorage.removeItem("typeahead")}catch(c){b=!1}return b}()),this.options.compression&&("object"==typeof LZString&&this.options.cache||(this.options.compression=!1)),"undefined"==typeof this.options.maxItem||/^\d+$/.test(this.options.maxItem)&&0!==this.options.maxItem||(this.options.maxItem=1/0),this.options.maxItemPerGroup&&!/^\d+$/.test(this.options.maxItemPerGroup)&&(this.options.maxItemPerGroup=null),!this.options.display||this.options.display instanceof Array||(this.options.display=[this.options.display]),!this.options.group||this.options.group instanceof Array||(this.options.group=[this.options.group]),!this.options.dynamicFilter||this.options.dynamicFilter instanceof Array||(this.options.dynamicFilter=[this.options.dynamicFilter]),this.options.resultContainer&&("string"==typeof this.options.resultContainer&&(this.options.resultContainer=c(this.options.resultContainer)),this.options.resultContainer instanceof jQuery&&this.options.resultContainer[0]&&(this.resultContainer=this.options.resultContainer)),this.options.group&&"string"==typeof this.options.group[0]&&this.options.maxItemPerGroup&&(this.groupBy=this.options.group[0]),this.options.callback&&this.options.callback.onClick&&(this.options.callback.onClickBefore=this.options.callback.onClick,delete this.options.callback.onClick),this.options=c.extend(!0,{},e,this.options)},unifySourceFormat:function(){if(this.options.source instanceof Array)return this.options.source={group:{data:this.options.source}},this.groupCount+=1,!0;("undefined"!=typeof this.options.source.data||"undefined"!=typeof this.options.source.url)&&(this.options.source={group:this.options.source});for(var a in this.options.source)if(this.options.source.hasOwnProperty(a)){if(("string"==typeof this.options.source[a]||this.options.source[a]instanceof Array)&&(this.options.source[a]={url:this.options.source[a]}),!this.options.source[a].data&&!this.options.source[a].url)return!1;!this.options.source[a].display||this.options.source[a].display instanceof Array||(this.options.source[a].display=[this.options.source[a].display]),this.options.source[a].ignore&&(this.options.source[a].ignore instanceof RegExp||delete this.options.source[a].ignore),this.groupCount+=1}return!0},init:function(){this.helper.executeCallback(this.options.callback.onInit,[this.node]),this.container=this.node.closest("."+this.options.selector.container)},delegateEvents:function(){var a=this,b=["focus"+f,"input"+f,"propertychange"+f,"keydown"+f,"keyup"+f,"dynamic"+f,"generateOnLoad"+f];this.container.off(f).on("click"+f+" touchstart"+f,function(b){b.stopPropagation(),a.options.dropdownFilter&&a.container.find("."+a.options.selector.dropdown.replace(" ",".")).hide()}),this.node.closest("form").on("submit",function(b){return a.options.mustSelectItem&&a.helper.isEmpty(a.item)?void b.preventDefault():(a.hideLayout(),a.rawQuery="",a.query="",a.helper.executeCallback(a.options.callback.onSubmit,[a.node,this,a.item,b])?!1:void 0)});var c=!1;this.node.off(f).on(b.join(" "),function(b){switch(b.type){case"generateOnLoad":case"focus":a.isGenerated&&a.options.searchOnFocus&&a.query.length>=a.options.minLength&&a.showLayout(),null!==a.isGenerated||a.options.dynamic||a.generateSource();break;case"keydown":a.isGenerated&&a.result.length&&b.keyCode&&~[13,27,38,39,40].indexOf(b.keyCode)&&(c=!0,a.navigate(b));break;case"keyup":h&&a.node[0].value.replace(/^\s+/,"").toString().length<a.query.length&&a.node.trigger("input"+f);break;case"propertychange":if(c){c=!1;break}case"input":if(a.rawQuery=a.node[0].value.toString(),a.query=a.node[0].value.replace(/^\s+/,"").toString(),a.options.hint&&a.hint.container&&""!==a.hint.container.val()&&0!==a.hint.container.val().indexOf(a.rawQuery)&&a.hint.container.val(""),a.options.dynamic)return a.isGenerated=null,void a.helper.typeWatch(function(){a.query.length>=a.options.minLength?a.generateSource():a.hideLayout()},a.options.delay);case"dynamic":if(!a.isGenerated)break;if(a.query.length<a.options.minLength){a.hideLayout();break}a.searchResult(),a.buildLayout(),a.result.length>0||a.options.emptyTemplate?a.showLayout():a.hideLayout()}}),this.options.generateOnLoad&&this.node.trigger("generateOnLoad"+f)},generateSource:function(){if(!this.isGenerated||this.options.dynamic){if(this.generatedGroupCount=0,this.isGenerated=!1,!this.helper.isEmpty(this.xhr)){for(var b in this.xhr)this.xhr.hasOwnProperty(b)&&this.xhr[b].abort();this.xhr={}}var c,d,e;for(c in this.options.source)if(this.options.source.hasOwnProperty(c)){if(this.options.cache&&(d=a.localStorage.getItem(this.node.selector+":"+c))){this.options.compression&&(d=LZString.decompressFromUTF16(d)),e=!1;try{d=JSON.parse(d+""),d.data&&d.ttl>(new Date).getTime()?(this.populateSource(d.data,c),e=!0):a.localStorage.removeItem(this.node.selector+":"+c)}catch(f){}if(e)continue}!this.options.source[c].data||this.options.source[c].url?this.options.source[c].url&&(this.requests[c]||(this.requests[c]=this.generateRequestObject(c))):this.populateSource("function"==typeof this.options.source[c].data&&this.options.source[c].data()||this.options.source[c].data,c)}this.handleRequests()}},generateRequestObject:function(a){var b={request:{url:null,dataType:"json"},extra:{path:null,group:a,callback:{done:null,fail:null,always:null,always:null}},validForGroup:[a]};!(this.options.source[a].url instanceof Array)&&this.options.source[a].url instanceof Object&&(this.options.source[a].url=[this.options.source[a].url]),this.options.source[a].url instanceof Array?(this.options.source[a].url[0]instanceof Object?(this.options.source[a].url[0].callback&&(b.extra.callback=this.options.source[a].url[0].callback,delete this.options.source[a].url[0].callback),b.request=c.extend(!0,b.request,this.options.source[a].url[0])):"string"==typeof this.options.source[a].url[0]&&(b.request.url=this.options.source[a].url[0]),this.options.source[a].url[1]&&"string"==typeof this.options.source[a].url[1]&&(b.extra.path=this.options.source[a].url[1])):"string"==typeof this.options.source[a].url&&(b.request.url=this.options.source[a].url),"jsonp"===b.request.dataType.toLowerCase()&&(b.request.jsonpCallback="callback_"+a);var d;for(var e in this.requests)if(this.requests.hasOwnProperty(e)&&(d=JSON.stringify(this.requests[e].request),d===JSON.stringify(b.request))){this.requests[e].validForGroup.push(a),b.isDuplicated=!0,delete b.validForGroup;break}return b},handleRequests:function(){var a=this,b=Object.keys(this.requests).length;b&&this.helper.executeCallback(this.options.callback.onSendRequest,[this.node,this.query]);for(var d in this.requests)this.requests.hasOwnProperty(d)&&(this.requests[d].isDuplicated||!function(d,e){var f;if(~e.request.url.indexOf("{{query}}")&&(e.request.url=e.request.url.replace("{{query}}",a.query)),e.request.data)for(var g in e.request.data)if(e.request.data.hasOwnProperty(g)&&~String(e.request.data[g]).indexOf("{{query}}")){e=c.extend(!0,{},e),e.request.data[g]=e.request.data[g].replace("{{query}}",a.query);break}a.xhr[d]=c.ajax(e.request).done(function(c,d,g){for(var h,i=0;i<e.validForGroup.length;i++)f=a.requests[e.validForGroup[i]],f.extra.callback.done instanceof Function&&(h=f.extra.callback.done(c,d,g),c=h instanceof Array&&h||c),a.populateSource(c,f.extra.group,f.extra.path),b-=1,0===b&&a.helper.executeCallback(a.options.callback.onReceiveRequest,[a.node,a.query])}).fail(function(b,c,d){for(var g=0;g<e.validForGroup.length;g++)f=a.requests[e.validForGroup[g]],f.extra.callback.fail instanceof Function&&f.extra.callback.fail(b,c,d)}).always(function(b,c){for(var d=0;d<e.validForGroup.length;d++)f=a.requests[e.validForGroup[d]],f.extra.callback.always instanceof Function&&f.extra.callback.always(b,c)}).always(function(b,c,d){for(var g=0;g<e.validForGroup.length;g++)f=a.requests[e.validForGroup[g]],f.extra.callback.always instanceof Function&&f.extra.callback.always(b,c,d)})}(d,this.requests[d]))},populateSource:function(a,b,c){var d=this,e=this.options.source[b].url&&this.options.source[b].data;a="string"==typeof c?this.helper.namespace(c,a):a,a instanceof Array||(a=[]),e&&("function"==typeof e&&(e=e()),e instanceof Array&&(a=a.concat(e)));for(var f,g=this.options.source[b].display?"compiled"===this.options.source[b].display[0]?this.options.source[b].display[1]:this.options.source[b].display[0]:"compiled"===this.options.display[0]?this.options.display[1]:this.options.display[0],h=0;h<a.length;h++)"string"==typeof a[h]&&(f={},f[g]=a[h],a[h]=f),a[h].group=b;if(this.options.correlativeTemplate){var i=this.options.source[b].template||this.options.template;if(i){i=i.replace(/<.+?>/g,"");for(var h=0;h<a.length;h++)a[h].compiled=i.replace(/\{\{([\w\-\.]+)(?:\|(\w+))?}}/g,function(b,c){return d.helper.namespace(c,a[h],"get","")}).trim();this.options.source[b].display?~this.options.source[b].display.indexOf("compiled")||this.options.source[b].display.unshift("compiled"):~this.options.display.indexOf("compiled")||this.options.display.unshift("compiled")}else;}if(this.source[b]=a,this.options.cache&&!localStorage.getItem(this.node.selector+":"+b)){var j=JSON.stringify({data:a,ttl:(new Date).getTime()+this.options.ttl});this.options.compression&&(j=LZString.compressToUTF16(j)),localStorage.setItem(this.node.selector+":"+b,j)}this.incrementGeneratedGroup()},incrementGeneratedGroup:function(){this.generatedGroupCount+=1,this.groupCount===this.generatedGroupCount&&(this.isGenerated=!0,this.node.trigger("dynamic"+f))},navigate:function(a){this.helper.executeCallback(this.options.callback.onNavigate,[this.node,this.query,a]);var b=this.resultContainer.find("> ul > li:not([data-search-group])"),c=b.filter(".active"),d=c[0]&&b.index(c)||null;if(27===a.keyCode)return void(this.container.hasClass("result")&&(a.preventDefault(),this.hideLayout()));if(13===a.keyCode){if(c.length>0)return a.preventDefault(),a.stopPropagation(),void c.find("a:first").trigger("click");if(this.options.mustSelectItem&&this.helper.isEmpty(this.item))return;return void this.hideLayout()}if(39===a.keyCode)return void(d?b.eq(d).find("a:first").trigger("click"):this.options.hint&&""!==this.hint.container.val()&&this.helper.getCaret(this.node[0])>=this.query.length&&b.find('a[data-index="'+this.hintIndex+'"]').trigger("click"));if(b.length>0&&c.removeClass("active"),38===a.keyCode?(a.preventDefault(),c.length>0?d-1>=0&&b.eq(d-1).addClass("active"):b.last().addClass("active")):40===a.keyCode&&(a.preventDefault(),c.length>0?d+1<b.length&&b.eq(d+1).addClass("active"):b.first().addClass("active")),c=b.filter(".active"),this.options.hint&&this.hint.container&&(c.length>0?this.hint.container.css("color",this.hint.container.css("background-color")||"fff"):this.hint.container.css("color",this.hint.css.color)),c.length>0){var e=c.find("a:first").attr("data-index");e&&this.node.val(this.result[e][this.result[e].matchedKey])}else this.node.val(this.rawQuery)},searchResult:function(a){a||(this.item={}),this.helper.executeCallback(this.options.callback.onSearch,[this.node,this.query]),this.result=[],this.resultCount=0;var b,c,d,e,f,g,h,i,j,k=this,l=this.query.toLowerCase(),m={},n=this.filters.dropdown&&this.filters.dropdown.key||this.groupBy,o=this.filters.dynamic&&!this.helper.isEmpty(this.filters.dynamic);this.options.accent&&(l=this.helper.removeAccent(l));for(b in this.source)if(this.source.hasOwnProperty(b)&&(!this.filters.dropdown||"group"!==this.filters.dropdown.key||this.filters.dropdown.value===b)){if(this.options.maxItemPerGroup&&"group"===n)if(m[b]){if(m[b]>=this.options.maxItemPerGroup&&!this.options.callback.onResult)break}else m[b]=0;g="undefined"==typeof this.options.source[b].filter||this.options.source[b].filter===!0;for(var p=0;p<this.source[b].length&&(!(this.result.length>=this.options.maxItem)||this.options.callback.onResult);p++)if(!o||this.dynamicFilter.validate.apply(this,[this.source[b][p]])){if(c=this.source[b][p],this.options.maxItemPerGroup&&"group"!==n)if(m[c[n]]){if(m[c[n]]>=this.options.maxItemPerGroup&&!this.options.callback.onResult)continue}else m[c[n]]=0;f=this.options.source[b].display||this.options.display;for(var q=0;q<f.length;q++){if(g){if(e=c[f[q]],!e)continue;if(e=e.toString().toLowerCase(),this.options.accent&&(e=this.helper.removeAccent(e)),d=e.indexOf(l),this.options.correlativeTemplate&&"compiled"===f[q]&&0>d&&/\s/.test(l)){h=!0,i=l.split(" "),j=e;for(var r=0;r<i.length;r++)if(""!==i[r]){if(!~j.indexOf(i[r])){h=!1;break}j=j.replace(i[r],"")}}if(0>d&&!h)continue;if(this.options.offset&&0!==d)continue;if(this.options.source[b].ignore&&this.options.source[b].ignore.test(e))continue}if(!this.filters.dropdown||this.filters.dropdown.value==c[this.filters.dropdown.key]){if(this.resultCount+=1,this.options.callback.onResult&&this.result.length>=this.options.maxItem||this.options.maxItemPerGroup&&m[c[n]]>=this.options.maxItemPerGroup)break;c.matchedKey=f[q],this.result.push(c),this.options.maxItemPerGroup&&(m[c[n]]+=1);break}}}}if(this.options.order){for(var s,f=[],q=0;q<this.result.length;q++)s=this.options.source[this.result[q].group].display||this.options.display,~f.indexOf(s[0])||f.push(s[0]);this.result.sort(k.helper.sort(f,"asc"===k.options.order,function(a){return a.toString().toUpperCase()}))}this.helper.executeCallback(this.options.callback.onResult,[this.node,this.query,this.result,this.resultCount])},buildLayout:function(){this.resultContainer||(this.resultContainer=c("<div/>",{"class":this.options.selector.result}),this.container.append(this.resultContainer));var a=this.query.toLowerCase();this.options.accent&&(a=this.helper.removeAccent(a));var b=this,d=c("<ul/>",{"class":this.options.selector.list+(b.helper.isEmpty(b.result)?" empty":""),html:function(){if(b.options.emptyTemplate&&b.helper.isEmpty(b.result))return c("<li/>",{html:c("<a/>",{href:"javascript:;",html:"function"==typeof b.options.emptyTemplate&&b.options.emptyTemplate(b.query)||b.options.emptyTemplate.replace(/\{\{query}}/gi,b.query)})});for(var d in b.result)b.result.hasOwnProperty(d)&&!function(d,e,f){var g,h,i,j,k,l=e.group,m={},n=b.options.source[e.group].display||b.options.display,o=b.options.source[e.group].href||b.options.href;b.options.group&&("boolean"!=typeof b.options.group[0]&&e[b.options.group[0]]&&(l=e[b.options.group[0]]),c(f).find('li[data-search-group="'+l+'"]')[0]||c(f).append(c("<li/>",{"class":b.options.selector.group,html:c("<a/>",{href:"javascript:;",html:b.options.group[1]&&b.options.group[1].replace(/(\{\{group}})/gi,e[b.options.group[0]]||l)||l}),"data-search-group":l})));for(var p=0;p<n.length;p++)i=n[p],m[i]=e[i];g=c("<li/>",{html:c("<a/>",{href:function(){return o&&("string"==typeof o?o=o.replace(/\{\{([\w\-\.]+)(?:\|(\w+))?}}/g,function(a,c,d){var f=b.helper.namespace(c,e,"get","");return d&&"raw"===d?f:b.helper.slugify(f)}):"function"==typeof o&&(o=o(e)),e.href=o),o||"javascript:;"},"data-group":l,"data-index":d,html:function(){k=e.group&&b.options.source[e.group].template||b.options.template,h=k?k.replace(/\{\{([\w\-\.]+)(?:\|(\w+))?}}/g,function(a,c,d){var f=b.helper.namespace(c,e,"get","");return d&&"raw"===d?f:b.helper.namespace(c,m,"get","")||f}):'<span class="'+b.options.selector.display+'">'+b.helper.joinObject(m," ")+"</span>",b.options.highlight&&(h=b.helper.highlight(h,a.split(" "),b.options.accent)),c(this).append(h)},click:function(a){return b.options.mustSelectItem&&b.helper.isEmpty(e)?void a.preventDefault():(b.item=e,b.helper.executeCallback(b.options.callback.onClickBefore,[b.node,this,e,a]),void(a.isDefaultPrevented()||(a.preventDefault(),b.query=b.rawQuery=e[e.matchedKey].toString(),b.node.val(b.query).focus(),b.searchResult(!0),b.buildLayout(),b.hideLayout(),b.helper.executeCallback(b.options.callback.onClickAfter,[b.node,this,e,a]))))},mouseenter:function(a){c(this).closest("ul").find("li.active").removeClass("active"),c(this).closest("li").addClass("active"),b.helper.executeCallback(b.options.callback.onMouseEnter,[b.node,this,e,a])},mouseleave:function(a){c(this).closest("li").removeClass("active"),b.helper.executeCallback(b.options.callback.onMouseLeave,[b.node,this,e,a])}})}),b.options.group?(j=c(f).find('a[data-group="'+l+'"]:last').closest("li"),j[0]||(j=c(f).find('li[data-search-group="'+l+'"]')),c(g).insertAfter(j)):c(f).append(g)}(d,b.result[d],this)}});if(this.options.callback.onLayoutBuiltBefore){var f=this.helper.executeCallback(this.options.callback.onLayoutBuiltBefore,[this.node,this.query,this.result,d]);f instanceof jQuery&&(d=f)}if(this.container.addClass("result"),this.resultContainer.html(d),this.options.callback.onLayoutBuiltAfter&&this.helper.executeCallback(this.options.callback.onLayoutBuiltAfter,[this.node,this.query,this.result]),this.options.backdrop&&(this.backdrop.container?this.backdrop.container.show():(this.backdrop.css=c.extend({opacity:.6,filter:"alpha(opacity=60)",position:"fixed",top:0,right:0,bottom:0,left:0,"z-index":1040,"background-color":"#000"},this.options.backdrop),this.backdrop.container=c("<div/>",{"class":this.options.selector.backdrop,css:this.backdrop.css,click:function(){b.hideLayout()}}).insertAfter(this.container)),this.container.addClass("backdrop").css({"z-index":this.backdrop.css["z-index"]+1,position:"relative"})),this.options.hint){var g="";if(this.result.length>0&&this.query.length>0){this.hint.container||(this.hint.css=c.extend({"border-color":"transparent",position:"absolute",top:0,display:"inline","z-index":-1,"float":"none",color:"silver","box-shadow":"none",cursor:"default","-webkit-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none"},this.options.hint),this.hint.container=c("<input/>",{type:this.node.attr("type"),"class":this.node.attr("class"),readonly:!0,unselectable:"on",tabindex:-1,click:function(){b.node.focus()}}).addClass(e.selector.hint).css(this.hint.css).insertAfter(this.node),this.node.parent().css({position:"relative"})),this.hint.container.css("color",this.hint.css.color);var h,i,j;this.hintIndex=null;for(var k=0;k<this.result.length;k++){i=this.result[k].group,h=b.options.source[i].display||b.options.display;for(var l=0;l<h.length;l++)if(j=String(this.result[k][h[l]]).toLowerCase(),this.options.accent&&(j=this.helper.removeAccent(j)),0===j.indexOf(a)){g=String(this.result[k][h[l]]),this.hintIndex=k;break}if(null!==this.hintIndex)break}}this.hint.container&&this.hint.container.val(g.length>0&&this.rawQuery+g.substring(this.query.length)||"").show()}},buildDropdownLayout:function(){function a(a){"*"===a.value?delete this.filters.dropdown:this.filters.dropdown=a,this.container.removeClass("filter").find("."+this.options.selector.filterValue).html(a.display||a.value),this.node.trigger("dynamic"+f),this.node.focus()}if(this.options.dropdownFilter){var b,d=this;if("boolean"==typeof this.options.dropdownFilter)b="all";else if("string"==typeof this.options.dropdownFilter)b=this.options.dropdownFilter;else if(this.options.dropdownFilter instanceof Array)for(var e=0;e<this.options.dropdownFilter.length;e++)if("*"===this.options.dropdownFilter[e].value&&this.options.dropdownFilter[e].display){b=this.options.dropdownFilter[e].display;break}c("<span/>",{"class":this.options.selector.filter,html:function(){c(this).append(c("<button/>",{type:"button","class":d.options.selector.filterButton,html:"<span class='"+d.options.selector.filterValue+"'>"+b+"</span> <span class='"+d.options.selector.dropdownCarret+"'></span>",click:function(a){a.stopPropagation();var b=d.container.find("."+d.options.selector.dropdown.replace(" ","."));b.is(":visible")?(d.container.removeClass("filter"),b.hide(),c("html").off(f+".dropdownFilter")):(d.container.addClass("filter"),b.show(),c("html").off(f+".dropdownFilter").on("click"+f+".dropdownFilter touchstart"+f+".dropdownFilter",function(){d.container.removeClass("filter"),b.hide(),c(this).off(f+".dropdownFilter")}))}})),c(this).append(c("<ul/>",{"class":d.options.selector.dropdown,html:function(){var b=d.options.dropdownFilter;if(~["string","boolean"].indexOf(typeof d.options.dropdownFilter)){b=[];for(var e in d.options.source)d.options.source.hasOwnProperty(e)&&b.push({key:"group",value:e});b.push({key:"group",value:"*",display:"string"==typeof d.options.dropdownFilter&&d.options.dropdownFilter||"All"})}for(var f=0;f<b.length;f++)!function(b,e,f){(e.key||"*"===e.value)&&e.value&&("*"===e.value&&c(f).append(c("<li/>",{"class":"divider"})),c(f).append(c("<li/>",{html:c("<a/>",{href:"javascript:;",html:e.display||e.value,click:function(b){b.preventDefault(),a.apply(d,[e])}})})))}(f,b[f],this)}}))}}).insertAfter(d.container.find("."+d.options.selector.query))}},dynamicFilter:{validate:function(a){var b,c,d=null,e=null;for(var f in this.filters.dynamic)if(this.filters.dynamic.hasOwnProperty(f)&&(c=~f.indexOf(".")?this.helper.namespace(f,a,"get"):a[f],"|"!==this.filters.dynamic[f].modifier||d||(d=c==this.filters.dynamic[f].value||!1),"&"===this.filters.dynamic[f].modifier)){if(c!=this.filters.dynamic[f].value){e=!1;break}e=!0}return b=d,null!==e&&(b=e,e===!0&&null!==d&&(b=d)),!!b},set:function(a,b){var c=a.match(/^([|&])?(.+)/);b?this.filters.dynamic[c[2]]={modifier:c[1]||"|",value:b}:delete this.filters.dynamic[c[2]],this.searchResult(),this.buildLayout()},bind:function(){if(this.options.dynamicFilter)for(var a,b=this,d=0;d<this.options.dynamicFilter.length;d++)a=this.options.dynamicFilter[d],"string"==typeof a.selector&&(a.selector=c(a.selector)),a.selector instanceof jQuery&&a.selector[0]&&a.key&&!function(a){a.selector.off(f).on("change"+f,function(){b.dynamicFilter.set.apply(b,[a.key,b.dynamicFilter.getValue(this)])}).trigger("change"+f)}(a)},getValue:function(a){var b;return"SELECT"===a.tagName?b=a.value:"INPUT"===a.tagName&&("checkbox"===a.type?b=a.checked||null:"radio"===a.type&&a.checked&&(b=a.value)),b}},showLayout:function(){var a=this;c("html").off(f).on("click"+f+" touchstart"+f,function(){a.hideLayout(),c(this).off(f)}),(this.result.length||this.options.emptyTemplate)&&this.container.addClass("result hint backdrop")},hideLayout:function(){this.container.removeClass("result hint backdrop filter")},__construct:function(){this.extendOptions(),this.unifySourceFormat()&&(this.init(),this.delegateEvents(),this.buildDropdownLayout(),this.dynamicFilter.bind.apply(this),this.helper.executeCallback(this.options.callback.onReady,[this.node]))},helper:{isEmpty:function(a){for(var b in a)if(a.hasOwnProperty(b))return!1;return!0},removeAccent:function(a){return"string"==typeof a?a=a.toLowerCase().replace(new RegExp("["+g.from+"]","g"),function(a){return g.to[g.from.indexOf(a)]}):void 0},slugify:function(a){return a=String(a),""!==a&&(a=this.removeAccent(a),a=a.replace(/[^-a-z0-9]+/g,"-").replace(/-+/g,"-").trim("-")),a},sort:function(a,b,c){var d=function(b){for(var d=0;d<a.length;d++)if("undefined"!=typeof b[a[d]])return c(b[a[d]])};return b=[-1,1][+!!b],function(a,c){return a=d(a),c=d(c),b*((a>c)-(c>a))}},replaceAt:function(a,b,c,d){return a.substring(0,b)+d+a.substring(b+c)},highlight:function(a,b,c){a=String(a);var d=c&&this.removeAccent(a)||a,e=[];b instanceof Array||(b=[b]),b.sort(function(a,b){return b.length-a.length});for(var f=b.length-1;f>=0;f--)""!==b[f].trim()?b[f]=b[f].replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"):b.splice(f,1);d.replace(new RegExp("(?:"+b.join("|")+")(?!([^<]+)?>)","gi"),function(a,b,c){e.push({offset:c,length:a.length})});for(var f=e.length-1;f>=0;f--)a=this.replaceAt(a,e[f].offset,e[f].length,"<strong>"+a.substr(e[f].offset,e[f].length)+"</strong>");return a},joinObject:function(a,b){var c="",d=0;for(var e in a)a.hasOwnProperty(e)&&(0!==d&&(c+=b),c+=a[e],d++);return c},getCaret:function(a){if(a.selectionStart)return a.selectionStart;if(b.selection){a.focus();var c=b.selection.createRange();if(null==c)return 0;var d=a.createTextRange(),e=d.duplicate();return d.moveToBookmark(c.getBookmark()),e.setEndPoint("EndToStart",d),e.text.length}return 0},executeCallback:function(b,d){if(!b)return!1;var e;d[0];if("function"==typeof b)e=b;else if(("string"==typeof b||b instanceof Array)&&("string"==typeof b&&(b=[b,[]]),e=this.helper.namespace(b[0],a),"function"!=typeof e))return!1;return e.apply(this,c.merge(b[1]||[],d?d:[]))||!0},namespace:function(b,c,e,f){if("string"!=typeof b||""===b)return!1;for(var g=b.split("."),h=c||a,e=e||"get",i=f||{},j="",k=0,l=g.length;l>k;k++){if(j=g[k],"undefined"==typeof h[j]){if(~["get","delete"].indexOf(e))return"undefined"!=typeof f?f:d;h[j]={}}if(~["set","create","delete"].indexOf(e)&&k===l-1){if("set"!==e&&"create"!==e)return delete h[j],!0;h[j]=i}h=h[j]}return h},typeWatch:function(){var a=0;return function(b,c){clearTimeout(a),a=setTimeout(b,c)}}()}},c.fn.typeahead=c.typeahead=function(a){return j.typeahead(this,a)};var j={typeahead:function(b,d){if(d&&d.source&&"object"==typeof d.source){if("function"==typeof b){if(!d.input)return;b=c(d.input)}if(b.length)for(var e,f=0;f<b.length;f++)e=1===b.length?b:c(b.selector.split(",")[f].trim()),a.Typeahead[e.selector]=new i(e,d)}}};a.console=a.console||{log:function(){}},"trim"in String.prototype||(String.prototype.trim=function(){return this.replace(/^\s+/,"").replace(/\s+$/,"")}),"indexOf"in Array.prototype||(Array.prototype.indexOf=function(a,b){b===d&&(b=0),0>b&&(b+=this.length),0>b&&(b=0);for(var c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1}),Object.keys||(Object.keys=function(a){var b,c=[];for(b in a)Object.prototype.hasOwnProperty.call(a,b)&&c.push(b);return c})}(window,document,window.jQuery); diff --git a/web/packs/src/vendor/javascripts/moment.min.js b/web/packs/src/vendor/javascripts/moment.min.js deleted file mode 100644 index 3272fa4..0000000 --- a/web/packs/src/vendor/javascripts/moment.min.js +++ /dev/null @@ -1,7 +0,0 @@ -//! moment.js -//! version : 2.10.6 -//! authors : Tim Wood, Iskren Chernev, Moment.js contributors -//! license : MIT -//! momentjs.com -!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.moment=b()}(this,function(){"use strict";function a(){return Hc.apply(null,arguments)}function b(a){Hc=a}function c(a){return"[object Array]"===Object.prototype.toString.call(a)}function d(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function e(a,b){var c,d=[];for(c=0;c<a.length;++c)d.push(b(a[c],c));return d}function f(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function g(a,b){for(var c in b)f(b,c)&&(a[c]=b[c]);return f(b,"toString")&&(a.toString=b.toString),f(b,"valueOf")&&(a.valueOf=b.valueOf),a}function h(a,b,c,d){return Ca(a,b,c,d,!0).utc()}function i(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function j(a){return null==a._pf&&(a._pf=i()),a._pf}function k(a){if(null==a._isValid){var b=j(a);a._isValid=!(isNaN(a._d.getTime())||!(b.overflow<0)||b.empty||b.invalidMonth||b.invalidWeekday||b.nullInput||b.invalidFormat||b.userInvalidated),a._strict&&(a._isValid=a._isValid&&0===b.charsLeftOver&&0===b.unusedTokens.length&&void 0===b.bigHour)}return a._isValid}function l(a){var b=h(NaN);return null!=a?g(j(b),a):j(b).userInvalidated=!0,b}function m(a,b){var c,d,e;if("undefined"!=typeof b._isAMomentObject&&(a._isAMomentObject=b._isAMomentObject),"undefined"!=typeof b._i&&(a._i=b._i),"undefined"!=typeof b._f&&(a._f=b._f),"undefined"!=typeof b._l&&(a._l=b._l),"undefined"!=typeof b._strict&&(a._strict=b._strict),"undefined"!=typeof b._tzm&&(a._tzm=b._tzm),"undefined"!=typeof b._isUTC&&(a._isUTC=b._isUTC),"undefined"!=typeof b._offset&&(a._offset=b._offset),"undefined"!=typeof b._pf&&(a._pf=j(b)),"undefined"!=typeof b._locale&&(a._locale=b._locale),Jc.length>0)for(c in Jc)d=Jc[c],e=b[d],"undefined"!=typeof e&&(a[d]=e);return a}function n(b){m(this,b),this._d=new Date(null!=b._d?b._d.getTime():NaN),Kc===!1&&(Kc=!0,a.updateOffset(this),Kc=!1)}function o(a){return a instanceof n||null!=a&&null!=a._isAMomentObject}function p(a){return 0>a?Math.ceil(a):Math.floor(a)}function q(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=p(b)),c}function r(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;e>d;d++)(c&&a[d]!==b[d]||!c&&q(a[d])!==q(b[d]))&&g++;return g+f}function s(){}function t(a){return a?a.toLowerCase().replace("_","-"):a}function u(a){for(var b,c,d,e,f=0;f<a.length;){for(e=t(a[f]).split("-"),b=e.length,c=t(a[f+1]),c=c?c.split("-"):null;b>0;){if(d=v(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&r(e,c,!0)>=b-1)break;b--}f++}return null}function v(a){var b=null;if(!Lc[a]&&"undefined"!=typeof module&&module&&module.exports)try{b=Ic._abbr,require("./locale/"+a),w(b)}catch(c){}return Lc[a]}function w(a,b){var c;return a&&(c="undefined"==typeof b?y(a):x(a,b),c&&(Ic=c)),Ic._abbr}function x(a,b){return null!==b?(b.abbr=a,Lc[a]=Lc[a]||new s,Lc[a].set(b),w(a),Lc[a]):(delete Lc[a],null)}function y(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return Ic;if(!c(a)){if(b=v(a))return b;a=[a]}return u(a)}function z(a,b){var c=a.toLowerCase();Mc[c]=Mc[c+"s"]=Mc[b]=a}function A(a){return"string"==typeof a?Mc[a]||Mc[a.toLowerCase()]:void 0}function B(a){var b,c,d={};for(c in a)f(a,c)&&(b=A(c),b&&(d[b]=a[c]));return d}function C(b,c){return function(d){return null!=d?(E(this,b,d),a.updateOffset(this,c),this):D(this,b)}}function D(a,b){return a._d["get"+(a._isUTC?"UTC":"")+b]()}function E(a,b,c){return a._d["set"+(a._isUTC?"UTC":"")+b](c)}function F(a,b){var c;if("object"==typeof a)for(c in a)this.set(c,a[c]);else if(a=A(a),"function"==typeof this[a])return this[a](b);return this}function G(a,b,c){var d=""+Math.abs(a),e=b-d.length,f=a>=0;return(f?c?"+":"":"-")+Math.pow(10,Math.max(0,e)).toString().substr(1)+d}function H(a,b,c,d){var e=d;"string"==typeof d&&(e=function(){return this[d]()}),a&&(Qc[a]=e),b&&(Qc[b[0]]=function(){return G(e.apply(this,arguments),b[1],b[2])}),c&&(Qc[c]=function(){return this.localeData().ordinal(e.apply(this,arguments),a)})}function I(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function J(a){var b,c,d=a.match(Nc);for(b=0,c=d.length;c>b;b++)Qc[d[b]]?d[b]=Qc[d[b]]:d[b]=I(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function K(a,b){return a.isValid()?(b=L(b,a.localeData()),Pc[b]=Pc[b]||J(b),Pc[b](a)):a.localeData().invalidDate()}function L(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Oc.lastIndex=0;d>=0&&Oc.test(a);)a=a.replace(Oc,c),Oc.lastIndex=0,d-=1;return a}function M(a){return"function"==typeof a&&"[object Function]"===Object.prototype.toString.call(a)}function N(a,b,c){dd[a]=M(b)?b:function(a){return a&&c?c:b}}function O(a,b){return f(dd,a)?dd[a](b._strict,b._locale):new RegExp(P(a))}function P(a){return a.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e}).replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function Q(a,b){var c,d=b;for("string"==typeof a&&(a=[a]),"number"==typeof b&&(d=function(a,c){c[b]=q(a)}),c=0;c<a.length;c++)ed[a[c]]=d}function R(a,b){Q(a,function(a,c,d,e){d._w=d._w||{},b(a,d._w,d,e)})}function S(a,b,c){null!=b&&f(ed,a)&&ed[a](b,c._a,c,a)}function T(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function U(a){return this._months[a.month()]}function V(a){return this._monthsShort[a.month()]}function W(a,b,c){var d,e,f;for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),d=0;12>d;d++){if(e=h([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}}function X(a,b){var c;return"string"==typeof b&&(b=a.localeData().monthsParse(b),"number"!=typeof b)?a:(c=Math.min(a.date(),T(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a)}function Y(b){return null!=b?(X(this,b),a.updateOffset(this,!0),this):D(this,"Month")}function Z(){return T(this.year(),this.month())}function $(a){var b,c=a._a;return c&&-2===j(a).overflow&&(b=c[gd]<0||c[gd]>11?gd:c[hd]<1||c[hd]>T(c[fd],c[gd])?hd:c[id]<0||c[id]>24||24===c[id]&&(0!==c[jd]||0!==c[kd]||0!==c[ld])?id:c[jd]<0||c[jd]>59?jd:c[kd]<0||c[kd]>59?kd:c[ld]<0||c[ld]>999?ld:-1,j(a)._overflowDayOfYear&&(fd>b||b>hd)&&(b=hd),j(a).overflow=b),a}function _(b){a.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+b)}function aa(a,b){var c=!0;return g(function(){return c&&(_(a+"\n"+(new Error).stack),c=!1),b.apply(this,arguments)},b)}function ba(a,b){od[a]||(_(b),od[a]=!0)}function ca(a){var b,c,d=a._i,e=pd.exec(d);if(e){for(j(a).iso=!0,b=0,c=qd.length;c>b;b++)if(qd[b][1].exec(d)){a._f=qd[b][0];break}for(b=0,c=rd.length;c>b;b++)if(rd[b][1].exec(d)){a._f+=(e[6]||" ")+rd[b][0];break}d.match(ad)&&(a._f+="Z"),va(a)}else a._isValid=!1}function da(b){var c=sd.exec(b._i);return null!==c?void(b._d=new Date(+c[1])):(ca(b),void(b._isValid===!1&&(delete b._isValid,a.createFromInputFallback(b))))}function ea(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 1970>a&&h.setFullYear(a),h}function fa(a){var b=new Date(Date.UTC.apply(null,arguments));return 1970>a&&b.setUTCFullYear(a),b}function ga(a){return ha(a)?366:365}function ha(a){return a%4===0&&a%100!==0||a%400===0}function ia(){return ha(this.year())}function ja(a,b,c){var d,e=c-b,f=c-a.day();return f>e&&(f-=7),e-7>f&&(f+=7),d=Da(a).add(f,"d"),{week:Math.ceil(d.dayOfYear()/7),year:d.year()}}function ka(a){return ja(a,this._week.dow,this._week.doy).week}function la(){return this._week.dow}function ma(){return this._week.doy}function na(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")}function oa(a){var b=ja(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")}function pa(a,b,c,d,e){var f,g=6+e-d,h=fa(a,0,1+g),i=h.getUTCDay();return e>i&&(i+=7),c=null!=c?1*c:e,f=1+g+7*(b-1)-i+c,{year:f>0?a:a-1,dayOfYear:f>0?f:ga(a-1)+f}}function qa(a){var b=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")}function ra(a,b,c){return null!=a?a:null!=b?b:c}function sa(a){var b=new Date;return a._useUTC?[b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate()]:[b.getFullYear(),b.getMonth(),b.getDate()]}function ta(a){var b,c,d,e,f=[];if(!a._d){for(d=sa(a),a._w&&null==a._a[hd]&&null==a._a[gd]&&ua(a),a._dayOfYear&&(e=ra(a._a[fd],d[fd]),a._dayOfYear>ga(e)&&(j(a)._overflowDayOfYear=!0),c=fa(e,0,a._dayOfYear),a._a[gd]=c.getUTCMonth(),a._a[hd]=c.getUTCDate()),b=0;3>b&&null==a._a[b];++b)a._a[b]=f[b]=d[b];for(;7>b;b++)a._a[b]=f[b]=null==a._a[b]?2===b?1:0:a._a[b];24===a._a[id]&&0===a._a[jd]&&0===a._a[kd]&&0===a._a[ld]&&(a._nextDay=!0,a._a[id]=0),a._d=(a._useUTC?fa:ea).apply(null,f),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[id]=24)}}function ua(a){var b,c,d,e,f,g,h;b=a._w,null!=b.GG||null!=b.W||null!=b.E?(f=1,g=4,c=ra(b.GG,a._a[fd],ja(Da(),1,4).year),d=ra(b.W,1),e=ra(b.E,1)):(f=a._locale._week.dow,g=a._locale._week.doy,c=ra(b.gg,a._a[fd],ja(Da(),f,g).year),d=ra(b.w,1),null!=b.d?(e=b.d,f>e&&++d):e=null!=b.e?b.e+f:f),h=pa(c,d,e,g,f),a._a[fd]=h.year,a._dayOfYear=h.dayOfYear}function va(b){if(b._f===a.ISO_8601)return void ca(b);b._a=[],j(b).empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,k=0;for(e=L(b._f,b._locale).match(Nc)||[],c=0;c<e.length;c++)f=e[c],d=(h.match(O(f,b))||[])[0],d&&(g=h.substr(0,h.indexOf(d)),g.length>0&&j(b).unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),k+=d.length),Qc[f]?(d?j(b).empty=!1:j(b).unusedTokens.push(f),S(f,d,b)):b._strict&&!d&&j(b).unusedTokens.push(f);j(b).charsLeftOver=i-k,h.length>0&&j(b).unusedInput.push(h),j(b).bigHour===!0&&b._a[id]<=12&&b._a[id]>0&&(j(b).bigHour=void 0),b._a[id]=wa(b._locale,b._a[id],b._meridiem),ta(b),$(b)}function wa(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&12>b&&(b+=12),d||12!==b||(b=0),b):b}function xa(a){var b,c,d,e,f;if(0===a._f.length)return j(a).invalidFormat=!0,void(a._d=new Date(NaN));for(e=0;e<a._f.length;e++)f=0,b=m({},a),null!=a._useUTC&&(b._useUTC=a._useUTC),b._f=a._f[e],va(b),k(b)&&(f+=j(b).charsLeftOver,f+=10*j(b).unusedTokens.length,j(b).score=f,(null==d||d>f)&&(d=f,c=b));g(a,c||b)}function ya(a){if(!a._d){var b=B(a._i);a._a=[b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],ta(a)}}function za(a){var b=new n($(Aa(a)));return b._nextDay&&(b.add(1,"d"),b._nextDay=void 0),b}function Aa(a){var b=a._i,e=a._f;return a._locale=a._locale||y(a._l),null===b||void 0===e&&""===b?l({nullInput:!0}):("string"==typeof b&&(a._i=b=a._locale.preparse(b)),o(b)?new n($(b)):(c(e)?xa(a):e?va(a):d(b)?a._d=b:Ba(a),a))}function Ba(b){var f=b._i;void 0===f?b._d=new Date:d(f)?b._d=new Date(+f):"string"==typeof f?da(b):c(f)?(b._a=e(f.slice(0),function(a){return parseInt(a,10)}),ta(b)):"object"==typeof f?ya(b):"number"==typeof f?b._d=new Date(f):a.createFromInputFallback(b)}function Ca(a,b,c,d,e){var f={};return"boolean"==typeof c&&(d=c,c=void 0),f._isAMomentObject=!0,f._useUTC=f._isUTC=e,f._l=c,f._i=a,f._f=b,f._strict=d,za(f)}function Da(a,b,c,d){return Ca(a,b,c,d,!1)}function Ea(a,b){var d,e;if(1===b.length&&c(b[0])&&(b=b[0]),!b.length)return Da();for(d=b[0],e=1;e<b.length;++e)(!b[e].isValid()||b[e][a](d))&&(d=b[e]);return d}function Fa(){var a=[].slice.call(arguments,0);return Ea("isBefore",a)}function Ga(){var a=[].slice.call(arguments,0);return Ea("isAfter",a)}function Ha(a){var b=B(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;this._milliseconds=+k+1e3*j+6e4*i+36e5*h,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._locale=y(),this._bubble()}function Ia(a){return a instanceof Ha}function Ja(a,b){H(a,0,0,function(){var a=this.utcOffset(),c="+";return 0>a&&(a=-a,c="-"),c+G(~~(a/60),2)+b+G(~~a%60,2)})}function Ka(a){var b=(a||"").match(ad)||[],c=b[b.length-1]||[],d=(c+"").match(xd)||["-",0,0],e=+(60*d[1])+q(d[2]);return"+"===d[0]?e:-e}function La(b,c){var e,f;return c._isUTC?(e=c.clone(),f=(o(b)||d(b)?+b:+Da(b))-+e,e._d.setTime(+e._d+f),a.updateOffset(e,!1),e):Da(b).local()}function Ma(a){return 15*-Math.round(a._d.getTimezoneOffset()/15)}function Na(b,c){var d,e=this._offset||0;return null!=b?("string"==typeof b&&(b=Ka(b)),Math.abs(b)<16&&(b=60*b),!this._isUTC&&c&&(d=Ma(this)),this._offset=b,this._isUTC=!0,null!=d&&this.add(d,"m"),e!==b&&(!c||this._changeInProgress?bb(this,Ya(b-e,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?e:Ma(this)}function Oa(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}function Pa(a){return this.utcOffset(0,a)}function Qa(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(Ma(this),"m")),this}function Ra(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(Ka(this._i)),this}function Sa(a){return a=a?Da(a).utcOffset():0,(this.utcOffset()-a)%60===0}function Ta(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Ua(){if("undefined"!=typeof this._isDSTShifted)return this._isDSTShifted;var a={};if(m(a,this),a=Aa(a),a._a){var b=a._isUTC?h(a._a):Da(a._a);this._isDSTShifted=this.isValid()&&r(a._a,b.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function Va(){return!this._isUTC}function Wa(){return this._isUTC}function Xa(){return this._isUTC&&0===this._offset}function Ya(a,b){var c,d,e,g=a,h=null;return Ia(a)?g={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(g={},b?g[b]=a:g.milliseconds=a):(h=yd.exec(a))?(c="-"===h[1]?-1:1,g={y:0,d:q(h[hd])*c,h:q(h[id])*c,m:q(h[jd])*c,s:q(h[kd])*c,ms:q(h[ld])*c}):(h=zd.exec(a))?(c="-"===h[1]?-1:1,g={y:Za(h[2],c),M:Za(h[3],c),d:Za(h[4],c),h:Za(h[5],c),m:Za(h[6],c),s:Za(h[7],c),w:Za(h[8],c)}):null==g?g={}:"object"==typeof g&&("from"in g||"to"in g)&&(e=_a(Da(g.from),Da(g.to)),g={},g.ms=e.milliseconds,g.M=e.months),d=new Ha(g),Ia(a)&&f(a,"_locale")&&(d._locale=a._locale),d}function Za(a,b){var c=a&&parseFloat(a.replace(",","."));return(isNaN(c)?0:c)*b}function $a(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function _a(a,b){var c;return b=La(b,a),a.isBefore(b)?c=$a(a,b):(c=$a(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c}function ab(a,b){return function(c,d){var e,f;return null===d||isNaN(+d)||(ba(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period)."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=Ya(c,d),bb(this,e,a),this}}function bb(b,c,d,e){var f=c._milliseconds,g=c._days,h=c._months;e=null==e?!0:e,f&&b._d.setTime(+b._d+f*d),g&&E(b,"Date",D(b,"Date")+g*d),h&&X(b,D(b,"Month")+h*d),e&&a.updateOffset(b,g||h)}function cb(a,b){var c=a||Da(),d=La(c,this).startOf("day"),e=this.diff(d,"days",!0),f=-6>e?"sameElse":-1>e?"lastWeek":0>e?"lastDay":1>e?"sameDay":2>e?"nextDay":7>e?"nextWeek":"sameElse";return this.format(b&&b[f]||this.localeData().calendar(f,this,Da(c)))}function db(){return new n(this)}function eb(a,b){var c;return b=A("undefined"!=typeof b?b:"millisecond"),"millisecond"===b?(a=o(a)?a:Da(a),+this>+a):(c=o(a)?+a:+Da(a),c<+this.clone().startOf(b))}function fb(a,b){var c;return b=A("undefined"!=typeof b?b:"millisecond"),"millisecond"===b?(a=o(a)?a:Da(a),+a>+this):(c=o(a)?+a:+Da(a),+this.clone().endOf(b)<c)}function gb(a,b,c){return this.isAfter(a,c)&&this.isBefore(b,c)}function hb(a,b){var c;return b=A(b||"millisecond"),"millisecond"===b?(a=o(a)?a:Da(a),+this===+a):(c=+Da(a),+this.clone().startOf(b)<=c&&c<=+this.clone().endOf(b))}function ib(a,b,c){var d,e,f=La(a,this),g=6e4*(f.utcOffset()-this.utcOffset());return b=A(b),"year"===b||"month"===b||"quarter"===b?(e=jb(this,f),"quarter"===b?e/=3:"year"===b&&(e/=12)):(d=this-f,e="second"===b?d/1e3:"minute"===b?d/6e4:"hour"===b?d/36e5:"day"===b?(d-g)/864e5:"week"===b?(d-g)/6048e5:d),c?e:p(e)}function jb(a,b){var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),f=a.clone().add(e,"months");return 0>b-f?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)}function kb(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function lb(){var a=this.clone().utc();return 0<a.year()&&a.year()<=9999?"function"==typeof Date.prototype.toISOString?this.toDate().toISOString():K(a,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):K(a,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]")}function mb(b){var c=K(this,b||a.defaultFormat);return this.localeData().postformat(c)}function nb(a,b){return this.isValid()?Ya({to:this,from:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function ob(a){return this.from(Da(),a)}function pb(a,b){return this.isValid()?Ya({from:this,to:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function qb(a){return this.to(Da(),a)}function rb(a){var b;return void 0===a?this._locale._abbr:(b=y(a),null!=b&&(this._locale=b),this)}function sb(){return this._locale}function tb(a){switch(a=A(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===a&&this.weekday(0),"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this}function ub(a){return a=A(a),void 0===a||"millisecond"===a?this:this.startOf(a).add(1,"isoWeek"===a?"week":a).subtract(1,"ms")}function vb(){return+this._d-6e4*(this._offset||0)}function wb(){return Math.floor(+this/1e3)}function xb(){return this._offset?new Date(+this):this._d}function yb(){var a=this;return[a.year(),a.month(),a.date(),a.hour(),a.minute(),a.second(),a.millisecond()]}function zb(){var a=this;return{years:a.year(),months:a.month(),date:a.date(),hours:a.hours(),minutes:a.minutes(),seconds:a.seconds(),milliseconds:a.milliseconds()}}function Ab(){return k(this)}function Bb(){return g({},j(this))}function Cb(){return j(this).overflow}function Db(a,b){H(0,[a,a.length],0,b)}function Eb(a,b,c){return ja(Da([a,11,31+b-c]),b,c).week}function Fb(a){var b=ja(this,this.localeData()._week.dow,this.localeData()._week.doy).year;return null==a?b:this.add(a-b,"y")}function Gb(a){var b=ja(this,1,4).year;return null==a?b:this.add(a-b,"y")}function Hb(){return Eb(this.year(),1,4)}function Ib(){var a=this.localeData()._week;return Eb(this.year(),a.dow,a.doy)}function Jb(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)}function Kb(a,b){return"string"!=typeof a?a:isNaN(a)?(a=b.weekdaysParse(a),"number"==typeof a?a:null):parseInt(a,10)}function Lb(a){return this._weekdays[a.day()]}function Mb(a){return this._weekdaysShort[a.day()]}function Nb(a){return this._weekdaysMin[a.day()]}function Ob(a){var b,c,d;for(this._weekdaysParse=this._weekdaysParse||[],b=0;7>b;b++)if(this._weekdaysParse[b]||(c=Da([2e3,1]).day(b),d="^"+this.weekdays(c,"")+"|^"+this.weekdaysShort(c,"")+"|^"+this.weekdaysMin(c,""),this._weekdaysParse[b]=new RegExp(d.replace(".",""),"i")),this._weekdaysParse[b].test(a))return b}function Pb(a){var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=Kb(a,this.localeData()),this.add(a-b,"d")):b}function Qb(a){var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")}function Rb(a){return null==a?this.day()||7:this.day(this.day()%7?a:a-7)}function Sb(a,b){H(a,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),b)})}function Tb(a,b){return b._meridiemParse}function Ub(a){return"p"===(a+"").toLowerCase().charAt(0)}function Vb(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"}function Wb(a,b){b[ld]=q(1e3*("0."+a))}function Xb(){return this._isUTC?"UTC":""}function Yb(){return this._isUTC?"Coordinated Universal Time":""}function Zb(a){return Da(1e3*a)}function $b(){return Da.apply(null,arguments).parseZone()}function _b(a,b,c){var d=this._calendar[a];return"function"==typeof d?d.call(b,c):d}function ac(a){var b=this._longDateFormat[a],c=this._longDateFormat[a.toUpperCase()];return b||!c?b:(this._longDateFormat[a]=c.replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a])}function bc(){return this._invalidDate}function cc(a){return this._ordinal.replace("%d",a)}function dc(a){return a}function ec(a,b,c,d){var e=this._relativeTime[c];return"function"==typeof e?e(a,b,c,d):e.replace(/%d/i,a)}function fc(a,b){var c=this._relativeTime[a>0?"future":"past"];return"function"==typeof c?c(b):c.replace(/%s/i,b)}function gc(a){var b,c;for(c in a)b=a[c],"function"==typeof b?this[c]=b:this["_"+c]=b;this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function hc(a,b,c,d){var e=y(),f=h().set(d,b);return e[c](f,a)}function ic(a,b,c,d,e){if("number"==typeof a&&(b=a,a=void 0),a=a||"",null!=b)return hc(a,b,c,e);var f,g=[];for(f=0;d>f;f++)g[f]=hc(a,f,c,e);return g}function jc(a,b){return ic(a,b,"months",12,"month")}function kc(a,b){return ic(a,b,"monthsShort",12,"month")}function lc(a,b){return ic(a,b,"weekdays",7,"day")}function mc(a,b){return ic(a,b,"weekdaysShort",7,"day")}function nc(a,b){return ic(a,b,"weekdaysMin",7,"day")}function oc(){var a=this._data;return this._milliseconds=Wd(this._milliseconds),this._days=Wd(this._days),this._months=Wd(this._months),a.milliseconds=Wd(a.milliseconds),a.seconds=Wd(a.seconds),a.minutes=Wd(a.minutes),a.hours=Wd(a.hours),a.months=Wd(a.months),a.years=Wd(a.years),this}function pc(a,b,c,d){var e=Ya(b,c);return a._milliseconds+=d*e._milliseconds,a._days+=d*e._days,a._months+=d*e._months,a._bubble()}function qc(a,b){return pc(this,a,b,1)}function rc(a,b){return pc(this,a,b,-1)}function sc(a){return 0>a?Math.floor(a):Math.ceil(a)}function tc(){var a,b,c,d,e,f=this._milliseconds,g=this._days,h=this._months,i=this._data;return f>=0&&g>=0&&h>=0||0>=f&&0>=g&&0>=h||(f+=864e5*sc(vc(h)+g),g=0,h=0),i.milliseconds=f%1e3,a=p(f/1e3),i.seconds=a%60,b=p(a/60),i.minutes=b%60,c=p(b/60),i.hours=c%24,g+=p(c/24),e=p(uc(g)),h+=e,g-=sc(vc(e)),d=p(h/12),h%=12,i.days=g,i.months=h,i.years=d,this}function uc(a){return 4800*a/146097}function vc(a){return 146097*a/4800}function wc(a){var b,c,d=this._milliseconds;if(a=A(a),"month"===a||"year"===a)return b=this._days+d/864e5,c=this._months+uc(b),"month"===a?c:c/12;switch(b=this._days+Math.round(vc(this._months)),a){case"week":return b/7+d/6048e5;case"day":return b+d/864e5;case"hour":return 24*b+d/36e5;case"minute":return 1440*b+d/6e4;case"second":return 86400*b+d/1e3;case"millisecond":return Math.floor(864e5*b)+d;default:throw new Error("Unknown unit "+a)}}function xc(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*q(this._months/12)}function yc(a){return function(){return this.as(a)}}function zc(a){return a=A(a),this[a+"s"]()}function Ac(a){return function(){return this._data[a]}}function Bc(){return p(this.days()/7)}function Cc(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function Dc(a,b,c){var d=Ya(a).abs(),e=ke(d.as("s")),f=ke(d.as("m")),g=ke(d.as("h")),h=ke(d.as("d")),i=ke(d.as("M")),j=ke(d.as("y")),k=e<le.s&&["s",e]||1===f&&["m"]||f<le.m&&["mm",f]||1===g&&["h"]||g<le.h&&["hh",g]||1===h&&["d"]||h<le.d&&["dd",h]||1===i&&["M"]||i<le.M&&["MM",i]||1===j&&["y"]||["yy",j];return k[2]=b,k[3]=+a>0,k[4]=c,Cc.apply(null,k)}function Ec(a,b){return void 0===le[a]?!1:void 0===b?le[a]:(le[a]=b,!0)}function Fc(a){var b=this.localeData(),c=Dc(this,!a,b);return a&&(c=b.pastFuture(+this,c)),b.postformat(c)}function Gc(){var a,b,c,d=me(this._milliseconds)/1e3,e=me(this._days),f=me(this._months);a=p(d/60),b=p(a/60),d%=60,a%=60,c=p(f/12),f%=12;var g=c,h=f,i=e,j=b,k=a,l=d,m=this.asSeconds();return m?(0>m?"-":"")+"P"+(g?g+"Y":"")+(h?h+"M":"")+(i?i+"D":"")+(j||k||l?"T":"")+(j?j+"H":"")+(k?k+"M":"")+(l?l+"S":""):"P0D"}var Hc,Ic,Jc=a.momentProperties=[],Kc=!1,Lc={},Mc={},Nc=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,Oc=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Pc={},Qc={},Rc=/\d/,Sc=/\d\d/,Tc=/\d{3}/,Uc=/\d{4}/,Vc=/[+-]?\d{6}/,Wc=/\d\d?/,Xc=/\d{1,3}/,Yc=/\d{1,4}/,Zc=/[+-]?\d{1,6}/,$c=/\d+/,_c=/[+-]?\d+/,ad=/Z|[+-]\d\d:?\d\d/gi,bd=/[+-]?\d+(\.\d{1,3})?/,cd=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,dd={},ed={},fd=0,gd=1,hd=2,id=3,jd=4,kd=5,ld=6;H("M",["MM",2],"Mo",function(){return this.month()+1}),H("MMM",0,0,function(a){return this.localeData().monthsShort(this,a)}),H("MMMM",0,0,function(a){return this.localeData().months(this,a)}),z("month","M"),N("M",Wc),N("MM",Wc,Sc),N("MMM",cd),N("MMMM",cd),Q(["M","MM"],function(a,b){b[gd]=q(a)-1}),Q(["MMM","MMMM"],function(a,b,c,d){var e=c._locale.monthsParse(a,d,c._strict);null!=e?b[gd]=e:j(c).invalidMonth=a});var md="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),nd="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),od={};a.suppressDeprecationWarnings=!1;var pd=/^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,qd=[["YYYYYY-MM-DD",/[+-]\d{6}-\d{2}-\d{2}/],["YYYY-MM-DD",/\d{4}-\d{2}-\d{2}/],["GGGG-[W]WW-E",/\d{4}-W\d{2}-\d/],["GGGG-[W]WW",/\d{4}-W\d{2}/],["YYYY-DDD",/\d{4}-\d{3}/]],rd=[["HH:mm:ss.SSSS",/(T| )\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss",/(T| )\d\d:\d\d:\d\d/],["HH:mm",/(T| )\d\d:\d\d/],["HH",/(T| )\d\d/]],sd=/^\/?Date\((\-?\d+)/i;a.createFromInputFallback=aa("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),H(0,["YY",2],0,function(){return this.year()%100}),H(0,["YYYY",4],0,"year"),H(0,["YYYYY",5],0,"year"),H(0,["YYYYYY",6,!0],0,"year"),z("year","y"),N("Y",_c),N("YY",Wc,Sc),N("YYYY",Yc,Uc),N("YYYYY",Zc,Vc),N("YYYYYY",Zc,Vc),Q(["YYYYY","YYYYYY"],fd),Q("YYYY",function(b,c){c[fd]=2===b.length?a.parseTwoDigitYear(b):q(b)}),Q("YY",function(b,c){c[fd]=a.parseTwoDigitYear(b)}),a.parseTwoDigitYear=function(a){return q(a)+(q(a)>68?1900:2e3)};var td=C("FullYear",!1);H("w",["ww",2],"wo","week"),H("W",["WW",2],"Wo","isoWeek"),z("week","w"),z("isoWeek","W"),N("w",Wc),N("ww",Wc,Sc),N("W",Wc),N("WW",Wc,Sc),R(["w","ww","W","WW"],function(a,b,c,d){b[d.substr(0,1)]=q(a)});var ud={dow:0,doy:6};H("DDD",["DDDD",3],"DDDo","dayOfYear"),z("dayOfYear","DDD"),N("DDD",Xc),N("DDDD",Tc),Q(["DDD","DDDD"],function(a,b,c){c._dayOfYear=q(a)}),a.ISO_8601=function(){};var vd=aa("moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(){var a=Da.apply(null,arguments);return this>a?this:a}),wd=aa("moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(){var a=Da.apply(null,arguments);return a>this?this:a});Ja("Z",":"),Ja("ZZ",""),N("Z",ad),N("ZZ",ad),Q(["Z","ZZ"],function(a,b,c){c._useUTC=!0,c._tzm=Ka(a)});var xd=/([\+\-]|\d\d)/gi;a.updateOffset=function(){};var yd=/(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,zd=/^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;Ya.fn=Ha.prototype;var Ad=ab(1,"add"),Bd=ab(-1,"subtract");a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ";var Cd=aa("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(a){return void 0===a?this.localeData():this.locale(a)});H(0,["gg",2],0,function(){return this.weekYear()%100}),H(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Db("gggg","weekYear"),Db("ggggg","weekYear"),Db("GGGG","isoWeekYear"),Db("GGGGG","isoWeekYear"),z("weekYear","gg"),z("isoWeekYear","GG"),N("G",_c),N("g",_c),N("GG",Wc,Sc),N("gg",Wc,Sc),N("GGGG",Yc,Uc),N("gggg",Yc,Uc),N("GGGGG",Zc,Vc),N("ggggg",Zc,Vc),R(["gggg","ggggg","GGGG","GGGGG"],function(a,b,c,d){b[d.substr(0,2)]=q(a)}),R(["gg","GG"],function(b,c,d,e){c[e]=a.parseTwoDigitYear(b)}),H("Q",0,0,"quarter"),z("quarter","Q"),N("Q",Rc),Q("Q",function(a,b){b[gd]=3*(q(a)-1)}),H("D",["DD",2],"Do","date"),z("date","D"),N("D",Wc),N("DD",Wc,Sc),N("Do",function(a,b){return a?b._ordinalParse:b._ordinalParseLenient}),Q(["D","DD"],hd),Q("Do",function(a,b){b[hd]=q(a.match(Wc)[0],10)});var Dd=C("Date",!0);H("d",0,"do","day"),H("dd",0,0,function(a){return this.localeData().weekdaysMin(this,a)}),H("ddd",0,0,function(a){return this.localeData().weekdaysShort(this,a)}),H("dddd",0,0,function(a){return this.localeData().weekdays(this,a)}),H("e",0,0,"weekday"),H("E",0,0,"isoWeekday"),z("day","d"),z("weekday","e"),z("isoWeekday","E"),N("d",Wc),N("e",Wc),N("E",Wc),N("dd",cd),N("ddd",cd),N("dddd",cd),R(["dd","ddd","dddd"],function(a,b,c){var d=c._locale.weekdaysParse(a);null!=d?b.d=d:j(c).invalidWeekday=a}),R(["d","e","E"],function(a,b,c,d){b[d]=q(a)});var Ed="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Fd="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Gd="Su_Mo_Tu_We_Th_Fr_Sa".split("_");H("H",["HH",2],0,"hour"),H("h",["hh",2],0,function(){return this.hours()%12||12}),Sb("a",!0),Sb("A",!1),z("hour","h"),N("a",Tb),N("A",Tb),N("H",Wc),N("h",Wc),N("HH",Wc,Sc),N("hh",Wc,Sc),Q(["H","HH"],id),Q(["a","A"],function(a,b,c){c._isPm=c._locale.isPM(a),c._meridiem=a}),Q(["h","hh"],function(a,b,c){b[id]=q(a),j(c).bigHour=!0});var Hd=/[ap]\.?m?\.?/i,Id=C("Hours",!0);H("m",["mm",2],0,"minute"),z("minute","m"),N("m",Wc),N("mm",Wc,Sc),Q(["m","mm"],jd);var Jd=C("Minutes",!1);H("s",["ss",2],0,"second"),z("second","s"),N("s",Wc),N("ss",Wc,Sc),Q(["s","ss"],kd);var Kd=C("Seconds",!1);H("S",0,0,function(){return~~(this.millisecond()/100)}),H(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),H(0,["SSS",3],0,"millisecond"),H(0,["SSSS",4],0,function(){return 10*this.millisecond()}),H(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),H(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),H(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),H(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),H(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),z("millisecond","ms"),N("S",Xc,Rc),N("SS",Xc,Sc),N("SSS",Xc,Tc);var Ld;for(Ld="SSSS";Ld.length<=9;Ld+="S")N(Ld,$c);for(Ld="S";Ld.length<=9;Ld+="S")Q(Ld,Wb);var Md=C("Milliseconds",!1);H("z",0,0,"zoneAbbr"),H("zz",0,0,"zoneName");var Nd=n.prototype;Nd.add=Ad,Nd.calendar=cb,Nd.clone=db,Nd.diff=ib,Nd.endOf=ub,Nd.format=mb,Nd.from=nb,Nd.fromNow=ob,Nd.to=pb,Nd.toNow=qb,Nd.get=F,Nd.invalidAt=Cb,Nd.isAfter=eb,Nd.isBefore=fb,Nd.isBetween=gb,Nd.isSame=hb,Nd.isValid=Ab,Nd.lang=Cd,Nd.locale=rb,Nd.localeData=sb,Nd.max=wd,Nd.min=vd,Nd.parsingFlags=Bb,Nd.set=F,Nd.startOf=tb,Nd.subtract=Bd,Nd.toArray=yb,Nd.toObject=zb,Nd.toDate=xb,Nd.toISOString=lb,Nd.toJSON=lb,Nd.toString=kb,Nd.unix=wb,Nd.valueOf=vb,Nd.year=td,Nd.isLeapYear=ia,Nd.weekYear=Fb,Nd.isoWeekYear=Gb,Nd.quarter=Nd.quarters=Jb,Nd.month=Y,Nd.daysInMonth=Z,Nd.week=Nd.weeks=na,Nd.isoWeek=Nd.isoWeeks=oa,Nd.weeksInYear=Ib,Nd.isoWeeksInYear=Hb,Nd.date=Dd,Nd.day=Nd.days=Pb,Nd.weekday=Qb,Nd.isoWeekday=Rb,Nd.dayOfYear=qa,Nd.hour=Nd.hours=Id,Nd.minute=Nd.minutes=Jd,Nd.second=Nd.seconds=Kd, -Nd.millisecond=Nd.milliseconds=Md,Nd.utcOffset=Na,Nd.utc=Pa,Nd.local=Qa,Nd.parseZone=Ra,Nd.hasAlignedHourOffset=Sa,Nd.isDST=Ta,Nd.isDSTShifted=Ua,Nd.isLocal=Va,Nd.isUtcOffset=Wa,Nd.isUtc=Xa,Nd.isUTC=Xa,Nd.zoneAbbr=Xb,Nd.zoneName=Yb,Nd.dates=aa("dates accessor is deprecated. Use date instead.",Dd),Nd.months=aa("months accessor is deprecated. Use month instead",Y),Nd.years=aa("years accessor is deprecated. Use year instead",td),Nd.zone=aa("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",Oa);var Od=Nd,Pd={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},Qd={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},Rd="Invalid date",Sd="%d",Td=/\d{1,2}/,Ud={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},Vd=s.prototype;Vd._calendar=Pd,Vd.calendar=_b,Vd._longDateFormat=Qd,Vd.longDateFormat=ac,Vd._invalidDate=Rd,Vd.invalidDate=bc,Vd._ordinal=Sd,Vd.ordinal=cc,Vd._ordinalParse=Td,Vd.preparse=dc,Vd.postformat=dc,Vd._relativeTime=Ud,Vd.relativeTime=ec,Vd.pastFuture=fc,Vd.set=gc,Vd.months=U,Vd._months=md,Vd.monthsShort=V,Vd._monthsShort=nd,Vd.monthsParse=W,Vd.week=ka,Vd._week=ud,Vd.firstDayOfYear=ma,Vd.firstDayOfWeek=la,Vd.weekdays=Lb,Vd._weekdays=Ed,Vd.weekdaysMin=Nb,Vd._weekdaysMin=Gd,Vd.weekdaysShort=Mb,Vd._weekdaysShort=Fd,Vd.weekdaysParse=Ob,Vd.isPM=Ub,Vd._meridiemParse=Hd,Vd.meridiem=Vb,w("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===q(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),a.lang=aa("moment.lang is deprecated. Use moment.locale instead.",w),a.langData=aa("moment.langData is deprecated. Use moment.localeData instead.",y);var Wd=Math.abs,Xd=yc("ms"),Yd=yc("s"),Zd=yc("m"),$d=yc("h"),_d=yc("d"),ae=yc("w"),be=yc("M"),ce=yc("y"),de=Ac("milliseconds"),ee=Ac("seconds"),fe=Ac("minutes"),ge=Ac("hours"),he=Ac("days"),ie=Ac("months"),je=Ac("years"),ke=Math.round,le={s:45,m:45,h:22,d:26,M:11},me=Math.abs,ne=Ha.prototype;ne.abs=oc,ne.add=qc,ne.subtract=rc,ne.as=wc,ne.asMilliseconds=Xd,ne.asSeconds=Yd,ne.asMinutes=Zd,ne.asHours=$d,ne.asDays=_d,ne.asWeeks=ae,ne.asMonths=be,ne.asYears=ce,ne.valueOf=xc,ne._bubble=tc,ne.get=zc,ne.milliseconds=de,ne.seconds=ee,ne.minutes=fe,ne.hours=ge,ne.days=he,ne.weeks=Bc,ne.months=ie,ne.years=je,ne.humanize=Fc,ne.toISOString=Gc,ne.toString=Gc,ne.toJSON=Gc,ne.locale=rb,ne.localeData=sb,ne.toIsoString=aa("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Gc),ne.lang=Cd,H("X",0,0,"unix"),H("x",0,0,"valueOf"),N("x",_c),N("X",bd),Q("X",function(a,b,c){c._d=new Date(1e3*parseFloat(a,10))}),Q("x",function(a,b,c){c._d=new Date(q(a))}),a.version="2.10.6",b(Da),a.fn=Od,a.min=Fa,a.max=Ga,a.utc=h,a.unix=Zb,a.months=jc,a.isDate=d,a.locale=w,a.invalid=l,a.duration=Ya,a.isMoment=o,a.weekdays=lc,a.parseZone=$b,a.localeData=y,a.isDuration=Ia,a.monthsShort=kc,a.weekdaysMin=nc,a.defineLocale=x,a.weekdaysShort=mc,a.normalizeUnits=A,a.relativeTimeThreshold=Ec;var oe=a;return oe}); diff --git a/web/packs/src/vendor/stylesheets/.keep b/web/packs/src/vendor/stylesheets/.keep deleted file mode 100644 index e69de29..0000000 --- a/web/packs/src/vendor/stylesheets/.keep +++ /dev/null diff --git a/web/packs/src/vendor/stylesheets/jquery.typeahead.min.css b/web/packs/src/vendor/stylesheets/jquery.typeahead.min.css deleted file mode 100644 index c0720b9..0000000 --- a/web/packs/src/vendor/stylesheets/jquery.typeahead.min.css +++ /dev/null @@ -1 +0,0 @@ -.typeahead-field,.typeahead-query{position:relative;width:100%}.typeahead-button,.typeahead-container,.typeahead-field,.typeahead-filter,.typeahead-query{position:relative}.typeahead-container button,.typeahead-field input,.typeahead-select{border:1px solid #ccc;line-height:1.42857143;padding:6px 12px;height:32px}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}.typeahead-container,.typeahead-result.detached .typeahead-list{font-family:"Open Sans",Arial,Helvetica,Sans-Serif}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}.typeahead-container *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.typeahead-query{z-index:2}.typeahead-filter button{min-width:66px}.typeahead-field{display:table;border-collapse:separate}.typeahead-button{font-size:0;white-space:nowrap;width:1%;vertical-align:middle}.typeahead-field>span{display:table-cell;vertical-align:top}.typeahead-button button{border-top-right-radius:2px;border-bottom-right-radius:2px}.typeahead-field input,.typeahead-select{display:block;width:100%;font-size:13px;color:#555;background:0 0;border-radius:2px 0 0 2px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.typeahead-field input{-webkit-appearance:none;background:0 0}.typeahead-field input:last-child,.typeahead-hint{background:#fff}.typeahead-container button{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-color:#fff;white-space:nowrap;font-size:13px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:#333;box-shadow:inset 0 -2px 0 rgba(0,0,0,.05);-moz-box-shadow:inset 0 -2px 0 rgba(0,0,0,.05);-webkit-box-shadow:inset 0 -2px 0 rgba(0,0,0,.05)}.typeahead-container button:active,.typeahead-container button:focus{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}.typeahead-container button:focus,.typeahead-container button:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.typeahead-container button.active,.typeahead-container button:active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.typeahead-container button.disabled,.typeahead-container button[disabled],.typeahead-field input.disabled,.typeahead-field input[disabled]{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;background-color:#fff;border-color:#ccc}.typeahead-button button,.typeahead-filter button{margin-left:-1px;border-bottom-left-radius:0;border-top-left-radius:0}.typeahead-button,.typeahead-filter{z-index:1}.typeahead-button:active,.typeahead-button:active button:active,.typeahead-button:focus,.typeahead-button:focus button:focus,.typeahead-button:hover,.typeahead-container.filter .typeahead-filter,.typeahead-filter:active,.typeahead-filter:focus,.typeahead-filter:hover{z-index:1001}.typeahead-dropdown,.typeahead-list{position:absolute;top:100%;left:0;z-index:1000;width:100%;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:13px;text-align:left;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:2px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.typeahead-result.detached .typeahead-list{position:relative;z-index:1041;top:auto;left:auto}.typeahead-dropdown{right:0;left:auto;z-index:1001}.typeahead-list>li:first-child{border-top:none}.typeahead-list>li{position:relative;border-top:solid 1px rgba(0,0,0,.15)}.typeahead-dropdown>li>a,.typeahead-list>li>a{display:block;padding:6px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap;text-decoration:none}.typeahead-dropdown>li.active>a,.typeahead-dropdown>li>a:focus,.typeahead-dropdown>li>a:hover,.typeahead-list>li.active>a,.typeahead-list>li>a:focus,.typeahead-list>li>a:hover{background-color:#ebebeb;color:#333}.typeahead-list.empty>li.active>a,.typeahead-list.empty>li>a:focus,.typeahead-list.empty>li>a:hover{background-color:transparent}.typeahead-list.empty>li>a{cursor:default}.typeahead-list>li.typeahead-group.active>a,.typeahead-list>li.typeahead-group>a,.typeahead-list>li.typeahead-group>a:focus,.typeahead-list>li.typeahead-group>a:hover{border-color:#9cb4c5;color:#305d8c;background-color:#d6dde7;cursor:default}.typeahead-container.backdrop+.typeahead-backdrop,.typeahead-container.filter .typeahead-dropdown,.typeahead-container.hint .typeahead-hint,.typeahead-container.result .typeahead-list{display:block!important}.typeahead-container .typeahead-dropdown,.typeahead-container .typeahead-hint,.typeahead-container .typeahead-list,.typeahead-container+.typeahead-backdrop{display:none!important}.typeahead-dropdown .divider{height:1px;margin:5px 0;overflow:hidden;background-color:#e5e5e5}.typeahead-caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.typeahead-search-icon{min-width:40px;height:18px;font-size:13px;display:block;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABH0lEQVR4nJ3SvyvFYRTH8deVkkJ3UUZJIbJ8bzJjMtyMym6w2Njs/gCDP0AGCyWjxYDF5GdJYpS6xaIUw/d8771dT7qc+vZ8vs95zvuc5zmnlGWZsG6sYBGjsXeNHWzjQ8JKARjCEUZSh3CJeTy3OjoicxF8hwX0oi/0HSZwiK4UYKUpeBoHeMdb6OnwTWI5BVgMvYZaovwa1kMvpQBjoY8TwVp84ylAO/YV62cKcBt65hfAbKwPKcBu6E2UE8Hl8MF+CrCFG/nwnKKKnviqONOYj6NWQDFIg/I+/3ikFnuUX6d+lY4mR4ZVnMvnoIYLbKCCp0h0otG5egXt2HAED+BFPmAP7bYR7jGHV/RjCjr/AICryFzB3n8ARSX3xc83qRk4q9rDNWcAAAAASUVORK5CYII=) center center no-repeat} diff --git a/web/packs/useflags.js b/web/packs/useflags.js index 2c98c55..79db5ee 100644 --- a/web/packs/useflags.js +++ b/web/packs/useflags.js @@ -1,4 +1,4 @@ import 'd3/d3' -import './src/vendor/javascripts/jquery.typeahead.min' +import 'jquery-typeahead/dist/jquery.typeahead.min.js' import './src/javascript/useflags/typeahead' import './src/javascript/useflags/render-bubbles' diff --git a/web/templates/about/feedback.tmpl b/web/templates/about/feedback.tmpl deleted file mode 100644 index e7d50a8..0000000 --- a/web/templates/about/feedback.tmpl +++ /dev/null @@ -1,84 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - - -<div class="container mb-5"> - <div class="row"> - <div class="col-12"> - <ol class="breadcrumb"> - <li class="breadcrumb-item"><a href="/">Home</a></li> - <li class="breadcrumb-item"><a href="/about">About</a></li> - <li class="breadcrumb-item active">Feedback</li> - </ol> - - <h1>Feedback</h1> - - <p class="lead"> - Thanks for checking out the new packages.gentoo.org! - </p> - <p> - This site is currently in an <abbr title="minimum viable product">MVP</abbr> state and will be extended further to provide more useful features. - To help us prioritize new features and learn about your use case for the site, please share your ideas below. - <br><br> - </p> - - <div class="row"> - <div class="col-md-8"> - <div class="card"> - <h4 class="card-header"> - Send Feedback - </h4> - <div class="card-body"> - <form class="form-horizontal" method="post" action="/about/feedback"> - <div class="form-group row"> - <label for="feedback" class="col-sm-2 col-form-label font-weight-bold text-right">Your Feedback:</label> - <div class="col-sm-10"> - <textarea name="feedback" id="feedback" class="form-control" rows="10" placeholder="Please be sure to explain issues in detail and with exact URL references."></textarea> - </div> - </div> - <div class="form-group row"> - <label for="contact" class="col-sm-2 col-form-label font-weight-bold text-right">Contact (optional):</label> - <div class="col-sm-10"> - <input type="text" name="contact" class="form-control" id="contact" placeholder="How can we reach you to follow up on your feedback?"> - </div> - </div> - <div class="form-group row"> - <div class="offset-sm-2 col-sm-10"> - <button type="submit" class="btn btn-outline-primary">Send</button> - </div> - </div> - </form> - </div> - </div> - </div> - <div class="col-md-4"> - <div class="card"> - <h4 class="card-header"> - Other ways to get in touch - </h4> - <div class="list-group"> - <a href="mailto:gpackages@gentoo.org" class="list-group-item list-group-item-action text-dark"> - <span class="fa fa-fw fa-envelope"></span> - E-Mail: gpackages@gentoo.org - </a> - <a href="irc://irc.gentoo.org/gentoo-www" class="list-group-item list-group-item-action text-dark"> - <span class="fa fa-fw fa-comments-o"></span> - IRC: #gentoo-www - </a> - </div> - </div> - </div> - </div> - - </div> -</div> -</div> - - -{{template "footer" .Application }} - -</body> -</html> diff --git a/web/templates/about/feeds.tmpl b/web/templates/about/feeds.tmpl deleted file mode 100644 index a1560ad..0000000 --- a/web/templates/about/feeds.tmpl +++ /dev/null @@ -1,43 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - - -<div class="container mb-5"> - <div class="row"> - <div class="col-12"> - <ol class="breadcrumb"> - <li class="breadcrumb-item"><a href="/">Home</a></li> - <li class="breadcrumb-item"><a href="/about">About</a></li> - <li class="breadcrumb-item active">Update Feeds</li> - </ol> - - <h1>Update Feeds</h1> - - <p> - You can find Atom feeds here: - </p> - - <ul> - <li> - For all packages: Right column on the <a href="/categories">category listing</a>. - </li> - <li> - For specific architectures: In the <a href="/arches">architectures section</a>. - </li> - <li> - For specific packages: In the <em>Resources</em> box on the respective package pages. - </li> - </ul> - - </div> -</div> -</div> - - -{{template "footer" .Application }} - -</body> -</html> diff --git a/web/templates/about/help.tmpl b/web/templates/about/help.tmpl deleted file mode 100644 index e2c1fe6..0000000 --- a/web/templates/about/help.tmpl +++ /dev/null @@ -1,48 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - - -<div class="container mb-5"> - <div class="row"> - <div class="col-12"> - <ol class="breadcrumb"> - <li class="breadcrumb-item"><a href="/">Home</a></li> - <li class="breadcrumb-item"><a href="/about">About</a></li> - <li class="breadcrumb-item active">Help</li> - </ol> - - <h1>Help</h1> - - <h2 id="keyword-legend">Keyword table legend</h2> - - <ul class="list-group kk-keyword-legend"> - <li class="list-group-item kk-keyword-stable"> - <svg height="16" class="octicon octicon-diff-added" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM6 9H3V7h3V4h2v3h3v2H8v3H6V9z"></path></svg> Stable - </li> - <li class="list-group-item kk-keyword-testing"> - <svg height="16" class="octicon octicon-diff-modified" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM4 8c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3-3-1.34-3-3z"></path></svg> Testing - </li> - <li class="list-group-item kk-keyword-unavailable"> - <svg height="16" class="octicon octicon-diff-removed" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-2-5H3V7h8v2z"></path></svg> Explicitly unavailable - </li> - <li class="list-group-item kk-keyword-masked"> - <svg height="16" class="octicon octicon-diff-ignored" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-8.5-2H3v-1.5L9.5 4H11v1.5L4.5 12z"></path></svg> Masked - </li> - <li class="list-group-item kk-keyword-unknown"> - <span class="kk-octicon-spacer"></span> Unknown - </li> - </ul> - - - </div> -</div> -</div> - - -{{template "footer" .Application }} - -</body> -</html> diff --git a/web/templates/about/index.tmpl b/web/templates/about/index.tmpl deleted file mode 100644 index f280b64..0000000 --- a/web/templates/about/index.tmpl +++ /dev/null @@ -1,44 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - - -<div class="container mb-5"> - <div class="row"> - <div class="col-12 text-center"> - - <h1 class="px-3 pt-5 pb-1" style="font-size: 3em;">About packages.gentoo.org</h1> - <span style="font-size: 90%;" class="text-muted">Feel free to <a href="/about/feedback">get in touch</a> if you have any questions that are not answered on this page.<br/> - And welcome to the new packages.gentoo.org!</span> - - </div> - - <div class="col-12 mt-5 pt-4"> - - - <h2>FAQ</h2> - - <dl> - <dt>Which version is currently running?</dt> - <dd> - Currently {{.Application.Version}} is running. - </dd> - <br> - <dt>How often is the site updated?</dt> - <dd> - Updates are scheduled <strong>every 5 minutes now</strong>. - You can find the last time an import task was started in the footer. - </dd> - </dl> - -</div> -</div> -</div> - - -{{template "footer" .Application }} - -</body> -</html> diff --git a/web/templates/about/status.tmpl b/web/templates/about/status.tmpl deleted file mode 100644 index e2af6ac..0000000 --- a/web/templates/about/status.tmpl +++ /dev/null @@ -1,47 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - - -<div class="container mb-5"> - <div class="row"> - <div class="col-12 text-center"> - - <h1 class="px-3 pt-5 pb-1" style="font-size: 3em;">About packages.gentoo.org</h1> - <span style="font-size: 90%;" class="text-muted">Feel free to <a href="/about/feedback">get in touch</a> if you have any questions that are not answered on this page.<br/> - And welcome to the new packages.gentoo.org!</span> - - </div> - - <div class="col-8 offset-md-2 mt-5 pt-4"> - - <table class="table"> - <thead> - <tr> - <th scope="col">Type</th> - <th scope="col">Last Update</th> - <th scope="col">Age</th> - </tr> - </thead> - <tbody> - {{range .Applications}} - <tr> - <th scope="row" class="text-capitalize">{{.Id}}</th> - <td>{{.LastUpdate.Format "2 Jan 2006 15:04:05"}} UTC</td> - <td>{{timeSince .LastUpdate}}</td> - </tr> - {{end}} - </tbody> - </table> - - </div> -</div> -</div> - - -{{template "footer" .Application }} - -</body> -</html> diff --git a/web/templates/api/explore/graphiql.tmpl b/web/templates/api/explore/graphiql.tmpl deleted file mode 100644 index 584b5fc..0000000 --- a/web/templates/api/explore/graphiql.tmpl +++ /dev/null @@ -1,25 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - <head> - <title>GraphiQL - Gentoo Packages</title> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <meta name="theme-color" content="#54487a"> - <meta name="description" content="Gentoo Packages GraphiQL GraphQL API Explorer"> - <link rel="icon" href="https://packages.gentoo.org/favicon.ico" type="image/x-icon"> - <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> - <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> - <link rel="stylesheet" href="https://unpkg.com/graphiql/graphiql.min.css" /> - </head> - - <body> - <div id="graphiql"> - Loading... - </div> - <script src="https://unpkg.com/graphiql@0.17.5/graphiql.min.js" type="application/javascript"></script> - <script> - window.graphqlEndpoint = '{{ . }}'; - </script> - <script src="/assets/graphiql.js" type="application/javascript"></script> - </body> -</html> diff --git a/web/templates/arches/archesheader.tmpl b/web/templates/arches/archesheader.tmpl deleted file mode 100644 index a873732..0000000 --- a/web/templates/arches/archesheader.tmpl +++ /dev/null @@ -1,31 +0,0 @@ -{{define "archesheader"}} - <div class="kk-header-container"> - <div class="container"> - <div class="row"> - <div class="col-12"> - - <div class="row mt-3"> - <div class="col-md-5 pt-2"> - <h1 class="stick-top kk-package-title" id="package-title"> - <div> - <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-server"></span><span class="ml-2">Architectures</span></div> - </div> - </h1> - </div> - <div class="col-md-7"> - - </div> - - <div class="col-md-12 pt-4 mt-1"> - <nav class="nav kk-package-nav"> - {{range $.UserPreferences.Arches.Visible}} - <a class="nav-link {{if eq $.Arch .}}active{{end}}" href="/arches/{{.}}/{{$.UserPreferences.Arches.DefaultPage}}">{{.}}</a> - {{end}} - </nav> - </div> - </div> - </div> - </div> - </div> - </div> -{{end}} diff --git a/web/templates/arches/changedVersionRows.tmpl b/web/templates/arches/changedVersionRows.tmpl deleted file mode 100644 index d27def4..0000000 --- a/web/templates/arches/changedVersionRows.tmpl +++ /dev/null @@ -1,77 +0,0 @@ -{{define "changedversions"}} - {{range $index, $version := .Versions}} - <li class="list-group-item kk-package-detailed"> - <div class="row"> - <div class="col-xs-12 col-md-6"> - <h4 class="stick-top"><a href="/packages/{{.Atom}}">{{.Atom}}</a></h4> - <div class="kk-package-detailed-toolbox"> - - <button type="button" class="kk-btn-xs btn btn-outline-secondary" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> - <span class="fa fa-fw fa-navicon"></span> - </button> - <div class="dropdown-menu dropdown-menu-right"> - <a class="dropdown-item" href="https://bugs.gentoo.org/buglist.cgi?quicksearch={{.Category}}%2F{{.Package}}" target="_blank"> - <span class="fa fa-fw fa-bug"></span> - Related bugs - </a> - <a class="dropdown-item" href="https://wiki.gentoo.org/index.php?title=Special%3ASearch&fulltext=Search&search={{.Package}}" target="_blank"> - <span class="fa fa-fw fa-book"></span> - Documentation - </a> - <a class="dropdown-item" href="https://forums.gentoo.org/search.php?search_terms=all&show_results=topics&search_keywords={{.Package}}&mode=results" target="_blank"> - <span class="fa fa-fw fa-comments-o"></span> - Forums posts - </a> - <div class="dropdown-divider"></div> - <a class="dropdown-item" href="https://gitweb.gentoo.org/repo/gentoo.git/tree/{{.Atom}}" target="_blank"> - <span class="fa fa-fw fa-code-fork"></span> - Git repository browser - </a> - <a class="dropdown-item" href="https://gitweb.gentoo.org/repo/gentoo.git/log/{{.Atom}}?showmsg=1" target="_blank"> - <span class="fa fa-fw fa-history"></span> - Git log - </a> - <a class="dropdown-item" href="https://gitweb.gentoo.org/repo/gentoo.git/atom/{{.Atom}}?h=master" target="_blank"> - <span class="fa fa-fw fa-rss"></span> - Changes feed - </a> - </div> - - </div> - {{.Description}} - <br> - <small class="text-muted"> - </small> - {{if ge (len .Commits) 1 }} - <div class="kk-inline-changelog-entry"> - <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{ (index .Commits 0).Id }}" title="Git commit"> - <span class="octicon octicon-git-pull-request"></span> - <span class="kk-commit-message">{{ (index .Commits 0).Message }}</span> - </a> - </div> - {{end}} - </div> - <div class="col-xs-12 col-md-6"> - <small class="text-muted pull-right"> - <span class="kk-i18n-date" title="{{if ge (len .Commits) 1 }}{{(index .Commits 0).CommitterDate}}{{else}}unknown{{end}}">{{if ge (len .Commits) 1 }}{{(index .Commits 0).CommitterDate}}{{else}}unknown{{end}}</span> - </small> - <div class="kk-version-card"> - <p class="mb-2"><strong>{{.Version}}</strong><span class="kk-slot"> : {{.Slot}}</span> {{if .Restricts}}<span class="badge badge-danger kk-restrict-label" title="The following features are restricted: {{range .Restricts}}{{.}} {{end}}">{{formatRestricts .Restricts}}</span>{{end}}</p> - <p> - {{ range $.UserPreferences.Arches.Visible }} - {{if contains (print " " $version.Keywords " ") (print " " . " ")}} - <span class="label kk-keyword-stable" title="{{$version.Version}} is testing on {{.}}">{{.}}</span> - {{else if contains (print " " $version.Keywords " ") (print "~" . " ")}} - <span class="label kk-keyword-testing" title="{{$version}} is stable on {{.}}">~{{.}}</span> - {{else}} - <span class="label kk-keyword-unknown" title="{{$version.Version}} is unknown on {{.}}">?{{.}}</span> - {{end}} - {{end}} - </p> - </div> - - </div> - </div> - </li> - {{end}} -{{end}} diff --git a/web/templates/arches/changedVersions.tmpl b/web/templates/arches/changedVersions.tmpl deleted file mode 100644 index cdfafac..0000000 --- a/web/templates/arches/changedVersions.tmpl +++ /dev/null @@ -1,50 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - -{{template "archesheader" .}} - - -<div class="tab-content" id="myTabContent"> - -<div class="container mb-5"> - <div class="row"> - <div class="col-11"> - - {{if eq .Name "Keyworded"}} - <h3> - <a class="text-dark"><i class="fa fa-circle-o" aria-hidden="true"></i> Keyworded Packages</a> - <a href="/arches/{{.Arch}}/stable" class="ml-3 text-muted"><i class="fa fa-check-circle-o" aria-hidden="true"></i> Newly Stable Packages</a> - </h3> - {{else}} - <h3> - <a href="/arches/{{.Arch}}/keyworded" class="text-muted"><i class="fa fa-circle-o" aria-hidden="true"></i> Keyworded Packages</a> - <a class="ml-3 text-dark"><i class="fa fa-check-circle-o" aria-hidden="true"></i> Newly Stable Packages</a> - </h3> - {{end}} - </div> - <div class="col-1 text-right"> - <h3> - <a title="Atom feed" href="/arches/{{.Arch}}/{{.FeedName}}.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </h3> - </div> - <div class="col-12"> - <li class="list-group"> - {{template "changedversions" .}} - </li> - - - </div> - </div> -</div> - - -</div> - - -{{template "footer" .Application }} - -</body> -</html> diff --git a/web/templates/arches/index.tmpl b/web/templates/arches/index.tmpl deleted file mode 100644 index 340f33a..0000000 --- a/web/templates/arches/index.tmpl +++ /dev/null @@ -1,149 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - -{{template "archesheader" .}} - - -<div class="tab-content" id="myTabContent"> - -<div class="container mb-5"> - <div class="row"> - <div class="col-12"> - <div class="card border-top-0"> - <div class="table-responsive"> - <table class="table table-striped mb-0"> - <colgroup><col> - <col style="width: 20em;"> - <col style="width: 20em;"> - </colgroup><tbody> - <tr> - <th class="kk-nobreak-cell">alpha</th> - <td> - <a href="/arches/alpha/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a> - <a title="Atom feed" href="/arches/alpha/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - <td> - <a href="/arches/alpha/stable">Newly Stable Packages</a> - <a title="Atom feed" href="/arches/alpha/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - </tr> - <tr> - <th class="kk-nobreak-cell">amd64</th> - <td> - <a href="/arches/amd64/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a> - <a title="Atom feed" href="/arches/amd64/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - <td> - <a href="/arches/amd64/stable">Newly Stable Packages</a> - <a title="Atom feed" href="/arches/amd64/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - </tr> - <tr> - <th class="kk-nobreak-cell">arm</th> - <td> - <a href="/arches/arm/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a> - <a title="Atom feed" href="/arches/arm/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - <td> - <a href="/arches/arm/stable">Newly Stable Packages</a> - <a title="Atom feed" href="/arches/arm/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - </tr> - <tr> - <th class="kk-nobreak-cell">arm64</th> - <td> - <a href="/arches/arm64/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a> - <a title="Atom feed" href="/arches/arm64/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - <td> - <a href="/arches/arm64/stable">Newly Stable Packages</a> - <a title="Atom feed" href="/arches/arm64/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - </tr> - <tr> - <th class="kk-nobreak-cell">hppa</th> - <td> - <a href="/arches/hppa/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a> - <a title="Atom feed" href="/arches/hppa/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - <td> - <a href="/arches/hppa/stable">Newly Stable Packages</a> - <a title="Atom feed" href="/arches/hppa/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - </tr> - <tr> - <th class="kk-nobreak-cell">ia64</th> - <td> - <a href="/arches/ia64/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a> - <a title="Atom feed" href="/arches/ia64/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - <td> - <a href="/arches/ia64/stable">Newly Stable Packages</a> - <a title="Atom feed" href="/arches/ia64/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - </tr> - <tr> - <th class="kk-nobreak-cell">ppc</th> - <td> - <a href="/arches/ppc/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a> - <a title="Atom feed" href="/arches/ppc/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - <td> - <a href="/arches/ppc/stable">Newly Stable Packages</a> - <a title="Atom feed" href="/arches/ppc/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - </tr> - <tr> - <th class="kk-nobreak-cell">ppc64</th> - <td> - <a href="/arches/ppc64/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a> - <a title="Atom feed" href="/arches/ppc64/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - <td> - <a href="/arches/ppc64/stable">Newly Stable Packages</a> - <a title="Atom feed" href="/arches/ppc64/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - </tr> - <tr> - <th class="kk-nobreak-cell">sparc</th> - <td> - <a href="/arches/sparc/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a> - <a title="Atom feed" href="/arches/sparc/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - <td> - <a href="/arches/sparc/stable">Newly Stable Packages</a> - <a title="Atom feed" href="/arches/sparc/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - </tr> - <tr> - <th class="kk-nobreak-cell">x86</th> - <td> - <a href="/arches/x86/keyworded"><span class="translation_missing" title="translation missing: en.keyworded_packages">Keyworded Packages</span></a> - <a title="Atom feed" href="/arches/x86/keyworded.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - <td> - <a href="/arches/x86/stable">Newly Stable Packages</a> - <a title="Atom feed" href="/arches/x86/stable.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a> - </td> - </tr> - </tbody> - </table> - </div> - </div> - - </div> -</div> -</div> - - - -</div> - - -{{template "footer" .Application }} - -</body> -</html> diff --git a/web/templates/categories/browsecategoriesheader.tmpl b/web/templates/categories/browsecategoriesheader.tmpl deleted file mode 100644 index c5a43a5..0000000 --- a/web/templates/categories/browsecategoriesheader.tmpl +++ /dev/null @@ -1,36 +0,0 @@ -{{define "browsecategoriesheader"}} - <div class="kk-header-container"> - <div class="container"> - <div class="row"> - <div class="col-12"> - - <div class="row mt-3"> - <div class="col-md-5 pt-2"> - <h1 class="stick-top kk-package-title" id="package-title"> - <div> - <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-cubes"></span><span class="ml-2">Packages</span></div> - </div> - </h1> - </div> - <div class="col-md-7"> - - </div> - - <div class="col-md-12 pt-4 mt-1"> - <nav class="nav kk-package-nav"> - <a class="nav-link active" href="/categories/browse"><i class="fa fa-list-ul mr-1" aria-hidden="true"></i>Categories</a> - <a class="nav-link" href="/packages/added"><i class="fa fa-history mr-1" aria-hidden="true"></i> Added</a> - <a class="nav-link" href="/packages/updated"><i class="fa fa-asterisk mr-1" aria-hidden="true"></i> Updated</a> - <a class="nav-link" href="/packages/stable"><i class="fa fa-check-circle-o mr-1" aria-hidden="true"></i> Newly Stable</a> - <a class="nav-link" href="/packages/keyworded"><i class="fa fa-circle-o mr-1" aria-hidden="true"></i> Keyworded</a> - - <a class="nav-link d-none" href="/categories/insights"><i class="fa fa-bar-chart mr-1" aria-hidden="true"></i> Insights</a> - - </nav> - </div> - </div> - </div> - </div> - </div> - </div> -{{end}} diff --git a/web/templates/categories/categoryheader.tmpl b/web/templates/categories/categoryheader.tmpl deleted file mode 100644 index 3f51db6..0000000 --- a/web/templates/categories/categoryheader.tmpl +++ /dev/null @@ -1,30 +0,0 @@ -{{define "categoryheader"}} - - <div class="kk-header-container"> - <div class="container"> - <div class="row"> - <div class="col-12"> - - <div class="row mt-3 pt-2"> - <div class="col-md-5"> - <h1 class="stick-top kk-package-title" id="package-title"> - <div> - <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-cubes"></span><span class="ml-2">{{.Name}}</span></div> - </div> - </h1> - </div> - <div class="col-md-7"> - {{.Description}} - </div> - - <div class="col-md-12 pt-4 mt-1"> - <nav class="nav kk-package-nav"> - <a class="nav-link active" href="/categories"><i class="fa fa-list-ul mr-1" aria-hidden="true"></i>Packages</a> - </nav> - </div> - </div> - </div> - </div> - </div> - </div> -{{end}} diff --git a/web/templates/categories/index.tmpl b/web/templates/categories/index.tmpl deleted file mode 100644 index f56624e..0000000 --- a/web/templates/categories/index.tmpl +++ /dev/null @@ -1,51 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - - -{{template "browsecategoriesheader" .}} - - -<div class="tab-content" id="myTabContent"> - -<div class="container mb-5"> - <div class="row"> - <div class="col-12"> - - <div class="row"> - <div class="col-md-12"> - <h3 class="d-none mb-2">Browse all Categories</h3> - <div class="card rounded" style="background: none;border: none;"> - <div class="card-body"> - <ul class="kk-col-list kk-6col-list kk-category-listing"> - {{ $prevletter := "z"}} - {{range .Categories}} - {{ if (ne (printf "%.1s" .Name) $prevletter)}} - <li class="kk-col-list-header"><span class="kk-group-header">{{ printf "%.1s" .Name }}</span></li> - {{end}} - {{ $prevletter = (printf "%.1s" .Name) }} - - <li> - <a title="{{.Description}}" data-toggle="tooltip" data-placement="right" href="/categories/{{.Name}}">{{.Name}}</a> - </li> - {{end}} - </ul> - </div> - </div> - </div> - </div> - - - </div> - </div> -</div> - -</div> - - -{{template "footer" .Application }} - -</body> -</html> diff --git a/web/templates/categories/packageline.tmpl b/web/templates/categories/packageline.tmpl deleted file mode 100644 index 64a10df..0000000 --- a/web/templates/categories/packageline.tmpl +++ /dev/null @@ -1,6 +0,0 @@ -{{define "packageline"}} - <tr> - <th class="kk-nobreak-cell"><a href="/packages/{{.Atom}}">{{.Name}}</a></th> - <td>{{ (index .Versions 0).Description }}</td> - </tr> -{{end}} diff --git a/web/templates/categories/show.tmpl b/web/templates/categories/show.tmpl deleted file mode 100644 index 51c48de..0000000 --- a/web/templates/categories/show.tmpl +++ /dev/null @@ -1,69 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - - -{{template "categoryheader" .Category }} - - -<div class="tab-content" id="myTabContent"> - -<div class="container mb-5"> - <div class="row"> - <div class="col-12"> - - - <div class="row"> - <div class="col-md-9"> - <!--<p> - <input type="text" class="form-control form-control-xl" placeholder="Search packages in <%= @category.name %>"> - </p>--> - - <div class="card border-top-0 rounded"> - <table class="table mb-0 rounded"> - {{$prevCatLetter := (printf "%.1s" (index .Category.Packages 0).Name) }} - {{range .Category.Packages}} - {{ if ne (printf "%.1s" .Name) $prevCatLetter}} - {{$prevCatLetter = (printf "%.1s" .Name)}} - <tr id="{{$prevCatLetter}}"></tr> - {{end}} - {{template "packageline" .}} - {{end}} - </table> - </div> - </div> - <div class="col-md-3"> - <h4>Statistics</h4> - <dd class="ml-3"> - <dl>Packages: {{ len .Category.Packages }}</dl> - </dd> - <h4 class="mt-4">Filter by Category</h4> - <div class="row pl-4 pr-5 mr-5"> - {{$prevLetter := (printf "%.1s" (index .Category.Packages 0).Name) }} - {{ range .Category.Packages }} - {{ if ne (printf "%.1s" .Name) $prevLetter}} - <div class="col-md-2 px-2"><a href="#{{$prevLetter}}" class="text-muted text-capitalize">{{$prevLetter}}</a></div> - {{$prevLetter = (printf "%.1s" .Name)}} - {{end}} - {{end}} - <div class="col-md-2 px-2"><a href="#{{$prevLetter}}" class="text-muted text-capitalize">{{$prevLetter}}</a></div> - </div> - </div> - </div> - - - </div> - </div> -</div> - - - -</div> - - -{{template "footer" .Application }} - -</body> -</html> diff --git a/web/templates/index/show.tmpl b/web/templates/index/show.tmpl deleted file mode 100644 index 5f732e6..0000000 --- a/web/templates/index/show.tmpl +++ /dev/null @@ -1,86 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - -<div class="container mb-5"> - <div class="row"> - <div class="col-12"> - - - <div class="jumbotron mb-3" style="background: none!important;"> - <h2 class="site-welcome stick-top">Welcome to the Home <br/> - of <span class="text-primary"> {{.PackageCount}} </span> Gentoo Packages</h2> - - <form action="/packages/search" method="get"> - <div class="typeahead-container px-5"> - <div class="typeahead-field"> - <span class="typeahead-query" style="font-size: 1.1em; height: 2.3em;"> - <input class="rounded-left" style="font-size: 1.1em; height: 2.3em;border-right: 0px;" id="q" name="q" type="search" autocomplete="off" placeholder="Find Packages" aria-label="Find Packages" autofocus> - </span> - - <span class="typeahead-button" style="font-size: 1.1em!important; height: 2.3em!important;border-left: 0px;"> - <button style="border-top-right-radius: 0.25rem !important; border-bottom-right-radius: 0.25rem !important; font-size: 1.1em!important; height: 2.3em!important;border-left: 0px;box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);!important;" type="submit" title="Find" aria-label="Find"> - <span class="typeahead-search-icon"></span><span class="sr-only">Find</span> - </button> - </span> - </div> - </div> - </form> - <br/> - <small class="mt-4 px-5 text-muted" style="font-size: 12px;">This is the new packages.gentoo.org site. If anything isn't working as expected, <a href="mailto:gpackages@gentoo.org">contact us</a>.</small><br> - <small class="px-5 text-muted" style - - ="font-size: 12px;">You can search by <a href="/packages/search?q=sys-kernel/gentoo-sources">atom</a>, <a href="/packages/search?q=sys-kernel">category</a>, <a href="/packages/search?q=gentoo-sources">name</a>, <a href="/packages/search?q=kernel@gentoo.org">maintainer</a> or <a href="/packages/search?q=x11-wm%20haskell@gentoo.org">combine</a> queries. Results similar to your query will be found as well.</small> - - </div> - </div> - <div class="col-12"> - <h3 class="mb-2"><span class="fa fa-fw fa-history"></span> - {{if eq .UserPreferences.General.LandingPageLayout "classic"}}<a class="text-dark" href="/packages/added">Added Packages</a>{{else}}<a class="text-dark">Search History</a>{{end}} - </h3> - <div class="card border-top-0 mb-4"> - <div class="table-responsive rounded"> - <table class="table table-striped rounded mb-0"> - <tbody> - {{range .AddedPackages}} - <tr> - <td> - <a href="/packages/{{.Atom}}"> - <span class="text-muted">{{.Category}}</span>/<strong>{{.Name}}</strong> - </a> - </td> - <td>{{(index .Versions 0).Description}}</td> - </tr> - {{end}} - {{if eq .UserPreferences.General.LandingPageLayout "full"}} - {{if eq (len .AddedPackages) 0}} - <tr><td class="text-center"><i>Visited packages will be displayed here in future</i></td></tr> - {{end}} - {{end}} - </tbody> - </table> - </div> - </div> - </div> - <div class="col-12"> - <h3 class="pt-3 mb-2"><span class="fa fa-fw fa-asterisk"></span> - <a class="text-dark" href="/packages/updated">Updated Packages</a></h3> - <ul class="list-group"> - {{range .UpdatedPackages}} - {{template "changedversion" .}} - {{end}} - </ul> - - </div> - </div> -</div> - - -{{template "footer" .Application}} - -<script src="assets/index.js"></script> - -</body> -</html> diff --git a/web/templates/layout/footer.tmpl b/web/templates/layout/footer.tmpl deleted file mode 100644 index 280d137..0000000 --- a/web/templates/layout/footer.tmpl +++ /dev/null @@ -1,49 +0,0 @@ -{{define "footer"}} - <footer style="background-color: #fafafa; box-shadow:none!important;"> - <div class="container pt-4" style="border-top: 1px solid #dddddd;"> - <div class="row d-none"> - <div class="col-12 offset-md-2 col-md-7"> - <h3 class="footerhead">Gentoo Packages Database</h3> - <div class="row"> - <div class="col-xs-12 col-md-4"> - <span class="kk-group-header">Data as current of</span><br>{{ .LastUpdate.Format "Jan 02, 2006 15:04:05 UTC" }} - </div> - <div class="col-xs-12 col-md-4"> - </div> - <div class="col-xs-12 col-md-4"> - </div> - </div> - </div> - <div class="col-12 col-md-3"> - <h3 class="footerhead">Questions or comments?</h3> - Please feel free to <a href="https://www.gentoo.org/inside-gentoo/contact/">contact us</a>. - <p class="mt-2"><a href="https://gitweb.gentoo.org/sites/soko.git/">{{ .Version }}</a></p> - </div> - </div> - <div class="row"> - <div class="col-2 col-sm-2 col-md-2"> - <ul class="footerlinks three-icons"> - <li><a href="https://twitter.com/gentoo" title="@Gentoo on Twitter"><span class="fa fa-twitter fa-fw"></span></a></li> - <li><a href="https://www.facebook.com/gentoo.org" title="Gentoo on Facebook"><span class="fa fa-facebook fa-fw"></span></a></li> - <li><a href="https://www.reddit.com/r/Gentoo/" title="Gentoo on Reddit"><span class="fa fa-reddit-alien fa-fw"></span></a></li> - </ul> - </div> - <div class="col-8 col-sm-8 col-md-8"> - <strong>© 2001–2020 Gentoo Foundation, Inc.</strong><br> - <small> - Gentoo is a trademark of the Gentoo Foundation, Inc. - The contents of this document, unless otherwise expressly stated, are licensed under the - <a href="https://creativecommons.org/licenses/by-sa/4.0/" rel="license">CC-BY-SA-4.0</a> license. - The <a href="https://www.gentoo.org/inside-gentoo/foundation/name-logo-guidelines.html">Gentoo Name and Logo Usage Guidelines</a> apply. - </small> - </div> - <div class="col-2 col-sm-2 col-md-2 text-right"> - <strong><a class="text-dark" href="https://www.gentoo.org/inside-gentoo/contact/">Contact</a></strong><br> - <small> - {{ .Version }} - </small> - </div> - </div> - </div> - </footer> -{{end}} diff --git a/web/templates/layout/head.tmpl b/web/templates/layout/head.tmpl deleted file mode 100644 index 3dc694d..0000000 --- a/web/templates/layout/head.tmpl +++ /dev/null @@ -1,14 +0,0 @@ -{{define "head"}} - <head> - <title>{{.Title}}Gentoo Packages</title> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <meta name="theme-color" content="#54487a"> - <meta name="description" content="Gentoo Packages Database"> - <!-- link rel="stylesheet" media="screen" href="/packs/css/application-024b2074.css" /--> - <!-- script src="/packs/js/application-cfb73e71df8935c3a9ed.js"></script --> - <script src="/assets/stylesheets.js"></script> - <script src="/assets/application.js"></script> - <link rel="icon" href="https://packages.gentoo.org/favicon.ico" type="image/x-icon"> - </head> -{{end}} diff --git a/web/templates/layout/header.tmpl b/web/templates/layout/header.tmpl deleted file mode 100644 index 571a58b..0000000 --- a/web/templates/layout/header.tmpl +++ /dev/null @@ -1,6 +0,0 @@ -{{define "header"}} - <header> - {{template "sitetitle"}} - {{template "tyrian-navbar" .}} - </header> -{{end}} diff --git a/web/templates/layout/sitetitle.tmpl b/web/templates/layout/sitetitle.tmpl deleted file mode 100644 index f528d70..0000000 --- a/web/templates/layout/sitetitle.tmpl +++ /dev/null @@ -1,37 +0,0 @@ -{{define "sitetitle"}} - <div class="site-title"> - <div class="container"> - <div class="row justify-content-between"> - <div class="logo"> - <a href="/" title="Back to the homepage" class="site-logo"> - <img src="https://assets.gentoo.org/tyrian/site-logo.png" alt="Gentoo" srcset="https://assets.gentoo.org/tyrian/site-logo.svg"> - </a> - <span class="site-label">Packages</span> - </div> - <div class="site-title-buttons"> - <div class="btn-group btn-group-sm"> - <a href="https://get.gentoo.org/" role="button" class="btn get-gentoo"><span class="fa fa-fw fa-download"></span> <strong>Get Gentoo!</strong></a> - <div class="btn-group btn-group-sm"> - <a class="btn gentoo-org-sites dropdown-toggle" data-toggle="dropdown" data-target="#" href="#"> - <span class="fa fa-fw fa-map-o"></span> <span class="d-none d-sm-inline">gentoo.org sites</span> <span class="caret"></span> - </a> - <div class="dropdown-menu dropdown-menu-right"> - <a class="dropdown-item" href="https://www.gentoo.org/" title="Main Gentoo website"><span class="fa fa-home fa-fw"></span> gentoo.org</a> - <a class="dropdown-item" href="https://wiki.gentoo.org/" title="Find and contribute documentation"><span class="fa fa-file-text-o fa-fw"></span> Wiki</a> - <a class="dropdown-item" href="https://bugs.gentoo.org/" title="Report issues and find common issues"><span class="fa fa-bug fa-fw"></span> Bugs</a> - <a class="dropdown-item" href="https://forums.gentoo.org/" title="Discuss with the community"><span class="fa fa-comments-o fa-fw"></span> Forums</a> - <a class="dropdown-item" href="https://packages.gentoo.org/" title="Find software for your Gentoo"><span class="fa fa-hdd-o fa-fw"></span> Packages</a> - <div class="dropdown-divider"></div> - <a class="dropdown-item" href="https://planet.gentoo.org/" title="Find out what's going on in the developer community"><span class="fa fa-rss fa-fw"></span> Planet</a> - <a class="dropdown-item" href="https://archives.gentoo.org/" title="Read up on past discussions"><span class="fa fa-archive fa-fw"></span> Archives</a> - <a class="dropdown-item" href="https://sources.gentoo.org/" title="Browse our source code"><span class="fa fa-code fa-fw"></span> Sources</a> - <div class="dropdown-divider"></div> - <a class="dropdown-item" href="https://infra-status.gentoo.org/" title="Get updates on the services provided by Gentoo"><span class="fa fa-server fa-fw"></span> Infra Status</a> - </div> - </div> - </div> - </div> - </div> - </div> - </div> -{{end}} diff --git a/web/templates/layout/tyriannav.tmpl b/web/templates/layout/tyriannav.tmpl deleted file mode 100644 index 575b32d..0000000 --- a/web/templates/layout/tyriannav.tmpl +++ /dev/null @@ -1,45 +0,0 @@ -{{define "tyrian-navbar"}} - <nav class="tyrian-navbar navbar navbar-dark navbar-expand-lg bg-primary" role="navigation"> - <div class="container"> - <div class="navbar-header"> - <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar-main-collapse" aria-controls="navbar-main-collapse" aria-expanded="false" aria-label="Toggle navigation"> - <span class="navbar-toggler-icon"></span> - </button> - </div> - <div class="collapse navbar-collapse navbar-main-collapse" id="navbar-main-collapse"> - <ul class="navbar-nav mr-auto"> - - <li class="nav-item {{ if (eq .Tab "home")}}active{{end}}"><a class="nav-link" href="/">Home</a></li> - <li class="nav-item {{ if (eq .Tab "packages")}}active{{end}}"><a class="nav-link" href="/categories">Packages</a></li> - <li class="nav-item {{ if (eq .Tab "maintainers")}}active{{end}}"><a class="nav-link" href="/maintainers">Maintainers</a></li> - <li class="nav-item {{ if (eq .Tab "useflags")}}active{{end}}"><a class="nav-link" href="/useflags">USE flags</a></li> - <li class="nav-item {{ if (eq .Tab "arches")}}active{{end}}"><a class="nav-link" href="/arches">Architectures</a></li> - <li class="nav-item {{ if (eq .Tab "about")}}active{{end}}"><a class="nav-link" href="/about">About</a></li> - - </ul> - - {{ if ne .Tab "home"}} - <form class="form-inline inlinesearch" role="search" action="/packages/search" method="get"> - - <div class="input-group"> - - <div class="input-group-prepend"> - <span class="input-group-text" id="basic-addon1"><i class="fa fa-search" aria-hidden="true"></i></span> - </div> - - <input class="form-control" type="text" name="q" type="text" placeholder="Find Packages" aria-label="Find Packages"> - </div> - - </form> - {{end}} - - <!-- - <ul class="navbar-nav"> - <li class="nav-item"><a class="nav-link" href="/user/preferences"><i class="fa fa-user-circle-o" aria-hidden="true"></i></a></li> - </ul> - --> - - </div> - </div> - </nav> -{{end}} diff --git a/web/templates/maintainer/browse.tmpl b/web/templates/maintainer/browse.tmpl deleted file mode 100644 index 822142d..0000000 --- a/web/templates/maintainer/browse.tmpl +++ /dev/null @@ -1,103 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - -{{template "maintainersbrowseheader" .}} - -<div class="tab-content" id="myTabContent"> - -<div class="container mb-5"> - <div class="row"> - <div class="col-12"> - - <div class="row"> - <div class="col-md-12"> - {{if eq .TabName "projects"}} - <ul class="kk-col-list kk-6col-list kk-category-listing"> - {{ $prevletter := "z"}} - {{range .Maintainers}} - {{ if eq .Type "project"}} - {{ if (ne (printf "%.1s" .Name) $prevletter)}} - <li class="kk-col-list-header"><span class="kk-group-header">{{if .Name}}{{ printf "%.1s" .Name }}{{else}}#{{end}}</span></li> - {{end}} - {{ $prevletter = (printf "%.1s" .Name) }} - - <li> - <a title="{{.Name}}" data-toggle="tooltip" data-placement="right" href="/maintainer/{{.Email}}">{{if .Name}}{{.Name}}{{else}}{{.Email}}{{end}}</a> - </li> - {{end}} - {{end}} - </ul> - {{else if eq .TabName "gentoo-developers"}} - <ul class="kk-col-list kk-6col-list kk-category-listing"> - {{ $prevletter := "z"}} - {{range .Maintainers}} - {{ if eq .Type "gentoo-developer"}} - {{ if (ne (printf "%.1s" .Name) $prevletter)}} - <li class="kk-col-list-header"><span class="kk-group-header">{{if .Name}}{{ printf "%.1s" .Name }}{{else}}#{{end}}</span></li> - {{end}} - {{ $prevletter = (printf "%.1s" .Name) }} - - <li> - <a title="{{.Name}}" data-toggle="tooltip" data-placement="right" href="/maintainer/{{.Email}}">{{if .Name}}{{.Name}}{{else}}{{.Email}}{{end}}</a> - </li> - {{end}} - {{end}} - </ul> - {{else if eq .TabName "proxied-maintainers"}} - <ul class="kk-col-list kk-6col-list kk-category-listing"> - {{ $prevletter := "z"}} - {{range .Maintainers}} - {{ if eq .Type "proxied-maintainer"}} - {{ if (ne (printf "%.1s" .Name) $prevletter)}} - <li class="kk-col-list-header"><span class="kk-group-header">{{if .Name}}{{ printf "%.1s" .Name }}{{else}}#{{end}}</span></li> - {{end}} - {{ $prevletter = (printf "%.1s" .Name) }} - - <li> - <a title="{{.Name}}" data-toggle="tooltip" data-placement="right" href="/maintainer/{{.Email}}">{{if .Name}}{{.Name}}{{else}}{{.Email}}{{end}}</a> - </li> - {{end}} - {{end}} - </ul> - {{end}} - - - </div> - <div class="col-md-3 d-none"> - <h4 class="">Description</h4> - {{if eq .TabName "projects"}} - <span class="text-muted"> - A project in Gentoo is according to <a href="https://www.gentoo.org/glep/glep-0039.html">GLEP 39</a> a group of developers working towards a goal (or a set of goals). - </span> - {{else if eq .TabName "gentoo-developers"}} - <span class="text-muted"> - Here you can see all official <a href="https://www.gentoo.org/inside-gentoo/developers/">Gentoo developers</a> that are listed as the maintainer of at least one package in the tree.<br/><br/> - Interested into becoming a Gentoo developer? We do have some <a href="https://www.gentoo.org/get-involved/become-developer/">guidance</a>. - </span> - {{else if eq .TabName "proxied-maintainers"}} - <span class="text-muted"> - Proxied maintainers are users who are maintaining packages in the official Gentoo package repository. <br/><br/> - Want to become a Proxied maintainer? Follow <a href="https://wiki.gentoo.org/wiki/Project:Proxy_Maintainers/User_Guide">this guide</a>.<br/><br/> - You might especially be intersted into <a href="/maintainer/maintainer-needed@gentoo.org">packages that need a maintainer</a>. - </span> - - {{end}} - </div> - </div> - - - </div> - </div> -</div> - - -</div> - - -{{template "footer" .Application }} - -</body> -</html> diff --git a/web/templates/maintainer/components/bugs.tmpl b/web/templates/maintainer/components/bugs.tmpl deleted file mode 100644 index f069dad..0000000 --- a/web/templates/maintainer/components/bugs.tmpl +++ /dev/null @@ -1,136 +0,0 @@ -{{define "bugs"}} - <div class="row"> - <div class="col-md-9"> - {{$security_bugs := 0}} - {{$non_security_bugs := 0}} - {{range getAllBugs .Packages}} - {{if eq .Component "Vulnerabilities"}} - {{$security_bugs = (add $security_bugs 1)}} - {{else}} - {{$non_security_bugs = (add $non_security_bugs 1)}} - {{end}} - {{end}} - - {{$general_bugs := 0}} - {{$stabilization_bugs := 0}} - {{$keywording_bugs := 0}} - {{range getAllBugs .Packages}} - {{if eq .Component "Current packages"}} - {{$general_bugs = (add $general_bugs 1)}} - {{else if eq .Component "Stabilization"}} - {{$stabilization_bugs = (add $stabilization_bugs 1)}} - {{else if eq .Component "Keywording"}} - {{$keywording_bugs = (add $keywording_bugs 1)}} - {{end}} - {{end}} - - - {{if $non_security_bugs}} - - {{if $general_bugs}} - <h3 id="packages" class="mb-4">Bug Reports</h3> - <ul class="list-group"> - {{range getAllBugs .Packages}} - {{if eq .Component "Current packages"}} - <li class="list-group-item"> - <div class="row"> - <div class="col-md-12"> - <i class="fa fa-bug" aria-hidden="true"></i> - <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a> - </div> - <div class="col-md-12 text-muted"> - {{.Id}} - Assigned to {{.Assignee}} - </div> - </div> - </li> - {{end}} - {{end}} - </ul> - {{end}} - - {{if $stabilization_bugs}} - <h3 id="stabilization" class="my-4">Stabilization Bug Reports</h3> - <ul class="list-group"> - {{range getAllBugs .Packages}} - {{if eq .Component "Stabilization"}} - <li class="list-group-item"> - <div class="row"> - <div class="col-md-12"> - <i class="fa fa-bug" aria-hidden="true"></i> - <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a> - </div> - <div class="col-md-12 text-muted"> - {{.Id}} - Assigned to {{.Assignee}} - </div> - </div> - </li> - {{end}} - {{end}} - </ul> - {{end}} - - {{if $keywording_bugs}} - <h3 id="keywording" class="my-4">Keywording Bug Reports</h3> - <ul class="list-group"> - {{range getAllBugs .Packages}} - {{if eq .Component "Keywording"}} - <li class="list-group-item"> - <div class="row"> - <div class="col-md-12"> - <i class="fa fa-bug" aria-hidden="true"></i> - <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a> - </div> - <div class="col-md-12 text-muted"> - {{.Id}} - Assigned to {{.Assignee}} - </div> - </div> - </li> - {{end}} - {{end}} - </ul> - {{end}} - {{else}} - <div class="row pt-5"> - <div class="col-md-4"> - <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/> - </div> - <div class="col-md-8 pt-3"> - <h2>Good job! There are no bugs.</h2> - <span>You think something is missing here? <br/> Start with filling a <a href="https://bugs.gentoo.org/enter_bug.cgi">new bug</a>.</span> - </div> - </div> - {{end}} - </div> - <div class="col-md-3 pt-5"> - <h4 class=""> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> - Description - </a> - </h4> - <div class="collapse show" id="collapseDescription"> - <span class="text-muted"> - Gentoo Bugzilla is where we track bugs of Gentoo and its packages; you are welcome to report, confirm and resolve bugs: - <ul> - <li><a href="https://bugs.gentoo.org/enter_bug.cgi">File a new Bug</a></li> - <li><a href="https://bugs.gentoo.org/">Confirm a bug</a></li> - <li><a href="https://sites.google.com/site/yacoset/Home/how-to-fix-bugs-step-by-step">Offer solutions for open bugs</a></li> - <li><a href="https://wiki.gentoo.org/wiki/Bugday">Participate in our monthly Bugday</a></li> - </ul> - </span> - </div> - <h4 class=""> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseShortcuts" role="button" aria-expanded="false" aria-controls="collapseShortcuts"> - Shortcuts - </a> - </h4> - <div class="collapse show" id="collapseShortcuts"> - <ul> - <li>{{if $general_bugs}}<a href="#packages">Packages Bugs ({{$general_bugs}})</a>{{else}}<a>Packages Bugs (0)</a>{{end}}</li> - <li>{{if $stabilization_bugs}}<a href="#stabilization">Stabilization Bugs ({{$stabilization_bugs}})</a>{{else}}<a>Stabilization Bugs (0)</a>{{end}}</li> - <li>{{if $keywording_bugs}}<a href="#keywording">Keywording Bugs ({{$keywording_bugs}})</a>{{else}}<a>Keywording Bugs (0)</a>{{end}}</li> - </ul> - </div> - </div> - </div> -{{end}} - diff --git a/web/templates/maintainer/components/changelog.tmpl b/web/templates/maintainer/components/changelog.tmpl deleted file mode 100644 index 79ae1e7..0000000 --- a/web/templates/maintainer/components/changelog.tmpl +++ /dev/null @@ -1,173 +0,0 @@ -{{define "changelog"}} -<div class="row"> - <div class="col-md-9"> - {{ $commits := (index .Packages 0).Commits}} - {{ range $key, $value := .Packages}} - {{if ne $key 0}} - {{$commits = appendCommits $commits $value.Commits}} - {{end}} - {{end}} - - {{$commits = sortCommits $commits}} - - {{ if $commits }} - - <div class="col-md-12"> - <h3>Latest Commits</h3> - <ul class="timeline"> - <li> - <span class="text-muted">Commits on {{((index $commits 0).CommitterDate).Format "Jan 02, 2006"}}</span> - <ul class="list-group"> - {{$last_date := (index $commits 0).CommitterDate}} - {{range $commits}} - {{if eq ($last_date.Format "Jan 02, 2006") (.CommitterDate.Format "Jan 02, 2006")}} - <li class="list-group-item"> - <div class="row"> - <div class="col-md-8"><a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}"><b style="color:#424242!important;">{{.Message}}</b></a></div><div class="col-md-4 text-right text-muted"><a title="{{.Id}}" class="kk-commit" href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}">{{ printf "%.7s" .Id }}</a></div> - <div class="col-md-12" style="color:#424242!important;"> - {{ if (ne .AuthorName .CommitterName)}} - <span data-toggle="tooltip" title="authored on {{ .AuthorDate }}"><img class="rounded-sm inline" data-toggle="popover" data-img="http://placehold.it/400x200" src="{{ gravatar .AuthorEmail}}"> - <a href="mailto:{{ .AuthorEmail }}">{{ .AuthorName }}</a> authored</span> and - {{end}} - <img class="rounded-sm inline" src="{{ gravatar .CommitterEmail}}"> - <a href="mailto:{{ .CommitterEmail }}">{{ .CommitterName }}</a> committed on {{ .CommitterDate.Format "2 Jan 2006 15:04:05" }} - </div> - <div class="col-md-12"> - {{$commit := .}} - {{range $key, $value := .ChangedFiles.Added }} - {{if le $key 100}} - <style> - .kk-added-file-badge { - background-color: #dff0d8; - font-weight: normal; - } - .kk-added-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-added-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ .Path }}?id={{ $commit.Id }}">{{ .Path }}</a></span> - {{end}} - {{end}} - {{range $key, $value := .ChangedFiles.Modified }} - {{if le $key 100}} - <style> - .kk-modified-file-badge { - background-color: #fcf8e3; - font-weight: normal; - } - .kk-modified-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-modified-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ .Path }}?id={{ $commit.Id }}">{{ .Path }}</a></span> - {{end}} - {{end}} - {{range $key, $value := .ChangedFiles.Deleted }} - {{if le $key 100}} - <style> - .kk-deleted-file-badge { - background-color: #f2dede; - font-weight: normal; - } - .kk-deleted-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-deleted-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ .Path }}?id={{ $commit.Id }}">{{ .Path }}</a></span> - {{end}} - {{end}} - </div> - </div> - </li> - {{else}} - </ul> - </li> - <li> - <span class="text-muted">Commits on {{.CommitterDate.Format "Jan 02, 2006"}}</span> - <ul class="list-group"> - <li class="list-group-item"> - <div class="row"> - <div class="col-md-8"><a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}"><b style="color:#424242!important;">{{.Message}}</b></a></div><div class="col-md-4 text-right text-muted"><a title="{{.Id}}" class="kk-commit" href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}">{{ printf "%.7s" .Id }}</a></div> - <div class="col-md-12"> - {{ if (ne .AuthorName .CommitterName)}} - <span data-toggle="tooltip" title="authored on {{ .AuthorDate }}"><img class="rounded-sm inline" data-toggle="popover" data-img="http://placehold.it/400x200" src="{{ gravatar .AuthorEmail}}"> - <a href="mailto:{{ .AuthorEmail }}">{{ .AuthorName }}</a> authored</span> and - {{end}} - <img class="rounded-sm inline" src="{{ gravatar .CommitterEmail}}"> - <a href="mailto:{{ .CommitterEmail }}">{{ .CommitterName }}</a> committed on {{ .CommitterDate.Format "2 Jan 2006 15:04:05" }} - </div> - <div class="col-md-12"> - {{$commit := .}} - {{range $key, $value := .ChangedFiles.Added }} - {{if le $key 100}} - <style> - .kk-added-file-badge { - background-color: #dff0d8; - font-weight: normal; - } - .kk-added-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-added-file-badge badge-light"><a title="{{ .Path }} has been added" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ .Path }}?id={{ $commit.Id }}">{{ .Path }}</a></span> - {{end}} - {{end}} - {{range $key, $value := .ChangedFiles.Modified }} - {{if le $key 100}} - <style> - .kk-modified-file-badge { - background-color: #fcf8e3; - font-weight: normal; - } - .kk-modified-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-modified-file-badge badge-light"><a title="{{ .Path }} has been modified" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ .Path}}?id={{ $commit.Id }}">{{ .Path }}</a></span> - {{end}} - {{end}} - {{range $key, $value := .ChangedFiles.Deleted }} - {{if le $key 100}} - <style> - .kk-deleted-file-badge { - background-color: #f2dede; - font-weight: normal; - } - .kk-deleted-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-deleted-file-badge badge-light"><a title="{{ .Path }} has been deleted" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ .Path }}?id={{ $commit.Id }}">{{ .Path }}</a></span> - {{end}} - {{end}} - {{if gt (len .ChangedFiles.Added) 100}} - <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}" class="text-muted">...</a> - {{else if gt (len .ChangedFiles.Modified) 100}} - <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}" class="text-muted">...</a> - {{else if gt (len .ChangedFiles.Deleted) 100}} - <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}" class="text-muted">...</a> - {{end}} - </div> - </div> - </li> - {{end}} - {{$last_date = .CommitterDate}} - {{end}} - </ul> - </li> - </ul> - </div> - - {{else}} - <li class="list-group-item kk-panel-content-sorry"> - This package has not been changed since our repository has moved to Git. - <br><br> - <a href="https://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/<%= @package.atom %>/ChangeLog?view=markup" class="btn btn-default"> - <span class="fa fa-fw fa-history"></span> - View old CVS Changelog - </a> - </li> - {{end}} - </div> -</div> -{{end}}
\ No newline at end of file diff --git a/web/templates/maintainer/components/outdated.tmpl b/web/templates/maintainer/components/outdated.tmpl deleted file mode 100644 index dc2fd6e..0000000 --- a/web/templates/maintainer/components/outdated.tmpl +++ /dev/null @@ -1,52 +0,0 @@ -{{define "outdated"}} - <div class="row"> - <div class="col-md-9"> - {{if .Maintainer.PackagesInformation.Outdated}} - <h3 class="mb-4">Outdated Packages</h3> - <ul class="list-group"> - {{range .Packages}} - {{if .Outdated}} - <li class="list-group-item"> - <div class="row"> - <div class="col-md-4"> - <a href="/packages/{{.Atom}}" class="text-dark"><b>{{.Atom}}</b></a> - </div> - <div class="col-md-8 text-muted"> - {{.Description}} - </div> - </div> - </li> - {{end}} - {{end}} - </ul> - - {{else}} - <div class="row pt-5"> - <div class="col-md-4"> - <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/> - </div> - <div class="col-md-8 pt-3"> - <h2>Good job!</h2> - <span>According to repology.org there are no outdated packages here. <br/> - Please use this information with care though. The repology data might not be accurate. - </span> - </div> - </div> - {{end}} - </div> - <div class="col-md-3 pt-4"> - <h4 class=""> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> - Description - </a> - </h4> - <div class="collapse show" id="collapseDescription"> - <span class="text-muted"> - Based on the data of <a href="https://repology.org/">repology.org</a>, there might be a new version available for these packages. <br/> - Please don't solely rely on this information, as the repology data might not be accurate. - </span> - </div> - </div> - </div> -{{end}} - diff --git a/web/templates/maintainer/components/packages.tmpl b/web/templates/maintainer/components/packages.tmpl deleted file mode 100644 index f399678..0000000 --- a/web/templates/maintainer/components/packages.tmpl +++ /dev/null @@ -1,121 +0,0 @@ -{{define "packages"}} - <div class="row"> - <div class="col-md-9"> - {{if .Packages}} - <ul class="list-group"> - {{$category := ""}} - - {{ range .Packages }} - {{ if eq .Category $category}} - <li class="list-group-item"> - <div class="row"> - <div class="col-md-4"> - <a href="/packages/{{.Atom}}" class="text-dark"><b>{{.Atom}}</b></a> - </div> - <div class="col-md-8 text-muted"> - {{.Description}} - </div> - </div> - </li> - {{$category = .Category}} - {{else}} - </ul> - <h3 id="{{.Category}}" class="{{if ne $category ""}}mt-4{{end}}"> - {{$category = .Category}} - {{$category}} - </h3> - <ul class="list-group"> - <li class="list-group-item"> - <div class="row"> - <div class="col-md-4"> - <a href="/packages/{{.Atom}}" class="text-dark"><b>{{.Atom}}</b></a> - </div> - <div class="col-md-8 text-muted"> - {{.Description}} - </div> - </div> - </li> - {{end}} - {{end}} - - - - </ul> - - {{else}} - <div class="row"> - <div class="col-md-8"> - </div> - <div class="col-md-4"> - <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/> - </div> - </div> - {{end}} - </div> - <div class="col-md-3 pt-4"> - {{if .Maintainer.Project.Description}} - <h4 class=""> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> - Description - </a> - </h4> - <div class="collapse show" id="collapseDescription"> - <dl> - <dd class="ml-3 mb-0 text-muted"> - {{.Maintainer.Project.Description}} - </dd> - </dl> - </div> - - <h4 class="mt-4"> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseMembers" role="button" aria-expanded="false" aria-controls="collapseMembers"> - Members - </a> - </h4> - <div class="collapse show" id="collapseMembers"> - <dl> - {{range .Maintainer.Project.Members}} - <dd class="ml-3 mb-0"><a href="/maintainer/{{.Email}}">{{.Name}}</a>{{if .IsLead}} (Lead){{end}}</dd> - {{end}} - </dl> - </div> - {{end}} - {{if .Maintainer.Projects}} - <h4 class=""> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseProjects" role="button" aria-expanded="false" aria-controls="collapseProjects"> - Projects - </a> - </h4> - <div class="collapse show" id="collapseProjects"> - <dl> - {{range .Maintainer.Projects}} - <dd class="ml-3 mb-0"><a href="/maintainer/{{.Email}}">{{.Name}}</a></dd> - {{end}} - </dl> - </div> - {{end}} - <h4 class="{{if .Maintainer.Project.Description}}mt-4{{end}}"> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseShortcuts" role="button" aria-expanded="false" aria-controls="collapseShortcuts"> - Shortcuts - </a> - </h4> - <div class="collapse show" id="collapseShortcuts"> - <dl> - {{$category := (index .Packages 0).Category}} - {{$packageCounter := 0}} - {{ range .Packages }} - {{ if ne .Category $category}} - <dd class="ml-3 mb-0"><a href="#{{$category}}">{{$category}} ({{$packageCounter}})</a></dd> - {{$category = .Category}} - {{$packageCounter = 1}} - {{else}} - {{$packageCounter = add $packageCounter 1}} - {{end}} - {{end}} - <dd class="ml-3 mb-0"><a href="#{{$category}}">{{$category}} ({{$packageCounter}})</a></dd> - </dl> - </div> - </div> - </div> -{{end}} - diff --git a/web/templates/maintainer/components/pullrequests.tmpl b/web/templates/maintainer/components/pullrequests.tmpl deleted file mode 100644 index 83c262a..0000000 --- a/web/templates/maintainer/components/pullrequests.tmpl +++ /dev/null @@ -1,73 +0,0 @@ -{{define "pull-requests"}} - - <div class="row"> - <div class="col-md-9"> - - {{if .Maintainer.PackagesInformation.PullRequests}} - - <h3 class="mb-4">Pull Requests</h3> - <ul class="list-group"> - - {{range getPullRequests .Packages}} - - <li class="list-group-item"> - <div class="row"> - <div class="col-md-11"> - <span class="octicon octicon-git-pull-request opticon-resource-icon ml-1" style="color:SeaGreen;"></span> - <a href="https://github.com/gentoo/gentoo/pull/{{.Id}}" class="text-dark"><b>{{.Title}}</b></a> - {{if eq .CiState "SUCCESS"}} - <a href="{{.CiStateLink}}"><i class="fa fa-check mx-1" aria-hidden="true" style="color: SeaGreen;"></i></a> - {{else}} - <a href="{{.CiStateLink}}"><i class="fa fa-times mx-1" aria-hidden="true" style="color: #b60205;"></i></a> - {{end}} - {{range .Labels}} - <span class="badge badge-pill badge-light p-1" style="font-weight: normal; {{if eq .Color "5319e7" "0052cc" "b60205"}}color:#FFF;{{end}} background-color: #{{.Color}}!important;">{{.Name}}</span> - {{end}} - </div> - <div class="col-md-1 text-right"> - <a href="https://github.com/gentoo/gentoo/pull/{{.Id}}" class="text-muted"> - <i class="fa fa-comment-o" aria-hidden="true"></i> - {{.Comments}} - </a> - </div> - <div class="col-md-12 text-muted"> - <span style="font-size: 90%;"> - #{{.Id}} opened {{.CreatedAt}} by {{.Author}} - </span> - </div> - </div> - </li> - - {{end}} - </ul> - - {{else}} - - <div class="row pt-5"> - <div class="col-md-4"> - <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/> - </div> - <div class="col-md-8 pt-3"> - <h2>There are no pull requests</h2> - <span>You think something is missing here? <br/> Start with filling a <a href="https://wiki.gentoo.org/wiki/Gentoo_GitHub">new pull requests</a>.</span> - </div> - </div> - - {{end}} - </div> - <div class="col-md-3 pt-4"> - <h4 class=""> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> - Description - </a> - </h4> - <div class="collapse show" id="collapseDescription"> - <span class="text-muted"> - If you also like to help the Gentoo project, you can consider sending a Pull Request via GitHub.<br/> - Before doing so, you might want to take a look at <a href="https://wiki.gentoo.org/wiki/Gentoo_GitHub">the wiki page</a>. - </span> - </div> - </div> - </div> - -{{end}} diff --git a/web/templates/maintainer/components/security.tmpl b/web/templates/maintainer/components/security.tmpl deleted file mode 100644 index fd05247..0000000 --- a/web/templates/maintainer/components/security.tmpl +++ /dev/null @@ -1,52 +0,0 @@ -{{define "security"}} - <div class="row"> - <div class="col-md-9"> - - {{if .Maintainer.PackagesInformation.SecurityBugs}} - - <h3 class="mb-4">Security Bug Reports</h3> - <ul class="list-group"> - {{range (getAllBugs .Packages)}} - {{if eq .Component "Vulnerabilities"}} - <li class="list-group-item"> - <div class="row"> - <div class="col-md-12"> - <i class="fa fa-bug" aria-hidden="true"></i> - <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a> - </div> - <div class="col-md-12 text-muted"> - {{.Id}} - Assigned to {{.Assignee}} - </div> - </div> - </li> - {{end}} - {{end}} - </ul> - - {{else}} - <div class="row pt-5"> - <div class="col-md-4"> - <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/> - </div> - <div class="col-md-8 pt-3"> - <h2>There are no open security bugs.</h2> - <span>You think something is missing here? <br/> Start with filling a <a href="https://bugs.gentoo.org/">new security bug</a>.</span> - </div> - </div> - {{end}} - </div> - <div class="col-md-3 pt-4"> - <h4> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> - Contact Information - </a> - </h4> - <div class="collapse show" id="collapseDescription"> - <span class="text-muted"> - Please file new vulnerability reports on <a href="https://bugs.gentoo.org/">Gentoo Bugzilla</a> and assign them to the Gentoo Security product and Vulnerabilities component. - </span> - </div> - </div> - </div> -{{end}} - diff --git a/web/templates/maintainer/components/stabilization.tmpl b/web/templates/maintainer/components/stabilization.tmpl deleted file mode 100644 index 7026be5..0000000 --- a/web/templates/maintainer/components/stabilization.tmpl +++ /dev/null @@ -1,96 +0,0 @@ -{{define "stabilization"}} - <div class="row"> - <div class="col-md-9"> - - <h3>Stable Requests</h3> - <ul class="timeline"> - {{$stable_requests := 0}} - {{range .Packages}} - {{range $index, $element := .Versions}} - {{ if .PkgCheckResults }} - {{ range .PkgCheckResults }} - {{if eq .Class "StableRequest"}} - {{$stable_requests = (add $stable_requests 1)}} - <li> - <ul class="list-group"> - <li class="list-group-item"> - <a href="/packages/{{.Category}}/{{.Package}}" class="text-dark"><strong>{{.Category}}/{{.Package}}-{{.Version}}</strong></a><br/> - <span class="kk-version kk-cell-sep-right text-muted"> - {{ .Message }} - </span> - </li> - </ul> - </li> - {{end}} - {{end}} - {{end}} - {{end}} - {{end}} - </ul> - {{if eq $stable_requests 0}} - <div class="text-center w-100"><i>- No Stable Requests found -</i></div> - {{end}} - - - {{$security_bugs := 0}} - {{$non_security_bugs := 0}} - {{range getAllBugs .Packages}} - {{if eq .Component "Vulnerabilities"}} - {{$security_bugs = (add $security_bugs 1)}} - {{else}} - {{$non_security_bugs = (add $non_security_bugs 1)}} - {{end}} - {{end}} - - {{$general_bugs := 0}} - {{$stabilization_bugs := 0}} - {{$keywording_bugs := 0}} - {{range getAllBugs .Packages}} - {{if eq .Component "Current packages"}} - {{$general_bugs = (add $general_bugs 1)}} - {{else if eq .Component "Stabilization"}} - {{$stabilization_bugs = (add $stabilization_bugs 1)}} - {{else if eq .Component "Keywording"}} - {{$keywording_bugs = (add $keywording_bugs 1)}} - {{end}} - {{end}} - - - {{if $non_security_bugs}} - {{if $stabilization_bugs}} - <h3 id="stabilization" class="my-4">Stabilization Bug Reports</h3> - <ul class="list-group"> - {{range getAllBugs .Packages}} - {{if eq .Component "Stabilization"}} - <li class="list-group-item"> - <div class="row"> - <div class="col-md-12"> - <i class="fa fa-bug" aria-hidden="true"></i> - <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a> - </div> - <div class="col-md-12 text-muted"> - {{.Id}} - Assigned to {{.Assignee}} - </div> - </div> - </li> - {{end}} - {{end}} - </ul> - {{end}} - {{end}} - </div> - <div class="col-md-3 pt-4"> - <h4 class=""> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> - Description - </a> - </h4> - <div class="collapse show" id="collapseDescription"> - <span class="text-muted"> - This page lists potential stabilization candidates. Please have a look at the <a href="https://wiki.gentoo.org/wiki/Stable_request">wiki page</a> for more information. - </span> - </div> - </div> - </div> -{{end}} - diff --git a/web/templates/maintainer/maintainerheader.tmpl b/web/templates/maintainer/maintainerheader.tmpl deleted file mode 100644 index c0a4de9..0000000 --- a/web/templates/maintainer/maintainerheader.tmpl +++ /dev/null @@ -1,68 +0,0 @@ -{{define "maintainerheader"}} - <div class="kk-header-container"> - <div class="container"> - <div class="row"> - <div class="col-12"> - - <div class="row mt-3"> - <div class="col-md-5"> - <h1 class="stick-top kk-package-title" id="package-title"> - <small class="kk-package-cat"> - {{if eq .Maintainer.Type "project"}} - Gentoo Project - {{else if contains .Maintainer.Email "@gentoo.org"}} - Gentoo Developer - {{else if ne .Maintainer.Email ""}} - Proxied Maintainer - {{end}}</small> - <div> - <svg height="32" class="octicon octicon-person right left kk-package-icon" aria-label="Package icon" viewBox="0 0 16 16" version="1.1" width="32" role="img"><path fill-rule="evenodd" d="M10.5 5a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm.061 3.073a4 4 0 10-5.123 0 6.004 6.004 0 00-3.431 5.142.75.75 0 001.498.07 4.5 4.5 0 018.99 0 .75.75 0 101.498-.07 6.005 6.005 0 00-3.432-5.142z"></path></svg> - <div class="kk-package-name">{{if .Maintainer.Name}}{{.Maintainer.Name}}{{else if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}Maintainer Needed{{end}}</div> - </div> - </h1> - </div> - <div class="col-md-7"> - <p class="lead kk-package-maindesc"> - <!-- TODO --> - </p> - </div> - {{$outdated_packages_counts := 0}} - {{range .Packages}} - {{if .Outdated}} - {{$outdated_packages_counts = add $outdated_packages_counts 1}} - {{end}} - {{end}} - - {{$pull_requests_counts := 0}} - {{range .Packages}} - {{$pull_requests_counts = add $pull_requests_counts (len .PullRequests)}} - {{end}} - - {{$security_bugs := 0}} - {{$non_security_bugs := 0}} - {{range .Packages}} - {{range .Bugs}} - {{if eq .Component "Vulnerabilities"}} - {{$security_bugs = (add $security_bugs 1)}} - {{else}} - {{$non_security_bugs = (add $non_security_bugs 1)}} - {{end}} - {{end}} - {{end}} - <div class="col-md-12 pt-4 mt-1"> - <nav class="nav kk-package-nav"> - <a class="nav-link {{if eq .PageName "packages"}}active{{end}}" href="/maintainer/{{if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}maintainer-needed{{end}}"><i class="fa fa-info mr-1" aria-hidden="true"></i> Packages <span class="ml-1 badge badge-pill kk-misc-badge">{{len .Packages}}</span></a> - <a class="nav-link {{if eq .PageName "stabilization"}}active{{end}}" href="/maintainer/{{if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}maintainer-needed{{end}}/stabilization"><i class="fa fa-check-circle-o mr-1" aria-hidden="true"></i> Stabilization <span class="ml-1 badge badge-pill kk-misc-badge">{{.Maintainer.PackagesInformation.StableRequests}}</span></a> - <a class="nav-link {{if eq .PageName "outdated"}}active{{end}}" href="/maintainer/{{if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}maintainer-needed{{end}}/outdated"><i class="fa fa-tag mr-1" aria-hidden="true"></i> Outdated <span class="ml-1 badge badge-pill kk-misc-badge">{{.Maintainer.PackagesInformation.Outdated}}</span></a> - <a class="nav-link {{if eq .PageName "pull-requests"}}active{{end}}" href="/maintainer/{{if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}maintainer-needed{{end}}/pull-requests"><span class="octicon octicon-git-pull-request opticon-resource-icon ml-1"></span> Pull requests <span class="ml-1 badge badge-pill kk-misc-badge">{{.Maintainer.PackagesInformation.PullRequests}}</span></a> - <a class="nav-link {{if eq .PageName "bugs"}}active{{end}}" href="/maintainer/{{if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}maintainer-needed{{end}}/bugs"><i class="fa fa-bug" aria-hidden="true"></i> Bugs <span class="ml-1 badge badge-pill kk-misc-badge">{{.Maintainer.PackagesInformation.Bugs}}</span></a> - <a class="nav-link {{if eq .PageName "security"}}active{{end}}" href="/maintainer/{{if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}maintainer-needed{{end}}/security"><i class="fa fa-shield" aria-hidden="true"></i> Security <span class="ml-1 badge badge-pill kk-misc-badge">{{.Maintainer.PackagesInformation.SecurityBugs}}</span></a> - <a class="nav-link {{if eq .PageName "changelog"}}active{{end}}" href="/maintainer/{{if .Maintainer.Email}}{{.Maintainer.Email}}{{else}}maintainer-needed{{end}}/changelog"><i class="fa fa-fw fa-history"></i> Changelog</a> - </nav> - </div> - </div> - </div> - </div> - </div> - </div> -{{end}} diff --git a/web/templates/maintainer/maintainersbrowseheader.tmpl b/web/templates/maintainer/maintainersbrowseheader.tmpl deleted file mode 100644 index 548ee66..0000000 --- a/web/templates/maintainer/maintainersbrowseheader.tmpl +++ /dev/null @@ -1,31 +0,0 @@ -{{define "maintainersbrowseheader"}} - <div class="kk-header-container"> - <div class="container"> - <div class="row"> - <div class="col-12"> - - <div class="row mt-3"> - <div class="col-md-5 pt-2"> - <h1 class="stick-top kk-package-title" id="package-title"> - <div> - <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-users"></span><span class="ml-2">Maintainers</span></div> - </div> - </h1> - </div> - <div class="col-md-7"> - - </div> - - <div class="col-md-12 pt-4 mt-1"> - <nav class="nav kk-package-nav"> - <a class="nav-link {{if eq .TabName "projects"}}active{{end}}" href="/maintainers/gentoo-projects"><i class="fa fa-users mr-1" aria-hidden="true"></i>Gentoo Projects</a> - <a class="nav-link {{if eq .TabName "gentoo-developers"}}active{{end}}" href="/maintainers/gentoo-developers"><i class="fa fa-user mr-1" aria-hidden="true"></i>Gentoo Developers</a> - <a class="nav-link {{if eq .TabName "proxied-maintainers"}}active{{end}}" href="/maintainers/proxied-maintainers"><i class="fa fa-user-o mr-1" aria-hidden="true"></i>Proxied Maintainers</a> - </nav> - </div> - </div> - </div> - </div> - </div> - </div> -{{end}} diff --git a/web/templates/maintainer/show.tmpl b/web/templates/maintainer/show.tmpl deleted file mode 100644 index 2f7ee1e..0000000 --- a/web/templates/maintainer/show.tmpl +++ /dev/null @@ -1,33 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - -{{template "maintainerheader" .}} - -<div class="tab-content" id="myTabContent"> - <div class="container mb-5 tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="overview-tab"> - {{if eq .PageName "packages"}} - {{template "packages" .}} - {{else if eq .PageName "outdated"}} - {{template "outdated" .}} - {{else if eq .PageName "pull-requests"}} - {{template "pull-requests" .}} - {{else if eq .PageName "stabilization"}} - {{template "stabilization" .}} - {{else if eq .PageName "bugs"}} - {{template "bugs" .}} - {{else if eq .PageName "security"}} - {{template "security" .}} - {{else if eq .PageName "changelog"}} - {{template "changelog" .}} - {{end}} - </div> -</div> - -{{template "footer" .Application }} - - -</body> -</html> diff --git a/web/templates/packages/browsepackagesheader.tmpl b/web/templates/packages/browsepackagesheader.tmpl deleted file mode 100644 index 75317a2..0000000 --- a/web/templates/packages/browsepackagesheader.tmpl +++ /dev/null @@ -1,34 +0,0 @@ -{{define "browsepackagesheader"}} - <div class="kk-header-container"> - <div class="container"> - <div class="row"> - <div class="col-12"> - - <div class="row mt-3 pt-2"> - <div class="col-md-5"> - <h1 class="stick-top kk-package-title" id="package-title"> - <div> - <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-cubes"></span><span class="ml-2">Packages</span></div> - </div> - </h1> - </div> - <div class="col-md-7"> - - </div> - - <div class="col-md-12 pt-4 mt-1"> - <nav class="nav kk-package-nav"> - <a class="nav-link {{if eq .Name "Categories"}}active{{end}}" href="/categories"><i class="fa fa-list-ul mr-1" aria-hidden="true"></i>Categories</a> - <a class="nav-link {{if eq .Name "Added"}}active{{end}}" href="/packages/added"><i class="fa fa-history mr-1" aria-hidden="true"></i> Added</a> - <a class="nav-link {{if eq .Name "Updated"}}active{{end}}" href="/packages/updated"><i class="fa fa-asterisk mr-1" aria-hidden="true"></i> Updated</a> - <a class="nav-link {{if eq .Name "Stabilized"}}active{{end}}" href="/packages/stable"><i class="fa fa-check-circle-o mr-1" aria-hidden="true"></i> Newly Stable</a> - <a class="nav-link {{if eq .Name "Keyworded"}}active{{end}}" href="/packages/keyworded"><i class="fa fa-circle-o mr-1" aria-hidden="true"></i> Keyworded</a> - - </nav> - </div> - </div> - </div> - </div> - </div> - </div> -{{end}} diff --git a/web/templates/packages/changedVersionRow.tmpl b/web/templates/packages/changedVersionRow.tmpl deleted file mode 100644 index 22b27b9..0000000 --- a/web/templates/packages/changedVersionRow.tmpl +++ /dev/null @@ -1,76 +0,0 @@ -{{define "changedversion"}} - <li class="list-group-item kk-package-detailed"> - <div class="row"> - <div class="col-xs-12 col-md-6"> - <h4 class="stick-top"><a href="/packages/{{.Atom}}">{{.Atom}}</a></h4> - <div class="kk-package-detailed-toolbox"> - - <button type="button" class="kk-btn-xs btn btn-outline-secondary" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> - <span class="fa fa-fw fa-navicon"></span> - </button> - <div class="dropdown-menu dropdown-menu-right"> - <a class="dropdown-item" href="https://bugs.gentoo.org/buglist.cgi?quicksearch={{.Category}}%2F{{.Package}}" target="_blank"> - <span class="fa fa-fw fa-bug"></span> - Related bugs - </a> - <a class="dropdown-item" href="https://wiki.gentoo.org/index.php?title=Special%3ASearch&fulltext=Search&search={{.Package}}" target="_blank"> - <span class="fa fa-fw fa-book"></span> - Documentation - </a> - <a class="dropdown-item" href="https://forums.gentoo.org/search.php?search_terms=all&show_results=topics&search_keywords={{.Package}}&mode=results" target="_blank"> - <span class="fa fa-fw fa-comments-o"></span> - Forums posts - </a> - <div class="dropdown-divider"></div> - <a class="dropdown-item" href="https://gitweb.gentoo.org/repo/gentoo.git/tree/{{.Atom}}" target="_blank"> - <span class="fa fa-fw fa-code-fork"></span> - Git repository browser - </a> - <a class="dropdown-item" href="https://gitweb.gentoo.org/repo/gentoo.git/log/{{.Atom}}?showmsg=1" target="_blank"> - <span class="fa fa-fw fa-history"></span> - Git log - </a> - <a class="dropdown-item" href="https://gitweb.gentoo.org/repo/gentoo.git/atom/{{.Atom}}?h=master" target="_blank"> - <span class="fa fa-fw fa-rss"></span> - Changes feed - </a> - </div> - - </div> - {{.Description}} - <br> - <small class="text-muted"> - </small> - {{if ge (len .Commits) 1 }} - <div class="kk-inline-changelog-entry"> - <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{ (index .Commits 0).Id }}" title="Git commit"> - <span class="octicon octicon-git-pull-request"></span> - <span class="kk-commit-message">{{ (index .Commits 0).Message }}</span> - </a> - </div> - {{end}} - </div> - <div class="col-xs-12 col-md-6"> - <small class="text-muted pull-right"> - <span class="kk-i18n-date" title="{{if ge (len .Commits) 1 }}{{(index .Commits 0).CommitterDate}}{{else}}unknown{{end}}">{{if ge (len .Commits) 1 }}{{(index .Commits 0).CommitterDate}}{{else}}unknown{{end}}</span> - </small> - <div class="kk-version-card"> - <p class="mb-2"><strong>{{.Version}}</strong><span class="kk-slot"> : {{.Slot}}</span> {{if .Restricts}}<span class="badge badge-danger kk-restrict-label" title="The following features are restricted: {{range .Restricts}}{{.}} {{end}}">{{formatRestricts .Restricts}}</span>{{end}}</p> - <p> - {{ $arches := mkSlice "amd64" "x86" "alpha" "arm" "arm64" "hppa" "ia64" "ppc" "ppc64" "sparc" }} - {{ range $arches }} - {{if contains (print " " $.Keywords " ") (print " " . " ")}} - <span class="label kk-keyword-stable" title="{{$.Version}} is testing on {{.}}">{{.}}</span> - {{else if contains (print " " $.Keywords " ") (print "~" . " ")}} - <span class="label kk-keyword-testing" title="{{$.Version}} is stable on {{.}}">~{{.}}</span> - {{else}} - <span class="label kk-keyword-unknown" title="{{$.Version}} is unknown on {{.}}">?{{.}}</span> - {{end}} - {{end}} - </p> - </div> - - </div> - </div> - </li> -{{end}} diff --git a/web/templates/packages/changedVersions.tmpl b/web/templates/packages/changedVersions.tmpl deleted file mode 100644 index 3c60338..0000000 --- a/web/templates/packages/changedVersions.tmpl +++ /dev/null @@ -1,37 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - -{{template "browsepackagesheader" .}} - - -<div class="tab-content" id="myTabContent"> - - -<div class="container mb-5"> - <div class="row"> - <div class="col-12"> - <h3 class="mb-2">{{.Name}} Packages <a title="Atom feed" href="/packages/{{tolower .Name}}.atom" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a></h3> - - <li class="list-group rounded"> - {{range .Versions}} - {{template "changedversion" .}} - {{end}} - - </li> - - - </div> - </div> -</div> - - -</div> - - -{{template "footer" .Application }} - -</body> -</html> diff --git a/web/templates/packages/changelog/changelog.tmpl b/web/templates/packages/changelog/changelog.tmpl deleted file mode 100644 index 261e1ed..0000000 --- a/web/templates/packages/changelog/changelog.tmpl +++ /dev/null @@ -1,175 +0,0 @@ -<html> -<head></head> -<body> - -{{ if .Commits }} - - <div class="col-md-12"> - <h3>Latest Commits</h3> - <ul class="timeline"> - <li> - <span class="text-muted">Commits on {{(index .Package.Commits 0).CommitterDate.Format "Jan 02, 2006"}}</span> - <ul class="list-group"> - {{$last_date := (index .Commits 0).CommitterDate}} - {{range .Commits}} - {{if eq ($last_date.Format "Jan 02, 2006") (.CommitterDate.Format "Jan 02, 2006")}} - <li class="list-group-item"> - <div class="row"> - <div class="col-md-8"><b style="color:#424242!important;">{{.Message}}</b></div><div class="col-md-4 text-right text-muted"><a title="{{.Id}}" class="kk-commit" href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}">{{ printf "%.7s" .Id }}</a></div> - <div class="col-md-12" style="color:#424242!important;"> - {{ if (ne .AuthorName .CommitterName)}} - <span data-toggle="tooltip" title="authored on {{ .AuthorDate }}"><img class="rounded-sm inline" data-toggle="popover" data-img="http://placehold.it/400x200" src="{{ gravatar .AuthorEmail}}"> - <a href="mailto:{{ .AuthorEmail }}">{{ .AuthorName }}</a> authored</span> and - {{end}} - <img class="rounded-sm inline" src="{{ gravatar .CommitterEmail}}"> - <a href="mailto:{{ .CommitterEmail }}">{{ .CommitterName }}</a> committed on {{ .CommitterDate.Format "2 Jan 2006 15:04:05" }} - </div> - <div class="col-md-12"> - {{$commit := .}} - {{range $key, $value := .ChangedFiles.Added }} - {{if le $key 100}} - {{ if contains .Path (print $.Atom "/")}} - <style> - .kk-added-file-badge { - background-color: #dff0d8; - font-weight: normal; - } - .kk-added-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-added-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Atom }}/{{replaceall .Path (print $.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Atom "/") ""}}</a></span> - {{end}} - {{end}} - {{end}} - {{range $key, $value := .ChangedFiles.Modified }} - {{if le $key 100}} - {{ if contains $value.Path (print $.Atom "/")}} - <style> - .kk-modified-file-badge { - background-color: #fcf8e3; - font-weight: normal; - } - .kk-modified-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-modified-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Atom }}/{{replaceall $value.Path (print $.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall $value.Path (print $.Atom "/") ""}}</a></span> - {{end}} - {{end}} - {{end}} - {{range $key, $value := .ChangedFiles.Deleted }} - {{if le $key 100}} - {{ if contains .Path (print $.Atom "/")}} - <style> - .kk-deleted-file-badge { - background-color: #f2dede; - font-weight: normal; - } - .kk-deleted-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-deleted-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Atom }}/{{replaceall .Path (print $.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Atom "/") ""}}</a></span> - {{end}} - {{end}} - {{end}} - {{if gt (len .ChangedFiles.Added) 100}} - <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}" class="text-muted">...</a> - {{else if gt (len .ChangedFiles.Modified) 100}} - <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}" class="text-muted">...</a> - {{else if gt (len .ChangedFiles.Deleted) 100}} - <a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}" class="text-muted">...</a> - {{end}} - </div> - </div> - </li> - {{else}} - </ul> - </li> - <li> - <span class="text-muted">Commits on {{.CommitterDate.Format "Jan 02, 2006"}}</span> - <ul class="list-group"> - <li class="list-group-item"> - <div class="row"> - <div class="col-md-8"><b>{{.Message}}</b></div><div class="col-md-4 text-right text-muted"><a title="{{.Id}}" class="kk-commit" href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}">{{ printf "%.7s" .Id }}</a></div> - <div class="col-md-12"> - {{ if (ne .AuthorName .CommitterName)}} - <span data-toggle="tooltip" title="authored on {{ .AuthorDate }}"><img class="rounded-sm inline" data-toggle="popover" data-img="http://placehold.it/400x200" src="{{ gravatar .AuthorEmail}}"> - <a href="mailto:{{ .AuthorEmail }}">{{ .AuthorName }}</a> authored</span> and - {{end}} - <img class="rounded-sm inline" src="{{ gravatar .CommitterEmail}}"> - <a href="mailto:{{ .CommitterEmail }}">{{ .CommitterName }}</a> committed on {{ .CommitterDate.Format "2 Jan 2006 15:04:05" }} - </div> - <div class="col-md-12"> - {{$commit := .}} - {{range $key, $value := .ChangedFiles.Added }} - {{if le $key 50}} - {{ if contains $value.Path (print $.Atom "/")}} - <style> - .kk-added-file-badge { - background-color: #dff0d8; - font-weight: normal; - } - .kk-added-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-added-file-badge badge-light"><a title="{{replaceall $value.Path (print $.Atom "/") ""}} has been added" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Atom }}/{{replaceall $value.Path (print $.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall $value.Path (print $.Atom "/") ""}}</a></span> - {{end}} - {{end}} - {{end}} - {{range $key, $value := .ChangedFiles.Modified }} - {{if le $key 50}} - {{ if contains $value.Path (print $.Atom "/")}} - <style> - .kk-modified-file-badge { - background-color: #fcf8e3; - font-weight: normal; - } - .kk-modified-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-modified-file-badge badge-light"><a title="{{replaceall $value.Path (print $.Atom "/") ""}} has been modified" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Atom }}/{{replaceall $value.Path (print $.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Atom "/") ""}}</a></span> - {{end}} - {{end}} - {{end}} - {{range .ChangedFiles.Deleted }} - {{ if contains .Path (print $.Atom "/")}} - <style> - .kk-deleted-file-badge { - background-color: #f2dede; - font-weight: normal; - } - .kk-deleted-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-deleted-file-badge badge-light"><a title="{{replaceall .Path (print $.Atom "/") ""}} has been deleted" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Atom }}/{{replaceall .Path (print $.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Atom "/") ""}}</a></span> - {{end}} - {{end}} - </div> - </div> - </li> - {{end}} - {{$last_date = .CommitterDate}} - {{end}} - </ul> - </li> - </ul> - </div> - -{{else}} - <li class="list-group-item kk-panel-content-sorry"> - This package has not been changed since our repository has moved to Git. - <br><br> - <a href="https://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/<%= @package.atom %>/ChangeLog?view=markup" class="btn btn-default"> - <span class="fa fa-fw fa-history"></span> - View old CVS Changelog - </a> - </li> -{{end}} - -</body> -</html> diff --git a/web/templates/packages/changelogwrapper.tmpl b/web/templates/packages/changelogwrapper.tmpl deleted file mode 100644 index 98de287..0000000 --- a/web/templates/packages/changelogwrapper.tmpl +++ /dev/null @@ -1,17 +0,0 @@ -{{define "changelogwrapper"}} - - <div id="changelog-container"> - <li class="list-group-item kk-panel-content-sorry"> - <span class="fa fa-refresh fa-spin fa-3x"></span> - <noscript> - <br><br> - Inline Changelog cannot be displayed. - <br><br> - <a href="https://gitweb.gentoo.org/repo/gentoo.git/log/{{ .Package.Atom }}?showmsg=1" class="btn btn-default"> - <span class="fa fa-fw fa-history"></span> - View Git Changelog - </a> - </noscript> - </li> - </div> -{{end}} diff --git a/web/templates/packages/components/bugs.tmpl b/web/templates/packages/components/bugs.tmpl deleted file mode 100644 index e63a986..0000000 --- a/web/templates/packages/components/bugs.tmpl +++ /dev/null @@ -1,127 +0,0 @@ -{{define "bugs"}} - <div class="row"> - <div class="col-md-9"> - {{$general_bugs := 0}} - {{$stabilization_bugs := 0}} - {{$keywording_bugs := 0}} - {{range .Package.AllBugs}} - {{if eq .Component "Current packages"}} - {{$general_bugs = (add $general_bugs 1)}} - {{else if eq .Component "Stabilization"}} - {{$stabilization_bugs = (add $stabilization_bugs 1)}} - {{else if eq .Component "Keywording"}} - {{$keywording_bugs = (add $keywording_bugs 1)}} - {{end}} - {{end}} - - {{if .Package.AllBugs}} - - {{if $general_bugs}} - <h3 class="mb-4">Bug Reports</h3> - <ul class="list-group"> - {{range .Package.Bugs}} - {{if eq .Component "Current packages"}} - <li class="list-group-item"> - <div class="row"> - <div class="col-md-12"> - <i class="fa fa-bug" aria-hidden="true"></i> - <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a> - </div> - <div class="col-md-12 text-muted"> - {{.Id}} - Assigned to {{.Assignee}} - </div> - </div> - </li> - {{end}} - {{end}} - </ul> - {{end}} - - - - {{if $stabilization_bugs}} - <h3 class="my-4">Stabilization Bug Reports</h3> - <ul class="list-group"> - {{range .Package.AllBugs}} - {{if eq .Component "Stabilization"}} - <li class="list-group-item"> - <div class="row"> - <div class="col-md-12"> - <i class="fa fa-bug" aria-hidden="true"></i> - <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a> - </div> - <div class="col-md-12 text-muted"> - {{.Id}} - Assigned to {{.Assignee}} - </div> - </div> - </li> - {{end}} - {{end}} - </ul> - {{end}} - - {{if $keywording_bugs}} - <h3 class="my-4">Keywording Bug Reports</h3> - <ul class="list-group"> - {{range .Package.AllBugs}} - {{if eq .Component "Keywording"}} - <li class="list-group-item"> - <div class="row"> - <div class="col-md-12"> - <i class="fa fa-bug" aria-hidden="true"></i> - <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a> - </div> - <div class="col-md-12 text-muted"> - {{.Id}} - Assigned to {{.Assignee}} - </div> - </div> - </li> - {{end}} - {{end}} - </ul> - {{end}} - {{else}} - <div class="row pt-5"> - <div class="col-md-4"> - <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/> - </div> - <div class="col-md-8 pt-3"> - <h2>Good job! There are no bugs.</h2> - <span>You think something is missing here? <br/> Start with filling a <a href="https://bugs.gentoo.org/enter_bug.cgi">new bug</a>.</span> - </div> - </div> - {{end}} - </div> - <div class="col-md-3 pt-5"> - <h4 class=""> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> - Description - </a> - </h4> - <div class="collapse show" id="collapseDescription"> - <span class="text-muted"> - Gentoo Bugzilla is where we track bugs of Gentoo and its packages; you are welcome to report, confirm and resolve bugs: - <ul> - <li><a href="https://bugs.gentoo.org/enter_bug.cgi">File a new Bug</a></li> - <li><a href="https://bugs.gentoo.org/">Confirm a bug</a></li> - <li><a href="https://sites.google.com/site/yacoset/Home/how-to-fix-bugs-step-by-step">Offer solutions for open bugs</a></li> - <li><a href="https://wiki.gentoo.org/wiki/Bugday">Participate in our monthly Bugday</a></li> - </ul> - </span> - </div> - <h4 class=""> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseShortcuts" role="button" aria-expanded="false" aria-controls="collapseShortcuts"> - Shortcuts - </a> - </h4> - <div class="collapse show" id="collapseShortcuts"> - <ul> - <li>{{if $general_bugs}}<a href="#packages">Packages Bugs ({{$general_bugs}})</a>{{else}}<a>Packages Bugs (0)</a>{{end}}</li> - <li>{{if $stabilization_bugs}}<a href="#stabilization">Stabilization Bugs ({{$stabilization_bugs}})</a>{{else}}<a>Stabilization Bugs (0)</a>{{end}}</li> - <li>{{if $keywording_bugs}}<a href="#keywording">Keywording Bugs ({{$keywording_bugs}})</a>{{else}}<a>Keywording Bugs (0)</a>{{end}}</li> - </ul> - </div> - </div> - </div> -{{end}} - diff --git a/web/templates/packages/components/changelog.tmpl b/web/templates/packages/components/changelog.tmpl deleted file mode 100644 index 4e01724..0000000 --- a/web/templates/packages/components/changelog.tmpl +++ /dev/null @@ -1,153 +0,0 @@ -{{define "changelog"}} - - {{ if .Package.Commits }} - - - <h3>Latest Commits</h3> - <ul class="timeline"> - <li> - <span class="text-muted">Commits on {{(index .Package.Commits 0).CommitterDate.Format "Jan 02, 2006"}}</span> - <ul class="list-group"> - {{$last_date := (index .Package.Commits 0).CommitterDate}} - {{range .Package.Commits}} - {{if eq ($last_date.Format "Jan 02, 2006") (.CommitterDate.Format "Jan 02, 2006")}} - <li class="list-group-item"> - <div class="row"> - <div class="col-md-8"><a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}"><b style="color:#424242!important;">{{.Message}}</b></a></div><div class="col-md-4 text-right text-muted"><a title="{{.Id}}" class="kk-commit" href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}">{{ printf "%.7s" .Id }}</a></div> - <div class="col-md-12" style="color:#424242!important;"> - {{ if (ne .AuthorName .CommitterName)}} - <span data-toggle="tooltip" title="authored on {{ .AuthorDate }}"><img class="rounded-sm inline" data-toggle="popover" data-img="http://placehold.it/400x200" src="{{ gravatar .AuthorEmail}}"> - <a href="mailto:{{ .AuthorEmail }}">{{ .AuthorName }}</a> authored</span> and - {{end}} - <img class="rounded-sm inline" src="{{ gravatar .CommitterEmail}}"> - <a href="mailto:{{ .CommitterEmail }}">{{ .CommitterName }}</a> committed on {{ .CommitterDate.Format "2 Jan 2006 15:04:05" }} - </div> - <div class="col-md-12"> - {{$commit := .}} - {{range .ChangedFiles.Added }} - {{ if contains .Path (print $.Package.Atom "/")}} - <style> - .kk-added-file-badge { - background-color: #dff0d8; - font-weight: normal; - } - .kk-added-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-added-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Package.Atom }}/{{replaceall .Path (print $.Package.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Package.Atom "/") ""}}</a></span> - {{end}} - {{end}} - {{range .ChangedFiles.Modified }} - {{ if contains .Path (print $.Package.Atom "/")}} - <style> - .kk-modified-file-badge { - background-color: #fcf8e3; - font-weight: normal; - } - .kk-modified-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-modified-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Package.Atom }}/{{replaceall .Path (print $.Package.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Package.Atom "/") ""}}</a></span> - {{end}} - {{end}} - {{range .ChangedFiles.Deleted }} - {{ if contains .Path (print $.Package.Atom "/")}} - <style> - .kk-deleted-file-badge { - background-color: #f2dede; - font-weight: normal; - } - .kk-deleted-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-deleted-file-badge badge-light"><a class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Package.Atom }}/{{replaceall .Path (print $.Package.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Package.Atom "/") ""}}</a></span> - {{end}} - {{end}} - </div> - </div> - </li> - {{else}} - </ul> - </li> - <li> - <span class="text-muted">Commits on {{.CommitterDate.Format "Jan 02, 2006"}}</span> - <ul class="list-group"> - <li class="list-group-item"> - <div class="row"> - <div class="col-md-8"><a href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}"><b style="color:#424242!important;">{{.Message}}</b></a></div><div class="col-md-4 text-right text-muted"><a title="{{.Id}}" class="kk-commit" href="https://gitweb.gentoo.org/repo/gentoo.git/commit/?id={{.Id}}">{{ printf "%.7s" .Id }}</a></div> - <div class="col-md-12"> - {{ if (ne .AuthorName .CommitterName)}} - <span data-toggle="tooltip" title="authored on {{ .AuthorDate }}"><img class="rounded-sm inline" data-toggle="popover" data-img="http://placehold.it/400x200" src="{{ gravatar .AuthorEmail}}"> - <a href="mailto:{{ .AuthorEmail }}">{{ .AuthorName }}</a> authored</span> and - {{end}} - <img class="rounded-sm inline" src="{{ gravatar .CommitterEmail}}"> - <a href="mailto:{{ .CommitterEmail }}">{{ .CommitterName }}</a> committed on {{ .CommitterDate.Format "2 Jan 2006 15:04:05" }} - </div> - <div class="col-md-12"> - {{$commit := .}} - {{range .ChangedFiles.Added }} - {{ if contains .Path (print $.Package.Atom "/")}} - <style> - .kk-added-file-badge { - background-color: #dff0d8; - font-weight: normal; - } - .kk-added-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-added-file-badge badge-light"><a title="{{replaceall .Path (print $.Package.Atom "/") ""}} has been added" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Package.Atom }}/{{replaceall .Path (print $.Package.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Package.Atom "/") ""}}</a></span> - {{end}} - {{end}} - {{range .ChangedFiles.Modified }} - {{ if contains .Path (print $.Package.Atom "/")}} - <style> - .kk-modified-file-badge { - background-color: #fcf8e3; - font-weight: normal; - } - .kk-modified-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-modified-file-badge badge-light"><a title="{{replaceall .Path (print $.Package.Atom "/") ""}} has been modified" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Package.Atom }}/{{replaceall .Path (print $.Package.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Package.Atom "/") ""}}</a></span> - {{end}} - {{end}} - {{range .ChangedFiles.Deleted }} - {{ if contains .Path (print $.Package.Atom "/")}} - <style> - .kk-deleted-file-badge { - background-color: #f2dede; - font-weight: normal; - } - .kk-deleted-file-badge > a { - color: #424242!important; - } - </style> - <span class="badge badge-pill kk-deleted-file-badge badge-light"><a title="{{replaceall .Path (print $.Package.Atom "/") ""}} has been deleted" class="text-muted" href="https://gitweb.gentoo.org/repo/gentoo.git/diff/{{ $.Package.Atom }}/{{replaceall .Path (print $.Package.Atom "/") ""}}?id={{ $commit.Id }}">{{replaceall .Path (print $.Package.Atom "/") ""}}</a></span> - {{end}} - {{end}} - </div> - </div> - </li> - {{end}} - {{$last_date = .CommitterDate}} - {{end}} - </ul> - </li> - </ul> - - {{else}} - <li class="list-group-item kk-panel-content-sorry"> - This package has not been changed since our repository has moved to Git. - <br><br> - <a href="https://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/<%= @package.atom %>/ChangeLog?view=markup" class="btn btn-default"> - <span class="fa fa-fw fa-history"></span> - View old CVS Changelog - </a> - </li> - {{end}} -{{end}}
\ No newline at end of file diff --git a/web/templates/packages/components/dependencies.tmpl b/web/templates/packages/components/dependencies.tmpl deleted file mode 100644 index d63a0b5..0000000 --- a/web/templates/packages/components/dependencies.tmpl +++ /dev/null @@ -1,63 +0,0 @@ -{{define "dependencies"}} - <div class="row"> - <div class="col-md-9"> - <h3><a class="text-dark"><i class="fa fa-level-down" aria-hidden="true"></i> Dependencies</a> <a href="/packages/{{.Package.Atom}}/reverse-dependencies" class="ml-3 text-muted"><i class="fa fa-level-up" aria-hidden="true"></i> Reverse-Dependencies</a></h3> - - <ul class="timeline"> - - {{range $index, $element := .Package.Versions}} - <li> - <span class="text-muted">{{.Version}}</span> - - {{$depMap := $element.BuildDepMap}} - - {{if len $depMap}} - <div class="card mt-4"> - <div class="table-responsive border-0"> - <table class="table mb-0"> - <thead> - <tr> - <th scope="col">Version</th> - <th scope="col">RDEPEND</th> - <th scope="col">DEPEND</th> - <th scope="col">BDEPEND</th> - <th scope="col">PDEPEND</th> - </tr> - </thead> - <tbody> - - {{ range $key, $value := $depMap }} - <tr> - <th scope="row"><a class="text-dark" href="/packages/{{$value.Atom}}">{{$key}}</a></th> - <td>{{if $value.rdepend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td> - <td>{{if $value.depend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td> - <td>{{if $value.bdepend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td> - <td>{{if $value.pdepend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td> - </tr> - {{end}} - - </tbody> - </table> - </div> - </div> - {{end}} - - </li> - {{end}} - </ul> - - </div> - <div class="col-md-3 pt-5"> - <h4 class=""> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> - Description - </a> - </h4> - <div class="collapse show" id="collapseDescription"> - <span class="text-muted"> - The dependencies are regularly computed based on the <a href="https://qa-reports.gentoo.org/">qa-reports</a>. - </span> - </div> - </div> - </div> -{{end}} diff --git a/web/templates/packages/components/overview.tmpl b/web/templates/packages/components/overview.tmpl deleted file mode 100644 index 3f5bca3..0000000 --- a/web/templates/packages/components/overview.tmpl +++ /dev/null @@ -1,86 +0,0 @@ -{{define "overview"}} -<div class="row"> - <div class="col-md-9"> - - {{ if .UserPreferences.Packages.Overview.ShowOutdated}} - {{ if .Package.Outdated }} - {{$outdatedFound := false}} - {{range .Versions}} - {{if eq (index $.Package.Outdated 0).NewestVersion .Version}} - {{$outdatedFound = true}} - {{end}} - {{end}} - {{if not $outdatedFound}} - <div class="alert alert-info"> - <strong><span class="fa fa-fw fa-lightbulb-o"></span> Version {{ (index .Package.Outdated 0).NewestVersion }} is available upstream. Please consider updating!</strong><br> - It seems that version {{ (index .Package.Outdated 0).NewestVersion }} is available upstream, while the latest version in the Gentoo tree is {{ (index .Package.Outdated 0).GentooVersion }}.<br/> - <small><i>You think this warning is false? Read more about it <a href="https://archives.gentoo.org/gentoo-dev/message/b793f4da5a5b5e20a063ea431500a820">here</a>.</i></small> - </div> - {{end}} - {{ end }} - {{ end }} - - {{template "versions" .}} - - {{ if isMasked .Versions }} - - <h3 class="pt-3 mb-2">Masks</h3> - - <div class="card kk-mask mb-3"> - <ul class="list-group list-group-flush kk-mask"> - <li class="list-group-item kk-mask"> - {{ if showRemovalNotice .Versions }} - <p style="color:#721c24;"> - <strong><span class="fa fa-fw fa-warning"></span> This package is masked and could be removed soon!</strong><br> - The mask comment indicates that this package is scheduled for removal from our package repository.<br> - Please review the mask information below for more details. - </p> - {{end}} - - <strong class="kk-mask-reason">{{(getMask .Versions).Reason}}</strong> - - <div class="kk-mask-details"> - - <div class="row"> - <div class="col-xs-12 col-md-3 kk-metadata-key"> - Affected packages - </div> - <div class="col-xs-12 col-md-9 kk-mask-atoms overflow-hidden"> - {{(getMask .Versions).Versions}} - </div> - </div> - <div class="row"> - <div class="col-xs-12 col-md-3 kk-metadata-key"> - Author/Date - </div> - <div class="col-xs-12 col-md-9"> - {{(getMask .Versions).Author}} <{{(getMask .Versions).AuthorEmail}}> <span class="text-muted">({{(getMask .Versions).Date}})</span> - </div> - </div> - </div> - </li> - </ul> - </div> - {{end}} - - {{ if not .Package.Maintainers }} - <div class="alert alert-info"> - <strong><span class="fa fa-fw fa-wrench"></span> This package needs a new maintainer!</strong><br> - If you are interested in helping with the maintenance of {{.Package.Name}}, please get in touch with our - <a href="https://wiki.gentoo.org/wiki/Project:Proxy_Maintainers" class="alert-link">Proxy Maintainers team</a>. - </div> - {{end}} - - {{template "metadata" .}} - - {{ if eq .UserPreferences.Packages.Overview.Layout "full" }} - <div class="mt-4 pt-4"></div> - {{template "changelog" .}} - {{end}} - - </div> - <div class="col-md-3 pl-4 pt-4 mt-2"> - {{template "resources" .}} - </div> -</div> -{{end}} diff --git a/web/templates/packages/components/pullrequests.tmpl b/web/templates/packages/components/pullrequests.tmpl deleted file mode 100644 index 7782c62..0000000 --- a/web/templates/packages/components/pullrequests.tmpl +++ /dev/null @@ -1,75 +0,0 @@ -{{define "pull-requests"}} - - <div class="row"> - <div class="col-md-9"> - - {{if .Package.PullRequests}} - - <h3 class="mb-4">Pull Requests</h3> - - <ul class="list-group"> - - {{range .Package.PullRequests}} - - <li class="list-group-item"> - <div class="row"> - <div class="col-md-11"> - <span class="octicon octicon-git-pull-request opticon-resource-icon ml-1" style="color:SeaGreen;"></span> - <a href="https://github.com/gentoo/gentoo/pull/{{.Id}}" class="text-dark"><b>{{.Title}}</b></a> - {{if eq .CiState "SUCCESS"}} - <a href="{{.CiStateLink}}"><i class="fa fa-check mx-1" aria-hidden="true" style="color: SeaGreen;"></i></a> - {{else}} - <a href="{{.CiStateLink}}"><i class="fa fa-times mx-1" aria-hidden="true" style="color: #b60205;"></i></a> - {{end}} - {{range .Labels}} - <span class="badge badge-pill badge-light p-1" style="font-weight: normal; {{if eq .Color "5319e7" "0052cc" "b60205"}}color:#FFF;{{end}} background-color: #{{.Color}}!important;">{{.Name}}</span> - {{end}} - </div> - <div class="col-md-1 text-right"> - <a href="https://github.com/gentoo/gentoo/pull/{{.Id}}" class="text-muted"> - <i class="fa fa-comment-o" aria-hidden="true"></i> - {{.Comments}} - </a> - </div> - <div class="col-md-12 text-muted"> - <span style="font-size: 90%;"> - #{{.Id}} opened {{.CreatedAt}} by {{.Author}} - </span> - </div> - </div> - </li> - - {{end}} - </ul> - - {{else}} - - <div class="row pt-5"> - <div class="col-md-4"> - <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/> - </div> - <div class="col-md-8 pt-3"> - <h2>There are no pull requests</h2> - <span>You think something is missing here? <br/> Start with filling a <a href="https://wiki.gentoo.org/wiki/Gentoo_GitHub">new pull requests</a>.</span> - </div> - </div> - - {{end}} - - </div> - <div class="col-md-3 pt-5"> - <h4 class=""> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> - Description - </a> - </h4> - <div class="collapse show" id="collapseDescription"> - <span class="text-muted"> - If you also like to help the Gentoo project, you can consider sending a Pull Request via GitHub.<br/> - Before doing so, you might want to take a look at <a href="https://wiki.gentoo.org/wiki/Gentoo_GitHub">the wiki page</a>. - </span> - </div> - </div> - </div> - -{{end}} diff --git a/web/templates/packages/components/qareport.tmpl b/web/templates/packages/components/qareport.tmpl deleted file mode 100644 index 536e382..0000000 --- a/web/templates/packages/components/qareport.tmpl +++ /dev/null @@ -1,82 +0,0 @@ -{{define "qa-report"}} - <div class="row"> - <div class="col-md-9"> - - <h3>Pkgcheck Warnings</h3> - <ul class="timeline"> - <li> - <span class="text-muted">All Versions</span> - <ul class="list-group"> - - {{ if .Package.PkgCheckResults }} - {{ range $.Package.PkgCheckResults }} - {{if $.UserPreferences.ContainsPkgcheckClass .Class}} - {{if not .Version}} - <li class="list-group-item"> - <strong>{{ .Class }}</strong><br/> - <span class="kk-version kk-cell-sep-right text-muted"> - {{ .Message }} - </span> - </li> - {{end}} - {{end}} - {{end}} - {{end}} - </ul> - </li> - - {{range $index, $element := .Package.Versions}} - <li> - <span class="text-muted">{{.Version}}</span> - <ul class="list-group"> - - {{ if .PkgCheckResults }} - {{ range .PkgCheckResults }} - {{if $.UserPreferences.ContainsPkgcheckClass .Class}} - <li class="list-group-item"> - <strong>{{ .Class }}</strong><br/> - <span class="kk-version kk-cell-sep-right text-muted"> - {{ .Message }} - </span> - </li> - {{end}} - {{end}} - {{end}} - </ul> - </li> - {{end}} - </ul> - </div> - <div class="col-md-3 pt-5"> - <h4 class=""> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> - Description - </a> - </h4> - <div class="collapse show" id="collapseDescription"> - <span class="text-muted"> - Pkgcheck is used regularly to generate QA reports. Pkgcheck is a pkgcore-based QA utility for ebuild repos. - </span> - </div> - <h4 class="mt-4"> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseExternalResources" role="button" aria-expanded="false" aria-controls="collapseExternalResources"> - External Resources - </a> - </h4> - <div class="collapse show" id="collapseExternalResources"> - <ul> - <li> - <a href="https://qa-reports.gentoo.org/output/gentoo-ci/output.html;pkg={{.Package.Category}}:{{.Package.Name}}" target="_blank"> - CI Report - </a> - </li> - <li> - <a href="https://qa-reports.gentoo.org/output/gentoo-ci/output.verbose.html;pkg={{.Package.Category}}:{{.Package.Name}}" target="_blank"> - CI Report (verbose) - </a> - </li> - </ul> - </div> - </div> - </div> -{{end}} diff --git a/web/templates/packages/components/reverse-dependencies.tmpl b/web/templates/packages/components/reverse-dependencies.tmpl deleted file mode 100644 index 0415b78..0000000 --- a/web/templates/packages/components/reverse-dependencies.tmpl +++ /dev/null @@ -1,59 +0,0 @@ -{{define "reverse-dependencies"}} - <div class="row"> - <div class="col-md-9"> - - <h3><a class="text-muted" href="/packages/{{.Package.Atom}}/dependencies"><i class="fa fa-level-down" aria-hidden="true"></i> Dependencies</a> <a class="ml-3 text-dark"><i class="fa fa-level-up" aria-hidden="true"></i> Reverse-Dependencies</a></h3> - - {{$revDevMap := .Package.BuildRevDepMap}} - - <div class="card mt-4"> - <div class="table-responsive border-0"> - <table class="table mb-0"> - <thead> - <tr> - <th scope="col">Version</th> - <th scope="col">RDEPEND</th> - <th scope="col">DEPEND</th> - <th scope="col">BDEPEND</th> - <th scope="col">PDEPEND</th> - </tr> - </thead> - <tbody> - - {{ range $key, $value := $revDevMap }} - <tr> - <th scope="row"><a class="text-dark" href="/packages/{{replaceall $value.Atom "[B]" ""}}">{{$key}}</a></th> - <td>{{if $value.rdepend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td> - <td>{{if $value.depend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td> - <td>{{if $value.bdepend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td> - <td>{{if $value.pdepend}}<i class="fa fa-check" style="color:green;" aria-hidden="true"></i>{{else}}<i class="fa fa-times" style="color:#E1E1E1;" aria-hidden="true"></i>{{end}}</td> - </tr> - {{end}} - - </tbody> - </table> - </div> - </div> - - - </div> - <div class="col-md-3 pt-5"> - <h4 class=""> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> - Description - </a> - </h4> - <div class="collapse show" id="collapseDescription"> - <span class="text-muted"> - The reverse dependencies are regularly parsed from the <a href="https://qa-reports.gentoo.org/">qa-reports</a>. The sources can be found at: - <ul> - <li><a href="https://qa-reports.gentoo.org/output/genrdeps/rindex/{{.Package.Atom}}">rdepend</a></li> - <li><a href="https://qa-reports.gentoo.org/output/genrdeps/dindex/{{.Package.Atom}}">depend</a></li> - <li><a href="https://qa-reports.gentoo.org/output/genrdeps/bindex/{{.Package.Atom}}">bdepend</a></li> - <li><a href="https://qa-reports.gentoo.org/output/genrdeps/pindex/{{.Package.Atom}}">pdepend</a></li> - </ul> - </span> - </div> - </div> - </div> -{{end}} diff --git a/web/templates/packages/components/security.tmpl b/web/templates/packages/components/security.tmpl deleted file mode 100644 index 8b4cd91..0000000 --- a/web/templates/packages/components/security.tmpl +++ /dev/null @@ -1,72 +0,0 @@ -{{define "security"}} - <div class="row"> - <div class="col-md-9"> - - {{$security_bugs := 0}} - {{range .Package.AllBugs}} - {{if eq .Component "Vulnerabilities"}} - {{$security_bugs = (add $security_bugs 1)}} - {{end}} - {{end}} - - {{if $security_bugs}} - - <h3 class="mb-4">Security Bug Reports</h3> - <ul class="list-group"> - {{range .Package.AllBugs}} - {{if eq .Component "Vulnerabilities"}} - <li class="list-group-item"> - <div class="row"> - <div class="col-md-12"> - <i class="fa fa-bug" aria-hidden="true"></i> - <a href="https://bugs.gentoo.org/{{.Id}}" class="text-dark"><b>{{.Summary}}</b></a> - </div> - <div class="col-md-12 text-muted"> - {{.Id}} - Assigned to {{.Assignee}} - </div> - </div> - </li> - {{end}} - {{end}} - </ul> - - {{else}} - - <div class="row pt-5"> - <div class="col-md-4"> - <img style="width: 100%;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Larry-the-cow-full.svg/1200px-Larry-the-cow-full.svg.png"/> - </div> - <div class="col-md-8 pt-3"> - <h2>There are no open security bugs.</h2> - <span>You think something is missing here? <br/> Start with filling a <a href="https://bugs.gentoo.org/">new security bug</a>.</span> - </div> - </div> - - {{end}} - - </div> - <div class="col-md-3 pt-5"> - <h4> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseDescription" role="button" aria-expanded="false" aria-controls="collapseDescription"> - Contact Information - </a> - </h4> - <div class="collapse show" id="collapseDescription"> - <span class="text-muted"> - Please file new vulnerability reports on <a href="https://bugs.gentoo.org/">Gentoo Bugzilla</a> and assign them to the Gentoo Security product and Vulnerabilities component. - </span> - </div> - <h4 class="mt-4"> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseExternalResources" role="button" aria-expanded="false" aria-controls="collapseExternalResources"> - External Resources - </a> - </h4> - <div class="collapse show" id="collapseExternalResources"> - <ul> - <li><a href="https://bugs.gentoo.org/buglist.cgi?bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=IN_PROGRESS&bug_status=RESOLVED&bug_status=VERIFIED&email1=security%40gentoo.org&emailassigned_to1=1&emailtype1=equals&list_id=4699406&query_format=advanced&resolution=---&resolution=FIXED&resolution=INVALID&resolution=WONTFIX&resolution=LATER&resolution=REMIND&resolution=DUPLICATE&resolution=WORKSFORME&resolution=CANTFIX&resolution=NEEDINFO&resolution=TEST-REQUEST&resolution=UPSTREAM&resolution=OBSOLETE&short_desc={{.Package.Category}}%2F{{.Package.Name}}&short_desc_type=allwordssubstr">All security bugs for this package</a></li> - </ul> - </div> - </div> - </div> -{{end}} - diff --git a/web/templates/packages/metadata.tmpl b/web/templates/packages/metadata.tmpl deleted file mode 100644 index 758e01c..0000000 --- a/web/templates/packages/metadata.tmpl +++ /dev/null @@ -1,171 +0,0 @@ -{{define "metadata"}} -{{if gt (len .UserPreferences.Packages.Overview.MetadataFields) 0 }} - <h3 class="pt-3 mb-2">Package Metadata</h3> -{{end}} - -<div class="card border-0 mb-3"> - <ul class="list-group kk-metadata-list"> - - <!-- TODO --> - {{if listContains .UserPreferences.Packages.Overview.MetadataFields "homepage"}} - {{ if gt (len (index .Versions 0).Homepage) 1 }} - <li class="kk-metadata-item list-group-item"> - <div class="row"> - <div class="col-xs-12 col-md-3 kk-metadata-key"> - <span class="fa fa-fw fa-home"></span> - Other homepage(s) - </div> - <div class="col-xs-12 col-md-9"> - <a href="{{ (index (index .Versions 0).Homepage 1) }}">{{ (index (index .Versions 0).Homepage 1) }}</a> - </div> - </div> - </li> - {{end}} - {{end}} - - {{if listContains .UserPreferences.Packages.Overview.MetadataFields "upstream"}} - {{ if .Package.Upstream }} - {{ if or .Package.Upstream.Doc .Package.Upstream.Changelog .Package.Upstream.BugsTo .Package.Upstream.RemoteIds }} - <li class="kk-metadata-item list-group-item"> - <div class="row"> - <div class="col-xs-12 col-md-3 kk-metadata-key"> - <span class="fa fa-fw fa-code-fork"></span> - Upstream - </div> - <div class="col-xs-12 col-md-9"> - <table> - {{if .Package.Upstream.Doc}} - {{range $k, $v := .Package.Upstream.Doc}} - <tr> - <td>{{if eq $k 0}}<span class="kk-useflag-group float-right mr-2">Documentation </span>{{end}}</td> - {{if not (eq $v "")}} - <td><a href="{{ $v}}">{{ $v }}</a></td> - {{end}} - </tr> - {{end}} - {{end}} - {{if .Package.Upstream.Changelog}} - {{range $k, $v := .Package.Upstream.Changelog}} - <tr> - <td>{{if eq $k 0}}<span class="kk-useflag-group float-right mr-2">Changelog</span>{{end}}</td> - {{if not (eq $v "")}} - <td><a href="{{ $v}}">{{ $v }}</a></td> - {{end}} - </tr> - {{end}} - {{end}} - {{if .Package.Upstream.BugsTo}} - {{range $k, $v := .Package.Upstream.BugsTo}} - <tr> - <td>{{if eq $k 0}}<span class="kk-useflag-group float-right mr-2">Bugs-To</span>{{end}}</td> - {{if not (eq $v "")}} - <td><a href="{{ $v}}">{{ $v }}</a></td> - {{end}} - </tr> - {{end}} - {{end}} - {{if .Package.Upstream.RemoteIds}} - {{range $k, $v := .Package.Upstream.RemoteIds}} - {{ $link := RemoteIdLink . }} - {{if not (eq $link "")}} - <tr> - <td>{{if eq $k 0}}<span class="kk-useflag-group float-right mr-2">Remote-Id</span>{{end}}</td> - <td><a href="{{ $link}}">{{ $link }}</a></td> - </tr> - {{end}} - {{end}} - {{end}} - </table> - </div> - </div> - </li> - {{end}} - {{end}} - {{end}} - - {{if listContains .UserPreferences.Packages.Overview.MetadataFields "longdescription"}} - {{ if .Package.Longdescription }} - <li class="kk-metadata-item list-group-item"> - <div class="row"> - <div class="col-xs-12 col-md-3 kk-metadata-key"> - <span class="fa fa-fw fa-info"></span> - Full description - </div> - <div class="col-xs-12 col-md-9"> - {{ .Package.Longdescription }} - </div> - </div> - </li> - {{end}} - {{end}} - - {{if listContains .UserPreferences.Packages.Overview.MetadataFields "useflags"}} - {{ if or .LocalUseflags .GlobalUseflags .UseExpands }} - <li class="kk-metadata-item list-group-item"> - <div class="row"> - <div class="col-xs-12 col-md-3 kk-metadata-key"> - <span class="fa fa-fw fa-sliders"></span> - USE flags - </div> - <div class="col-xs-12 col-md-9"> - {{ template "useflag" .}} - </div> - </div> - </li> - {{end}} - {{end}} - - {{if listContains .UserPreferences.Packages.Overview.MetadataFields "license"}} - {{ if (index .Versions 0).License }} - <li class="kk-metadata-item list-group-item"> - <div class="row"> - <div class="col-xs-12 col-md-3 kk-metadata-key"> - <span class="fa fa-fw fa-legal"></span> - License - </div> - <div class="col-xs-12 col-md-9"> - {{ (index .Versions 0).License }} - </div> - </div> - </li> - {{end}} - {{end}} - - <!-- TODO - <li class="kk-metadata-item list-group-item"> - <div class="row"> - <div class="col-xs-12 col-md-3 kk-metadata-key"> - <span class="fa fa-fw fa-group"></span> - <%= t :herds %> - </div> - <div class="col-xs-12 col-md-9"> - <%= render partial: 'herd', collection: package.herds.sort, as: 'herd', spacer_template: 'maintainer_spacer' %> - </div> - </div> - </li> - --> - - {{if listContains .UserPreferences.Packages.Overview.MetadataFields "maintainers"}} - {{ if .Package.Maintainers }} - <li class="kk-metadata-item list-group-item"> - <div class="row"> - <div class="col-xs-12 col-md-3 kk-metadata-key"> - <span class="fa fa-fw fa-user"></span> - Maintainer(s) - </div> - <div class="col-xs-12 col-md-9"> - {{ range .Package.Maintainers }} - {{if (ne .Name (index $.Package.Maintainers 0).Name)}} - , - {{end}} - <a title="{{if .Name}}{{.Name}}{{else}}{{.Email}}{{end}}" href="/maintainer/{{.Email}}">{{if .Name}}{{.Name}}{{else}}{{.Email}}{{end}}</a> <a href="mailto:{{.Email}}"><i class="fa fa-envelope-o" style="font-size: .925em;" aria-hidden="true"></i></a> - {{end}} - </div> - </div> - </li> - {{end}} - {{end}} - - </ul> -</div> -{{end}} diff --git a/web/templates/packages/packageheader.tmpl b/web/templates/packages/packageheader.tmpl deleted file mode 100644 index 06a4ff0..0000000 --- a/web/templates/packages/packageheader.tmpl +++ /dev/null @@ -1,72 +0,0 @@ -{{define "packageheader"}} - <div class="kk-header-container"> - <div class="container"> - <div class="row"> - <div class="col-12"> - - <div class="row mt-3"> - <div class="col-md-5"> - <h1 class="stick-top kk-package-title" id="package-title" data-atom="{{.Package.Atom}}" data-category="{{.Package.Category}}" data-name="{{.Package.Name}}"> - <small class="kk-package-cat"><a href="/categories/{{.Package.Category}}" class="text-dark">{{.Package.Category}}</a>/</small> - <div> - <svg height="32" class="octicon octicon-package right left kk-package-icon" aria-label="Package icon" viewBox="0 0 16 16" version="1.1" width="32" role="img"><path fill-rule="evenodd" d="M1 4.27v7.47c0 .45.3.84.75.97l6.5 1.73c.16.05.34.05.5 0l6.5-1.73c.45-.13.75-.52.75-.97V4.27c0-.45-.3-.84-.75-.97l-6.5-1.74a1.4 1.4 0 0 0-.5 0L1.75 3.3c-.45.13-.75.52-.75.97zm7 9.09l-6-1.59V5l6 1.61v6.75zM2 4l2.5-.67L11 5.06l-2.5.67L2 4zm13 7.77l-6 1.59V6.61l2-.55V8.5l2-.53V5.53L15 5v6.77zm-2-7.24L6.5 2.8l2-.53L15 4l-2 .53z"></path></svg> - <div class="kk-package-name">{{.Package.Name}}</div> - </div> - </h1> - </div> - <div class="col-md-7"> - <p class="lead kk-package-maindesc"> - {{(index .Versions 0).Description}} - </p> - {{if (index .Versions 0).Homepage}} - <p class="kk-package-homepage"> - <a href="{{ ( index (index .Versions 0).Homepage 0) }}">{{ ( index (index .Versions 0).Homepage 0) }}</a> - </p> - {{end}} - </div> - {{$security_bugs := 0}} - {{$non_security_bugs := 0}} - {{range .Package.AllBugs}} - {{if eq .Component "Vulnerabilities"}} - {{$security_bugs = (add $security_bugs 1)}} - {{else}} - {{$non_security_bugs = (add $non_security_bugs 1)}} - {{end}} - {{end}} - <div class="col-md-12 pt-4 mt-1"> - <nav class="nav kk-package-nav"> - {{if listContains $.UserPreferences.Packages.Tabs.Visible "Overview"}} - <a class="nav-link {{if eq .PageName "overview"}}active{{end}}" href="/packages/{{.Package.Atom}}"><i class="fa fa-info mr-1" aria-hidden="true"></i> Overview</a> - {{end}} - - {{if listContains $.UserPreferences.Packages.Tabs.Visible "Dependencies"}} - <a class="nav-link {{if eq .PageName "dependencies" "reverse-dependencies"}}active{{end}}" href="/packages/{{.Package.Atom}}/{{.UserPreferences.Packages.Dependencies.Default}}"><i class="fa fa-link"></i> Dependencies</a> - {{end}} - - {{if listContains $.UserPreferences.Packages.Tabs.Visible "QA report"}} - <a class="nav-link {{if eq .PageName "qa-report"}}active{{end}}" href="/packages/{{.Package.Atom}}/qa-report"><i class="fa fa-fw fa-chain-broken"></i> QA report </a> - {{end}} - - {{if listContains $.UserPreferences.Packages.Tabs.Visible "Pull requests"}} - <a class="nav-link {{if eq .PageName "pull-requests"}}active{{end}}" href="/packages/{{.Package.Atom}}/pull-requests"><span class="octicon octicon-git-pull-request opticon-resource-icon ml-1"></span> Pull requests <span class="ml-1 badge badge-pill kk-misc-badge">{{len .Package.PullRequests}}</span></a> - {{end}} - - {{if listContains $.UserPreferences.Packages.Tabs.Visible "Bugs"}} - <a class="nav-link {{if eq .PageName "bugs"}}active{{end}}" href="/packages/{{.Package.Atom}}/bugs"><i class="fa fa-bug" aria-hidden="true"></i> Bugs <span class="ml-1 badge badge-pill kk-misc-badge">{{$non_security_bugs}}</span></a> - {{end}} - - {{if listContains $.UserPreferences.Packages.Tabs.Visible "Security"}} - <a class="nav-link {{if eq .PageName "security"}}active{{end}}" href="/packages/{{.Package.Atom}}/security"><i class="fa fa-shield" aria-hidden="true"></i> Security <span class="ml-1 badge badge-pill kk-misc-badge">{{$security_bugs}}</span></a> - {{end}} - - {{if listContains $.UserPreferences.Packages.Tabs.Visible "Changelog"}} - <a class="nav-link {{if eq .PageName "changelog"}}active{{end}}" href="/packages/{{.Package.Atom}}/changelog"><i class="fa fa-fw fa-history"></i> Changelog</a> - {{end}} - </nav> - </div> - </div> - </div> - </div> - </div> - </div> -{{end}} diff --git a/web/templates/packages/resources.tmpl b/web/templates/packages/resources.tmpl deleted file mode 100644 index 784a691..0000000 --- a/web/templates/packages/resources.tmpl +++ /dev/null @@ -1,65 +0,0 @@ -{{define "resources"}} - - <h4 class="mb-2 ml-1"> - <a class="collapseLink" style="color:#000000;" data-toggle="collapse" href="#collapseExternalResources" role="button" aria-expanded="false" aria-controls="collapseExternalResources"> - External Resources - </a> - </h4> - - <div class="collapse show" id="collapseExternalResources"> - <dl class="ml-3"> - <dd> - <span class="fa fa-fw fa-bug"></span> - <a href="https://bugs.gentoo.org/buglist.cgi?quicksearch={{.Package.Atom}}" class="" target="_blank"> - Related bugs - </a> - </dd> - <dd> - <span class="fa fa-fw fa-chain-broken"></span> - <a href="https://qa-reports.gentoo.org/output/gentoo-ci/output.html;pkg={{.Package.Category}}:{{.Package.Name}}" title="CI report" target="_blank">CI Report</a> - (<a href="https://qa-reports.gentoo.org/output/gentoo-ci/output.verbose.html;pkg={{.Package.Category}}:{{.Package.Name}}" title="Verbose CI report" target="_blank">verbose</a>) - </dd> - <dd> - <span class="fa fa-fw fa-sort-numeric-desc"></span> - <a href="https://repology.org/project/{{.Package.Name}}" target="_blank"> - Repology - </a> - </dd> - <dd> - <span class="octicon octicon-git-pull-request opticon-resource-icon ml-1"></span> - <a href="https://github.com/gentoo/gentoo/pulls?q=is%3Apr+is%3Aopen+in%3Atitle+{{.Package.Category}}%2F{{.Package.Name}}" target="_blank"> - Open Pull Requests - </a> - </dd> - <dd> - <span class="fa fa-fw fa-book"></span> - <a href="https://wiki.gentoo.org/wiki/Special:Search/{{.Package.Name}}" target="_blank"> - Documentation - </a> - </dd> - <dd> - <span class="fa fa-fw fa-comments-o"></span> - <a href="https://forums.gentoo.org/search.php?search_terms=all&show_results=topics&search_keywords={{.Package.Name}}&mode=results" target="_blank"> - Forums posts - </a> - </dd> - <dd> - <span class="fa fa-fw fa-code-fork"></span> - <a href="https://gitweb.gentoo.org/repo/gentoo.git/tree/{{.Package.Atom}}" target="_blank"> - Git repository browser - </a> - </dd> - <dd> - <span class="fa fa-fw fa-history"></span> - <a href="https://gitweb.gentoo.org/repo/gentoo.git/log/{{.Package.Atom}}?showmsg=1" title="Git log" target="_blank">Git log</a> - (<a href="https://gitweb.gentoo.org/repo/gentoo.git/log/{{.Package.Atom}}" title="Short git log" target="_blank">short</a>) - </dd> - <dd> - <span class="fa fa-fw fa-rss"></span> - <a href="https://gitweb.gentoo.org/repo/gentoo.git/atom/{{.Package.Atom}}?h=master" target="_blank"> - Changes Feed - </a> - </dd> - </dl> - </div> -{{end}} diff --git a/web/templates/packages/search.tmpl b/web/templates/packages/search.tmpl deleted file mode 100644 index 476830b..0000000 --- a/web/templates/packages/search.tmpl +++ /dev/null @@ -1,71 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - -<div class="container mb-5"> - <div class="row"> - <div class="col-12"> - - - <h1 class="first-header">Search Results <small>for {{.Search}}</small> - <a title="Atom feed" href="/packages/search.atom?q={{.Search}}" class="kk-feed-icon"><span class="fa fa-fw fa-rss-square"></span></a></h1> - - {{ if .Packages }} - <div class="panel panel-default"> - <div class="panel-heading"> - Results 1—{{len .Packages}} of {{len .Packages}} - </div> - <div class="list-group"> - {{range .Packages}} - <a class="list-group-item list-group-item-action" href="/packages/{{.Atom}}"> - <h3 class="kk-search-result-header"><span class="text-muted">{{.Category}}/</span>{{.Name}}</h3> - {{ (index .Versions 0).Description}} - </a> - {{end}} - </div> - <!-- TODO paging - <div class="panel-footer"> - <div class="btn-group" role="group" aria-label="Result navigation"> - <%= link_to '< Prev', search_packages_path(q: params[:q], o: [@offset - PackageRepository.default_search_size, 0].max), class: 'btn btn-default' + (@offset > 0 ? '' : ' disabled') %> - <%= link_to 'Next >', search_packages_path(q: params[:q], o: @offset + PackageRepository.default_search_size), class: 'btn btn-default ' + ((@offset + PackageRepository.default_search_size) > @packages.total ? 'disabled' : '') %> - </div> - </div> - --> - - </div> - - <!-- TODO in head: alternate_feed_link(search_packages_url(format: :atom, params: request.query_parameters), t(:atom_feed)) --> - {{ else }} - <div class="jumbotron"> - <h2 class="site-welcome stick-top">Nothing found. :( Try again?</h2> - - <form action="/packages/search" method="get"> - <div class="typeahead-container"> - <div class="typeahead-field"> - <span class="typeahead-query"> - <input id="q" name="q" type="search" autocomplete="off" placeholder="Find Packages" aria-label="Find Packages" value="{{.Search}}"> - </span> - <span class="typeahead-button"> - <button type="submit" title="Find" aria-label="Find"> - <span class="typeahead-search-icon"></span><span class="sr-only">Find</span> - </button> - </span> - </div> - </div> - </form> - </div> - {{end}} - - - </div> - </div> -</div> - - -{{template "footer" .Application }} - - -</body> -</html> diff --git a/web/templates/packages/show.tmpl b/web/templates/packages/show.tmpl deleted file mode 100644 index c2f2a39..0000000 --- a/web/templates/packages/show.tmpl +++ /dev/null @@ -1,41 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - -{{template "packageheader" .}} - -<div class="tab-content" id="myTabContent"> - <div class="container mb-5 tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="overview-tab"> - {{if eq .PageName "overview"}} - {{template "overview" .}} - {{else if eq .PageName "qa-report"}} - {{template "qa-report" .}} - {{else if eq .PageName "pull-requests"}} - {{template "pull-requests" .}} - {{else if eq .PageName "bugs"}} - {{template "bugs" .}} - {{else if eq .PageName "security"}} - {{template "security" .}} - {{else if eq .PageName "dependencies"}} - {{template "dependencies" .}} - {{else if eq .PageName "reverse-dependencies"}} - {{template "reverse-dependencies" .}} - {{else if eq .PageName "changelog"}} - <div class="row"> - <div class="col-md-9"> - {{template "changelog" .}} - </div> - </div> - {{end}} - </div> -</div> - -{{template "footer" .Application }} - -<script src="/assets/packages.js"></script> - - -</body> -</html> diff --git a/web/templates/packages/useflag.tmpl b/web/templates/packages/useflag.tmpl deleted file mode 100644 index ce136af..0000000 --- a/web/templates/packages/useflag.tmpl +++ /dev/null @@ -1,40 +0,0 @@ -{{define "useflag"}} - {{ if .LocalUseflags }} - <span class="kk-useflag-group">Local Use Flags</span> - <ul class="kk-useflag-container {{ if ge (len .LocalUseflags) 10 }}kk-useflag-container-many{{else}}kk-useflag-container-few{{end}}"> - {{range .LocalUseflags}} - <li class="kk-useflag"> - <a title="{{.Description}}" data-toggle="tooltip" href="/useflags/{{.Name}}">{{.Name}}</a> - </li> - {{end}} - </ul> - - {{end}} - - - - {{ if .GlobalUseflags }} - <span class="kk-useflag-group">Global Use Flags</span> - <ul class="kk-useflag-container {{ if ge (len .GlobalUseflags) 10 }}kk-useflag-container-many{{else}}kk-useflag-container-few{{end}}"> - {{range .GlobalUseflags}} - <li class="kk-useflag"> - <a title="{{.Description}}" data-toggle="tooltip" href="/useflags/{{.Name}}">{{.Name}}</a> - </li> - {{end}} - </ul> - {{end}} - - - {{ if .UseExpands }} - {{range $key, $flags := .UseExpands}} - <span class="kk-useflag-group">{{ $key }} (Use Expand)</span> - <ul class="kk-useflag-container {{ if ge (len $flags) 10 }}kk-useflag-container-many{{else}}kk-useflag-container-few{{end}}"> - {{range $flags}} - <li class="kk-useflag"> - <a title="{{.Description}}" data-toggle="tooltip" href="/useflags/{{.Name}}">{{ replaceall .Name (print .UseExpand "_") "" }}</a> - </li> - {{end}} - </ul> - {{end}} - {{end}} -{{end}} diff --git a/web/templates/packages/versionrows.tmpl b/web/templates/packages/versionrows.tmpl deleted file mode 100644 index 56248ae..0000000 --- a/web/templates/packages/versionrows.tmpl +++ /dev/null @@ -1,75 +0,0 @@ -{{define "versionrows"}} - {{range $index, $version := .Package.Versions}} - <tr> - <td class="kk-version "><strong><a class="kk-ebuild-link" href="https://gitweb.gentoo.org/repo/gentoo.git/tree/{{$version.Atom}}/{{$version.Package}}-{{$version.Version}}.ebuild">{{$version.Version}}</a></strong><span class="kk-slot" title="subslot {{ $version.Subslot }}"> : {{ $version.Slot }}</span> - {{ if $version.Restricts }} - <span class="badge badge-danger kk-restrict-label" title="The following features are restricted: {{ $version.Restricts }}">{{ formatRestricts $version.Restricts }}</span> - {{ end }} - {{ if eq $.UserPreferences.Packages.Overview.EAPI "inline"}} - <span style="background-color: white;border:1px solid grey;color: grey;" class="badge badge-danger kk-restrict-label" title="The following features are restricted:">EAPI {{$version.EAPI}}</span> - {{end}} - </td> - - {{ if eq $.UserPreferences.Packages.Overview.EAPI "column"}} - <td class="text-center"> - {{$version.EAPI}} - </td> - {{end}} - - {{ range $.UserPreferences.Packages.Overview.Keywords }} - - {{ if contains (print " " $version " ") (print "~" . " ") }} - - {{ if ge (len $version.Masks) 1 }} - <td class="kk-keyword kk-keyword-masked" title="{{$version.Version}} is masked (testing) on {{.}}"> - <svg height="16" class="octicon octicon-diff-modified" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-8.5-2H3v-1.5L9.5 4H11v1.5L4.5 12z"></path></svg> - <span class="sr-only">~{{.}}</span> - </td> - {{else}} - <td class="kk-keyword kk-keyword-testing" title="{{$version.Version}} is testing on {{.}}"> - <svg height="16" class="octicon octicon-diff-modified" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM4 8c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3-3-1.34-3-3z"></path></svg> - <span class="sr-only">~{{.}}</span> - </td> - {{end}} - - {{ else if contains (print " " $version.Keywords " ") (print "-" . " ") }} - - <td class="kk-keyword kk-keyword-unavailable" title="{{$version.Version}} is unavailable on {{.}}"> - <svg height="16" class="octicon octicon-diff-removed" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-2-5H3V7h8v2z"></path></svg> - <span class="sr-only">-{{.}}</span> - </td> - - {{ else if contains (print " " $version.Keywords " ") (print . " ") }} - - {{ if ge (len $version.Masks) 1 }} - <td class="kk-keyword kk-keyword-masked" title="{{$version.Version}} is masked (stable) on {{.}}"> - <svg height="16" class="octicon octicon-diff-added" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-8.5-2H3v-1.5L9.5 4H11v1.5L4.5 12z"></path></svg> - <span class="sr-only">{{.}}</span> - </td> - {{else}} - <td class="kk-keyword kk-keyword-stable" title="{{$version.Version}} is stable on {{.}}"> - <svg height="16" class="octicon octicon-diff-added" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM6 9H3V7h3V4h2v3h3v2H8v3H6V9z"></path></svg> - <span class="sr-only">{{.}}</span> - </td> - {{end}} - - {{ else if contains $version.Keywords "-*" }} - - <td class="kk-keyword kk-keyword-unavailable" title="{{$version.Version}} is unavailable on {{.}}"> - <svg height="16" class="octicon octicon-diff-removed" viewBox="0 0 14 16" version="1.1" width="14" aria-hidden="true"><path fill-rule="evenodd" d="M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-2-5H3V7h8v2z"></path></svg> - <span class="sr-only">-{{.}}</span> - </td> - - {{else}} - - <td class="kk-keyword kk-keyword-unkown" title="{{$version.Version}} is unknown on {{.}}"> - <span class="sr-only">{{.}}</span> - </td> - - {{end}} - - {{end}} - - </tr> - {{end}} -{{end}} diff --git a/web/templates/packages/versions.tmpl b/web/templates/packages/versions.tmpl deleted file mode 100644 index 1b36baf..0000000 --- a/web/templates/packages/versions.tmpl +++ /dev/null @@ -1,25 +0,0 @@ -{{define "versions"}} - - <h3 class="mb-2">Available Versions</h3> - - <div class="card mb-4 rounded"> - <div class="table-responsive border-0"> - <table class="table table-bordered kk-versions-table mb-0 overflow-hidden border-0"> - <thead class="border-0"> - <tr class="border-0"> - <th class="kk-version border-left-0 border-top-0">Version</th> - {{ if eq .UserPreferences.Packages.Overview.EAPI "column"}} - <th class="kk-keyword-header kk-keyword border-left-0 border-top-0">EAPI</th> - {{end}} - {{range .UserPreferences.Packages.Overview.Keywords}} - <th class="kk-keyword-header kk-keyword border-left-0 border-top-0">{{.}}</th> - {{end}} - </tr> - </thead> - <tbody> - {{template "versionrows" .}} - </tbody> - </table> - </div> - </div> -{{end}} diff --git a/web/templates/useflags/browseuseflagsheader.tmpl b/web/templates/useflags/browseuseflagsheader.tmpl deleted file mode 100644 index fd26f82..0000000 --- a/web/templates/useflags/browseuseflagsheader.tmpl +++ /dev/null @@ -1,33 +0,0 @@ -{{define "browseuseflagsheader"}} - <div class="kk-header-container"> - <div class="container"> - <div class="row"> - <div class="col-12"> - - <div class="row mt-3 pt-2"> - <div class="col-md-5"> - <h1 class="stick-top kk-package-title" id="package-title"> - <div> - <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-sliders"></span><span class="ml-2">USE flags</span></div> - </div> - </h1> - </div> - <div class="col-md-7"> - - </div> - - <div class="col-md-12 pt-4 mt-1"> - <nav class="nav kk-package-nav"> - <a class="nav-link {{if eq .Page "browse"}}active{{end}}" href="/useflags"><i class="fa fa-line-chart mr-1" aria-hidden="true"></i> Widely used</a> - <a class="nav-link {{if eq .Page "search"}}active{{end}}" href="/useflags/search"><i class="fa fa-search mr-1" aria-hidden="true"></i> Search</a> - <a class="nav-link {{if eq .Page "global"}}active{{end}}" href="/useflags/global"><i class="fa fa-globe mr-1" aria-hidden="true"></i> Global</a> - <a class="nav-link {{if eq .Page "local"}}active{{end}}" href="/useflags/local"><i class="fa fa-map-marker mr-1" aria-hidden="true"></i> Local</a> - - </nav> - </div> - </div> - </div> - </div> - </div> - </div> -{{end}} diff --git a/web/templates/useflags/index.tmpl b/web/templates/useflags/index.tmpl deleted file mode 100644 index 455e7d3..0000000 --- a/web/templates/useflags/index.tmpl +++ /dev/null @@ -1,47 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - -{{template "browseuseflagsheader" .}} - - -<div class="tab-content" id="myTabContent"> - - -<div class="container mb-5"> - <div class="row"> - - <div class="col-12"> - - - <div class="card" style="background: none;border: none;"> - <noscript> - <div class="panel-body kk-panel-content-sorry"> - This feature requires JavaScript to work. - </div> - </noscript> - <div class="panel-body kk-useflag-bubble-container" id="bubble-placeholder" style="overflow: hidden!important; display: none;"> - </div> - </div> - - <!-- javascript_pack_tag 'useflags' --> - - - </div> - </div> -</div> - - -</div> - - -{{template "footer" .Application }} - - -<script src="/assets/useflags.js"></script> - - -</body> -</html> diff --git a/web/templates/useflags/list.tmpl b/web/templates/useflags/list.tmpl deleted file mode 100644 index 27c29dc..0000000 --- a/web/templates/useflags/list.tmpl +++ /dev/null @@ -1,45 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - -{{template "browseuseflagsheader" .}} - - -<div class="tab-content" id="myTabContent"> - - -<div class="container mb-5"> - <div class="row"> - <div class="col-12"> - - {{if .Useflags}} - <h3><span class="text-capitalize">{{.Page}}</span> USE flags</h3> - - <div class="card border-0"> - <div class="list-group"> - {{ range .Useflags }} - <a class="list-group-item list-group-item-action text-dark" href="/useflags/{{.Name}}"> - <h3 class="kk-search-result-header">{{.Name}}</h3> - {{.Description}} - </a> - {{end}} - </div> - </div> - {{end}} - - - </div> - </div> -</div> - - -</div> - - -{{template "footer" .Application }} - - -</body> -</html> diff --git a/web/templates/useflags/listlocal.tmpl b/web/templates/useflags/listlocal.tmpl deleted file mode 100644 index e6d52eb..0000000 --- a/web/templates/useflags/listlocal.tmpl +++ /dev/null @@ -1,61 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - -{{template "browseuseflagsheader" .}} - - -<div class="tab-content" id="myTabContent"> - - -<div class="container mb-5"> - <div class="row"> - <div class="col-12"> - - {{if .Useflags}} - {{$package := (index .Useflags 0).Package}} - <h3>{{$package}}</h3> - - <div class="card border-0"> - <div class="list-group"> - {{ range .Useflags }} - {{ if eq .Package $package}} - <a class="list-group-item list-group-item-action text-dark" href="/useflags/{{.Name}}"> - <h3 class="kk-search-result-header">{{.Name}}</h3> - {{.Description}} - </a> - {{$package = .Package}} - {{else}} - {{$package = .Package}} - </div> - </div> - <h3 class="mt-4">{{$package}}</h3> - - <div class="card border-0"> - <div class="list-group"> - <a class="list-group-item list-group-item-action text-dark" href="/useflags/{{.Name}}"> - <h3 class="kk-search-result-header">{{.Name}}</h3> - {{.Description}} - </a> - {{end}} - {{end}} - </div> - </div> - {{end}} - - - </div> - </div> -</div> - - -</div> - - -{{template "footer" .Application }} - - -</body> -</html> diff --git a/web/templates/useflags/search.tmpl b/web/templates/useflags/search.tmpl deleted file mode 100644 index 210d7e1..0000000 --- a/web/templates/useflags/search.tmpl +++ /dev/null @@ -1,68 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - -{{template "browseuseflagsheader" .}} - - -<div class="tab-content" id="myTabContent"> - - -<div class="container mb-5"> - <div class="row"> - <div class="col-12 {{if not .Useflags}}mt-5 pt-5{{end}}"> - - <div class="col-12 mt-3 text-center"> - <h2>Find USE flags</h2> - </div> - - <div class="col-12"> - <form action="/useflags/search" method="get" class="useflag-search mt-3 mb-5 mx-5 px-5"> - <div class="typeahead-container mx-5 px-5"> - <div class="typeahead-field"> - <span class="typeahead-query" style="font-size: 1.1em; height: 2.3em;"> - <input id="q" name="q" class="rounded-left" style="font-size: 1.1em; height: 2.3em;border-right: 0px;" type="search" autocomplete="off" placeholder="Find USE flags"> - </span> - <span class="typeahead-button" style="font-size: 1.1em!important; height: 2.3em!important;border-left: 0px;"> - <button style="border-top-right-radius: 0.25rem !important; border-bottom-right-radius: 0.25rem !important; font-size: 1.1em!important; height: 2.3em!important;border-left: 0px;box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);!important;" type="submit"> - <span class="typeahead-search-icon"></span> - </button> - </span> - </div> - </div> - </form> - </div> - - {{if .Search}} - {{if .Useflags}} - <h2>USE Flag Search Results <small>for {{ .Search }}</small></h2> - - <div class="card border-0"> - <div class="list-group"> - {{ range .Useflags }} - <a class="list-group-item list-group-item-action text-dark" href="/useflags/{{.Name}}"> - <h3 class="kk-search-result-header">{{.Name}}</h3> - {{.Description}} - </a> - {{end}} - </div> - </div> - {{else}} - <h2>No results found <small> for {{ .Search }}</small></h2> - {{end}} - {{end}} - </div> - </div> -</div> - - -</div> - - -{{template "footer" .Application }} - - -</body> -</html> diff --git a/web/templates/useflags/show.tmpl b/web/templates/useflags/show.tmpl deleted file mode 100644 index 48d6048..0000000 --- a/web/templates/useflags/show.tmpl +++ /dev/null @@ -1,67 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - - -{{template "useflagsheader" .}} - - -<div class="tab-content" id="myTabContent"> - -<div class="container mb-5"> - <div class="row"> - <div class="col-12"> - - - {{ if .LocalUseflags }} - <h3 class="mb-2">Packages describing “{{.Useflag.Name}}” as local USE flag</h3> - <div class="card mb-4 border-top-0"> - <div class="table-responsive"> - <table class="table mb-0"> - <thead> - <th>Package</th> - <th>“{{.Useflag.Name}}” Flag Description</th> - </thead> - <tbody> - <!-- TODO sort by package --> - {{ range .LocalUseflags}} - <tr> - <th class="kk-nobreak-cell"><a href="/packages/{{.Package}}">{{.Package}}</a></th> - <!-- TODO sanitization needed here? --> - <td>{{.Description}}</td> - </tr> - {{end}} - </tbody> - </table> - </div> - </div> - {{end}} - - {{ if .Packages }} - <h3 class="mb-2 pt-2">All packages providing a “{{.Useflag.Name}}” USE flag ({{len .Packages}})</h3> - <div class="card"> - <div class="card-body"> - <ul class="kk-col-list kk-3col-list kk-useflag-listing mb-0"> - {{range .Packages}} - <li><a href="/packages/{{.}}">{{.}}</a></li> - {{end}} - </ul> - </div> - </div> - {{end}} - - </div> - </div> -</div> - -</div> - - -{{template "footer" .Application }} - - - -</body> -</html> diff --git a/web/templates/useflags/showexpand.tmpl b/web/templates/useflags/showexpand.tmpl deleted file mode 100644 index 9ed145a..0000000 --- a/web/templates/useflags/showexpand.tmpl +++ /dev/null @@ -1,65 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - - - -{{template "useflagsheader" .}} - - -<div class="tab-content" id="myTabContent"> - -<div class="container mb-5"> - <div class="row"> - <div class="col-12"> - - {{ if .OtherUseExpands }} - <h3 class="mb-2">Other “{{.Useflag.UseExpand}}” USE_EXPAND flag values</h3> - <div class="card"> - <div class="table-responsive"> - <table class="table"> - <thead> - <th>Use Flag</th> - <th>Description</th> - </thead> - <tbody> - {{range .OtherUseExpands}} - <tr> - <th class="kk-nobreak-cell"><a href="/useflags/{{.Name}}">{{.Name}}</a></th> - <td>{{.Description}}</td> - </tr> - {{end}} - </tbody> - </table> - </div> - </div> - {{end}} - - {{ if .Packages }} - <h3 class="mb-2 mt-4">All packages providing a “{{.Useflag.Name}}” USE flag ({{len .Packages}})</h3> - <div class="card"> - <div class="card-body"> - <ul class="kk-col-list kk-3col-list kk-useflag-listing"> - {{range .Packages}} - <li><a href="/packages/{{.}}">{{.}}</a></li> - {{end}} - </ul> - </div> - </div> - {{end}} - - </div> - </div> -</div> - -</div> - - -{{template "footer" .Application }} - - - -</body> -</html> diff --git a/web/templates/useflags/useflagsheader.tmpl b/web/templates/useflags/useflagsheader.tmpl deleted file mode 100644 index 05291df..0000000 --- a/web/templates/useflags/useflagsheader.tmpl +++ /dev/null @@ -1,34 +0,0 @@ -{{define "useflagsheader"}} - <div class="kk-header-container"> - <div class="container"> - <div class="row"> - <div class="col-12"> - - <div class="row mt-3 pt-2"> - <div class="col-md-5"> - <h1 class="stick-top kk-package-title" id="package-title"> - - <small class="kk-package-cat"><a href="/useflags" class="text-dark ml-1 {{if .Useflag.UseExpand}}{{else}}text-capitalize{{end}}">{{if .Useflag.UseExpand}}{{.Useflag.UseExpand}}{{else}}{{.Useflag.Scope}} USE flag{{end}}</a></small> - <div> - <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-sliders"></span><span class="ml-2">{{if .Useflag.UseExpand}}{{ replaceall .Useflag.Name (print .Useflag.UseExpand "_") ""}}{{else}}{{.Useflag.Name}}{{end}}</span></div> - </div> - </h1> - </div> - <div class="col-md-7"> - <p class="lead kk-package-maindesc"> - {{.Useflag.Description}} - </p> - </div> - - <div class="col-md-12 pt-4 mt-1"> - <nav class="nav kk-package-nav"> - <a class="nav-link active" href="/categories/browse"><i class="fa fa-list mr-1" aria-hidden="true"></i> Packages</a> - - </nav> - </div> - </div> - </div> - </div> - </div> - </div> -{{end}} diff --git a/web/templates/user/preferences.tmpl b/web/templates/user/preferences.tmpl deleted file mode 100644 index d7fe321..0000000 --- a/web/templates/user/preferences.tmpl +++ /dev/null @@ -1,49 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -{{template "head" .Header}} -<body> -{{template "header" .Header}} - -{{template "userheader" . }} - - -<div class="tab-content" id="myTabContent"> - - <div class="container mb-5"> - {{if eq .PageName "general"}} - {{template "general" .}} - {{else if eq .PageName "packages"}} - {{template "packages" .}} - {{else if eq .PageName "maintainers"}} - {{template "maintainers" .}} - {{else if eq .PageName "useflags"}} - {{template "useflags" .}} - {{else if eq .PageName "arches"}} - {{template "arches" .}} - {{end}} - </div> - -</div> - - -{{template "footer" .Application }} - -<script src="/assets/userpref.js"></script> -<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script> -<script> - if(document.getElementById("example1") != null && document.getElementById("example2") != null) { - new Sortable(example1, { - group: 'shared', - animation: 150, - ghostClass: 'bg-info' - }); - new Sortable(example2, { - group: 'shared', - animation: 150, - ghostClass: 'bg-info' - }); - } -</script> - -</body> -</html> diff --git a/web/templates/user/preferences/arches.tmpl b/web/templates/user/preferences/arches.tmpl deleted file mode 100644 index df1c653..0000000 --- a/web/templates/user/preferences/arches.tmpl +++ /dev/null @@ -1,77 +0,0 @@ -{{define "arches"}} - <div class="row"> - - <div class="col-2 mt-1"> - <div class="nav flex-column" role="tablist" aria-orientation="vertical" style="position: fixed;"> - <a class="nav-link user-pref-nav-link active" id="keywords-tab" href="#keywords" aria-controls="overview-settings">Keywords</a> - <a class="nav-link user-pref-nav-link" id="defaults-tab" href="#defaults">Defaults</a> - </div> - </div> - - <div class="col-10 mt-1"> - - <form method="post" action="/user/preferences/arches/visible"> - <h3 class="" id="keywords">Keywords</h3><hr class="mt-1"/> - <div class="row pl-3"> - <ul id="example1" class="list-group col-6"> - {{range $index, $keyword := .UserPreferences.Arches.Visible}} - <li class="list-group-item"> - <div class="form-check form-check-inline w-100"> - <input type="checkbox" id="visible-arches-{{$keyword}}" name="visible-arches" value="{{$keyword}}" {{if Contains $.UserPreferences.Arches.Visible $keyword}}checked{{end}}/> - <label class="form-check-label ml-1" for="visible-arches-{{$keyword}}">{{$keyword}}</label> <i class="fa fa-arrows ml-auto" aria-hidden="true"></i> - </div> - </li> - {{end}} - {{$counter := 0}} - {{range $index, $keyword := .UserPreferences.GetAllKeywords}} - {{if not (Contains $.UserPreferences.Arches.Visible $keyword)}} - {{$counter = add $counter 1}} - <li class="list-group-item"> - <div class="form-check form-check-inline w-100"> - <input type="checkbox" id="visible-arches-{{$keyword}}" name="visible-arches" value="{{$keyword}}" {{if Contains $.UserPreferences.Arches.Visible $keyword}}checked{{end}}/> - <label class="form-check-label ml-1" for="visible-arches-{{$keyword}}">{{$keyword}}</label> <i class="fa fa-arrows ml-auto" aria-hidden="true"></i> - </div> - </li> - {{end}} - - {{if eq (add (len $.UserPreferences.Arches.Visible) $counter) 16}} - </ul> - <ul id="example2" class="list-group col-6"> - {{end}} - {{end}} - </ul> - </div> - - <h3 class="mt-5" id="defaults">Defaults</h3><hr class="mt-1"/> - <div class="card"> - <div class="card-body"> - <div class="row"> - <div class="col-6"> - Default arch <select class="form-control" style="max-width: 200px;display: inline;" name="arches-default-arch" id="arches-default-arch"> - {{range $index, $keyword := .UserPreferences.GetAllKeywords}} - <option value="{{$keyword}}" {{if eq $.UserPreferences.Arches.DefaultArch $keyword}}selected{{end}}>{{$keyword}}</option> - {{end}} - </select> - </div> - <div class="col-6"> - Default page <select class="form-control" style="max-width: 150px;display: inline;" name="arches-default-page" id="arches-default-page"> - <option value="keyworded" {{if eq .UserPreferences.Arches.DefaultPage "keyworded"}}selected{{end}}>keyworded</option> - <option value="stable" {{if eq .UserPreferences.Arches.DefaultPage "stable"}}selected{{end}}>newly stable</option> - </select> - </div> - </div> - </div> - </div> - - <div class="row"> - <div class="col-12 mt-4"> - <button type="submit" class="float-right btn btn-sm btn-primary">Save</button> - <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/arches/reset">Reset to Defaults</a> - </div> - </div> - - </form> - - </div> - </div> -{{end}} diff --git a/web/templates/user/preferences/general.tmpl b/web/templates/user/preferences/general.tmpl deleted file mode 100644 index bfc6883..0000000 --- a/web/templates/user/preferences/general.tmpl +++ /dev/null @@ -1,46 +0,0 @@ -{{define "general"}} - <form method="post" action="/user/preferences/general/layout"> - <div class="row"> - - <div class="col-5 offset-1 mt-1"> - <div class="card" style="background: transparent;"> - <div class="card-body"> - <img id="img1" alt="Recently Added Packages (default)" src="/assets/pgo3.png" style="width: 100%;cursor: pointer;" /> - </div> - </div> - <div class="text-center mt-2"> - <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;"> - <input type="radio" id="classicLandingpageLayout" name="landingpage-layout" value="classic" {{if eq .UserPreferences.General.LandingPageLayout "classic"}}checked{{end}}> - <label class="form-check-label ml-1" for="classicLandingpageLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Recently Added Packages (default)">Recently Added Packages <i>(default)</i></label> - </div> - </div> - </div> - - <div class="col-5 mt-1"> - <div class="card" style="background: transparent;"> - <div class="card-body"> - <img id="img2" alt="Recently Visited Packages" src="/assets/pgo4.png" style="width: 100%;cursor: pointer;" /> - </div> - </div> - <div class="text-center mt-2"> - <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;"> - <input type="radio" id="fullLandingpageLayout" name="landingpage-layout" value="full" {{if eq .UserPreferences.General.LandingPageLayout "full"}}checked{{end}}> - <label class="form-check-label ml-1" for="fullLandingpageLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Recently Visited Packages">Recently Visited Packages</label> - </div> - </div> - </div> - - <div class="col-10 offset-1 mt-4"> - <button type="submit" class="float-right btn btn-sm btn-primary">Save</button> - <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/general/reset">Reset to Defaults</a> - </div> - - </div> - </form> - - <div id="myModal" class="modal"> - <span class="close">×</span> - <img class="modal-content" id="img01"> - <div id="caption"></div> - </div> -{{end}} diff --git a/web/templates/user/preferences/maintainers.tmpl b/web/templates/user/preferences/maintainers.tmpl deleted file mode 100644 index 561aad7..0000000 --- a/web/templates/user/preferences/maintainers.tmpl +++ /dev/null @@ -1,44 +0,0 @@ -{{define "maintainers"}} - <form method="post" action="/user/preferences/maintainers/edit"> - <div class="row"> - <div class="col-12"> - <h3 class="mt-0" id="qa-report">Include Project Packages</h3> - <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;"> - <input type="checkbox" id="include-packages" name="include-packages" value="true" {{if $.UserPreferences.Maintainers.IncludeProjectPackages }}checked{{end}} /> - <label class="form-check-label ml-1" for="include-packages" style="overflow:hidden;text-overflow: ellipsis;" title="">Include packages of projects the maintainer is part of</label> - </div> - <i>If this option is enabled, all packages, QA reports, pull requests and bugs of projects a maintainer is part of will be displayed as well on the maintainer page. That is, if <i>Larry</i> is part of the <i>Python</i> project, all packages, QA reports, pull requests and bugs of the Python project will be displayed as well on the maintainer page of <i>Larry</i>.<br/>Below you can furthermore specify projects that will be excluded on the maintainer page. E.g. if Larry is furthermore part of the proxy-maintainers project, and the project is marked below, packages of the proxy maintainers project won't be shown on Larry's maintainer page.</i> - </div> - - - <div class="col-12"> - <h3 class="mt-4 pt-3" id="qa-report">Excluded Projects</h3> - </div> - <div class="col-3"> - {{range $index, $project := .Projects}} - <ul class="list-group mb-2"> - <li class="list-group-item"> - <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;height:21px;"> - <input type="checkbox" id="excluded-projects-{{$project.Email}}" name="excluded-projects" value="{{$project.Email}}" {{if (Contains $.UserPreferences.Maintainers.ExcludedProjects $project.Email) }}checked{{end}}/> - <label class="form-check-label ml-1" for="excluded-projects-{{$project.Email}}" style="overflow:hidden;text-overflow: ellipsis;height:21px;" title="{{$project.Name}}">{{$project.Name}}</label> - </div> - </li> - </ul> - {{if eq $index 40}} - </div><div class="col-3"> - {{else if eq $index 81}} - </div><div class="col-3"> - {{else if eq $index 122}} - </div><div class="col-3"> - {{end}} - {{end}} - </div> - - <div class="col-12 mt-4"> - <button type="submit" class="float-right btn btn-sm btn-primary">Save</button> - <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/maintainers/reset">Reset to Defaults</a> - </div> - - </div> - </form> -{{end}} diff --git a/web/templates/user/preferences/packages.tmpl b/web/templates/user/preferences/packages.tmpl deleted file mode 100644 index ae4e9b2..0000000 --- a/web/templates/user/preferences/packages.tmpl +++ /dev/null @@ -1,319 +0,0 @@ -{{define "packages"}} - <div class="row"> - - <div class="col-2 mt-1"> - <div class="nav flex-column" role="tablist" aria-orientation="vertical" style="position: fixed;"> - <a class="nav-link user-pref-nav-link active" id="overview-tab" href="#overview" aria-controls="overview-settings">Overview</a> - <a class="nav-link user-pref-nav-link" id="dependencies-tab" href="#dependencies">Dependencies</a> - <a class="nav-link user-pref-nav-link" id="pull-requests-tab" href="#pull-requests" aria-controls="pull-requests-settings">Pull requests</a> - <a class="nav-link user-pref-nav-link" id="bugs-tab" href="#bugs" aria-controls="bugs-settings">Bugs</a> - <a class="nav-link user-pref-nav-link" id="security-tab" href="#security" aria-controls="security-settings">Security</a> - <a class="nav-link user-pref-nav-link" id="changelog-tab" href="#changelog" aria-controls="changelog-settings">Changelog</a> - <a class="nav-link user-pref-nav-link" id="qa-report-tab" href="#qa-report" aria-controls="qa-report-settings">QA report</a> - <a class="nav-link user-pref-nav-link" id="tabs-tab" href="#tabs" aria-controls="tabs-settings">Tabs</a> - </div> - </div> - - <div class="col-9 mt-1"> - - <form method="post" action="/user/preferences/packages/edit"> - - <h3 id="overview">Overview</h3><hr class="mt-1"/> - <h4 class="mb-1">Layout</h4> - - <div class="row"> - <div class="col-6 mt-1"> - <div class="card" style="background: transparent;"> - <div class="card-body"> - <img id="img1" alt="Versions + Metadata (default)" src="/assets/pgo2.png" style="width: 100%;cursor: pointer;" /> - </div> - </div> - <div class="text-center mt-2"> - <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;"> - <input type="radio" id="minimalOverviewLayout" name="overview-layout" value="minimal" {{if eq .UserPreferences.Packages.Overview.Layout "minimal"}}checked{{end}}> - <label class="form-check-label ml-1" for="minimalOverviewLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Versions + Metadata (default)">Versions + Metadata <i>(default)</i></label> - </div> - </div> - </div> - - <div class="col-6 mt-1"> - <div class="card" style="background: transparent;"> - <div class="card-body"> - <img id="img2" alt="Versions + Metadata + Changelog" src="/assets/pgo1.png" onclick="document.getElementById('fullOverviewLayout').checked = true;" style="width: 100%;cursor: pointer;" /> - </div> - </div> - <div class="text-center mt-2"> - <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;"> - <input type="radio" id="fullOverviewLayout" name="overview-layout" value="full" {{if eq .UserPreferences.Packages.Overview.Layout "full"}}checked{{end}}> - <label class="form-check-label ml-1" for="fullOverviewLayout" style="overflow:hidden;text-overflow: ellipsis;" title="Versions + Metadata + Changelog">Versions + Metadata + Changelog</label> - </div> - </div> - </div> - </div> - - <h4 class="mt-4 mb-1">Keywords</h4> - <div class="row pl-3"> - <ul id="example1" class="list-group col-6"> - {{range $index, $keyword := .UserPreferences.Packages.Overview.Keywords}} - <li class="list-group-item"> - <div class="form-check form-check-inline w-100"> - <input type="checkbox" id="overview-keywords-{{$keyword}}" name="overview-keywords" value="{{$keyword}}" {{if Contains $.UserPreferences.Packages.Overview.Keywords $keyword}}checked{{end}}/> - <label class="form-check-label ml-1" for="overview-keywords-{{$keyword}}">{{$keyword}}</label> <i class="fa fa-arrows ml-auto" aria-hidden="true"></i> - </div> - </li> - {{end}} - {{$counter := 0}} - {{range $index, $keyword := .UserPreferences.GetAllKeywords}} - {{if not (Contains $.UserPreferences.Packages.Overview.Keywords $keyword)}} - {{$counter = add $counter 1}} - <li class="list-group-item"> - <div class="form-check form-check-inline w-100"> - <input type="checkbox" id="overview-keywords-{{$keyword}}" name="overview-keywords" value="{{$keyword}}" {{if Contains $.UserPreferences.Packages.Overview.Keywords $keyword}}checked{{end}}/> - <label class="form-check-label ml-1" for="overview-keywords-{{$keyword}}">{{$keyword}}</label> <i class="fa fa-arrows ml-auto" aria-hidden="true"></i> - </div> - </li> - {{end}} - - {{if eq (add (len $.UserPreferences.Packages.Overview.Keywords) $counter) 16}} - </ul> - <ul id="example2" class="list-group col-6"> - {{end}} - {{end}} - </ul> - </div> - - <h4 class="mt-4 mb-1">EAPI version</h4> - <div class="card"> - <div class="card-body"> - Show <select class="form-control form-control-sm ml-2" style="max-width: 100px;display: inline;" name="overview-eapi" id="overview-eapi"> - <option value="none" {{if eq .UserPreferences.Packages.Overview.EAPI "none"}}selected{{end}}>none</option> - <option value="column" {{if eq .UserPreferences.Packages.Overview.EAPI "column"}}selected{{end}}>in column</option> - <option value="inline" {{if eq .UserPreferences.Packages.Overview.EAPI "inline"}}selected{{end}}>inline</option> - </select> - </div> - </div> - - <h4 class="mt-4 mb-1">Outdated Versions</h4> - <div class="card"> - <div class="card-body"> - - <div class="form-check form-check-inline"> - <input type="checkbox" class="" id="overview-showOutdated" name="overview-showOutdated" value="true" {{if .UserPreferences.Packages.Overview.ShowOutdated}}checked{{end}}/> - <label class="form-check-label ml-1" for="overview-showOutdated">Show Outdated warnings?</label> - </div> - </div> - </div> - - <h4 class="mt-4 mb-1">Metadata</h4> - <div class="card"> - <div class="card-body"> - <div class="row"> - - <div class="col-4"> - <div class="form-check form-check-inline"> - <input type="checkbox" name="overview-metadata-fields" id="overview-metadata-fields-homepage" value="homepage" {{if Contains .UserPreferences.Packages.Overview.MetadataFields "homepage"}}checked{{end}}/> - <label class="form-check-label ml-1" for="overview-metadata-fields-homepage">Homepage</label> - </div> - </div> - <div class="col-4"> - <div class="form-check form-check-inline"> - <input type="checkbox" name="overview-metadata-fields" id="overview-metadata-fields-upstream" value="upstream" {{if Contains .UserPreferences.Packages.Overview.MetadataFields "upstream"}}checked{{end}}/> - <label class="form-check-label ml-1" for="overview-metadata-fields-upstream">Upstream</label> - </div> - </div> - <div class="col-4"> - <div class="form-check form-check-inline"> - <input type="checkbox" name="overview-metadata-fields" id="overview-metadata-fields-longdescription" value="longdescription" {{if Contains .UserPreferences.Packages.Overview.MetadataFields "longdescription"}}checked{{end}}/> - <label class="form-check-label ml-1" for="overview-metadata-fields-longdescription">Longdescription</label> - </div> - </div> - <div class="col-4"> - <div class="form-check form-check-inline"> - <input type="checkbox" name="overview-metadata-fields" id="overview-metadata-fields-useflags" value="useflags" {{if Contains .UserPreferences.Packages.Overview.MetadataFields "useflags"}}checked{{end}}/> - <label class="form-check-label ml-1" for="overview-metadata-fields-useflags">USE flags</label> - </div> - </div> - <div class="col-4"> - <div class="form-check form-check-inline"> - <input type="checkbox" name="overview-metadata-fields" id="overview-metadata-fields-license" value="license" {{if Contains .UserPreferences.Packages.Overview.MetadataFields "license"}}checked{{end}}/> - <label class="form-check-label ml-1" for="overview-metadata-fields-license">License</label> - </div> - </div> - <div class="col-4"> - <div class="form-check form-check-inline"> - <input type="checkbox" name="overview-metadata-fields" id="overview-metadata-fields-maintainers" value="maintainers" {{if Contains .UserPreferences.Packages.Overview.MetadataFields "maintainers"}}checked{{end}}/> - <label class="form-check-label ml-1" for="overview-metadata-fields-maintainers">Maintainers</label> - </div> - </div> - </div> - </div> - </div> - - <h4 class="mt-4 mb-1">Changelog</h4> - <div class="card"> - <div class="card-body"> - <div class="row"> - <div class="col-6"> - Layout <select class="form-control form-control-sm ml-1" style="max-width: 100px;display: inline;" name="overview-changelog-type" id="overview-changelog-type" disabled> - <option value="compact">default</option> - </select> - </div> - <div class="col-6"> - Size <input type="number" name="overview-changelog-size" class="form-control form-control-sm ml-1" style="width:150px;display: inline;" value="{{.UserPreferences.Packages.Overview.ChangelogLength }}" /> - </div> - </div> - </div> - </div> - - - <h3 class="mt-5" id="dependencies">Dependencies</h3><hr class="mt-1"/> - <div class="card"> - <div class="card-body"> - Default Page <select class="form-control form-control-sm ml-1" style="max-width: 200px;display: inline;" name="dependencies-default-page" id="dependencies-default-page"> - <option value="dependencies" {{if eq .UserPreferences.Packages.Dependencies.Default "dependencies"}}selected{{end}}>dependencies</option> - <option value="reverse-dependencies" {{if eq .UserPreferences.Packages.Dependencies.Default "reverse-dependencies"}}selected{{end}}>reverse-dependencies</option> - </select> - </div> - </div> - - - <h3 class="mt-5" id="pull-requests">Pull requests</h3><hr class="mt-1"/> - <div class="card"> - <div class="card-body"> - Layout <select class="form-control form-control-sm ml-1" style="max-width: 200px;display: inline;" name="pullrequests-layout" id="pullrequests-layout" disabled> - <option value="default" {{if eq .UserPreferences.Packages.PullRequests.Layout "default"}}selected{{end}}>default</option> - </select> - </div> - </div> - - - <h3 class="mt-5" id="bugs">Bugs</h3><hr class="mt-1"/> - <div class="card"> - <div class="card-body"> - Layout <select class="form-control form-control-sm ml-1" style="max-width: 200px;display: inline;" name="bugs-layout" id="bugs-layout" disabled> - <option value="default" {{if eq .UserPreferences.Packages.PullRequests.Layout "default"}}selected{{end}}>default</option> - </select> - </div> - </div> - - - <h3 class="mt-5" id="security">Security</h3><hr class="mt-1"/> - <div class="card"> - <div class="card-body"> - <div class="row"> - <div class="col-6"> - Layout <select class="form-control form-control-sm ml-1" style="max-width: 100px;display: inline;" name="security-layout" id="security-layout" disabled> - <option value="default">default</option> - </select> - </div> - <div class="col-6"> - <div class="form-check form-check-inline pt-2"> - <input type="checkbox" name="security-show-glsas" id="security-show-glsas" class="disabled" value="true" {{if .UserPreferences.Packages.Security.ShowGLSAs}}checked{{end}} disabled/> - <label class="form-check-label ml-1" style="color:grey;">Show GLSAs</label> - </div> - </div> - </div> - </div> - </div> - - - <h3 class="mt-5" id="changelog">Changelog</h3><hr class="mt-1"/> - <div class="card"> - <div class="card-body"> - <div class="row"> - <div class="col-6"> - Layout <select class="form-control form-control-sm ml-1" style="max-width: 100px;display: inline;" name="changelog-type" id="changelog-type" disabled> - <option value="compact">default</option> - </select> - </div> - <div class="col-6"> - Size <input type="number" name="changelog-size" class="form-control form-control-sm" style="display: inline;width: 150px;" value="{{.UserPreferences.Packages.Changelog.Size }}" /> - </div> - </div> - </div> - </div> - - <h3 class="mt-5" id="qa-report">QA Report</h3><hr class="mt-1"/> - <div class="row"> - <div class="col-4"> - {{range (CreateSlice 190)}} - <ul class="list-group mb-2"> - <li class="list-group-item"> - <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;"> - <input type="checkbox" id="qareport-classes-{{.}}" name="qareport-classes" value="{{.}}" {{if not (ContainsInt $.UserPreferences.Packages.QAReport.ExcludedWarningClasses .) }}checked{{end}} /> - <label class="form-check-label ml-1" for="qareport-classes-{{.}}" style="overflow:hidden;text-overflow: ellipsis;" title="{{GetPkgcheckClass .}}">{{GetPkgcheckClass .}}</label> - </div> - </li> - </ul> - {{if eq . 63}} - </div><div class="col-4"> - {{else if eq . 127}} - </div><div class="col-4"> - {{end}} - {{end}} - </div> - </div> - - - <h3 class="mt-5" id="tabs">Visible Tabs</h3><hr class="mt-1"/> - <div class="card"> - <div class="card-body"> - <div style="columns:3;"> - - <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;"> - <input type="checkbox" name="visible-tabs" id="visible-tabs-overview" value="Overview" {{if Contains .UserPreferences.Packages.Tabs.Visible "Overview"}}checked{{end}}/> - <label class="form-check-label ml-1" for="visible-tabs-overview" style="overflow:hidden;text-overflow: ellipsis;" title="Overview">Overview</label> - </div> - - <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;"> - <input type="checkbox" name="visible-tabs" id="visible-tabs-dependencies" value="Dependencies" {{if Contains .UserPreferences.Packages.Tabs.Visible "Dependencies"}}checked{{end}}/> - <label class="form-check-label ml-1" for="visible-tabs-dependencies" style="overflow:hidden;text-overflow: ellipsis;" title="Dependencies">Dependencies</label> - </div> - - <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;"> - <input type="checkbox" name="visible-tabs" id="visible-tabs-qa-report" value="QA report" {{if Contains .UserPreferences.Packages.Tabs.Visible "QA report"}}checked{{end}}/> - <label class="form-check-label ml-1" for="visible-tabs-qa-report" style="overflow:hidden;text-overflow: ellipsis;" title="QA report">QA report</label> - </div> - - <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;"> - <input type="checkbox" name="visible-tabs" id="visible-tabs-pull-requests" value="Pull requests" {{if Contains .UserPreferences.Packages.Tabs.Visible "Pull requests"}}checked{{end}}/> - <label class="form-check-label ml-1" for="visible-tabs-pull-requests" style="overflow:hidden;text-overflow: ellipsis;" title="Pull Requests">Pull Requests</label> - </div> - - <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;"> - <input type="checkbox" name="visible-tabs" id="visible-tabs-bugs" value="Bugs" {{if Contains .UserPreferences.Packages.Tabs.Visible "Bugs"}}checked{{end}}/> - <label class="form-check-label ml-1" for="visible-tabs-bugs" style="overflow:hidden;text-overflow: ellipsis;" title="Bugs">Bugs</label> - </div> - - <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;"> - <input type="checkbox" name="visible-tabs" id="visible-tabs-security" value="Security" {{if Contains .UserPreferences.Packages.Tabs.Visible "Security"}}checked{{end}}/> - <label class="form-check-label ml-1" for="visible-tabs-security" style="overflow:hidden;text-overflow: ellipsis;" title="Security">Security</label> - </div> - - <div class="form-check form-check-inline" style="text-overflow: ellipsis;overflow: hidden; width: 100%;"> - <input type="checkbox" name="visible-tabs" id="visible-tabs-changelog" value="Changelog" {{if Contains .UserPreferences.Packages.Tabs.Visible "Changelog"}}checked{{end}}/> - <label class="form-check-label ml-1" for="visible-tabs-changelog" style="overflow:hidden;text-overflow: ellipsis;" title="Changelog">Changelog</label> - </div> - - </div> - </div> - </div> - <div class="row"> - <div class="col-12 mt-4"> - <button type="submit" class="float-right btn btn-sm btn-primary">Save</button> - <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/packages/reset">Reset to Defaults</a> - </div> - </div> - - </form> - </div> - - </div> - - <div id="myModal" class="modal"> - <span class="close">×</span> - <img class="modal-content" id="img01"> - <div id="caption"></div> - </div> - -{{end}} diff --git a/web/templates/user/preferences/useflags.tmpl b/web/templates/user/preferences/useflags.tmpl deleted file mode 100644 index a59241e..0000000 --- a/web/templates/user/preferences/useflags.tmpl +++ /dev/null @@ -1,46 +0,0 @@ -{{define "useflags"}} - <form method="post" action="/user/preferences/useflags/edit"> - <div class="row"> - - <div class="col-5 offset-1 mt-1"> - <div class="card" style="background: transparent;"> - <div class="card-body"> - <img id="img1" alt="Popular USE flags (default)" src="/assets/pgo6.png" style="width: 100%;cursor: pointer;" /> - </div> - </div> - <div class="text-center mt-2"> - <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;"> - <input type="radio" id="BubbleUseflagDefaultPage" name="useflag-default-page" value="bubble" {{if eq .UserPreferences.Useflags.Layout "bubble"}}checked{{end}}> - <label class="form-check-label ml-1" for="BubbleUseflagDefaultPage" style="overflow:hidden;text-overflow: ellipsis;" title="Popular USE flags (default)">Popular USE flags <i>(default)</i></label> - </div> - </div> - </div> - - <div class="col-5 mt-1"> - <div class="card" style="background: transparent;"> - <div class="card-body"> - <img id="img2" alt="USE flags search" src="/assets/pgo5.png" style="width: 100%;cursor: pointer;" /> - </div> - </div> - <div class="text-center mt-2"> - <div class="form-check text-center form-check-inline" style="text-overflow: ellipsis;overflow: hidden;"> - <input type="radio" id="SearchUseflagDefaultPage" name="useflag-default-page" value="search" {{if eq .UserPreferences.Useflags.Layout "search"}}checked{{end}}> - <label class="form-check-label ml-1" for="SearchUseflagDefaultPage" style="overflow:hidden;text-overflow: ellipsis;" title="USE flags search">USE flags search</label> - </div> - </div> - </div> - - <div class="col-10 offset-1 mt-4"> - <button type="submit" class="float-right btn btn-sm btn-primary">Save</button> - <a class="float-right btn btn-sm btn-outline-danger mr-2" href="/user/preferences/useflags/reset">Reset to Defaults</a> - </div> - - </div> - </form> - - <div id="myModal" class="modal"> - <span class="close">×</span> - <img class="modal-content" id="img01"> - <div id="caption"></div> - </div> -{{end}} diff --git a/web/templates/user/userheader.tmpl b/web/templates/user/userheader.tmpl deleted file mode 100644 index 05fb535..0000000 --- a/web/templates/user/userheader.tmpl +++ /dev/null @@ -1,34 +0,0 @@ -{{define "userheader"}} - - <div class="kk-header-container"> - <div class="container"> - <div class="row"> - <div class="col-12"> - - <div class="row mt-3 pt-2"> - <div class="col-md-5"> - <h1 class="stick-top kk-package-title" id="package-title"> - <div> - <div class="kk-package-name" style="margin-left: 0px!important;"><span class="fa fa-fw fa-cog"></span><span class="ml-2">Preferences</span></div> - </div> - </h1> - </div> - <div class="col-md-7"> - <!-- You can customize the page contents to your needs here --> - </div> - - <div class="col-md-12 pt-4 mt-1"> - <nav class="nav kk-package-nav"> - <a class="nav-link {{if eq .PageName "general"}}active{{end}}" href="/user/preferences/general"><i class="fa fa-globe mr-1" aria-hidden="true"></i>General</a> - <a class="nav-link {{if eq .PageName "packages"}}active{{end}}" href="/user/preferences/packages"><i class="fa fa-cube mr-1" aria-hidden="true"></i>Packages</a> - <a class="nav-link {{if eq .PageName "maintainers"}}active{{end}}" href="/user/preferences/maintainers"><i class="fa fa-users mr-1" aria-hidden="true"></i>Maintainers</a> - <a class="nav-link {{if eq .PageName "useflags"}}active{{end}}" href="/user/preferences/useflags"><i class="fa fa-sliders mr-1" aria-hidden="true"></i>USE flags</a> - <a class="nav-link {{if eq .PageName "arches"}}active{{end}}" href="/user/preferences/arches"><i class="fa fa-server mr-1" aria-hidden="true"></i>Architectures</a> - </nav> - </div> - </div> - </div> - </div> - </div> - </div> -{{end}} diff --git a/webpack.config.js b/webpack.config.js index 84deb53..a6dd3e3 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,3 +1,4 @@ +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const webpack = require('webpack'); const path = require('path'); @@ -5,33 +6,25 @@ module.exports = { entry: { stylesheets: './web/packs/stylesheets.js', application: './web/packs/application.js', - graphiql: './web/packs/graphiql.js', - index: './web/packs/index.js', - packages: './web/packs/packages.js', - useflags: './web/packs/useflags.js', - userpref: './web/packs/userpref.js', + graphiql: './web/packs/graphiql.js', + index: './web/packs/index.js', + useflags: './web/packs/useflags.js', + userpref: './web/packs/userpref.js', }, + mode: 'production', output: { path: path.resolve(__dirname, 'assets'), filename: '[name].js', + assetModuleFilename: '[name].[ext]' }, - plugins: [ - require('postcss-import') - ], module: { rules: [ { test: /\.s[ac]ss$/i, use: [ - // Creates `style` nodes from JS strings - 'style-loader', - // Translates CSS into CommonJS - { - loader: 'css-loader', - },{ - loader: 'resolve-url-loader', - }, - // Compiles Sass to CSS + MiniCssExtractPlugin.loader, + 'css-loader', + 'resolve-url-loader', { loader: 'sass-loader', options: { @@ -42,15 +35,7 @@ module.exports = { }, { test: /\.(woff(2)?|ttf|eot|svg|png)(\?v=\d+\.\d+\.\d+)?$/, - use: [ - { - loader: 'file-loader', - options: { - name: '[name].[ext]', - publicPath: '/assets' - } - } - ] + type: 'asset/resource', } ], }, @@ -67,5 +52,8 @@ module.exports = { 'window.Tether': 'tether', Modal: 'exports-loader?Modal!bootstrap/js/dist/modal', }), + new MiniCssExtractPlugin({ + filename: '[name].css', + }), ], }; |