├── .editorconfig
├── .github
├── dependabot.yml
└── workflows
│ ├── front-lint.yml
│ └── php-lint.yml
├── .gitignore
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── UPGRADING.md
├── composer.json
├── config
└── nova-cards.php
├── dist
├── .vite
│ └── manifest.json
├── css
│ └── card.css
└── js
│ └── entry.js
├── duster.json
├── package.json
├── pint.json
├── postcss.config.cjs
├── resources
├── css
│ └── card.css
└── js
│ ├── cards
│ ├── Calendar.vue
│ ├── Countdown.vue
│ ├── Embed.vue
│ ├── Environment.vue
│ ├── Greeter.vue
│ ├── Html.vue
│ ├── Linkable.vue
│ ├── Percentage.vue
│ ├── ScheduledJobs.vue
│ ├── Ssl.vue
│ ├── SystemResources.vue
│ ├── Versions.vue
│ ├── Weather.vue
│ └── WorldClock.vue
│ ├── components
│ ├── Card.vue
│ ├── ToolbarButton.vue
│ └── WorldClockTimer.vue
│ ├── composables
│ └── useCurrentTime.js
│ └── entry.js
├── routes
└── api.php
├── screenshots
├── cards-2-dark.png
├── cards-2.png
├── cards-dark.png
├── cards-mobile.png
└── cards.png
├── src
├── Cards
│ ├── CalendarCard.php
│ ├── CountdownCard.php
│ ├── EmbedCard.php
│ ├── EnvironmentCard.php
│ ├── GreeterCard.php
│ ├── HtmlCard.php
│ ├── LinkableCard.php
│ ├── PercentageCard.php
│ ├── ScheduledJobsCard.php
│ ├── SslCard.php
│ ├── SystemResourcesCard.php
│ ├── VersionsCard.php
│ ├── WeatherCard.php
│ └── WorldClockCard.php
├── Http
│ └── Controllers
│ │ ├── ScheduledJobsController.php
│ │ ├── SslController.php
│ │ ├── SystemResourcesController.php
│ │ ├── VersionsController.php
│ │ ├── WeatherController.php
│ │ └── WorldClockController.php
├── LaravelMarkdownConverter.php
├── MarkdownConverter.php
├── NovaCardsServiceProvider.php
└── Traits
│ └── PollingTrait.php
├── tailwind.config.js
├── vite.config.js
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | insert_final_newline = true
7 | indent_style = space
8 | indent_size = 4
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
14 | [*.{yml,yaml}]
15 | indent_size = 2
16 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "composer"
4 | directory: "/" # Location of package manifests
5 | schedule:
6 | interval: "daily"
7 |
8 | - package-ecosystem: "npm"
9 | directory: "/"
10 | schedule:
11 | interval: "daily"
12 | # Always increase the version requirement
13 | # to match the new version.
14 | versioning-strategy: increase
15 |
--------------------------------------------------------------------------------
/.github/workflows/front-lint.yml:
--------------------------------------------------------------------------------
1 | # .github/workflows/duster.yml
2 | name: Front lint
3 |
4 | on:
5 | push:
6 | branches: main
7 | pull_request:
8 |
9 | env:
10 | NODE_VERSION: 20.10.0
11 |
12 | jobs:
13 | application-test:
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - uses: actions/checkout@v3
18 |
19 | - name: Setup Node
20 | uses: actions/setup-node@v3
21 | with:
22 | node-version: ${{env.NODE_VERSION}}
23 | cache: "npm"
24 |
25 | - name: "Setup PHP"
26 | uses: "shivammathur/setup-php@v2"
27 | with:
28 | php-version: "latest"
29 |
30 | - name: "composer install"
31 | run: composer install --no-cache --ignore-platform-reqs --no-interaction --prefer-dist --optimize-autoloader --apcu-autoloader
32 |
33 |
34 | - run: npm i
35 | - run: npm run nova:install
36 | - run: npm run build
37 |
--------------------------------------------------------------------------------
/.github/workflows/php-lint.yml:
--------------------------------------------------------------------------------
1 | # .github/workflows/duster.yml
2 | name: PHP Lint
3 |
4 | on:
5 | push:
6 | branches: main
7 | pull_request:
8 |
9 | jobs:
10 | php-lint:
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - uses: actions/checkout@v3
15 |
16 | - name: "Setup PHP"
17 | uses: "shivammathur/setup-php@v2"
18 | with:
19 | php-version: "latest"
20 |
21 | - name: "composer install"
22 | run: composer install --no-cache --ignore-platform-reqs --no-interaction --prefer-dist --optimize-autoloader --apcu-autoloader
23 |
24 | - name: "duster"
25 | uses: tighten/duster-action@v2
26 | with:
27 | args: lint --using=phpstan,tlint,phpcs,pint
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # Mac OS X
4 | .DS_Store
5 | ._.*
6 | ._*
7 |
8 | # Ignore local editor
9 | .project
10 | .settings
11 | /.idea
12 | /.vscode
13 | *.swp
14 | tags
15 | nbproject/*
16 |
17 | # Windows
18 | Thumbs.db
19 |
20 | auth.json
21 | npm-debug.log
22 | yarn-error.log
23 |
24 | .env
25 | .env.backup
26 | phpunit.xml
27 | .phpunit.result.cache
28 | docker-compose.override.yml
29 | Homestead.json
30 | Homestead.yaml
31 |
32 | config/version.yml
33 |
34 | package-lock.json
35 | composer.phar
36 | composer.lock
37 | yarn.lock
38 |
39 | _ide_helper.php
40 | _ide_helper_models.php
41 | .phpstorm.meta.php
42 | lighthouse-audit*
43 | .nova
44 |
45 | /node_modules
46 | /vendor
47 | /packages
48 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Release Notes
2 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Contributions are **welcome** and will be fully **credited**.
4 |
5 | Please read and understand the contribution guide before creating an issue or pull request.
6 |
7 | ## Etiquette
8 |
9 | This project is open source, and as such, the maintainers give their free time to build and maintain the source code
10 | held within. They make the code freely available in the hope that it will be of use to other developers. It would be
11 | extremely unfair for them to suffer abuse or anger for their hard work.
12 |
13 | Please be considerate towards maintainers when raising issues or presenting pull requests. Let's show the
14 | world that developers are civilized and selfless people.
15 |
16 | It's the duty of the maintainer to ensure that all submissions to the project are of sufficient
17 | quality to benefit the project. Many developers have different skillsets, strengths, and weaknesses. Respect the maintainer's decision, and do not be upset or abusive if your submission is not used.
18 |
19 | ## Viability
20 |
21 | When requesting or submitting new features, first consider whether it might be useful to others. Open
22 | source projects are used by many developers, who may have entirely different needs to your own. Think about
23 | whether or not your feature is likely to be used by other users of the project.
24 |
25 | ## Procedure
26 |
27 | Before filing an issue:
28 |
29 | - Attempt to replicate the problem, to ensure that it wasn't a coincidental incident.
30 | - Check to make sure your feature suggestion isn't already present within the project.
31 | - Check the pull requests tab to ensure that the bug doesn't have a fix in progress.
32 | - Check the pull requests tab to ensure that the feature isn't already in progress.
33 |
34 | Before submitting a pull request:
35 |
36 | - Check the codebase to ensure that your feature doesn't already exist.
37 | - Check the pull requests to ensure that another person hasn't already submitted the feature or fix.
38 |
39 | ## Requirements
40 |
41 | If the project maintainer has any additional requirements, you will find them listed here.
42 |
43 | - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](http://pear.php.net/package/PHP_CodeSniffer).
44 |
45 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests.
46 |
47 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date.
48 |
49 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option.
50 |
51 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
52 |
53 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting.
54 |
55 | **Happy coding**!
56 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 |
3 | Copyright (c) 2022 Artem Stepanenko
4 |
5 | > Permission is hereby granted, free of charge, to any person obtaining a copy
6 | > of this software and associated documentation files (the "Software"), to deal
7 | > in the Software without restriction, including without limitation the rights
8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | > copies of the Software, and to permit persons to whom the Software is
10 | > furnished to do so, subject to the following conditions:
11 | >
12 | > The above copyright notice and this permission notice shall be included in
13 | > all copies or substantial portions of the Software.
14 | >
15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | > THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Cards for Laravel Nova
3 |
4 | [](https://packagist.org/packages/stepanenko3/nova-cards)
5 | [](https://packagist.org/packages/stepanenko3/nova-cards)
6 | [](https://packagist.org/packages/stepanenko3/nova-cards)
7 |
8 | 
9 | 
10 |
11 | ## List of Cards
12 |
13 | - BlockchainExchangeCard (deleted)
14 | - CacheCard (Use stepanenkoe/nova-command-runner for cache manipulations)
15 | - CountdownCard
16 | - EmbedCard
17 | - EnvironmentCard
18 | - HtmlCard
19 | - LinkableCard
20 | - PercentageCard
21 | - ScheduledJobsCard
22 | - SslCard
23 | - SystemResourcesCard
24 | - VersionsCard
25 | - WorldClockCard
26 | - WeatherCard
27 | - CalendarCard
28 | - NovaReleaseCard (Use stepanenko3/nova-health for outdated packages)
29 | - GreetingCard
30 |
31 | ## Requirements
32 |
33 | - `php: >=8.0`
34 | - `laravel/nova: ^4.0`
35 |
36 | ## Installation
37 |
38 | ```bash
39 | # Install the package
40 | composer require stepanenko3/nova-cards
41 | ```
42 |
43 | Register the cards with Nova in the `cards()` method of the your Dashboards class:
44 |
45 | ```php
46 | // in app/Nova/Dashborads/Cards.php
47 |
48 | use Stepanenko3\NovaCards\Cards\GreetingCard;
49 | use Stepanenko3\NovaCards\Cards\CountdownCard;
50 | use Stepanenko3\NovaCards\Cards\EmbedCard;
51 | use Stepanenko3\NovaCards\Cards\EnvironmentCard;
52 | use Stepanenko3\NovaCards\Cards\HtmlCard;
53 | use Stepanenko3\NovaCards\Cards\LinkableCard;
54 | use Stepanenko3\NovaCards\Cards\PercentageCard;
55 | use Stepanenko3\NovaCards\Cards\ScheduledJobsCard;
56 | use Stepanenko3\NovaCards\Cards\SslCard;
57 | use Stepanenko3\NovaCards\Cards\SystemResourcesCard;
58 | use Stepanenko3\NovaCards\Cards\VersionsCard;
59 | use Stepanenko3\NovaCards\Cards\WorldClockCard;
60 | use Stepanenko3\NovaCards\Cards\WeatherCard;
61 | use Stepanenko3\NovaCards\Cards\CalendarCard;
62 |
63 | public function cards()
64 | {
65 | $user = auth()->user();
66 |
67 | return [
68 | GreeterCard::make()
69 | ->user(
70 | name: $user->name,
71 | title: 'Admin',
72 | )
73 | ->message(
74 | text: 'Welcome back,',
75 | )
76 | ->button(
77 | name: 'Profile',
78 | target: '/nova/resources/users/' . $user->id,
79 | )
80 | ->button(
81 | name: 'Users',
82 | target: '/nova/resources/users',
83 | )
84 | ->avatar(
85 | url: $user->avatar
86 | ? storage_url($user->avatar, 'public')
87 | : 'https://ui-avatars.com/api/?size=300&color=7F9CF5&background=EBF4FF&name=' . $user->name
88 | ),
89 |
90 | (new WeatherCard)
91 | ->pollingTime(60000) // Optional
92 | ->startPolling(), // Optional. Auto start polling
93 |
94 | (new CalendarCard),
95 |
96 | (new LinkableCard)
97 | ->title('Docs') // Required
98 | ->subtitle('subtitle') // Optional
99 | ->url('/') // Required
100 | ->target('_blank'), // Default: _self
101 |
102 | (new SystemResourcesCard),
103 |
104 | (new VersionsCard),
105 |
106 | (new ScheduledJobsCard)
107 | ->startPolling() // Optional. Auto start polling
108 | ->pollingTime(1000)
109 | ->width('1/2'),
110 |
111 | (new EnvironmentCard),
112 |
113 | (new SslCard)
114 | ->domain('test.com'), // Required
115 |
116 | (new SslCard)
117 | ->domain('laravel.com'), // Required
118 |
119 | (new HtmlCard)
120 | ->width('1/3')
121 | ->html('
Hello World!
'), // Required
122 |
123 | (new HtmlCard)
124 | ->width('1/3')
125 | ->markdown('# Hello World!'), // Required
126 |
127 | (new HtmlCard)
128 | ->width('1/3')
129 | ->view('cards.hello', ['name' => 'World']), // Required
130 |
131 | (new PercentageCard)
132 | ->name('Demo percents') // Optional
133 | ->label('$') // Optional
134 | ->count(33) // Required
135 | ->total(1000) // Required
136 | ->percentagePrecision(2), // Default: 2
137 |
138 | (new CountdownCard)
139 | ->to(now()->addDays(30)) // Required
140 | ->title('30 Days Later') // Optional
141 | ->label('30 Days Later'), // Optional
142 |
143 | (new WorldClockCard())
144 | ->timezones([ // Required
145 | 'Europe/Kiev',
146 | 'Asia/Tehran',
147 | 'America/new_york',
148 | 'America/los_angeles',
149 | ])
150 | ->title(__('World Clock')), // Optional
151 |
152 | // A most simple embed
153 | (new EmbedCard)
154 | ->url('https://www.youtube.com/embed/WhWc3b3KhnY'), // Required
155 |
156 | // A more complex embed of raw HTML
157 | (new EmbedCard)
158 | ->withoutPadding() // Optional remove padding in card
159 | ->url('https://www.youtube.com/embed/WhWc3b3KhnY'), // Required
160 | ];
161 | }
162 | ```
163 |
164 | ## Usage
165 |
166 | Open your Dashboard in your Nova app to see the cards.
167 |
168 | ## Screenshots
169 |
170 | 
171 | 
172 | 
173 |
174 | ## Credits
175 |
176 | - [Artem Stepanenko](https://github.com/stepanenko3)
177 |
178 | ## Contributing
179 |
180 | Thank you for considering contributing to this package! Please create a pull request with your contributions with detailed explanation of the changes you are proposing.
181 |
182 | ## License
183 |
184 | This package is open-sourced software licensed under the [MIT license](LICENSE.md).
185 |
--------------------------------------------------------------------------------
/UPGRADING.md:
--------------------------------------------------------------------------------
1 | # Upgrading
2 |
3 | ## To 1.0.0
4 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "stepanenko3/nova-cards",
3 | "description": "A Laravel Nova info cards.",
4 | "keywords": [
5 | "laravel",
6 | "nova",
7 | "cards"
8 | ],
9 | "license": "MIT",
10 | "require": {
11 | "php": ">=8.0",
12 | "erusev/parsedown": "^1.7",
13 | "laravel/framework": "^10.0|^11.0|^12.0",
14 | "laravel/nova": "^5.0",
15 | "spatie/ssl-certificate": "^2.0",
16 | "stepanenko3/laravel-system-resources": "^1.1.1",
17 | "stepanenko3/laravel-helpers": "^1.3.2"
18 | },
19 | "autoload": {
20 | "psr-4": {
21 | "Stepanenko3\\NovaCards\\": "src/"
22 | }
23 | },
24 | "extra": {
25 | "laravel": {
26 | "providers": [
27 | "Stepanenko3\\NovaCards\\NovaCardsServiceProvider"
28 | ]
29 | }
30 | },
31 | "config": {
32 | "sort-packages": true
33 | },
34 | "minimum-stability": "dev",
35 | "prefer-stable": true,
36 | "repositories": [
37 | {
38 | "type": "composer",
39 | "url": "https://laravelsatis.com"
40 | }
41 | ],
42 | "require-dev": {
43 | "phpstan/phpstan": "^2.0",
44 | "tightenco/duster": "^3.0"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/config/nova-cards.php:
--------------------------------------------------------------------------------
1 | env('OPENWAETHER_API_KEY', env('OPEN_WEATHER_TOKEN', '')),
5 | ];
6 |
--------------------------------------------------------------------------------
/dist/.vite/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "resources/js/entry.js": {
3 | "file": "js/entry.js",
4 | "name": "entry",
5 | "src": "resources/js/entry.js",
6 | "isEntry": true
7 | },
8 | "style.css": {
9 | "file": "css/card.css",
10 | "src": "style.css"
11 | }
12 | }
--------------------------------------------------------------------------------
/dist/css/card.css:
--------------------------------------------------------------------------------
1 | .nova-cards :is(.sr-only){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.nova-cards :is(.invisible){visibility:hidden}.nova-cards :is(.absolute){position:absolute}.nova-cards :is(.relative){position:relative}.nova-cards :is(.isolate){isolation:isolate}.nova-cards :is(.mx-auto){margin-left:auto;margin-right:auto}.nova-cards :is(.mb-1){margin-bottom:.25rem}.nova-cards :is(.mb-2){margin-bottom:.5rem}.nova-cards :is(.mb-4){margin-bottom:1rem}.nova-cards :is(.mr-1){margin-right:.25rem}.nova-cards :is(.mr-1\.5){margin-right:.375rem}.nova-cards :is(.mr-2){margin-right:.5rem}.nova-cards :is(.mr-6){margin-right:1.5rem}.nova-cards :is(.mt-1){margin-top:.25rem}.nova-cards :is(.mt-3){margin-top:.75rem}.nova-cards :is(.mt-4){margin-top:1rem}.nova-cards :is(.mt-6){margin-top:1.5rem}.nova-cards :is(.flex){display:flex}.nova-cards :is(.inline-flex){display:inline-flex}.nova-cards :is(.table){display:table}.nova-cards :is(.grid){display:grid}.nova-cards :is(.h-20){height:5rem}.nova-cards :is(.h-5){height:1.25rem}.nova-cards :is(.h-8){height:2rem}.nova-cards :is(.h-auto){height:auto}.nova-cards :is(.h-full){height:100%}.nova-cards :is(.min-h-40){min-height:10rem}.nova-cards :is(.w-20){width:5rem}.nova-cards :is(.w-5){width:1.25rem}.nova-cards :is(.w-8){width:2rem}.nova-cards :is(.w-full){width:100%}.nova-cards :is(.flex-shrink-0){flex-shrink:0}.nova-cards :is(.flex-grow){flex-grow:1}.nova-cards :is(.transform){transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.nova-cards :is(.grid-cols-1){grid-template-columns:repeat(1,minmax(0,1fr))}.nova-cards :is(.grid-cols-3){grid-template-columns:repeat(3,minmax(0,1fr))}.nova-cards :is(.grid-cols-4){grid-template-columns:repeat(4,minmax(0,1fr))}.nova-cards :is(.flex-row){flex-direction:row}.nova-cards :is(.flex-col){flex-direction:column}.nova-cards :is(.flex-wrap){flex-wrap:wrap}.nova-cards :is(.items-center){align-items:center}.nova-cards :is(.justify-center){justify-content:center}.nova-cards :is(.justify-between){justify-content:space-between}.nova-cards :is(.gap-6){gap:1.5rem}.nova-cards :is(.space-x-4>:not([hidden])~:not([hidden])){--tw-space-x-reverse: 0;margin-right:calc(1rem * var(--tw-space-x-reverse));margin-left:calc(1rem * calc(1 - var(--tw-space-x-reverse)))}.nova-cards :is(.space-y-4>:not([hidden])~:not([hidden])){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.nova-cards :is(.divide-x>:not([hidden])~:not([hidden])){--tw-divide-x-reverse: 0;border-right-width:calc(1px * var(--tw-divide-x-reverse));border-left-width:calc(1px * calc(1 - var(--tw-divide-x-reverse)))}.nova-cards :is(.divide-y>:not([hidden])~:not([hidden])){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.nova-cards :is(.divide-y-0>:not([hidden])~:not([hidden])){--tw-divide-y-reverse: 0;border-top-width:calc(0px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(0px * var(--tw-divide-y-reverse))}.nova-cards :is(.divide-gray-200>:not([hidden])~:not([hidden])){--tw-divide-opacity: 1;border-color:rgb(229 231 235 / var(--tw-divide-opacity))}.nova-cards :is(.overflow-hidden){overflow:hidden}.nova-cards :is(.rounded-full){border-radius:9999px}.nova-cards :is(.rounded-lg){border-radius:.5rem}.nova-cards :is(.border-t){border-top-width:1px}.nova-cards :is(.border-gray-200){--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity))}.nova-cards :is(.bg-gray-50){--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity))}.nova-cards :is(.bg-white){--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity))}.nova-cards :is(.\!p-0){padding:0!important}.nova-cards :is(.p-2){padding:.5rem}.nova-cards :is(.p-3){padding:.75rem}.nova-cards :is(.p-4){padding:1rem}.nova-cards :is(.px-2){padding-left:.5rem;padding-right:.5rem}.nova-cards :is(.px-6){padding-left:1.5rem;padding-right:1.5rem}.nova-cards :is(.py-2){padding-top:.5rem;padding-bottom:.5rem}.nova-cards :is(.py-3){padding-top:.75rem;padding-bottom:.75rem}.nova-cards :is(.py-4){padding-top:1rem;padding-bottom:1rem}.nova-cards :is(.pr-2){padding-right:.5rem}.nova-cards :is(.text-left){text-align:left}.nova-cards :is(.text-center){text-align:center}.nova-cards :is(.align-baseline){vertical-align:baseline}.nova-cards :is(.text-2xl){font-size:1.5rem;line-height:2rem}.nova-cards :is(.text-3xl){font-size:1.875rem;line-height:2.25rem}.nova-cards :is(.text-4xl){font-size:2.25rem;line-height:2.5rem}.nova-cards :is(.text-lg){font-size:1.125rem;line-height:1.75rem}.nova-cards :is(.text-sm){font-size:.875rem;line-height:1.25rem}.nova-cards :is(.text-xl){font-size:1.25rem;line-height:1.75rem}.nova-cards :is(.text-xs){font-size:.75rem;line-height:1rem}.nova-cards :is(.font-bold){font-weight:700}.nova-cards :is(.font-medium){font-weight:500}.nova-cards :is(.font-semibold){font-weight:600}.nova-cards :is(.uppercase){text-transform:uppercase}.nova-cards :is(.capitalize){text-transform:capitalize}.nova-cards :is(.italic){font-style:italic}.nova-cards :is(.tracking-wide){letter-spacing:.025em}.nova-cards :is(.text-gray-500){--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity))}.nova-cards :is(.text-gray-600){--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity))}.nova-cards :is(.text-gray-900){--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity))}.nova-cards :is(.text-green-400){--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity))}.nova-cards :is(.text-green-500){--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity))}.nova-cards :is(.text-red-500){--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity))}.nova-cards :is(.text-white){--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.nova-cards :is(.text-yellow-500){--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity))}.nova-cards :is(.shadow){--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.nova-cards :is(.hover\:opacity-50:hover){opacity:.5}.nova-cards :is(.focus\:outline-none:focus){outline:2px solid transparent;outline-offset:2px}.nova-cards :is(.focus\:ring:focus){--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.nova-cards :is(.dark\:divide-gray-700:is(.dark *)>:not([hidden])~:not([hidden])){--tw-divide-opacity: 1;border-color:rgb(55 65 81 / var(--tw-divide-opacity))}.nova-cards :is(.dark\:border-gray-700:is(.dark *)){--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity))}.nova-cards :is(.dark\:bg-gray-800:is(.dark *)){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity))}.nova-cards :is(.dark\:bg-gray-800\/25:is(.dark *)){background-color:#1f293740}.nova-cards :is(.dark\:text-gray-300:is(.dark *)){--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity))}.nova-cards :is(.dark\:text-gray-400:is(.dark *)){--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity))}.nova-cards :is(.dark\:text-green-500:is(.dark *)){--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity))}@media (min-width: 768px){.nova-cards :is(.md\:col-span-4){grid-column:span 4 / span 4}.nova-cards :is(.md\:ml-2){margin-left:.5rem}}
2 |
--------------------------------------------------------------------------------
/dist/js/entry.js:
--------------------------------------------------------------------------------
1 | (function(e,m){typeof exports=="object"&&typeof module<"u"?m(require("vue"),require("LaravelNova")):typeof define=="function"&&define.amd?define(["vue","LaravelNova"],m):(e=typeof globalThis<"u"?globalThis:e||self,m(e.Vue,e.LaravelNova))})(this,function(e,m){"use strict";const y={class:"nova-cards relative overflow-hidden bg-white dark:bg-gray-800 rounded-lg shadow isolate px-6 py-4 md:col-span-4 min-h-40 h-full"},k={key:0,class:"flex items-center justify-between mb-2 font-bold"},C={key:0,class:"md:ml-2 inline-flex items-center shadow rounded-lg bg-white dark:bg-gray-800 px-2 h-8"},N={class:"card-overflow"},E=e.defineComponent({__name:"Card",props:{heading:{default:""},headingClass:{default:""},showRefresh:{type:Boolean,default:!1},showPolling:{type:Boolean,default:!1},loading:{type:Boolean,default:!1},polling:{type:Boolean,default:!1},pollingInterval:{default:3e3}},emits:["refresh","update:polling"],setup(s,{emit:a}){const o=s,{__:t}=m.useLocalization(),l=e.ref(0),n=a;function r(){i(),o.polling&&c()}function c(){l.value=setInterval(async()=>{await n("refresh")},o.pollingInterval)}function i(){l.value&&(clearInterval(l.value),l.value=0)}e.watch(()=>o.polling,d=>{d?r():i()},{immediate:!0});async function p(){await n("refresh"),r()}return e.onMounted(async()=>{(o.showPolling||o.polling)&&await n("refresh"),o.polling&&c()}),e.onUnmounted(()=>{i()}),(d,_)=>{const h=e.resolveComponent("NovaCardsToolbarButton"),f=e.resolveDirective("tooltip");return e.openBlock(),e.createElementBlock("div",y,[d.heading?(e.openBlock(),e.createElementBlock("div",k,[e.createElementVNode("span",{class:e.normalizeClass([d.headingClass,"word-wrap: break-word"])},e.toDisplayString(d.heading),3),d.showRefresh||d.showPolling?(e.openBlock(),e.createElementBlock("div",C,[d.showRefresh?e.withDirectives((e.openBlock(),e.createBlock(h,{key:0,type:"refresh",loading:d.loading,onClick:e.withModifiers(p,["prevent"])},null,8,["loading"])),[[f,e.unref(t)("Refresh")]]):e.createCommentVNode("",!0),d.showPolling?e.withDirectives((e.openBlock(),e.createBlock(h,{key:1,type:"clock",onClick:_[0]||(_[0]=e.withModifiers(At=>n("update:polling",!d.polling),["prevent"])),class:e.normalizeClass([{"text-green-500":d.polling,"text-gray-500":!d.polling},"w-8 h-8"])},null,8,["class"])),[[f,e.unref(t)(d.polling?"Stop polling":"Start polling")]]):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0),e.createElementVNode("div",N,[e.renderSlot(d.$slots,"default")])])}}}),w=(s=null)=>{const a=e.ref(g(s)),o=e.ref(a.value.toISOString().match(/(\d{4}\-\d{2}\-\d{2})T(\d{2}:\d{2}:\d{2})/)),l=setInterval(()=>{a.value=g(s),o.value=a.value.toISOString().match(/(\d{4}\-\d{2}\-\d{2})T(\d{2}:\d{2}:\d{2})/)},1e3);return e.onBeforeUnmount(()=>{clearInterval(l)}),{currentTime:a,iso:o}};function g(s=null){return s?new Date(new Date().toLocaleString("en-US",{timeZone:s})):new Date}const V={class:"py-2 pr-2 font-bold"},B={class:"p-2"},$={class:"p-2"},b=e.defineComponent({__name:"WorldClockTimer",props:{timezone:{}},setup(s){const a=s,{currentTime:o,iso:t}=w(a.timezone);function l(n){const r=n.getHours();return r>6&&r<20}return(n,r)=>{const c=e.resolveComponent("Icon");return e.openBlock(),e.createElementBlock("tr",null,[e.createElementVNode("td",V,e.toDisplayString(a.timezone),1),e.createElementVNode("td",B,e.toDisplayString(e.unref(t)[2]||"-"),1),e.createElementVNode("td",$,[e.createVNode(c,{class:"text-primary-500",type:l(e.unref(o))?"sun":"moon"},null,8,["type"])])])}}}),S={key:0,class:"w-full text-left table-collapse"},D={class:"align-baseline"},x={class:"py-2 pr-2 font-bold"},T={class:"p-2"},L={class:"text-xs"},z={class:"text-xs"},I={key:0},P={class:"py-2 pr-2 font-bold"},R={class:"p-2"},u={class:"text-xs"},j={class:"text-xs"},M={class:"py-2 pr-2 font-bold"},U={class:"p-2"},F=e.createElementVNode("br",null,null,-1),q={class:"text-xs"},W={key:1},A=e.defineComponent({__name:"SystemResources",props:{card:{}},setup(s){const{__:a}=m.useLocalization(),o=e.ref(!1),t=e.ref(!0),l=e.ref();async function n(){o.value=!0,await fetch("/nova-vendor/stepanenko3/nova-cards/system-resources").then(r=>r.json()).then(r=>{l.value=r}).catch(r=>{console.error(r)}).finally(()=>{o.value=!1})}return(r,c)=>{const i=e.resolveComponent("NovaCardsCard");return e.openBlock(),e.createBlock(i,{heading:r.card.title||e.unref(a)("Server Metrics"),showPolling:r.card?.polling||!1,showRefresh:r.card?.refresh||!0,loading:o.value,polling:t.value,pollingInterval:1e4,"onUpdate:polling":c[0]||(c[0]=p=>t.value=p),onRefresh:n},{default:e.withCtx(()=>[l.value&&l.value.disk_space?(e.openBlock(),e.createElementBlock("table",S,[e.createElementVNode("tbody",D,[e.createElementVNode("tr",null,[e.createElementVNode("td",x,e.toDisplayString(e.unref(a)("Disk Space")),1),e.createElementVNode("td",T,[e.createTextVNode(e.toDisplayString(l.value.disk_space.use_percentage)+"% "+e.toDisplayString(e.unref(a)("Used"))+" ( "+e.toDisplayString(l.value.disk_space.used.memory)+" ",1),e.createElementVNode("span",L,e.toDisplayString(l.value.disk_space.used.unit.toLowerCase()),1),e.createTextVNode(" / "+e.toDisplayString(l.value.disk_space.total.memory)+" ",1),e.createElementVNode("span",z,e.toDisplayString(l.value.disk_space.total.unit.toLowerCase()),1),e.createTextVNode(" ) ")])]),l.value.memory_usage?(e.openBlock(),e.createElementBlock("tr",I,[e.createElementVNode("td",P,e.toDisplayString(e.unref(a)("Memory Usage")),1),e.createElementVNode("td",R,[e.createTextVNode(e.toDisplayString(l.value.memory_usage.use_percentage)+"% "+e.toDisplayString(e.unref(a)("Used"))+" ( "+e.toDisplayString(l.value.memory_usage.used.memory)+" ",1),e.createElementVNode("span",u,e.toDisplayString(l.value.memory_usage.used.unit.toLowerCase()),1),e.createTextVNode(" / "+e.toDisplayString(l.value.memory_usage.total.memory)+" ",1),e.createElementVNode("span",j,e.toDisplayString(l.value.memory_usage.total.unit.toLowerCase()),1),e.createTextVNode(" ) ")])])):e.createCommentVNode("",!0),e.createElementVNode("tr",null,[e.createElementVNode("td",M,e.toDisplayString(e.unref(a)("CPU Usage")),1),e.createElementVNode("td",U,[e.createTextVNode(e.toDisplayString(l.value.cpu_usage.use_percentage)+"% "+e.toDisplayString(e.unref(a)("Used"))+" ",1),F,e.createElementVNode("span",q,e.toDisplayString(l.value.cpu_usage.name),1)])])])])):(e.openBlock(),e.createElementBlock("div",W,e.toDisplayString(e.unref(a)("No Data")),1))]),_:1},8,["heading","showPolling","showRefresh","loading","polling"])}}}),H={key:0,class:"w-full text-left table-collapse"},O={class:"align-baseline"},G={class:"py-2 pr-2 font-bold"},K={class:"p-2"},Z={class:"py-2 pr-2 font-bold"},J={class:"p-2"},Y={class:"py-2 pr-2 font-bold"},Q={class:"p-2"},X={class:"py-2 pr-2 font-bold"},v={class:"p-2"},ee={class:"py-2 pr-2 font-bold"},te={class:"p-2"},oe=e.defineComponent({__name:"Versions",props:{card:{}},setup(s){const a=e.ref(!1),o=e.ref(!1),t=e.ref();async function l(){a.value=!0,await fetch("/nova-vendor/stepanenko3/nova-cards/versions").then(n=>n.json()).then(n=>{t.value=n}).catch(n=>{console.error("Error fetching weather:",n)}),a.value=!1}return(n,r)=>{const c=e.resolveComponent("NovaCardsCard");return e.openBlock(),e.createBlock(c,{heading:n.card.title||n.__("System Versions"),showPolling:n.card?.polling||!1,showRefresh:n.card?.refresh||!0,loading:a.value,polling:o.value,pollingInterval:1e4,"onUpdate:polling":r[0]||(r[0]=i=>o.value=i),onRefresh:l},{default:e.withCtx(()=>[t.value?(e.openBlock(),e.createElementBlock("table",H,[e.createElementVNode("tbody",O,[e.createElementVNode("tr",null,[e.createElementVNode("td",G,e.toDisplayString(n.__("OS")),1),e.createElementVNode("td",K,e.toDisplayString(t.value.os||"-"),1)]),e.createElementVNode("tr",null,[e.createElementVNode("td",Z,e.toDisplayString(n.__("PHP")),1),e.createElementVNode("td",J,e.toDisplayString(t.value.php||"-"),1)]),e.createElementVNode("tr",null,[e.createElementVNode("td",Y,e.toDisplayString(n.__("Database")),1),e.createElementVNode("td",Q,e.toDisplayString(t.value.database||"-"),1)]),e.createElementVNode("tr",null,[e.createElementVNode("td",X,e.toDisplayString(n.__("Laravel")),1),e.createElementVNode("td",v,e.toDisplayString(t.value.laravel||"-"),1)]),e.createElementVNode("tr",null,[e.createElementVNode("td",ee,e.toDisplayString(n.__("Nova")),1),e.createElementVNode("td",te,e.toDisplayString(t.value.nova||"-"),1)])])])):e.createCommentVNode("",!0)]),_:1},8,["heading","showPolling","showRefresh","loading","polling"])}}}),ne=["innerHTML"],ae=e.defineComponent({__name:"Html",props:{card:{}},setup(s){const a=s,o=e.computed(()=>{let t="";return a.card.center&&(t+=" flex flex-col justify-center text-center"),t});return(t,l)=>{const n=e.resolveComponent("NovaCardsCard");return t.card.withoutCardStyles?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["h-full",o.value]),innerHTML:t.card.content},null,10,ne)):(e.openBlock(),e.createBlock(n,{key:1,class:e.normalizeClass(o.value),innerHTML:t.card.content},null,8,["class","innerHTML"]))}}}),le={key:0},se={key:1,class:"w-full text-left table-collapse"},re={class:"align-baseline"},ce=["item"],ie={class:"py-2 pr-2 font-bold",style:{"word-wrap":"anywhere"}},de={class:"p-2"},pe={class:"p-2"},me=e.defineComponent({__name:"ScheduledJobs",props:{card:{}},setup(s){const{__:a}=m.useLocalization(),o=e.ref(!1),t=e.ref(!0),l=e.ref();async function n(){o.value=!0,await fetch("/nova-vendor/stepanenko3/nova-cards/scheduled-jobs").then(r=>r.json()).then(r=>{l.value=r}).catch(r=>{console.error("Error fetching weather:",r)}),o.value=!1}return(r,c)=>{const i=e.resolveComponent("NovaCardsCard");return e.openBlock(),e.createBlock(i,{heading:r.card.title||e.unref(a)("Scheduled Jobs"),showPolling:r.card?.polling||!1,showRefresh:r.card?.refresh||!0,loading:o.value,polling:t.value,pollingInterval:1e4,"onUpdate:polling":c[0]||(c[0]=p=>t.value=p),onRefresh:n},{default:e.withCtx(()=>[l.value.length?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("p",le,e.toDisplayString(e.unref(a)(o.value?"Loading...":"No Data")),1)),l.value.length?(e.openBlock(),e.createElementBlock("table",se,[e.createElementVNode("tbody",re,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(l.value,(p,d)=>(e.openBlock(),e.createElementBlock("tr",{item:p},[e.createElementVNode("td",ie,e.toDisplayString(p.command),1),e.createElementVNode("td",de,e.toDisplayString(p.expression),1),e.createElementVNode("td",pe,e.toDisplayString(p.humanReadableNextRun),1)],8,ce))),256))])])):e.createCommentVNode("",!0)]),_:1},8,["heading","showPolling","showRefresh","loading","polling"])}}}),_e={class:"flex items-center text-4xl mb-4"},fe={key:0},he={key:1},ge={class:"flex items-center"},ye={class:"text-80 font-bold"},ke={key:0},Ce={key:1},Ne=e.defineComponent({__name:"Percentage",props:{card:{}},setup(s){const a=s,{__:o}=m.useLocalization(),t=e.computed(()=>(a.card.count/a.card.total*100).toFixed(a.card.percentagePrecision));return(l,n)=>{const r=e.resolveComponent("NovaCardsCard");return e.openBlock(),e.createBlock(r,{heading:l.card.title,class:"flex flex-col items-center justify-center text-center"},{default:e.withCtx(()=>[e.createElementVNode("p",_e,[t.value!==null?(e.openBlock(),e.createElementBlock("span",fe,e.toDisplayString(t.value)+"% ",1)):(e.openBlock(),e.createElementBlock("span",he,"-"))]),e.createElementVNode("div",ge,[e.withDirectives(e.createElementVNode("p",ye,[l.card.count!==null?(e.openBlock(),e.createElementBlock("span",ke,e.toDisplayString(l.card.count),1)):e.createCommentVNode("",!0),e.createTextVNode(" "+e.toDisplayString(e.unref(o)("of"))+" ",1),l.total!==null?(e.openBlock(),e.createElementBlock("span",Ce,e.toDisplayString(l.card.total),1)):e.createCommentVNode("",!0),e.createTextVNode(" "+e.toDisplayString(l.card.label),1)],512),[[e.vShow,t.value!==null]]),e.withDirectives(e.createElementVNode("p",{class:"text-80 font-bold mt-4"},e.toDisplayString(e.unref(o)("No Data")),513),[[e.vShow,t.value===null]])])]),_:1},8,["heading"])}}}),Ee=["href","target"],we={key:0,calss:"text-basic font-semibold"},Ve=e.defineComponent({__name:"Linkable",props:{card:{}},setup(s){return(a,o)=>{const t=e.resolveComponent("NovaCardsCard");return e.openBlock(),e.createElementBlock("a",{class:"h-auto hover:opacity-50",href:a.card.url,target:a.card.target},[e.createVNode(t,{class:"flex flex-col items-center justify-center",heading:a.card.title,headingClass:"text-2xl font-bold"},{default:e.withCtx(()=>[a.card.subtitle?(e.openBlock(),e.createElementBlock("div",we,e.toDisplayString(a.card.subtitle),1)):e.createCommentVNode("",!0)]),_:1},8,["heading"])],8,Ee)}}}),Be={key:0},$e={key:1,class:"w-full text-left table-collapse"},be={class:"align-baseline"},Se={class:"py-2 pr-2 font-bold"},De={class:"p-2"},xe={class:"py-2 pr-2 font-bold"},Te={class:"p-2"},Le={class:"italic"},ze={key:2},Ie=e.defineComponent({__name:"Ssl",props:{card:{}},setup(s){const a=s,{__:o}=m.useLocalization(),t=e.ref(!1),l=e.ref(!1),n=e.ref(),r=e.ref(null);async function c(){t.value=!0,await fetch("/nova-vendor/stepanenko3/nova-cards/ssl?domain="+a.card.domain).then(i=>i.json()).then(i=>{n.value=i}).catch(i=>{r.value=i}),t.value=!1}return(i,p)=>{const d=e.resolveComponent("NovaCardsCard");return e.openBlock(),e.createBlock(d,{heading:i.card.domain+" - "+e.unref(o)(n.value?.is_valid?"Valid Certificate":"Invalid Certificate"),headingClass:{"text-green-500":n.value?.is_valid,"text-red-500":!n.value?.is_valid},showPolling:i.card?.polling||!1,showRefresh:i.card?.refresh||!0,loading:t.value,polling:l.value,pollingInterval:1e4,"onUpdate:polling":p[0]||(p[0]=_=>l.value=_),onRefresh:c},{default:e.withCtx(()=>[!n.value&&t.value?(e.openBlock(),e.createElementBlock("div",Be,e.toDisplayString(e.unref(o)("Loading...")),1)):n.value&&!r.value?(e.openBlock(),e.createElementBlock("table",$e,[e.createElementVNode("tbody",be,[e.createElementVNode("tr",null,[e.createElementVNode("td",Se,e.toDisplayString(e.unref(o)("Issuer")),1),e.createElementVNode("td",De,e.toDisplayString(n.value.issuer),1)]),e.createElementVNode("tr",null,[e.createElementVNode("td",xe,e.toDisplayString(e.unref(o)("Expiration")),1),e.createElementVNode("td",Te,[e.createTextVNode(e.toDisplayString(n.value.expiration_date)+" ( ",1),e.createElementVNode("strong",Le,e.toDisplayString(parseInt(n.value.expiration_date_in_days))+" days ",1),e.createTextVNode(" ) ")])])])])):(e.openBlock(),e.createElementBlock("div",ze,e.toDisplayString(r.value||""),1))]),_:1},8,["heading","headingClass","showPolling","showRefresh","loading","polling"])}}}),Pe={class:"flex items-center text-4xl mb-4"},Re={key:0,class:"text-center"},ue=e.defineComponent({__name:"Countdown",props:{card:{}},setup(s){const a=s,{__:o}=m.useLocalization(),t=e.ref("00:00:00:00"),l=e.ref(0),n=e.ref(0),r=e.ref(0),c=e.ref(0),i=e.ref(0);e.onMounted(()=>{l.value=a.card.to-new Date().getTime(),l.value>0&&window.requestAnimationFrame(d),window.addEventListener("focus",()=>{l.value<1e3&&(t.value="00:00:00:00",window.cancelAnimationFrame(d))})});const p=_=>("0"+Math.floor(_)).slice(-2),d=()=>{l.value=a.card.to-new Date().getTime(),n.value=p(l.value%(1e3*60)/1e3),r.value=p(l.value%(1e3*60*60)/(1e3*60)),c.value=p(l.value%(1e3*60*60*24)/(1e3*60*60)),i.value=p(l.value/(1e3*60*60*24)),l.value>=1e3?(t.value=`${i.value}:${c.value}:${r.value}:${n.value}`,window.requestAnimationFrame(d)):(window.cancelAnimationFrame(d),t.value="00:00:00:00")};return(_,h)=>{const f=e.resolveComponent("NovaCardsCard");return e.openBlock(),e.createBlock(f,{heading:_.card.title||e.unref(o)("Countdown"),class:"flex flex-col items-center justify-center text-center"},{default:e.withCtx(()=>[e.createElementVNode("p",Pe,e.toDisplayString(t.value),1),_.card.label?(e.openBlock(),e.createElementBlock("div",Re,e.toDisplayString(_.card.label),1)):e.createCommentVNode("",!0)]),_:1},8,["heading"])}}}),je={class:"card-overflow"},Me={key:0,class:"w-full text-left table-collapse"},Ue={class:"align-baseline"},Fe=e.defineComponent({__name:"WorldClock",props:{card:{}},setup(s){const{__:a}=m.useLocalization();return(o,t)=>{const l=e.resolveComponent("WorldClockTimer"),n=e.resolveComponent("NovaCardsCard");return e.openBlock(),e.createBlock(n,{class:"flex flex-col items-center justify-center text-center",heading:o.card.title||e.unref(a)("World Clock")},{default:e.withCtx(()=>[e.createElementVNode("div",je,[o.card.timezones.length>0?(e.openBlock(),e.createElementBlock("table",Me,[e.createElementVNode("tbody",Ue,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(o.card.timezones,r=>(e.openBlock(),e.createBlock(l,{timezone:r},null,8,["timezone"]))),256))])])):e.createCommentVNode("",!0)])]),_:1},8,["heading"])}}}),qe={class:"text-basic text-center mb-2"},We={key:0,class:"mr-2"},Ae=e.defineComponent({__name:"Environment",props:{card:{}},setup(s){const{__:a}=m.useLocalization();return(o,t)=>{const l=e.resolveComponent("NovaCardsCard");return e.openBlock(),e.createBlock(l,{class:"flex flex-col items-center justify-center"},{default:e.withCtx(()=>[e.createElementVNode("div",qe,e.toDisplayString(o.card.title||e.unref(a)("Current Environment")),1),e.createElementVNode("div",{class:e.normalizeClass(["flex items-center w-full text-lg font-bold uppercase",{"text-yellow-500":o.card.env!=="production","text-green-500":o.card.env==="production"}])},[o.card.env!=="production"?(e.openBlock(),e.createElementBlock("span",We," ( ! ) ")):e.createCommentVNode("",!0),e.createTextVNode(" "+e.toDisplayString(o.card.env),1)],2)]),_:1})}}}),He=["src"],Oe=e.defineComponent({__name:"Embed",props:{card:{}},setup(s){return(a,o)=>{const t=e.resolveComponent("NovaCardsCard");return e.openBlock(),e.createBlock(t,{class:e.normalizeClass(["h-auto overflow-hidden",{"p-3":a.card.hasPadding,"!p-none !p-0":!a.card.hasPadding}])},{default:e.withCtx(()=>[e.createElementVNode("iframe",{class:"w-full h-full",src:a.card.url,allow:"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:""},null,8,He)]),_:1},8,["class"])}}}),Ge={class:"flex items-center mb-2"},Ke=["src","alt"],Ze={class:"text-xl font-bold"},Je={class:"text-lg font-bold mb-4"},Ye={class:"grid grid-cols-4 gap-6 text-sm"},Qe={class:"flex flex-col"},Xe=e.createElementVNode("span",{class:"mb-1"}," Feels like ",-1),ve={class:"flex flex-col"},et=e.createElementVNode("span",{class:"mb-1"}," Humidity ",-1),tt={class:"flex flex-col"},ot=e.createElementVNode("span",{class:"mb-1"}," Sunrise ",-1),nt={class:"flex flex-col"},at=e.createElementVNode("span",null," Sunset ",-1),lt=e.defineComponent({__name:"Weather",props:{card:{}},setup(s){const a=s,{__:o}=m.useLocalization(),t=e.ref(!1),l=e.ref(!1),n=e.ref();async function r(){t.value=!0;const c=new URLSearchParams({q:a.card.city||"Kiev ",lang:a.card?.lang||""}).toString();await fetch("/nova-vendor/stepanenko3/nova-cards/weather"+(c?`?${c}`:"")).then(i=>i.json()).then(i=>{n.value=i}).catch(i=>{console.error("Error fetching weather:",i)}),t.value=!1}return(c,i)=>{const p=e.resolveComponent("NovaCardsCard"),d=e.resolveDirective("tooltip");return e.openBlock(),e.createBlock(p,{heading:n.value&&n.value.sys?`${n.value.name}, ${n.value.sys.country}`:e.unref(o)("Weather"),showPolling:c.card?.polling||!1,showRefresh:c.card?.refresh||!0,loading:t.value,polling:l.value,pollingInterval:1e4,"onUpdate:polling":i[0]||(i[0]=_=>l.value=_),onRefresh:r},{default:e.withCtx(()=>[n.value&&n.value.sys?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createElementVNode("div",Ge,[e.withDirectives(e.createElementVNode("img",{class:"mr-2",src:`http://openweathermap.org/img/wn/${n.value.weather[0].icon}@2x.png`,alt:n.value.weather[0].icon,width:"50",height:"50"},null,8,Ke),[[d,n.value.weather[0].description.charAt(0).toUpperCase()+n.value.weather[0].description.substring(1)]]),e.createElementVNode("div",Ze,e.toDisplayString(Math.round(n.value.main.temp))+" °C ",1)]),e.createElementVNode("div",Je,e.toDisplayString(n.value.weather[0].description.charAt(0).toUpperCase()+n.value.weather[0].description.substring(1)),1),e.createElementVNode("div",Ye,[e.createElementVNode("div",Qe,[Xe,e.createElementVNode("b",null,e.toDisplayString(Math.round(n.value.main.feels_like))+" °C ",1)]),e.createElementVNode("div",ve,[et,e.createElementVNode("b",null,e.toDisplayString(n.value.main.humidity)+"% ",1)]),e.createElementVNode("div",tt,[ot,e.createElementVNode("b",null,e.toDisplayString(new Date(n.value.sys.sunrise*1e3).toLocaleString("en-GB",{hour:"2-digit",minute:"2-digit",timeZone:"Europe/Kiev"})),1)]),e.createElementVNode("div",nt,[at,e.createElementVNode("b",null,e.toDisplayString(new Date(n.value.sys.sunset*1e3).toLocaleString("en-GB",{hour:"2-digit",minute:"2-digit",timeZone:"Europe/Kiev"})),1)])])],64)):e.createCommentVNode("",!0)]),_:1},8,["heading","showPolling","showRefresh","loading","polling"])}}}),st={class:"w-full text-left table-collapse"},rt={class:"align-baseline"},ct={class:"py-2 pr-2 font-bold"},it={class:"p-2"},dt={class:"py-2 pr-2 font-bold"},pt={class:"p-2"},mt={class:"py-2 pr-2 font-bold"},_t={class:"p-2"},ft={class:"py-2 pr-2 font-bold"},ht={class:"p-2"},gt={class:"py-2 pr-2 font-bold"},yt={class:"p-2"},kt=e.defineComponent({__name:"Calendar",props:{card:{}},setup(s){const{__:a}=m.useLocalization();return(o,t)=>{const l=e.resolveComponent("NovaCardsCard");return e.openBlock(),e.createBlock(l,{heading:`${o.card.day.name} ${o.card.day.withMonth}`},{default:e.withCtx(()=>[e.createElementVNode("table",st,[e.createElementVNode("tbody",rt,[e.createElementVNode("tr",null,[e.createElementVNode("td",ct,e.toDisplayString(e.unref(a)("Year")),1),e.createElementVNode("td",it,e.toDisplayString(o.card.year),1)]),e.createElementVNode("tr",null,[e.createElementVNode("td",dt,e.toDisplayString(e.unref(a)("Day of year")),1),e.createElementVNode("td",pt,e.toDisplayString(o.card.dayOfYear),1)]),e.createElementVNode("tr",null,[e.createElementVNode("td",mt,e.toDisplayString(e.unref(a)("Days in month")),1),e.createElementVNode("td",_t,e.toDisplayString(o.card.daysInMonth),1)]),e.createElementVNode("tr",null,[e.createElementVNode("td",ft,e.toDisplayString(e.unref(a)("Qarter")),1),e.createElementVNode("td",ht,e.toDisplayString(o.card.quarter),1)]),e.createElementVNode("tr",null,[e.createElementVNode("td",gt,e.toDisplayString(e.unref(a)("Timezone")),1),e.createElementVNode("td",yt,e.toDisplayString(o.card.timezone),1)])])])]),_:1},8,["heading"])}}}),Ct={class:"flex items-center justify-between flex-grow"},Nt={class:"flex items-center space-x-4"},Et={key:0,class:"flex-shrink-0"},wt=["src","alt"],Vt={key:1,class:"flex-shrink-0 text-3xl h-20 w-20 rounded-full bg-primary-500 tracking-wide text-white flex items-center justify-center"},Bt={class:"text-left"},$t={class:"text-sm font-medium text-gray-600 dark:text-gray-400"},bt={class:"font-bold text-xl"},St={key:0,class:"text-sm font-medium text-gray-600 dark:text-gray-400"},Dt={key:1,class:"mt-6 flex flex-col mt-1 flex-row flex-wrap"},xt={class:"sr-only"},Tt={class:"mt-3 flex justify-center text-sm text-gray-500 dark:text-gray-300 font-medium mr-6 mt-1 capitalize"},Lt=e.createElementVNode("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor",class:"flex-shrink-0 mr-1.5 h-5 w-5 text-green-400 dark:text-green-500","aria-hidden":"true"},[e.createElementVNode("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})],-1),zt={key:0,class:"space-y-4 flex flex-col"},It={key:0,class:"border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/25 grid grid-cols-1 divide-y divide-gray-200 dark:divide-gray-700 grid-cols-3 divide-y-0 divide-x"},Pt={class:"text-gray-900 dark:text-gray-300"},Rt={class:"text-gray-600 dark:text-gray-400"},ut=e.defineComponent({__name:"Greeter",props:{card:{}},setup(s){const{__:a}=m.useLocalization();function o(t){return t.match(/(\b\S)?/g).join("").match(/(^\S|\S$)?/g).join("").toUpperCase()}return(t,l)=>{const n=e.resolveComponent("OutlineButtonInertiaLink"),r=e.resolveComponent("NovaCardsCard");return e.openBlock(),e.createBlock(r,{class:"h-auto flex items-center p-4"},{default:e.withCtx(()=>[e.createElementVNode("div",Ct,[e.createElementVNode("div",Nt,[t.card.avatar?(e.openBlock(),e.createElementBlock("div",Et,[e.createElementVNode("img",{class:"mx-auto h-20 w-20 rounded-full",src:t.card.avatar_url,alt:t.card.user_name},null,8,wt)])):(e.openBlock(),e.createElementBlock("div",Vt,e.toDisplayString(o(t.card.user_name)),1)),e.createElementVNode("div",Bt,[e.createElementVNode("p",$t,e.toDisplayString(t.card.message??e.unref(a)("Welcome back,")),1),e.createElementVNode("p",bt,e.toDisplayString(t.card.user_name),1),t.card.user_title?(e.openBlock(),e.createElementBlock("p",St,e.toDisplayString(t.card.user_title),1)):e.createCommentVNode("",!0),t.card.verified?(e.openBlock(),e.createElementBlock("dl",Dt,[e.createElementVNode("dt",xt,e.toDisplayString(t.card.verified_text??e.unref(a)("Verified Account")),1),e.createElementVNode("dd",Tt,[Lt,e.createTextVNode(" "+e.toDisplayString(t.card.verified_text??e.unref(a)("Verified Account")),1)])])):e.createCommentVNode("",!0)])]),t.card.buttons.length>0?(e.openBlock(),e.createElementBlock("div",zt,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.card.buttons,c=>(e.openBlock(),e.createBlock(n,{href:c.target},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(c.name),1)]),_:2},1032,["href"]))),256))])):e.createCommentVNode("",!0)]),t.card.stats?(e.openBlock(),e.createElementBlock("div",It,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.card.stats,c=>(e.openBlock(),e.createElementBlock("div",{key:c.label,class:"px-6 py-3 text-sm font-medium text-center"},[e.createElementVNode("span",Pt,e.toDisplayString(c.value),1),e.createElementVNode("span",Rt,e.toDisplayString(c.label),1)]))),128))])):e.createCommentVNode("",!0)]),_:1})}}}),jt=(s,a)=>{const o=s.__vccOpts||s;for(const[t,l]of a)o[t]=l;return o},Mt={props:{type:{type:String,required:!1},processing:{type:Boolean,required:!1},loading:{type:Boolean,required:!1}}},Ut={type:"button",class:"relative inline-flex items-center justify-center w-8 h-8 focus:outline-none focus:ring rounded-lg"},Ft={key:0,class:"absolute",style:{top:"50%",left:"50%",transform:"translate(-50%, -50%)"}};function qt(s,a,o,t,l,n){const r=e.resolveComponent("Icon"),c=e.resolveComponent("Loader");return e.openBlock(),e.createElementBlock("button",Ut,[e.createElementVNode("span",{class:e.normalizeClass({invisible:o.processing||o.loading})},[e.renderSlot(s.$slots,"default"),o.type?(e.openBlock(),e.createBlock(r,{key:0,solid:"",type:o.type},null,8,["type"])):e.createCommentVNode("",!0)],2),o.processing||o.loading?(e.openBlock(),e.createElementBlock("span",Ft,[e.createVNode(c,{class:"text-gray-500",width:"32"})])):e.createCommentVNode("",!0)])}const Wt=jt(Mt,[["render",qt]]);Nova.booting(s=>{s.component("NovaCardsCard",E),s.component("NovaCardsToolbarButton",Wt),s.component("WorldClockTimer",b),s.component("system-resources-card",A),s.component("versions-card",oe),s.component("html-card",ae),s.component("scheduled-jobs-card",me),s.component("percentage-card",Ne),s.component("linkable-card",Ve),s.component("ssl-card",Ie),s.component("countdown-card",ue),s.component("world-clock-card",Fe),s.component("environment-card",Ae),s.component("embed-card",Oe),s.component("cache-card",Cache),s.component("weather-card",lt),s.component("calendar-card",kt),s.component("greeter-card",ut)})});
2 |
--------------------------------------------------------------------------------
/duster.json:
--------------------------------------------------------------------------------
1 | {
2 | "exclude": [
3 | "bootstrap",
4 | "config"
5 | ],
6 | "scripts": {
7 | "lint": {
8 | "phpstan": [
9 | "./vendor/bin/phpstan",
10 | "analyse",
11 | "src",
12 | "--memory-limit=1G"
13 | ]
14 | }
15 | },
16 | "processTimeout": 120
17 | }
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "dev": "vite build --watch",
5 | "build": "vite build",
6 | "nova:install": "npm --prefix='vendor/laravel/nova' ci"
7 | },
8 | "devDependencies": {
9 | "@inertiajs/inertia": "^0.11.1",
10 | "@inertiajs/inertia-vue3": "^0.6.0",
11 | "@vitejs/plugin-vue": "^5.2.1",
12 | "@vue/compiler-sfc": "^3.5.13",
13 | "postcss": "^8.4.49",
14 | "vite": "^6.2.1"
15 | },
16 | "dependencies": {
17 | "autoprefixer": "^10.4.21",
18 | "tailwindcss": "^4.0.13"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/pint.json:
--------------------------------------------------------------------------------
1 | {
2 | "preset": "laravel",
3 | "rules": {
4 | "@PSR12": true,
5 | "@PSR12:risky": true,
6 | "@PHP80Migration": true,
7 | "@PHP80Migration:risky": true,
8 | "@PHP81Migration": true,
9 | "align_multiline_comment": {
10 | "comment_type": "phpdocs_only"
11 | },
12 | "array_indentation": true,
13 | "array_syntax": {
14 | "syntax": "short"
15 | },
16 | "blank_line_after_namespace": true,
17 | "blank_line_after_opening_tag": true,
18 | "blank_line_before_statement": {
19 | "statements": [
20 | "break",
21 | "case",
22 | "continue",
23 | "declare",
24 | "default",
25 | "exit",
26 | "goto",
27 | "include",
28 | "include_once",
29 | "phpdoc",
30 | "require",
31 | "require_once",
32 | "return",
33 | "switch",
34 | "throw",
35 | "try",
36 | "yield",
37 | "yield_from"
38 | ]
39 | },
40 | "blank_line_between_import_groups": true,
41 | "braces": {
42 | "allow_single_line_anonymous_class_with_empty_body": true,
43 | "allow_single_line_closure": true
44 | },
45 | "cast_spaces": {
46 | "space": "single"
47 | },
48 | "class_attributes_separation": {
49 | "elements": {
50 | "method": "one"
51 | }
52 | },
53 | "class_definition": {
54 | "single_line": true,
55 | "space_before_parenthesis": true
56 | },
57 | "class_reference_name_casing": true,
58 | "clean_namespace": true,
59 | "combine_consecutive_issets": true,
60 | "combine_consecutive_unsets": true,
61 | "compact_nullable_typehint": true,
62 | "concat_space": {
63 | "spacing": "one"
64 | },
65 | "constant_case": {
66 | "case": "lower"
67 | },
68 | "declare_equal_normalize": {
69 | "space": "single"
70 | },
71 | "echo_tag_syntax": true,
72 | "elseif": true,
73 | "empty_loop_body": true,
74 | "empty_loop_condition": true,
75 | "encoding": true,
76 | "escape_implicit_backslashes": true,
77 | "explicit_indirect_variable": true,
78 | "explicit_string_variable": true,
79 | "full_opening_tag": true,
80 | "fully_qualified_strict_types": true,
81 | "function_declaration": true,
82 | "function_typehint_space": true,
83 | "general_phpdoc_tag_rename": {
84 | "replacements": {
85 | "inheritDocs": "inheritDoc"
86 | }
87 | },
88 | "heredoc_to_nowdoc": true,
89 | "include": true,
90 | "increment_style": {
91 | "style": "post"
92 | },
93 | "indentation_type": true,
94 | "integer_literal_case": true,
95 | "lambda_not_used_import": true,
96 | "line_ending": true,
97 | "linebreak_after_opening_tag": true,
98 | "lowercase_cast": true,
99 | "lowercase_keywords": true,
100 | "lowercase_static_reference": true,
101 | "magic_constant_casing": true,
102 | "magic_method_casing": true,
103 | "method_argument_space": {
104 | "on_multiline": "ensure_single_line",
105 | "after_heredoc": true,
106 | "keep_multiple_spaces_after_comma": true
107 | },
108 | "method_chaining_indentation": true,
109 | "multiline_comment_opening_closing": true,
110 | "multiline_whitespace_before_semicolons": {
111 | "strategy": "no_multi_line"
112 | },
113 | "native_function_casing": true,
114 | "native_function_type_declaration_casing": true,
115 | "new_with_braces": {
116 | "anonymous_class": true,
117 | "named_class": true
118 | },
119 | "no_alias_language_construct_call": true,
120 | "no_alternative_syntax": true,
121 | "no_binary_string": true,
122 | "no_blank_lines_after_class_opening": true,
123 | "no_blank_lines_after_phpdoc": true,
124 | "no_break_comment": true,
125 | "no_closing_tag": true,
126 | "no_empty_phpdoc": true,
127 | "no_empty_statement": true,
128 | "no_extra_blank_lines": {
129 | "tokens": [
130 | "attribute",
131 | "break",
132 | "case",
133 | "continue",
134 | "curly_brace_block",
135 | "default",
136 | "extra",
137 | "parenthesis_brace_block",
138 | "return",
139 | "square_brace_block",
140 | "switch",
141 | "throw",
142 | "use"
143 | ]
144 | },
145 | "no_leading_import_slash": true,
146 | "no_leading_namespace_whitespace": true,
147 | "no_mixed_echo_print": true,
148 | "no_multiline_whitespace_around_double_arrow": true,
149 | "no_null_property_initialization": true,
150 | "no_short_bool_cast": true,
151 | "no_singleline_whitespace_before_semicolons": true,
152 | "no_space_around_double_colon": true,
153 | "no_spaces_after_function_name": true,
154 | "no_spaces_around_offset": true,
155 | "no_spaces_inside_parenthesis": true,
156 | "no_superfluous_elseif": true,
157 | "no_superfluous_phpdoc_tags": {
158 | "allow_mixed": true,
159 | "allow_unused_params": true
160 | },
161 | "no_trailing_comma_in_singleline": true,
162 | "no_trailing_whitespace": true,
163 | "no_trailing_whitespace_in_comment": true,
164 | "no_unneeded_control_parentheses": {
165 | "statements": [
166 | "break",
167 | "clone",
168 | "continue",
169 | "echo_print",
170 | "negative_instanceof",
171 | "others",
172 | "return",
173 | "switch_case",
174 | "yield",
175 | "yield_from"
176 | ]
177 | },
178 | "no_unneeded_curly_braces": {
179 | "namespaces": true
180 | },
181 | "no_unneeded_import_alias": true,
182 | "no_unset_cast": true,
183 | "no_unused_imports": true,
184 | "no_useless_else": true,
185 | "no_useless_nullsafe_operator": true,
186 | "no_useless_return": true,
187 | "no_whitespace_before_comma_in_array": true,
188 | "no_whitespace_in_blank_line": true,
189 | "normalize_index_brace": true,
190 | "object_operator_without_whitespace": true,
191 | "operator_linebreak": {
192 | "position": "beginning",
193 | "only_booleans": true
194 | },
195 | "ordered_class_elements": true,
196 | "ordered_interfaces": true,
197 | "ordered_imports": true,
198 | "phpdoc_add_missing_param_annotation": true,
199 | "phpdoc_align": {
200 | "align": "left"
201 | },
202 | "phpdoc_annotation_without_dot": true,
203 | "phpdoc_indent": true,
204 | "phpdoc_inline_tag_normalizer": true,
205 | "phpdoc_no_access": true,
206 | "phpdoc_no_alias_tag": true,
207 | "phpdoc_no_empty_return": true,
208 | "phpdoc_no_package": true,
209 | "phpdoc_no_useless_inheritdoc": true,
210 | "phpdoc_order": {
211 | "order": [
212 | "param",
213 | "throws",
214 | "return"
215 | ]
216 | },
217 | "phpdoc_order_by_value": true,
218 | "phpdoc_return_self_reference": true,
219 | "phpdoc_scalar": true,
220 | "phpdoc_separation": true,
221 | "phpdoc_single_line_var_spacing": true,
222 | "phpdoc_summary": true,
223 | "phpdoc_tag_type": {
224 | "tags": {
225 | "inheritDoc": "inline"
226 | }
227 | },
228 | "phpdoc_to_comment": true,
229 | "phpdoc_trim": true,
230 | "phpdoc_trim_consecutive_blank_line_separation": true,
231 | "phpdoc_types": true,
232 | "phpdoc_types_order": true,
233 | "phpdoc_var_annotation_correct_order": true,
234 | "phpdoc_var_without_name": true,
235 | "protected_to_private": true,
236 | "return_assignment": true,
237 | "return_type_declaration": true,
238 | "semicolon_after_instruction": true,
239 | "short_scalar_cast": true,
240 | "simple_to_complex_string_variable": true,
241 | "single_blank_line_at_eof": true,
242 | "single_blank_line_before_namespace": false,
243 | "single_class_element_per_statement": true,
244 | "single_import_per_statement": true,
245 | "single_line_after_imports": true,
246 | "single_line_comment_spacing": true,
247 | "single_line_comment_style": true,
248 | "single_line_throw": true,
249 | "single_quote": {
250 | "strings_containing_single_quote_chars": true
251 | },
252 | "single_space_after_construct": {
253 | "constructs": [
254 | "abstract",
255 | "as",
256 | "attribute",
257 | "break",
258 | "case",
259 | "catch",
260 | "class",
261 | "clone",
262 | "comment",
263 | "const",
264 | "const_import",
265 | "continue",
266 | "do",
267 | "echo",
268 | "else",
269 | "elseif",
270 | "enum",
271 | "extends",
272 | "final",
273 | "finally",
274 | "for",
275 | "foreach",
276 | "function",
277 | "function_import",
278 | "global",
279 | "goto",
280 | "if",
281 | "implements",
282 | "include",
283 | "include_once",
284 | "instanceof",
285 | "insteadof",
286 | "interface",
287 | "match",
288 | "named_argument",
289 | "namespace",
290 | "new",
291 | "open_tag_with_echo",
292 | "php_doc",
293 | "php_open",
294 | "print",
295 | "private",
296 | "protected",
297 | "public",
298 | "readonly",
299 | "require",
300 | "require_once",
301 | "return",
302 | "static",
303 | "switch",
304 | "throw",
305 | "trait",
306 | "try",
307 | "type_colon",
308 | "use",
309 | "use_lambda",
310 | "use_trait",
311 | "var",
312 | "while",
313 | "yield",
314 | "yield_from"
315 | ]
316 | },
317 | "single_trait_insert_per_statement": true,
318 | "space_after_semicolon": {
319 | "remove_in_empty_for_expressions": true
320 | },
321 | "standardize_increment": true,
322 | "standardize_not_equals": true,
323 | "switch_case_semicolon_to_colon": true,
324 | "switch_case_space": true,
325 | "switch_continue_to_break": true,
326 | "ternary_operator_spaces": true,
327 | "trailing_comma_in_multiline": true,
328 | "trim_array_spaces": true,
329 | "types_spaces": {
330 | "space": "single"
331 | },
332 | "unary_operator_spaces": true,
333 | "visibility_required": {
334 | "elements": [
335 | "property",
336 | "method",
337 | "const"
338 | ]
339 | },
340 | "whitespace_after_comma_in_array": {
341 | "ensure_single_space": true
342 | },
343 | "array_push": true,
344 | "combine_nested_dirname": true,
345 | "comment_to_phpdoc": true,
346 | "dir_constant": true,
347 | "ereg_to_preg": true,
348 | "error_suppression": true,
349 | "final_internal_class": true,
350 | "fopen_flag_order": true,
351 | "fopen_flags": {
352 | "b_mode": false
353 | },
354 | "function_to_constant": true,
355 | "implode_call": true,
356 | "is_null": true,
357 | "logical_operators": true,
358 | "modernize_types_casting": true,
359 | "native_constant_invocation": {
360 | "fix_built_in": false,
361 | "include": [
362 | "DIRECTORY_SEPARATOR",
363 | "PHP_INT_SIZE",
364 | "PHP_SAPI",
365 | "PHP_VERSION_ID"
366 | ],
367 | "scope": "namespaced",
368 | "strict": true
369 | },
370 | "no_alias_functions": {
371 | "sets": [
372 | "@all"
373 | ]
374 | },
375 | "no_homoglyph_names": true,
376 | "no_php4_constructor": true,
377 | "no_trailing_whitespace_in_string": true,
378 | "no_unneeded_final_method": true,
379 | "no_unreachable_default_argument_value": true,
380 | "no_unset_on_property": true,
381 | "no_useless_sprintf": true,
382 | "ordered_traits": true,
383 | "pow_to_exponentiation": true,
384 | "psr_autoloading": true,
385 | "self_accessor": true,
386 | "set_type_to_cast": true,
387 | "string_length_to_empty": true,
388 | "ternary_to_elvis_operator": true,
389 |
390 |
391 |
392 |
393 | "declare_strict_types": false,
394 | "yoda_style": false,
395 | "group_import": false,
396 | "not_operator_with_successor_space": false,
397 | "simplified_null_return": true,
398 | "nullable_type_declaration_for_default_null_value": {
399 | "use_nullable_type_declaration": true
400 | },
401 | "assign_null_coalescing_to_coalesce_equal": true,
402 | "ternary_to_null_coalescing": true,
403 | "get_class_to_class_keyword": true
404 | }
405 | }
406 |
--------------------------------------------------------------------------------
/postcss.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/resources/css/card.css:
--------------------------------------------------------------------------------
1 | @tailwind components;
2 | @tailwind utilities;
3 |
--------------------------------------------------------------------------------
/resources/js/cards/Calendar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ __('Year') }}
8 | |
9 |
10 | {{ card.year }}
11 | |
12 |
13 |
21 |
22 |
23 | {{ __('Day of year') }}
24 | |
25 |
26 | {{ card.dayOfYear }}
27 | |
28 |
29 |
37 |
45 |
46 |
47 | {{ __('Days in month') }}
48 | |
49 |
50 | {{ card.daysInMonth }}
51 | |
52 |
53 |
54 |
55 | {{ __('Qarter') }}
56 | |
57 |
58 | {{ card.quarter }}
59 | |
60 |
61 |
62 |
63 | {{ __('Timezone') }}
64 | |
65 |
66 | {{ card.timezone }}
67 | |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
97 |
--------------------------------------------------------------------------------
/resources/js/cards/Countdown.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | {{ timeLeft }}
8 |
9 |
10 |
11 | {{ card.label }}
12 |
13 |
14 |
15 |
16 |
71 |
--------------------------------------------------------------------------------
/resources/js/cards/Embed.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
12 |
13 |
14 |
15 |
25 |
--------------------------------------------------------------------------------
/resources/js/cards/Environment.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ card.title || __("Current Environment") }}
5 |
6 |
13 | ( ! )
14 | {{ card.env }}
15 |
16 |
17 |
18 |
19 |
32 |
--------------------------------------------------------------------------------
/resources/js/cards/Greeter.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
![]()
11 |
12 |
16 | {{ getInitials(card.user_name) }}
17 |
18 |
19 |
22 | {{ card.message ?? __("Welcome back,") }}
23 |
24 |
25 | {{ card.user_name }}
26 |
27 |
31 | {{ card.user_title }}
32 |
33 |
37 | -
38 | {{ card.verified_text ?? __("Verified Account") }}
39 |
40 | -
43 |
58 | {{ card.verified_text ?? __("Verified Account") }}
59 |
60 |
61 |
62 |
63 |
64 |
68 | {{ button.name }}
69 |
70 |
71 |
72 |
73 |
77 |
82 |
83 | {{ stat.value }}
84 |
85 |
86 | {{ stat.label }}
87 |
88 |
89 |
90 |
91 |
92 |
93 |
122 |
--------------------------------------------------------------------------------
/resources/js/cards/Html.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
27 |
--------------------------------------------------------------------------------
/resources/js/cards/Linkable.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
12 |
13 | {{ card.subtitle }}
14 |
15 |
16 |
17 |
18 |
19 |
31 |
--------------------------------------------------------------------------------
/resources/js/cards/Percentage.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | {{ percentage }}%
8 | -
9 |
10 |
11 |
12 |
13 | {{ card.count }}
14 | {{ __("of") }}
15 | {{ card.total }}
16 | {{ card.label }}
17 |
18 |
19 | {{ __("No Data") }}
20 |
21 |
22 |
23 |
24 |
25 |
47 |
--------------------------------------------------------------------------------
/resources/js/cards/ScheduledJobs.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 | {{ __(loading ? "Loading..." : "No Data") }}
14 |
15 |
16 |
17 |
18 |
19 |
20 | {{ item.command }}
21 | |
22 |
23 | {{ item.expression }}
24 | |
25 |
26 | {{ item.humanReadableNextRun }}
27 | |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
67 |
--------------------------------------------------------------------------------
/resources/js/cards/Ssl.vue:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 | {{ __('Loading...') }}
22 |
23 |
24 |
25 |
26 |
27 | {{ __('Issuer') }}
28 | |
29 |
30 | {{ response.issuer }}
31 | |
32 |
33 |
34 |
35 | {{ __('Expiration') }}
36 | |
37 |
38 | {{ response.expiration_date }}
39 | (
40 |
41 | {{ parseInt(response.expiration_date_in_days) }} days
42 |
43 | )
44 | |
45 |
46 |
47 |
48 |
49 |
50 | {{ errorMessage || '' }}
51 |
52 |
53 |
54 |
55 |
91 |
--------------------------------------------------------------------------------
/resources/js/cards/SystemResources.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
16 |
17 |
18 |
19 | {{ __("Disk Space") }}
20 | |
21 |
22 | {{ response.disk_space.use_percentage }}%
23 | {{ __("Used") }} (
24 | {{ response.disk_space.used.memory }}
25 |
26 | {{ response.disk_space.used.unit.toLowerCase() }}
27 |
28 | /
29 | {{ response.disk_space.total.memory }}
30 |
31 | {{ response.disk_space.total.unit.toLowerCase() }}
32 |
33 | )
34 | |
35 |
36 |
37 |
38 | {{ __("Memory Usage") }}
39 | |
40 |
41 | {{ response.memory_usage.use_percentage }}%
42 | {{ __("Used") }} (
43 | {{ response.memory_usage.used.memory }}
44 |
45 |
46 | {{ response.memory_usage.used.unit.toLowerCase() }}
47 |
48 | / {{ response.memory_usage.total.memory }}
49 |
50 | {{ response.memory_usage.total.unit.toLowerCase() }}
51 |
52 | )
53 | |
54 |
55 |
56 |
57 | {{ __("CPU Usage") }}
58 | |
59 |
60 | {{ response.cpu_usage.use_percentage }}%
61 | {{ __("Used") }}
62 |
63 |
64 | {{ response.cpu_usage.name }}
65 |
66 | |
67 |
68 |
69 |
70 |
71 | {{ __("No Data") }}
72 |
73 |
74 |
75 |
76 |
110 |
--------------------------------------------------------------------------------
/resources/js/cards/Versions.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 | {{ __("OS") }}
17 | |
18 |
19 | {{ response.os || "-" }}
20 | |
21 |
22 |
23 |
24 | {{ __("PHP") }}
25 | |
26 |
27 | {{ response.php || "-" }}
28 | |
29 |
30 |
31 |
32 | {{ __("Database") }}
33 | |
34 |
35 | {{ response.database || "-" }}
36 | |
37 |
38 |
39 |
40 | {{ __("Laravel") }}
41 | |
42 |
43 | {{ response.laravel || "-" }}
44 | |
45 |
46 |
47 |
48 | {{ __("Nova") }}
49 | |
50 |
51 | {{ response.nova || "-" }}
52 | |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
89 |
--------------------------------------------------------------------------------
/resources/js/cards/Weather.vue:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
![]()
31 |
32 |
33 | {{ Math.round(response.main.temp) }} °C
34 |
35 |
36 |
37 |
38 | {{
39 | response.weather[0].description.charAt(0).toUpperCase() +
40 | response.weather[0].description.substring(1)
41 | }}
42 |
43 |
44 |
45 |
46 | Feels like
47 | {{ Math.round(response.main.feels_like) }} °C
48 |
49 |
50 | Humidity
51 | {{ response.main.humidity }}%
52 |
53 |
54 | Sunrise
55 |
56 | {{
57 | new Date(
58 | response.sys.sunrise * 1000
59 | ).toLocaleString("en-GB", {
60 | hour: "2-digit",
61 | minute: "2-digit",
62 | timeZone: "Europe/Kiev",
63 | })
64 | }}
65 |
66 |
67 |
68 | Sunset
69 |
70 | {{
71 | new Date(response.sys.sunset * 1000).toLocaleString(
72 | "en-GB",
73 | {
74 | hour: "2-digit",
75 | minute: "2-digit",
76 | timeZone: "Europe/Kiev",
77 | }
78 | )
79 | }}
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
129 |
--------------------------------------------------------------------------------
/resources/js/cards/WorldClock.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
19 |
20 |
21 |
22 |
34 |
--------------------------------------------------------------------------------
/resources/js/components/Card.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
10 | {{ heading }}
11 |
12 |
13 |
17 |
24 |
25 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
132 |
--------------------------------------------------------------------------------
/resources/js/components/ToolbarButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 |
39 |
--------------------------------------------------------------------------------
/resources/js/components/WorldClockTimer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ props.timezone }}
5 | |
6 |
7 | {{ iso[2] || "-" }}
8 | |
9 |
10 |
14 | |
15 |
16 |
17 |
18 |
33 |
--------------------------------------------------------------------------------
/resources/js/composables/useCurrentTime.js:
--------------------------------------------------------------------------------
1 | import { ref, onBeforeUnmount } from "vue";
2 |
3 | export const useCurrentTime = (timezone = null) => {
4 | const currentTime = ref(getDate(timezone));
5 | const iso = ref(currentTime.value.toISOString().match(/(\d{4}\-\d{2}\-\d{2})T(\d{2}:\d{2}:\d{2})/));
6 |
7 | const updateCurrentTime = () => {
8 | currentTime.value = getDate(timezone);
9 | iso.value = currentTime.value.toISOString().match(/(\d{4}\-\d{2}\-\d{2})T(\d{2}:\d{2}:\d{2})/);
10 | };
11 |
12 | const updateTimeInterval = setInterval(updateCurrentTime, 1000);
13 |
14 | onBeforeUnmount(() => {
15 | clearInterval(updateTimeInterval);
16 | });
17 |
18 | return {
19 | currentTime,
20 | iso,
21 | };
22 | };
23 |
24 | function getDate(timezone = null) {
25 | return timezone
26 | ? new Date(
27 | new Date().toLocaleString('en-US', {
28 | timeZone: timezone,
29 | }),
30 | )
31 | : new Date();
32 | }
33 |
--------------------------------------------------------------------------------
/resources/js/entry.js:
--------------------------------------------------------------------------------
1 | import '../css/card.css'
2 |
3 | import Card from './components/Card.vue'
4 | import WorldClockTimer from './components/WorldClockTimer.vue'
5 | //
6 | import SystemResources from './cards/SystemResources.vue'
7 | import Versions from './cards/Versions.vue'
8 | import Html from './cards/Html.vue'
9 | import ScheduledJobs from './cards/ScheduledJobs.vue'
10 | import Percentage from './cards/Percentage.vue'
11 | import Linkable from './cards/Linkable.vue'
12 | import Ssl from './cards/Ssl.vue'
13 | import Countdown from './cards/Countdown.vue'
14 | import WorldClock from './cards/WorldClock.vue'
15 | import Environment from './cards/Environment.vue'
16 | import Embed from './cards/Embed.vue'
17 | import Weather from './cards/Weather.vue'
18 | import Calendar from './cards/Calendar.vue'
19 | import Greeter from './cards/Greeter.vue'
20 | import ToolbarButton from './components/ToolbarButton.vue'
21 |
22 | Nova.booting((Vue) => {
23 | Vue.component('NovaCardsCard', Card);
24 | Vue.component('NovaCardsToolbarButton', ToolbarButton);
25 | Vue.component('WorldClockTimer', WorldClockTimer);
26 | //
27 | Vue.component('system-resources-card', SystemResources);
28 | Vue.component('versions-card', Versions);
29 | Vue.component('html-card', Html);
30 | Vue.component('scheduled-jobs-card', ScheduledJobs);
31 | Vue.component('percentage-card', Percentage);
32 | Vue.component('linkable-card', Linkable);
33 | Vue.component('ssl-card', Ssl);
34 | Vue.component('countdown-card', Countdown);
35 | Vue.component('world-clock-card', WorldClock);
36 | Vue.component('environment-card', Environment);
37 | Vue.component('embed-card', Embed);
38 | Vue.component('cache-card', Cache);
39 | Vue.component('weather-card', Weather);
40 | Vue.component('calendar-card', Calendar);
41 | Vue.component('greeter-card', Greeter);
42 | });
43 |
--------------------------------------------------------------------------------
/routes/api.php:
--------------------------------------------------------------------------------
1 | withMeta([
17 | 'day' => [
18 | 'name' => $now->dayName,
19 | 'shortName' => $now->minDayName,
20 | 'number' => $now->day,
21 | 'withMonth' => $now->isoFormat('Do MMMM'),
22 | ],
23 | 'month' => [
24 | 'name' => $now->monthName,
25 | 'name2' => $now->getTranslatedMonthName('Do MMMM'),
26 | 'shortName' => $now->shortMonthName,
27 | 'number' => $now->month,
28 | 'withDay' => $now->isoFormat('Do MMMM'),
29 | ],
30 | 'year' => $now->year,
31 | 'dayOfWeek' => $now->dayOfWeek,
32 | 'dayOfYear' => $now->dayOfYear,
33 | 'weekOfMonth' => $now->weekOfMonth,
34 | 'weekOfYear' => $now->weekOfYear,
35 | 'daysInMonth' => $now->daysInMonth,
36 | 'quarter' => $now->quarter,
37 | 'timestamp' => $now->timestamp,
38 | 'timezone' => $now->timezoneName,
39 | ]);
40 | }
41 |
42 | public function component(): string
43 | {
44 | return 'calendar-card';
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Cards/CountdownCard.php:
--------------------------------------------------------------------------------
1 | withMeta([
16 | 'label' => $label,
17 | ]);
18 | }
19 |
20 | public function title(
21 | string $title = '',
22 | ): self {
23 | return $this->withMeta([
24 | 'title' => $title,
25 | ]);
26 | }
27 |
28 | public function to(
29 | Carbon $date,
30 | ): self {
31 | return $this->withMeta([
32 | 'to' => $date->timestamp * 1000,
33 | ]);
34 | }
35 |
36 | public function component(): string
37 | {
38 | return 'countdown-card';
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Cards/EmbedCard.php:
--------------------------------------------------------------------------------
1 | withMeta([
15 | 'url' => false,
16 | 'hasPadding' => true,
17 | ]);
18 | }
19 |
20 | public function url(
21 | string $url,
22 | ): self {
23 | return $this->withMeta([
24 | 'url' => $url,
25 | ]);
26 | }
27 |
28 | public function withoutPadding(): self
29 | {
30 | return $this->withMeta([
31 | 'hasPadding' => false,
32 | ]);
33 | }
34 |
35 | public function component(): string
36 | {
37 | return 'embed-card';
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Cards/EnvironmentCard.php:
--------------------------------------------------------------------------------
1 | withMeta([
17 | 'env' => config('app.env'),
18 | ]);
19 | }
20 |
21 | public function title(
22 | string $title = '',
23 | ): self {
24 | return $this->withMeta([
25 | 'title' => $title,
26 | ]);
27 | }
28 |
29 | public function component(): string
30 | {
31 | return 'environment-card';
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Cards/GreeterCard.php:
--------------------------------------------------------------------------------
1 | withMeta([
22 | 'user_name' => auth()->user()?->name ?? __('Dear User'),
23 | 'buttons' => $this->buttons,
24 | ]);
25 | }
26 |
27 | public function user(
28 | ?string $name = null,
29 | ?string $title = null,
30 | ): self {
31 | return $this->withMeta([
32 | 'user_name' => $name ?? (auth()->user()?->name ?? __('Dear User')),
33 | 'user_title' => $title,
34 | ]);
35 | }
36 |
37 | public function message(
38 | string $text,
39 | ): self {
40 | return $this->withMeta([
41 | 'message' => $text,
42 | ]);
43 | }
44 |
45 | public function avatar(
46 | string $url,
47 | ): self {
48 | return $this->withMeta([
49 | 'avatar' => true,
50 | 'avatar_url' => $url,
51 | ]);
52 | }
53 |
54 | public function button(
55 | string $name,
56 | string $target,
57 | ?string $style = null,
58 | ): self {
59 | $this->buttons[] = [
60 | 'name' => $name,
61 | 'target' => $target,
62 | 'style' => $style,
63 | ];
64 |
65 | return $this->withMeta([
66 | 'buttons' => $this->buttons,
67 | ]);
68 | }
69 |
70 | public function stats(
71 | array $stats,
72 | ): self {
73 | if (count($stats) > 3) {
74 | $stats = array_slice($stats, 0, 3);
75 | }
76 |
77 | return $this->withMeta([
78 | 'stats' => $stats,
79 | ]);
80 | }
81 |
82 | public function verified(
83 | bool $verified = true,
84 | ?string $text = null,
85 | ): self {
86 | return $this->withMeta([
87 | 'verified' => $verified,
88 | 'verified_text' => $text,
89 | ]);
90 | }
91 |
92 | public function style(
93 | ?string $extend = null,
94 | ?string $override = null,
95 | ): self {
96 | return $this->withMeta([
97 | 'style_extend' => $extend,
98 | 'style_override' => $override,
99 | ]);
100 | }
101 |
102 | public function component(): string
103 | {
104 | return 'greeter-card';
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/Cards/HtmlCard.php:
--------------------------------------------------------------------------------
1 | withMeta([
19 | 'center' => false,
20 | 'withoutCardStyles' => false,
21 | 'content' => '',
22 | ]);
23 | }
24 |
25 | public function html(
26 | string $htmlContent,
27 | ): self {
28 | return $this->withMeta([
29 | 'content' => $htmlContent,
30 | ]);
31 | }
32 |
33 | public function markdown(
34 | string $markdownContent,
35 | ): self {
36 | $htmlContent = App::make(MarkdownConverter::class)::parse($markdownContent)
37 | ->toHtml();
38 |
39 | return $this->html(
40 | htmlContent: $htmlContent,
41 | );
42 | }
43 |
44 | public function view(
45 | string $view,
46 | array $viewData = [],
47 | ): self {
48 | $htmlContent = view($view, $viewData)
49 | ->render();
50 |
51 | return $this->html(
52 | htmlContent: $htmlContent,
53 | );
54 | }
55 |
56 | public function center(
57 | bool $centerContent = true,
58 | ): self {
59 | return $this->withMeta([
60 | 'center' => $centerContent,
61 | ]);
62 | }
63 |
64 | public function withoutCardStyles(
65 | bool $withoutStyles = true,
66 | ): self {
67 | return $this->withMeta([
68 | 'withoutCardStyles' => $withoutStyles,
69 | ]);
70 | }
71 |
72 | public function component(): string
73 | {
74 | return 'html-card';
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/Cards/LinkableCard.php:
--------------------------------------------------------------------------------
1 | withMeta([
15 | 'url' => '/',
16 | 'title' => 'Linkable Card',
17 | 'subtitle' => '',
18 | 'target' => '_self',
19 | ]);
20 | }
21 |
22 | public function url(
23 | string $url,
24 | ): self {
25 | return $this->withMeta([
26 | 'url' => $url,
27 | ]);
28 | }
29 |
30 | public function title(
31 | string $title,
32 | ): self {
33 | return $this->withMeta([
34 | 'title' => $title,
35 | ]);
36 | }
37 |
38 | public function subtitle(
39 | string $subtitle,
40 | ): self {
41 | return $this->withMeta([
42 | 'subtitle' => $subtitle,
43 | ]);
44 | }
45 |
46 | public function target(
47 | string $target,
48 | ): self {
49 | return $this->withMeta([
50 | 'target' => $target,
51 | ]);
52 | }
53 |
54 | public function component(): string
55 | {
56 | return 'linkable-card';
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/Cards/PercentageCard.php:
--------------------------------------------------------------------------------
1 | withMeta([
17 | 'name' => '',
18 | 'label' => '',
19 | 'count' => 0,
20 | 'total' => 0,
21 | 'percentagePrecision' => 2,
22 | ]);
23 | }
24 |
25 | public function name(
26 | string $text,
27 | ): self {
28 | return $this->withMeta([
29 | 'name' => $text,
30 | ]);
31 | }
32 |
33 | public function label(
34 | string $text,
35 | ): self {
36 | return $this->withMeta([
37 | 'label' => $text,
38 | ]);
39 | }
40 |
41 | public function count(
42 | int $count,
43 | ): self {
44 | return $this->withMeta([
45 | 'count' => $count,
46 | ]);
47 | }
48 |
49 | public function total(
50 | int $count,
51 | ): self {
52 | return $this->withMeta([
53 | 'total' => $count,
54 | ]);
55 | }
56 |
57 | public function percentagePrecision(
58 | int $precision,
59 | ): self {
60 | return $this->withMeta([
61 | 'percentagePrecision' => $precision,
62 | ]);
63 | }
64 |
65 | public function component(): string
66 | {
67 | return 'percentage-card';
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/Cards/ScheduledJobsCard.php:
--------------------------------------------------------------------------------
1 | initPolling();
20 | }
21 |
22 | public function title(
23 | string $title = '',
24 | ): self {
25 | return $this->withMeta([
26 | 'title' => $title,
27 | ]);
28 | }
29 |
30 | public function component(): string
31 | {
32 | return 'scheduled-jobs-card';
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Cards/SslCard.php:
--------------------------------------------------------------------------------
1 | initPolling();
20 | }
21 |
22 | public function domain(
23 | ?string $domain = null
24 | ): self {
25 | $domain = $domain ?: request()->getHost();
26 |
27 | return $this->withMeta([
28 | 'domain' => $domain,
29 | ]);
30 | }
31 |
32 | public function component(): string
33 | {
34 | return 'ssl-card';
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Cards/SystemResourcesCard.php:
--------------------------------------------------------------------------------
1 | initPolling();
20 | }
21 |
22 | public function title(
23 | string $title = '',
24 | ): self {
25 | return $this->withMeta([
26 | 'title' => $title,
27 | ]);
28 | }
29 |
30 | public function component(): string
31 | {
32 | return 'system-resources-card';
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Cards/VersionsCard.php:
--------------------------------------------------------------------------------
1 | initPolling();
20 | }
21 |
22 | public function title(
23 | string $title = '',
24 | ): self {
25 | return $this->withMeta([
26 | 'title' => $title,
27 | ]);
28 | }
29 |
30 | public function component(): string
31 | {
32 | return 'versions-card';
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Cards/WeatherCard.php:
--------------------------------------------------------------------------------
1 | initPolling();
20 | }
21 |
22 | public function city(
23 | string $cityName,
24 | ): self {
25 | return $this->withMeta([
26 | 'city' => $cityName,
27 | ]);
28 | }
29 |
30 | public function lang(
31 | string $lang,
32 | ): self {
33 | return $this->withMeta([
34 | 'lang' => $lang,
35 | ]);
36 | }
37 |
38 | public function component(): string
39 | {
40 | return 'weather-card';
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Cards/WorldClockCard.php:
--------------------------------------------------------------------------------
1 | withMeta([
15 | 'timezones' => $timezones,
16 | ]);
17 | }
18 |
19 | public function title(
20 | string $title = '',
21 | ): self {
22 | return $this->withMeta([
23 | 'title' => $title,
24 | ]);
25 | }
26 |
27 | public function component(): string
28 | {
29 | return 'world-clock-card';
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Http/Controllers/ScheduledJobsController.php:
--------------------------------------------------------------------------------
1 | events())
22 | ->map(function ($event) use ($timezone) {
23 | $nextDueDate = $this->getNextDueDateForEvent(
24 | event: $event,
25 | timezone: $timezone,
26 | );
27 |
28 | preg_match('/artisan.*?\\s(.*)/', $event->command, $matches);
29 |
30 | $command = $matches[1] ?? null;
31 |
32 | return [
33 | 'command' => $command,
34 | 'description' => $event->description,
35 | 'expression' => $event->expression,
36 | 'humanReadableExpression' => $nextDueDate->diffForHumans(),
37 | 'nextRunAt' => $nextDueDate->toIso8601String(),
38 | 'humanReadableNextRun' => $nextDueDate->diffForHumans(),
39 | 'timezone' => $timezone,
40 | 'withoutOverlapping' => $event->withoutOverlapping,
41 | 'onOneServer' => $event->onOneServer,
42 | ];
43 | });
44 |
45 | // $scheduler = app(\Illuminate\Console\Scheduling\Schedule::class);
46 | // $events = $scheduler->events();
47 |
48 | // foreach ($events as $event) {
49 | // preg_match('/artisan.*?\\s(.*)/', $event->command, $matches);
50 | // $command = $matches[1] ?? null; // Extract the command if available
51 |
52 | // $nextDueDate = $event->nextRunDate();
53 | // $timezone = $event->timezone ?: config('app.timezone');
54 |
55 | // $this->info(json_encode([
56 | // 'command' => $command,
57 | // 'description' => $event->description,
58 | // 'expression' => $event->expression,
59 | // 'humanReadableExpression' => $nextDueDate->diffForHumans(),
60 | // 'nextRunAt' => $nextDueDate->toIso8601String(),
61 | // 'humanReadableNextRun' => $nextDueDate->diffForHumans(),
62 | // 'timezone' => $timezone,
63 | // 'withoutOverlapping' => $event->withoutOverlapping,
64 | // 'onOneServer' => $event->onOneServer,
65 | // ]));
66 | // }
67 |
68 | return response()->json($jobs);
69 | }
70 |
71 | private function getNextDueDateForEvent(
72 | Event $event,
73 | DateTimeZone $timezone
74 | ): Carbon {
75 | return Carbon::instance(
76 | date: (new CronExpression($event->expression))
77 | ->getNextRunDate(
78 | currentTime: Carbon::now()
79 | ->setTimezone($event->timezone),
80 | )
81 | ->setTimezone($timezone)
82 | );
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/Http/Controllers/SslController.php:
--------------------------------------------------------------------------------
1 | domain,
17 | );
18 |
19 | return response()->json([
20 | 'issuer' => $certificate->getIssuer(),
21 | 'is_valid' => $certificate->isValid(),
22 | 'expiration_date' => $certificate->expirationDate()->diffForHumans(),
23 | 'expiration_date_in_days' => $certificate->expirationDate()->diffInDays(),
24 | ]);
25 | } catch (Exception $e) {
26 | return response()->json([
27 | 'error' => $e->getMessage(),
28 | ], 404);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Http/Controllers/SystemResourcesController.php:
--------------------------------------------------------------------------------
1 | json([
24 | 'disk_space' => [
25 | 'total' => formatMemory(
26 | size: $diskTotal,
27 | level: 0,
28 | asArray: true,
29 | base: 1024,
30 | ),
31 | 'used' => formatMemory(
32 | size: $diskUsed,
33 | level: 0,
34 | asArray: true,
35 | base: 1024,
36 | ),
37 | 'use_percentage' => round($disk, 1),
38 | ],
39 | 'memory_usage' => [
40 | 'total' => formatMemory(
41 | size: $ramTotal * 1024,
42 | level: 0,
43 | asArray: true,
44 | base: 1024,
45 | ),
46 | 'used' => formatMemory(
47 | size: $ramUsed * 1024,
48 | level: 0,
49 | asArray: true,
50 | base: 1024,
51 | ),
52 | 'use_percentage' => round($ram, 1),
53 | ],
54 | 'cpu_usage' => [
55 | 'name' => $cpuName,
56 | 'use_percentage' => $cpu,
57 | ],
58 | ]);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/Http/Controllers/VersionsController.php:
--------------------------------------------------------------------------------
1 | php_uname('s') . ' (' . php_uname('r') . ' - ' . php_uname('v') . ')',
14 | 'php' => PHP_VERSION,
15 | 'database' => $this->getDatabase(),
16 | 'laravel' => app()->version(),
17 | 'nova' => Nova::version(),
18 | ];
19 | }
20 |
21 | private function getDatabase(): string
22 | {
23 | $knownDatabases = [
24 | 'sqlite',
25 | 'mysql',
26 | 'pgsql',
27 | 'sqlsrv',
28 | ];
29 |
30 | if (!in_array(config('database.default'), $knownDatabases)) {
31 | return 'Unkown';
32 | }
33 |
34 | $results = DB::select('select version()');
35 |
36 | return config('database.default') . ' ' . ((array) $results[0])['version()'];
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Http/Controllers/WeatherController.php:
--------------------------------------------------------------------------------
1 | input('q', 'Kiev'),
17 | $request->input('units', 'metric'),
18 | $request->input('lang', config('app.locale')),
19 | ]),
20 | ttl: 10,
21 | callback: fn () => Http::get(
22 | url: 'https://api.openweathermap.org/data/2.5/weather',
23 | query: [
24 | 'q' => $request->input('q', 'Kiev'),
25 | 'appid' => config('nova-cards.open_weather_api_key'),
26 | 'units' => $request->input('units', 'metric'),
27 | 'lang' => $request->input('lang', config('app.locale')),
28 | ],
29 | )->json(),
30 | );
31 |
32 | return response()->json($data);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Http/Controllers/WorldClockController.php:
--------------------------------------------------------------------------------
1 | input('timezones', []) as $timezone) {
16 | $time = Carbon::now($timezone);
17 | $night = (int) $time->format('H') > 17;
18 | $name = explode('/', $time->getTimezone()->getName())[1];
19 | $name = str_replace('_', ' ', $name);
20 |
21 | $times[] = [
22 | 'name' => __(ucwords($name)),
23 | 'time' => $time->format($request->input('timeFormat', 'H:i:s')),
24 | 'night' => $night,
25 | ];
26 | }
27 |
28 | return $times;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/LaravelMarkdownConverter.php:
--------------------------------------------------------------------------------
1 | config();
15 |
16 | $this->app->booted(function (): void {
17 | $this->routes();
18 | });
19 |
20 | Nova::serving(function (ServingNova $event): void {
21 | Nova::script('nova-cards', __DIR__ . '/../dist/js/entry.js');
22 | Nova::style('nova-cards', __DIR__ . '/../dist/css/card.css');
23 | });
24 | }
25 |
26 | public function register(): void
27 | {
28 | $this->app->singleton(MarkdownConverter::class, LaravelMarkdownConverter::class);
29 | }
30 |
31 | protected function routes(): void
32 | {
33 | if ($this->app->routesAreCached()) {
34 | return;
35 | }
36 |
37 | Route::middleware(['nova'])
38 | ->prefix('nova-vendor/stepanenko3/nova-cards')
39 | ->group(__DIR__ . '/../routes/api.php');
40 | }
41 |
42 | private function config(): void
43 | {
44 | if ($this->app->runningInConsole()) {
45 | // Publish config
46 | $this->publishes([
47 | __DIR__ . '/../config/' => config_path(),
48 | ], 'config');
49 | }
50 |
51 | $this->mergeConfigFrom(
52 | __DIR__ . '/../config/nova-cards.php',
53 | 'nova-cards'
54 | );
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Traits/PollingTrait.php:
--------------------------------------------------------------------------------
1 | withMeta([
10 | 'polling' => true,
11 | 'pollingStart' => false,
12 | 'pollingTime' => 5000,
13 | ]);
14 | }
15 |
16 | public function startPolling(): static
17 | {
18 | return $this->withMeta([
19 | 'pollingStart' => true,
20 | ]);
21 | }
22 |
23 | public function pollingTime(
24 | int $ms = 1000,
25 | ): static {
26 | return $this->withMeta([
27 | 'pollingTime' => $ms,
28 | ]);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: ['./resources/js/**/*.{vue,js,ts,jsx,tsx}'],
4 | theme: {
5 | extend: {},
6 | },
7 | important: '.nova-cards',
8 | plugins: [],
9 | darkMode: 'class'
10 | };
11 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import vue from "@vitejs/plugin-vue";
2 | import { resolve } from "path";
3 | import { defineConfig } from "vite";
4 |
5 | export default defineConfig({
6 | plugins: [vue()],
7 |
8 | define: {
9 | "process.env": process.env, // Vite ditched process.env, so we need to pass it in
10 | },
11 |
12 | build: {
13 | outDir: resolve(__dirname, "dist"),
14 | emptyOutDir: true,
15 | target: "ES2022",
16 | minify: true,
17 | manifest: true,
18 | lib: {
19 | entry: resolve(__dirname, "resources/js/entry.js"),
20 | name: "cards",
21 | formats: ["umd"],
22 | fileName: () => "js/entry.js",
23 | },
24 | rollupOptions: {
25 | input: resolve(__dirname, "resources/js/entry.js"),
26 | external: ["vue", "Nova", "LaravelNova"],
27 | output: {
28 | globals: {
29 | vue: "Vue",
30 | nova: "Nova",
31 | "laravel-nova": "LaravelNova",
32 | },
33 | assetFileNames: "css/card.css",
34 | },
35 | },
36 | },
37 |
38 | optimizeDeps: {
39 | include: ["vue", "@inertiajs/inertia", "@inertiajs/inertia-vue3", "axios"],
40 | },
41 | });
42 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@babel/helper-string-parser@^7.25.9":
6 | version "7.25.9"
7 | resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c"
8 | integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==
9 |
10 | "@babel/helper-validator-identifier@^7.25.9":
11 | version "7.25.9"
12 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7"
13 | integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==
14 |
15 | "@babel/parser@^7.25.3":
16 | version "7.26.3"
17 | resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.3.tgz#8c51c5db6ddf08134af1ddbacf16aaab48bac234"
18 | integrity sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==
19 | dependencies:
20 | "@babel/types" "^7.26.3"
21 |
22 | "@babel/types@^7.26.3":
23 | version "7.26.3"
24 | resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.3.tgz#37e79830f04c2b5687acc77db97fbc75fb81f3c0"
25 | integrity sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==
26 | dependencies:
27 | "@babel/helper-string-parser" "^7.25.9"
28 | "@babel/helper-validator-identifier" "^7.25.9"
29 |
30 | "@esbuild/aix-ppc64@0.25.0":
31 | version "0.25.0"
32 | resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz#499600c5e1757a524990d5d92601f0ac3ce87f64"
33 | integrity sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==
34 |
35 | "@esbuild/android-arm64@0.25.0":
36 | version "0.25.0"
37 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz#b9b8231561a1dfb94eb31f4ee056b92a985c324f"
38 | integrity sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==
39 |
40 | "@esbuild/android-arm@0.25.0":
41 | version "0.25.0"
42 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.0.tgz#ca6e7888942505f13e88ac9f5f7d2a72f9facd2b"
43 | integrity sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==
44 |
45 | "@esbuild/android-x64@0.25.0":
46 | version "0.25.0"
47 | resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.0.tgz#e765ea753bac442dfc9cb53652ce8bd39d33e163"
48 | integrity sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==
49 |
50 | "@esbuild/darwin-arm64@0.25.0":
51 | version "0.25.0"
52 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz#fa394164b0d89d4fdc3a8a21989af70ef579fa2c"
53 | integrity sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==
54 |
55 | "@esbuild/darwin-x64@0.25.0":
56 | version "0.25.0"
57 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz#91979d98d30ba6e7d69b22c617cc82bdad60e47a"
58 | integrity sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==
59 |
60 | "@esbuild/freebsd-arm64@0.25.0":
61 | version "0.25.0"
62 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz#b97e97073310736b430a07b099d837084b85e9ce"
63 | integrity sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==
64 |
65 | "@esbuild/freebsd-x64@0.25.0":
66 | version "0.25.0"
67 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz#f3b694d0da61d9910ec7deff794d444cfbf3b6e7"
68 | integrity sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==
69 |
70 | "@esbuild/linux-arm64@0.25.0":
71 | version "0.25.0"
72 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz#f921f699f162f332036d5657cad9036f7a993f73"
73 | integrity sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==
74 |
75 | "@esbuild/linux-arm@0.25.0":
76 | version "0.25.0"
77 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz#cc49305b3c6da317c900688995a4050e6cc91ca3"
78 | integrity sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==
79 |
80 | "@esbuild/linux-ia32@0.25.0":
81 | version "0.25.0"
82 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz#3e0736fcfab16cff042dec806247e2c76e109e19"
83 | integrity sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==
84 |
85 | "@esbuild/linux-loong64@0.25.0":
86 | version "0.25.0"
87 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz#ea2bf730883cddb9dfb85124232b5a875b8020c7"
88 | integrity sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==
89 |
90 | "@esbuild/linux-mips64el@0.25.0":
91 | version "0.25.0"
92 | resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz#4cababb14eede09248980a2d2d8b966464294ff1"
93 | integrity sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==
94 |
95 | "@esbuild/linux-ppc64@0.25.0":
96 | version "0.25.0"
97 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz#8860a4609914c065373a77242e985179658e1951"
98 | integrity sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==
99 |
100 | "@esbuild/linux-riscv64@0.25.0":
101 | version "0.25.0"
102 | resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz#baf26e20bb2d38cfb86ee282dff840c04f4ed987"
103 | integrity sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==
104 |
105 | "@esbuild/linux-s390x@0.25.0":
106 | version "0.25.0"
107 | resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz#8323afc0d6cb1b6dc6e9fd21efd9e1542c3640a4"
108 | integrity sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==
109 |
110 | "@esbuild/linux-x64@0.25.0":
111 | version "0.25.0"
112 | resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz#08fcf60cb400ed2382e9f8e0f5590bac8810469a"
113 | integrity sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==
114 |
115 | "@esbuild/netbsd-arm64@0.25.0":
116 | version "0.25.0"
117 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz#935c6c74e20f7224918fbe2e6c6fe865b6c6ea5b"
118 | integrity sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==
119 |
120 | "@esbuild/netbsd-x64@0.25.0":
121 | version "0.25.0"
122 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz#414677cef66d16c5a4d210751eb2881bb9c1b62b"
123 | integrity sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==
124 |
125 | "@esbuild/openbsd-arm64@0.25.0":
126 | version "0.25.0"
127 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz#8fd55a4d08d25cdc572844f13c88d678c84d13f7"
128 | integrity sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==
129 |
130 | "@esbuild/openbsd-x64@0.25.0":
131 | version "0.25.0"
132 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz#0c48ddb1494bbc2d6bcbaa1429a7f465fa1dedde"
133 | integrity sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==
134 |
135 | "@esbuild/sunos-x64@0.25.0":
136 | version "0.25.0"
137 | resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz#86ff9075d77962b60dd26203d7352f92684c8c92"
138 | integrity sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==
139 |
140 | "@esbuild/win32-arm64@0.25.0":
141 | version "0.25.0"
142 | resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz#849c62327c3229467f5b5cd681bf50588442e96c"
143 | integrity sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==
144 |
145 | "@esbuild/win32-ia32@0.25.0":
146 | version "0.25.0"
147 | resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz#f62eb480cd7cca088cb65bb46a6db25b725dc079"
148 | integrity sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==
149 |
150 | "@esbuild/win32-x64@0.25.0":
151 | version "0.25.0"
152 | resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz#c8e119a30a7c8d60b9d2e22d2073722dde3b710b"
153 | integrity sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==
154 |
155 | "@inertiajs/inertia-vue3@^0.6.0":
156 | version "0.6.0"
157 | resolved "https://registry.npmjs.org/@inertiajs/inertia-vue3/-/inertia-vue3-0.6.0.tgz"
158 | integrity sha512-qhPBtd/G0VS7vVVbYw1rrqKB6JqRusxqt+5ec2GLmK6t7fTlBBnZ3KsakmGZLSM1m1OGkNcfn4ifmCk3zfA8RQ==
159 | dependencies:
160 | lodash.clonedeep "^4.5.0"
161 | lodash.isequal "^4.5.0"
162 |
163 | "@inertiajs/inertia@^0.11.1":
164 | version "0.11.1"
165 | resolved "https://registry.npmjs.org/@inertiajs/inertia/-/inertia-0.11.1.tgz"
166 | integrity sha512-btmV53c54oW4Z9XF0YyTdIUnM7ue0ONy3/KJOz6J1C5CYIwimiKfDMpz8ZbGJuxS+SPdOlNsqj2ZhlHslpJRZg==
167 | dependencies:
168 | axios "^0.21.1"
169 | deepmerge "^4.0.0"
170 | qs "^6.9.0"
171 |
172 | "@jridgewell/sourcemap-codec@^1.5.0":
173 | version "1.5.0"
174 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
175 | integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
176 |
177 | "@rollup/rollup-android-arm-eabi@4.34.8":
178 | version "4.34.8"
179 | resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz#731df27dfdb77189547bcef96ada7bf166bbb2fb"
180 | integrity sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==
181 |
182 | "@rollup/rollup-android-arm64@4.34.8":
183 | version "4.34.8"
184 | resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz#4bea6db78e1f6927405df7fe0faf2f5095e01343"
185 | integrity sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==
186 |
187 | "@rollup/rollup-darwin-arm64@4.34.8":
188 | version "4.34.8"
189 | resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz#a7aab77d44be3c44a20f946e10160f84e5450e7f"
190 | integrity sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==
191 |
192 | "@rollup/rollup-darwin-x64@4.34.8":
193 | version "4.34.8"
194 | resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz#c572c024b57ee8ddd1b0851703ace9eb6cc0dd82"
195 | integrity sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==
196 |
197 | "@rollup/rollup-freebsd-arm64@4.34.8":
198 | version "4.34.8"
199 | resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz#cf74f8113b5a83098a5c026c165742277cbfb88b"
200 | integrity sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==
201 |
202 | "@rollup/rollup-freebsd-x64@4.34.8":
203 | version "4.34.8"
204 | resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz#39561f3a2f201a4ad6a01425b1ff5928154ecd7c"
205 | integrity sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==
206 |
207 | "@rollup/rollup-linux-arm-gnueabihf@4.34.8":
208 | version "4.34.8"
209 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz#980d6061e373bfdaeb67925c46d2f8f9b3de537f"
210 | integrity sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==
211 |
212 | "@rollup/rollup-linux-arm-musleabihf@4.34.8":
213 | version "4.34.8"
214 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz#f91a90f30dc00d5a64ac2d9bbedc829cd3cfaa78"
215 | integrity sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==
216 |
217 | "@rollup/rollup-linux-arm64-gnu@4.34.8":
218 | version "4.34.8"
219 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz#fac700fa5c38bc13a0d5d34463133093da4c92a0"
220 | integrity sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==
221 |
222 | "@rollup/rollup-linux-arm64-musl@4.34.8":
223 | version "4.34.8"
224 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz#f50ecccf8c78841ff6df1706bc4782d7f62bf9c3"
225 | integrity sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==
226 |
227 | "@rollup/rollup-linux-loongarch64-gnu@4.34.8":
228 | version "4.34.8"
229 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz#5869dc0b28242da6553e2b52af41374f4038cd6e"
230 | integrity sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==
231 |
232 | "@rollup/rollup-linux-powerpc64le-gnu@4.34.8":
233 | version "4.34.8"
234 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz#5cdd9f851ce1bea33d6844a69f9574de335f20b1"
235 | integrity sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==
236 |
237 | "@rollup/rollup-linux-riscv64-gnu@4.34.8":
238 | version "4.34.8"
239 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz#ef5dc37f4388f5253f0def43e1440ec012af204d"
240 | integrity sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==
241 |
242 | "@rollup/rollup-linux-s390x-gnu@4.34.8":
243 | version "4.34.8"
244 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz#7dbc3ccbcbcfb3e65be74538dfb6e8dd16178fde"
245 | integrity sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==
246 |
247 | "@rollup/rollup-linux-x64-gnu@4.34.8":
248 | version "4.34.8"
249 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz#5783fc0adcab7dc069692056e8ca8d83709855ce"
250 | integrity sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==
251 |
252 | "@rollup/rollup-linux-x64-musl@4.34.8":
253 | version "4.34.8"
254 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz#00b6c29b298197a384e3c659910b47943003a678"
255 | integrity sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==
256 |
257 | "@rollup/rollup-win32-arm64-msvc@4.34.8":
258 | version "4.34.8"
259 | resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz#cbfee01f1fe73791c35191a05397838520ca3cdd"
260 | integrity sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==
261 |
262 | "@rollup/rollup-win32-ia32-msvc@4.34.8":
263 | version "4.34.8"
264 | resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz#95cdbdff48fe6c948abcf6a1d500b2bd5ce33f62"
265 | integrity sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==
266 |
267 | "@rollup/rollup-win32-x64-msvc@4.34.8":
268 | version "4.34.8"
269 | resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz#4cdb2cfae69cdb7b1a3cc58778e820408075e928"
270 | integrity sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==
271 |
272 | "@types/estree@1.0.6":
273 | version "1.0.6"
274 | resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
275 | integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
276 |
277 | "@vitejs/plugin-vue@^5.2.1":
278 | version "5.2.1"
279 | resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.2.1.tgz#d1491f678ee3af899f7ae57d9c21dc52a65c7133"
280 | integrity sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==
281 |
282 | "@vue/compiler-core@3.5.13":
283 | version "3.5.13"
284 | resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.13.tgz#b0ae6c4347f60c03e849a05d34e5bf747c9bda05"
285 | integrity sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==
286 | dependencies:
287 | "@babel/parser" "^7.25.3"
288 | "@vue/shared" "3.5.13"
289 | entities "^4.5.0"
290 | estree-walker "^2.0.2"
291 | source-map-js "^1.2.0"
292 |
293 | "@vue/compiler-dom@3.5.13":
294 | version "3.5.13"
295 | resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz#bb1b8758dbc542b3658dda973b98a1c9311a8a58"
296 | integrity sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==
297 | dependencies:
298 | "@vue/compiler-core" "3.5.13"
299 | "@vue/shared" "3.5.13"
300 |
301 | "@vue/compiler-sfc@^3.5.13":
302 | version "3.5.13"
303 | resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz#461f8bd343b5c06fac4189c4fef8af32dea82b46"
304 | integrity sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==
305 | dependencies:
306 | "@babel/parser" "^7.25.3"
307 | "@vue/compiler-core" "3.5.13"
308 | "@vue/compiler-dom" "3.5.13"
309 | "@vue/compiler-ssr" "3.5.13"
310 | "@vue/shared" "3.5.13"
311 | estree-walker "^2.0.2"
312 | magic-string "^0.30.11"
313 | postcss "^8.4.48"
314 | source-map-js "^1.2.0"
315 |
316 | "@vue/compiler-ssr@3.5.13":
317 | version "3.5.13"
318 | resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz#e771adcca6d3d000f91a4277c972a996d07f43ba"
319 | integrity sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==
320 | dependencies:
321 | "@vue/compiler-dom" "3.5.13"
322 | "@vue/shared" "3.5.13"
323 |
324 | "@vue/shared@3.5.13":
325 | version "3.5.13"
326 | resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.13.tgz#87b309a6379c22b926e696893237826f64339b6f"
327 | integrity sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==
328 |
329 | autoprefixer@^10.4.21:
330 | version "10.4.21"
331 | resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.21.tgz#77189468e7a8ad1d9a37fbc08efc9f480cf0a95d"
332 | integrity sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==
333 | dependencies:
334 | browserslist "^4.24.4"
335 | caniuse-lite "^1.0.30001702"
336 | fraction.js "^4.3.7"
337 | normalize-range "^0.1.2"
338 | picocolors "^1.1.1"
339 | postcss-value-parser "^4.2.0"
340 |
341 | axios@^0.21.1:
342 | version "0.21.4"
343 | resolved "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz"
344 | integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==
345 | dependencies:
346 | follow-redirects "^1.14.0"
347 |
348 | browserslist@^4.24.4:
349 | version "4.24.4"
350 | resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.4.tgz#c6b2865a3f08bcb860a0e827389003b9fe686e4b"
351 | integrity sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==
352 | dependencies:
353 | caniuse-lite "^1.0.30001688"
354 | electron-to-chromium "^1.5.73"
355 | node-releases "^2.0.19"
356 | update-browserslist-db "^1.1.1"
357 |
358 | call-bind@^1.0.0:
359 | version "1.0.2"
360 | resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz"
361 | integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
362 | dependencies:
363 | function-bind "^1.1.1"
364 | get-intrinsic "^1.0.2"
365 |
366 | caniuse-lite@^1.0.30001688, caniuse-lite@^1.0.30001702:
367 | version "1.0.30001703"
368 | resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001703.tgz#977cb4920598c158f491ecf4f4f2cfed9e354718"
369 | integrity sha512-kRlAGTRWgPsOj7oARC9m1okJEXdL/8fekFVcxA8Hl7GH4r/sN4OJn/i6Flde373T50KS7Y37oFbMwlE8+F42kQ==
370 |
371 | deepmerge@^4.0.0:
372 | version "4.3.1"
373 | resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz"
374 | integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
375 |
376 | electron-to-chromium@^1.5.73:
377 | version "1.5.73"
378 | resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.73.tgz#f32956ce40947fa3c8606726a96cd8fb5bb5f720"
379 | integrity sha512-8wGNxG9tAG5KhGd3eeA0o6ixhiNdgr0DcHWm85XPCphwZgD1lIEoi6t3VERayWao7SF7AAZTw6oARGJeVjH8Kg==
380 |
381 | entities@^4.5.0:
382 | version "4.5.0"
383 | resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz"
384 | integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
385 |
386 | esbuild@^0.25.0:
387 | version "0.25.0"
388 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.0.tgz#0de1787a77206c5a79eeb634a623d39b5006ce92"
389 | integrity sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==
390 | optionalDependencies:
391 | "@esbuild/aix-ppc64" "0.25.0"
392 | "@esbuild/android-arm" "0.25.0"
393 | "@esbuild/android-arm64" "0.25.0"
394 | "@esbuild/android-x64" "0.25.0"
395 | "@esbuild/darwin-arm64" "0.25.0"
396 | "@esbuild/darwin-x64" "0.25.0"
397 | "@esbuild/freebsd-arm64" "0.25.0"
398 | "@esbuild/freebsd-x64" "0.25.0"
399 | "@esbuild/linux-arm" "0.25.0"
400 | "@esbuild/linux-arm64" "0.25.0"
401 | "@esbuild/linux-ia32" "0.25.0"
402 | "@esbuild/linux-loong64" "0.25.0"
403 | "@esbuild/linux-mips64el" "0.25.0"
404 | "@esbuild/linux-ppc64" "0.25.0"
405 | "@esbuild/linux-riscv64" "0.25.0"
406 | "@esbuild/linux-s390x" "0.25.0"
407 | "@esbuild/linux-x64" "0.25.0"
408 | "@esbuild/netbsd-arm64" "0.25.0"
409 | "@esbuild/netbsd-x64" "0.25.0"
410 | "@esbuild/openbsd-arm64" "0.25.0"
411 | "@esbuild/openbsd-x64" "0.25.0"
412 | "@esbuild/sunos-x64" "0.25.0"
413 | "@esbuild/win32-arm64" "0.25.0"
414 | "@esbuild/win32-ia32" "0.25.0"
415 | "@esbuild/win32-x64" "0.25.0"
416 |
417 | escalade@^3.2.0:
418 | version "3.2.0"
419 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"
420 | integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
421 |
422 | estree-walker@^2.0.2:
423 | version "2.0.2"
424 | resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz"
425 | integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
426 |
427 | follow-redirects@^1.14.0:
428 | version "1.15.0"
429 | resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz"
430 | integrity sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==
431 |
432 | fraction.js@^4.3.7:
433 | version "4.3.7"
434 | resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz"
435 | integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==
436 |
437 | fsevents@~2.3.2, fsevents@~2.3.3:
438 | version "2.3.3"
439 | resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz"
440 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
441 |
442 | function-bind@^1.1.1:
443 | version "1.1.2"
444 | resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"
445 | integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
446 |
447 | get-intrinsic@^1.0.2:
448 | version "1.1.1"
449 | resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz"
450 | integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==
451 | dependencies:
452 | function-bind "^1.1.1"
453 | has "^1.0.3"
454 | has-symbols "^1.0.1"
455 |
456 | has-symbols@^1.0.1:
457 | version "1.0.3"
458 | resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz"
459 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
460 |
461 | has@^1.0.3:
462 | version "1.0.3"
463 | resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz"
464 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
465 | dependencies:
466 | function-bind "^1.1.1"
467 |
468 | lodash.clonedeep@^4.5.0:
469 | version "4.5.0"
470 | resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz"
471 | integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==
472 |
473 | lodash.isequal@^4.5.0:
474 | version "4.5.0"
475 | resolved "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz"
476 | integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==
477 |
478 | magic-string@^0.30.11:
479 | version "0.30.17"
480 | resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453"
481 | integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==
482 | dependencies:
483 | "@jridgewell/sourcemap-codec" "^1.5.0"
484 |
485 | nanoid@^3.3.8:
486 | version "3.3.8"
487 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf"
488 | integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==
489 |
490 | node-releases@^2.0.19:
491 | version "2.0.19"
492 | resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314"
493 | integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==
494 |
495 | normalize-range@^0.1.2:
496 | version "0.1.2"
497 | resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz"
498 | integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=
499 |
500 | object-inspect@^1.9.0:
501 | version "1.12.0"
502 | resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz"
503 | integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==
504 |
505 | picocolors@^1.1.0, picocolors@^1.1.1:
506 | version "1.1.1"
507 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
508 | integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
509 |
510 | postcss-value-parser@^4.2.0:
511 | version "4.2.0"
512 | resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
513 | integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
514 |
515 | postcss@^8.4.48, postcss@^8.4.49, postcss@^8.5.3:
516 | version "8.5.3"
517 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.3.tgz#1463b6f1c7fb16fe258736cba29a2de35237eafb"
518 | integrity sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==
519 | dependencies:
520 | nanoid "^3.3.8"
521 | picocolors "^1.1.1"
522 | source-map-js "^1.2.1"
523 |
524 | qs@^6.9.0:
525 | version "6.10.3"
526 | resolved "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz"
527 | integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==
528 | dependencies:
529 | side-channel "^1.0.4"
530 |
531 | rollup@^4.30.1:
532 | version "4.34.8"
533 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.34.8.tgz#e859c1a51d899aba9bcf451d4eed1d11fb8e2a6e"
534 | integrity sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==
535 | dependencies:
536 | "@types/estree" "1.0.6"
537 | optionalDependencies:
538 | "@rollup/rollup-android-arm-eabi" "4.34.8"
539 | "@rollup/rollup-android-arm64" "4.34.8"
540 | "@rollup/rollup-darwin-arm64" "4.34.8"
541 | "@rollup/rollup-darwin-x64" "4.34.8"
542 | "@rollup/rollup-freebsd-arm64" "4.34.8"
543 | "@rollup/rollup-freebsd-x64" "4.34.8"
544 | "@rollup/rollup-linux-arm-gnueabihf" "4.34.8"
545 | "@rollup/rollup-linux-arm-musleabihf" "4.34.8"
546 | "@rollup/rollup-linux-arm64-gnu" "4.34.8"
547 | "@rollup/rollup-linux-arm64-musl" "4.34.8"
548 | "@rollup/rollup-linux-loongarch64-gnu" "4.34.8"
549 | "@rollup/rollup-linux-powerpc64le-gnu" "4.34.8"
550 | "@rollup/rollup-linux-riscv64-gnu" "4.34.8"
551 | "@rollup/rollup-linux-s390x-gnu" "4.34.8"
552 | "@rollup/rollup-linux-x64-gnu" "4.34.8"
553 | "@rollup/rollup-linux-x64-musl" "4.34.8"
554 | "@rollup/rollup-win32-arm64-msvc" "4.34.8"
555 | "@rollup/rollup-win32-ia32-msvc" "4.34.8"
556 | "@rollup/rollup-win32-x64-msvc" "4.34.8"
557 | fsevents "~2.3.2"
558 |
559 | side-channel@^1.0.4:
560 | version "1.0.4"
561 | resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz"
562 | integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
563 | dependencies:
564 | call-bind "^1.0.0"
565 | get-intrinsic "^1.0.2"
566 | object-inspect "^1.9.0"
567 |
568 | source-map-js@^1.2.0, source-map-js@^1.2.1:
569 | version "1.2.1"
570 | resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
571 | integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
572 |
573 | tailwindcss@^4.0.13:
574 | version "4.0.13"
575 | resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-4.0.13.tgz#093935db2e4b80d245386f69da580528ac5b1b3c"
576 | integrity sha512-gbvFrB0fOsTv/OugXWi2PtflJ4S6/ctu6Mmn3bCftmLY/6xRsQVEJPgIIpABwpZ52DpONkCA3bEj5b54MHxF2Q==
577 |
578 | update-browserslist-db@^1.1.1:
579 | version "1.1.1"
580 | resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5"
581 | integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==
582 | dependencies:
583 | escalade "^3.2.0"
584 | picocolors "^1.1.0"
585 |
586 | vite@^6.2.1:
587 | version "6.2.1"
588 | resolved "https://registry.yarnpkg.com/vite/-/vite-6.2.1.tgz#ae865d4bb93a11844be1bc647c8b2dd1856ea180"
589 | integrity sha512-n2GnqDb6XPhlt9B8olZPrgMD/es/Nd1RdChF6CBD/fHW6pUyUTt2sQW2fPRX5GiD9XEa6+8A6A4f2vT6pSsE7Q==
590 | dependencies:
591 | esbuild "^0.25.0"
592 | postcss "^8.5.3"
593 | rollup "^4.30.1"
594 | optionalDependencies:
595 | fsevents "~2.3.3"
596 |
--------------------------------------------------------------------------------