diff --git a/app/Controllers/EpisodeController.php b/app/Controllers/EpisodeController.php index c484ca1416d0b2f5091d81466526809d2966fa34..e51ba7b75696a0958e3776ba569db63b8ec5dadc 100644 --- a/app/Controllers/EpisodeController.php +++ b/app/Controllers/EpisodeController.php @@ -103,7 +103,7 @@ class EpisodeController extends BaseController public function embeddablePlayer(string $theme = 'light-transparent'): string { - header('Content-Security-Policy: frame-ancestors https://* http://*'); + header('Content-Security-Policy: frame-ancestors http://*:* https://*:*'); // Prevent analytics hit when authenticated if (! can_user_interact()) { @@ -122,12 +122,13 @@ class EpisodeController extends BaseController $cacheName = "page_podcast#{$this->podcast->id}_episode#{$this->episode->id}_embeddable_player_{$theme}_{$locale}"; if (! ($cachedView = cache($cacheName))) { - $theme = EpisodeModel::$themes[$theme]; + $themeData = EpisodeModel::$themes[$theme]; $data = [ 'podcast' => $this->podcast, 'episode' => $this->episode, 'theme' => $theme, + 'themeData' => $themeData, ]; $secondsToNextUnpublishedEpisode = (new EpisodeModel())->getSecondsToNextUnpublishedEpisode( @@ -159,9 +160,9 @@ class EpisodeController extends BaseController 'html' => '<iframe src="' . $this->episode->embeddable_player_url . - '" width="100%" height="200" frameborder="0" scrolling="no"></iframe>', + '" width="100%" height="144" frameborder="0" scrolling="no"></iframe>', 'width' => 600, - 'height' => 200, + 'height' => 144, 'thumbnail_url' => $this->episode->image->large_url, 'thumbnail_width' => config('Images') ->largeSize, @@ -189,11 +190,11 @@ class EpisodeController extends BaseController htmlentities( '<iframe src="' . $this->episode->embeddable_player_url . - '" width="100%" height="200" frameborder="0" scrolling="no"></iframe>', + '" width="100%" height="144" frameborder="0" scrolling="no"></iframe>', ), ); $oembed->addChild('width', '600'); - $oembed->addChild('height', '200'); + $oembed->addChild('height', '144'); return $this->response->setXML((string) $oembed); } diff --git a/app/Helpers/components_helper.php b/app/Helpers/components_helper.php index 90e33641f77cb149eb7918b316c513592afc9de8..58f80a3a7a258009bde7c4d14da1e05e2521da4d 100644 --- a/app/Helpers/components_helper.php +++ b/app/Helpers/components_helper.php @@ -185,7 +185,7 @@ if (! function_exists('data_table')) { * @param mixed[] $data data to loop through and display in rows * @param mixed ...$rest Any other argument to pass to the `cell` function */ - function data_table(array $columns, array $data = [], ...$rest): string + function data_table(array $columns, array $data = [], string $class = '', ...$rest): string { $table = new Table(); @@ -199,8 +199,8 @@ if (! function_exists('data_table')) { 'cell_start' => '<td class="px-4 py-2">', 'cell_alt_start' => '<td class="px-4 py-2">', - 'row_start' => '<tr class="bg-gray-100 hover:bg-pine-100">', - 'row_alt_start' => '<tr class="hover:bg-pine-100">', + 'row_start' => '<tr class="bg-gray-50 hover:bg-pine-50">', + 'row_alt_start' => '<tr class="hover:bg-pine-50">', ]; $table->setTemplate($template); @@ -225,7 +225,7 @@ if (! function_exists('data_table')) { return lang('Common.no_data'); } - return '<div class="overflow-x-auto bg-white rounded-lg shadow" >' . + return '<div class="overflow-x-auto bg-white rounded-lg shadow ' . $class . '" >' . $table->generate() . '</div>'; } @@ -241,28 +241,16 @@ if (! function_exists('publication_pill')) { */ function publication_pill(?Time $publicationDate, string $publicationStatus, string $customClass = ''): string { - if ($publicationDate === null) { - return ''; - } - - $class = - $publicationStatus === 'published' - ? 'text-pine-500 border-pine-500' - : 'text-red-600 border-red-600'; - - $langOptions = [ - '<time pubdate datetime="' . - $publicationDate->format(DateTime::ATOM) . - '" title="' . - $publicationDate . - '">' . - lang('Common.mediumDate', [$publicationDate]) . - '</time>', - ]; + $class = match ($publicationStatus) { + 'published' => 'text-pine-600 border-pine-600 bg-pine-50', + 'scheduled' => 'text-red-600 border-red-600 bg-red-50', + 'not_published' => 'text-gray-600 border-gray-600 bg-gray-50', + default => 'text-gray-600 border-gray-600 bg-gray-50', + }; - $label = lang('Episode.publication_status.' . $publicationStatus, $langOptions); + $label = lang('Episode.publication_status.' . $publicationStatus); - return '<span class="px-1 font-semibold border ' . + return '<span ' . ($publicationDate === null ? '' : 'title="' . $publicationDate . '"') . ' class="px-1 font-semibold border rounded ' . $class . ' ' . $customClass . @@ -354,7 +342,7 @@ if (! function_exists('episode_numbering')) { } if ($isAbbr) { - return '<abbr class="' . + return '<abbr class="tracking-wider ' . $class . '" title="' . lang($transKey, $args) . @@ -450,4 +438,79 @@ if (! function_exists('person_list')) { } } + + // ------------------------------------------------------------------------ + +if (! function_exists('play_episode_button')) { + /** + * Returns play episode button + */ + function play_episode_button( + string $episodeId, + string $episodeThumbnail, + string $episodeTitle, + string $podcastTitle, + string $source, + string $mediaType, + string $class = '' + ): string { + $playLabel = lang('Common.play_episode_button.play'); + $playingLabel = lang('Common.play_episode_button.playing'); + + return <<<CODE_SAMPLE + <play-episode-button + class="${class}" + id="${episodeId}" + imageSrc=${episodeThumbnail} + title="${episodeTitle}" + podcast="${podcastTitle}" + src="${source}" + mediaType="${mediaType}" + playLabel="Play" + playingLabel="Playing" + ></play-episode-button> + CODE_SAMPLE; + } +} + +// ------------------------------------------------------------------------ + + +if (! function_exists('audio_player')) { + /** + * Returns audio player + */ + function audio_player(string $source, string $mediaType, string $class = ''): string + { + $language = service('request') + ->getLocale(); + + return <<<CODE_SAMPLE + <vm-player + id="castopod-vm-player" + theme="light" + language="${language}" + icons="castopod-icons" + class="${class}" + style="--vm-player-box-shadow:0; --vm-player-theme: #009486; --vm-control-spacing: 4px;" + > + <vm-audio preload="none"> + <source src="${source}" type="${mediaType}" /> + </vm-audio> + <vm-ui> + <vm-icon-library name="castopod-icons"></vm-icon-library> + <vm-controls full-width> + <vm-playback-control></vm-playback-control> + <vm-volume-control></vm-volume-control> + <vm-current-time></vm-current-time> + <vm-scrubber-control></vm-scrubber-control> + <vm-end-time></vm-end-time> + <vm-settings-control></vm-settings-control> + <vm-default-settings></vm-default-settings> + </vm-controls> + </vm-ui> + </vm-player> + CODE_SAMPLE; + } +} diff --git a/app/Helpers/misc_helper.php b/app/Helpers/misc_helper.php index f45726b09344f1aa41a0141cdbc1ffa31ec46b69..21a7ae5c055b8f4e8f84b9de041d8a60029f2b4a 100644 --- a/app/Helpers/misc_helper.php +++ b/app/Helpers/misc_helper.php @@ -136,20 +136,26 @@ if (! function_exists('slugify')) { if (! function_exists('format_duration')) { /** - * Formats duration in seconds to an hh:mm:ss string + * Formats duration in seconds to an hh:mm:ss string. Doesn't show leading zeros if any. + * + * âš ï¸ This uses php's gmdate function so any duration > 86000 seconds (24 hours) will not be formatted properly. * * @param int $seconds seconds to format */ - function format_duration(int $seconds, string $separator = ':'): string + function format_duration(int $seconds): string { - return sprintf( - '%02d%s%02d%s%02d', - floor($seconds / 3600), - $separator, - ($seconds / 60) % 60, - $separator, - $seconds % 60, - ); + if ($seconds < 60) { + return '0:' . $seconds; + } + if ($seconds < 3600) { + // < 1 hour: returns MM:SS + return ltrim(gmdate('i:s', $seconds), '0'); + } + if ($seconds < 36000) { + // < 10 hours: returns H:MM:SS + return ltrim(gmdate('h:i:s', $seconds), '0'); + } + return gmdate('h:i:s', $seconds); } } diff --git a/app/Language/en/Common.php b/app/Language/en/Common.php index 0bf26a681f480810469da0090d0e655ea13eba95..28afa79975e7fbb08b595f02b327fbbe44533303 100644 --- a/app/Language/en/Common.php +++ b/app/Language/en/Common.php @@ -41,4 +41,8 @@ return [ 'upload_file' => 'Upload a file', 'remote_url' => 'Remote URL', ], + 'play_episode_button' => [ + 'play' => 'Play', + 'playing' => 'Playing', + ], ]; diff --git a/app/Language/en/Episode.php b/app/Language/en/Episode.php index 4cd456887302948289c969692047dbba42557101..94f5fc1629d8a1a99c2745c8b6a5f6528aa0ea94 100644 --- a/app/Language/en/Episode.php +++ b/app/Language/en/Episode.php @@ -44,10 +44,16 @@ return [ 'go_to_page' => 'Go to page', 'create' => 'Add an episode', 'publication_status' => [ - 'published' => 'Published on {0}', - 'scheduled' => 'Scheduled for {0}', + 'published' => 'Published', + 'scheduled' => 'Scheduled', 'not_published' => 'Not published', ], + 'list' => [ + 'episode' => 'Episode', + 'visibility' => 'Visibility', + 'comments' => 'Comments', + 'actions' => 'Actions', + ], 'form' => [ 'warning' => 'In case of fatal error, try increasing the `memory_limit`, `upload_max_filesize` and `post_max_size` values in your php configuration file then restart your web server.<br />These values must be higher than the audio file you wish to upload.', diff --git a/app/Language/fr/Common.php b/app/Language/fr/Common.php index a3415467ce622863f0b9d1c7e3e7680a7600e59a..64997463fb820457028177e67b74942dec9f78a3 100644 --- a/app/Language/fr/Common.php +++ b/app/Language/fr/Common.php @@ -41,4 +41,8 @@ return [ 'upload_file' => 'Téléversez un fichier', 'remote_url' => 'URL distante', ], + 'play_episode_button' => [ + 'play' => 'Lire', + 'playing' => 'En cours', + ], ]; diff --git a/app/Language/fr/Episode.php b/app/Language/fr/Episode.php index 5f75b5061d54813e930ca363b5e97e4ef499d5d7..3a6557872e8e6d74835988f948b27d349f805043 100644 --- a/app/Language/fr/Episode.php +++ b/app/Language/fr/Episode.php @@ -44,10 +44,16 @@ return [ 'go_to_page' => 'Voir', 'create' => 'Ajouter un épisode', 'publication_status' => [ - 'published' => 'Publié le {0}', - 'scheduled' => 'Planifié pour le {0}', + 'published' => 'Publié', + 'scheduled' => 'Planifié', 'not_published' => 'Non publié', ], + 'list' => [ + 'episode' => 'Épisode', + 'visibility' => 'Visibilité', + 'comments' => 'Commentaires', + 'actions' => 'Actions', + ], 'form' => [ 'warning' => 'En cas d’erreur fatale, essayez d’augmenter les valeurs de `memory_limit`, `upload_max_filesize` et `post_max_size` dans votre fichier de configuration php puis redémarrez votre serveur web.<br />Les valeurs doivent être plus grandes que le fichier audio que vous souhaitez téléverser.', diff --git a/app/Models/EpisodeModel.php b/app/Models/EpisodeModel.php index 78bebf53feedc3d4e3d152deb92b64b877ab0223..d554062486ff9e1bf0a6d3781580f5095687e308 100644 --- a/app/Models/EpisodeModel.php +++ b/app/Models/EpisodeModel.php @@ -43,7 +43,7 @@ class EpisodeModel extends Model ], 'dark' => [ 'style' => 'background-color: #001f1a;', - 'background' => '#001f1a', + 'background' => '#313131', 'text' => '#fff', 'inverted' => '#000', ], diff --git a/app/Resources/icons/disc.svg b/app/Resources/icons/disc.svg new file mode 100644 index 0000000000000000000000000000000000000000..095d2cdad93f24b2a528648b91de5b26833de03c --- /dev/null +++ b/app/Resources/icons/disc.svg @@ -0,0 +1,6 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> + <g> + <path fill="none" d="M0 0h24v24H0z"/> + <path d="M13 9.17A3 3 0 1 0 15 12V2.458c4.057 1.274 7 5.064 7 9.542 0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2c.337 0 .671.017 1 .05v7.12z"/> + </g> +</svg> diff --git a/app/Resources/icons/pause.svg b/app/Resources/icons/pause.svg new file mode 100644 index 0000000000000000000000000000000000000000..81cffce1dfa678e3d3b170cbc81a8d5549046fa1 --- /dev/null +++ b/app/Resources/icons/pause.svg @@ -0,0 +1,6 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> + <g> + <path fill="none" d="M0 0h24v24H0z"/> + <path d="M6 5h2v14H6V5zm10 0h2v14h-2V5z"/> + </g> +</svg> diff --git a/app/Resources/icons/volume-high.svg b/app/Resources/icons/volume-high.svg new file mode 100644 index 0000000000000000000000000000000000000000..0aa5be363a85139fd7a9e6f3281d75cc6ffae9d2 --- /dev/null +++ b/app/Resources/icons/volume-high.svg @@ -0,0 +1,6 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> + <g> + <path fill="none" d="M0 0h24v24H0z"/> + <path d="M5.889 16H2a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1h3.889l5.294-4.332a.5.5 0 0 1 .817.387v15.89a.5.5 0 0 1-.817.387L5.89 16zm13.517 4.134l-1.416-1.416A8.978 8.978 0 0 0 21 12a8.982 8.982 0 0 0-3.304-6.968l1.42-1.42A10.976 10.976 0 0 1 23 12c0 3.223-1.386 6.122-3.594 8.134zm-3.543-3.543l-1.422-1.422A3.993 3.993 0 0 0 16 12c0-1.43-.75-2.685-1.88-3.392l1.439-1.439A5.991 5.991 0 0 1 18 12c0 1.842-.83 3.49-2.137 4.591z"/> + </g> +</svg> diff --git a/app/Resources/icons/volume-low.svg b/app/Resources/icons/volume-low.svg new file mode 100644 index 0000000000000000000000000000000000000000..6acfade5750648ac4ef61752c6defa5a9e54ff59 --- /dev/null +++ b/app/Resources/icons/volume-low.svg @@ -0,0 +1,6 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> + <g> + <path fill="none" d="M0 0h24v24H0z"/> + <path d="M8.889 16H5a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1h3.889l5.294-4.332a.5.5 0 0 1 .817.387v15.89a.5.5 0 0 1-.817.387L8.89 16zm9.974.591l-1.422-1.422A3.993 3.993 0 0 0 19 12c0-1.43-.75-2.685-1.88-3.392l1.439-1.439A5.991 5.991 0 0 1 21 12c0 1.842-.83 3.49-2.137 4.591z"/> + </g> +</svg> diff --git a/app/Resources/icons/volume-mute.svg b/app/Resources/icons/volume-mute.svg new file mode 100644 index 0000000000000000000000000000000000000000..79bd55ace244edd9a92b089ae728aae836260f5f --- /dev/null +++ b/app/Resources/icons/volume-mute.svg @@ -0,0 +1,6 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> + <g> + <path fill="none" d="M0 0h24v24H0z"/> + <path d="M5.889 16H2a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1h3.889l5.294-4.332a.5.5 0 0 1 .817.387v15.89a.5.5 0 0 1-.817.387L5.89 16zm14.525-4l3.536 3.536-1.414 1.414L19 13.414l-3.536 3.536-1.414-1.414L17.586 12 14.05 8.464l1.414-1.414L19 10.586l3.536-3.536 1.414 1.414L20.414 12z"/> + </g> +</svg> diff --git a/app/Resources/js/audio-player.ts b/app/Resources/js/audio-player.ts new file mode 100644 index 0000000000000000000000000000000000000000..0a120376b43693ad804e53a60a5fa8ae26fc80e1 --- /dev/null +++ b/app/Resources/js/audio-player.ts @@ -0,0 +1,125 @@ +import { + VmAudio, + VmCaptions, + VmClickToPlay, + VmControl, + VmControls, + VmCurrentTime, + VmDefaultControls, + VmDefaultSettings, + VmDefaultUi, + VmEndTime, + VmFile, + VmIcon, + VmIconLibrary, + VmLoadingScreen, + VmMenu, + VmMenuItem, + VmMenuRadio, + VmMenuRadioGroup, + VmMuteControl, + VmPlaybackControl, + VmPlayer, + VmScrubberControl, + VmSettings, + VmSettingsControl, + VmSkeleton, + VmSlider, + VmSubmenu, + VmTime, + VmTimeProgress, + VmTooltip, + VmUi, + VmVolumeControl, +} from "@vime/core"; +import "@vime/core/themes/default.css"; +import "@vime/core/themes/light.css"; +import { html, render } from "lit"; +import "./modules/play-episode-button"; + +const player = html`<div + id="castopod-audio-player" + class="fixed bottom-0 left-0 flex flex-col w-full bg-white border-t sm:flex-row" + data-episode="-1" + style="display: none;" +> + <div class="flex items-center"> + <img src="" alt="" class="h-[52px] w-[52px]" /> + <div class="flex flex-col px-2"> + <p class="text-sm w-48 truncate" title="" id="castopod-player-title"></p> + <p + class="text-xs w-48 truncate" + title="" + id="castopod-player-podcast" + ></p> + </div> + </div> + <vm-player + id="castopod-vm-player" + theme="light" + language="en" + icons="castopod-icons" + class="flex-1" + style="--vm-player-box-shadow:0; --vm-player-theme: #009486;" + > + <vm-audio preload="none" id="testing-audio"> + <source src="" type="" /> + </vm-audio> + <vm-ui> + <vm-icon-library name="castopod-icons"></vm-icon-library> + <vm-controls full-width> + <vm-playback-control></vm-playback-control> + <vm-volume-control></vm-volume-control> + <vm-current-time></vm-current-time> + <vm-scrubber-control></vm-scrubber-control> + <vm-end-time></vm-end-time> + <vm-settings-control></vm-settings-control> + <vm-default-settings></vm-default-settings> + </vm-controls> + </vm-ui> + </vm-player> +</div>`; + +render(player, document.body); + +// Register Castopod's icons library +const library: HTMLVmIconLibraryElement | null = document.querySelector( + 'vm-icon-library[name="castopod-icons"]' +); +if (library) { + library.resolver = (iconName) => `/assets/icons/${iconName}.svg`; +} + +// Vime elements for audio player +customElements.define("vm-player", VmPlayer); +customElements.define("vm-file", VmFile); +customElements.define("vm-audio", VmAudio); +customElements.define("vm-ui", VmUi); +customElements.define("vm-default-ui", VmDefaultUi); +customElements.define("vm-click-to-play", VmClickToPlay); +customElements.define("vm-captions", VmCaptions); +customElements.define("vm-loading-screen", VmLoadingScreen); +customElements.define("vm-default-controls", VmDefaultControls); +customElements.define("vm-default-settings", VmDefaultSettings); +customElements.define("vm-controls", VmControls); +customElements.define("vm-playback-control", VmPlaybackControl); +customElements.define("vm-volume-control", VmVolumeControl); +customElements.define("vm-scrubber-control", VmScrubberControl); +customElements.define("vm-current-time", VmCurrentTime); +customElements.define("vm-end-time", VmEndTime); +customElements.define("vm-settings-control", VmSettingsControl); +customElements.define("vm-time-progress", VmTimeProgress); +customElements.define("vm-control", VmControl); +customElements.define("vm-icon", VmIcon); +customElements.define("vm-icon-library", VmIconLibrary); +customElements.define("vm-tooltip", VmTooltip); +customElements.define("vm-mute-control", VmMuteControl); +customElements.define("vm-slider", VmSlider); +customElements.define("vm-time", VmTime); +customElements.define("vm-menu", VmMenu); +customElements.define("vm-menu-item", VmMenuItem); +customElements.define("vm-submenu", VmSubmenu); +customElements.define("vm-menu-radio-group", VmMenuRadioGroup); +customElements.define("vm-menu-radio", VmMenuRadio); +customElements.define("vm-settings", VmSettings); +customElements.define("vm-skeleton", VmSkeleton); diff --git a/app/Resources/js/embed.ts b/app/Resources/js/embed.ts new file mode 100644 index 0000000000000000000000000000000000000000..4689cf43ea92e68987e212c39dfe667fee284daa --- /dev/null +++ b/app/Resources/js/embed.ts @@ -0,0 +1,78 @@ +import { + VmAudio, + VmCaptions, + VmClickToPlay, + VmControl, + VmControls, + VmCurrentTime, + VmDefaultControls, + VmDefaultSettings, + VmDefaultUi, + VmEndTime, + VmFile, + VmIcon, + VmIconLibrary, + VmLoadingScreen, + VmMenu, + VmMenuItem, + VmMenuRadio, + VmMenuRadioGroup, + VmMuteControl, + VmPlaybackControl, + VmPlayer, + VmScrubberControl, + VmSettings, + VmSettingsControl, + VmSkeleton, + VmSlider, + VmSubmenu, + VmTime, + VmTimeProgress, + VmTooltip, + VmUi, + VmVolumeControl, +} from "@vime/core"; +import "@vime/core/themes/default.css"; +import "@vime/core/themes/light.css"; + +// Vime elements for audio player +customElements.define("vm-player", VmPlayer); +customElements.define("vm-file", VmFile); +customElements.define("vm-audio", VmAudio); +customElements.define("vm-ui", VmUi); +customElements.define("vm-default-ui", VmDefaultUi); +customElements.define("vm-click-to-play", VmClickToPlay); +customElements.define("vm-captions", VmCaptions); +customElements.define("vm-loading-screen", VmLoadingScreen); +customElements.define("vm-default-controls", VmDefaultControls); +customElements.define("vm-default-settings", VmDefaultSettings); +customElements.define("vm-controls", VmControls); +customElements.define("vm-playback-control", VmPlaybackControl); +customElements.define("vm-volume-control", VmVolumeControl); +customElements.define("vm-scrubber-control", VmScrubberControl); +customElements.define("vm-current-time", VmCurrentTime); +customElements.define("vm-end-time", VmEndTime); +customElements.define("vm-settings-control", VmSettingsControl); +customElements.define("vm-time-progress", VmTimeProgress); +customElements.define("vm-control", VmControl); +customElements.define("vm-icon", VmIcon); +customElements.define("vm-icon-library", VmIconLibrary); +customElements.define("vm-tooltip", VmTooltip); +customElements.define("vm-mute-control", VmMuteControl); +customElements.define("vm-slider", VmSlider); +customElements.define("vm-time", VmTime); +customElements.define("vm-menu", VmMenu); +customElements.define("vm-menu-item", VmMenuItem); +customElements.define("vm-submenu", VmSubmenu); +customElements.define("vm-menu-radio-group", VmMenuRadioGroup); +customElements.define("vm-menu-radio", VmMenuRadio); +customElements.define("vm-settings", VmSettings); +customElements.define("vm-skeleton", VmSkeleton); + +// Register Castopod's icons library +const library: HTMLVmIconLibraryElement | null = document.querySelector( + 'vm-icon-library[name="castopod-icons"]' +); +if (library) { + library.resolver = (iconName) => `/assets/icons/${iconName}.svg`; +} diff --git a/app/Resources/js/modules/play-episode-button.ts b/app/Resources/js/modules/play-episode-button.ts new file mode 100644 index 0000000000000000000000000000000000000000..7ec0d41705620e31db24c6259919e654115dbff1 --- /dev/null +++ b/app/Resources/js/modules/play-episode-button.ts @@ -0,0 +1,263 @@ +import { css, html, LitElement, TemplateResult } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; + +@customElement("play-episode-button") +export class PlayEpisodeButton extends LitElement { + @property() + id = "0"; + + @property() + src = ""; + + @property() + mediaType = ""; + + @property() + title!: string; + + @property() + podcast!: string; + + @property() + imageSrc!: string; + + @property() + playLabel!: string; + + @property() + playingLabel!: string; + + @property() + isPlaying!: boolean; + + @property() + _castopodAudioPlayer!: HTMLDivElement; + + @property() + _audio!: HTMLAudioElement; + + @state() + _playbackSpeed = 1; + + @state() + _events = [ + { + name: "canplay", + onEvent: (event: Event): void => { + (event.target as HTMLAudioElement)?.play(); + }, + }, + { + name: "play", + onEvent: (): void => { + this.isPlaying = true; + }, + }, + { + name: "pause", + onEvent: (): void => { + this.isPlaying = false; + }, + }, + { + name: "ratechange", + onEvent: (event: Event): void => { + this._playbackSpeed = (event.target as HTMLAudioElement)?.playbackRate; + console.log(this._playbackSpeed); + }, + }, + ]; + + async connectedCallback(): Promise<void> { + super.connectedCallback(); + + await this._elementReady("div[id=castopod-audio-player]"); + await this._elementReady("div[id=castopod-audio-player] audio"); + + this._castopodAudioPlayer = document.body.querySelector( + "div[id=castopod-audio-player]" + ) as HTMLDivElement; + + this._audio = this._castopodAudioPlayer.querySelector( + "audio" + ) as HTMLAudioElement; + } + + private _elementReady(selector: string) { + return new Promise((resolve) => { + const element = document.querySelector(selector); + if (element) { + resolve(element); + } + new MutationObserver((_, observer) => { + // Query for elements matching the specified selector + Array.from(document.querySelectorAll(selector)).forEach((element) => { + resolve(element); + //Once we have resolved we don't need the observer anymore. + observer.disconnect(); + }); + }).observe(document.documentElement, { + childList: true, + subtree: true, + }); + }); + } + + play(): void { + const currentlyPlayingEpisode = this._castopodAudioPlayer.dataset.episode; + + const isCurrentEpisode = currentlyPlayingEpisode === this.id; + + if (currentlyPlayingEpisode === "-1") { + this._showPlayer(); + } + + if (isCurrentEpisode) { + this._audio.play(); + } else { + const playingEpisodeButton = document.querySelector( + `play-episode-button[id="${currentlyPlayingEpisode}"]` + ) as PlayEpisodeButton; + if (playingEpisodeButton) { + this._flushLastPlayButton(playingEpisodeButton); + } + + this._loadEpisode(); + } + } + + pause(): void { + this._audio.pause(); + } + + private _showPlayer(): void { + this._castopodAudioPlayer.style.display = ""; + document.body.style.paddingBottom = "52px"; + } + + private _flushLastPlayButton(playingEpisodeButton: PlayEpisodeButton): void { + playingEpisodeButton.isPlaying = false; + + for (const event of playingEpisodeButton._events) { + playingEpisodeButton._audio.removeEventListener( + event.name, + event.onEvent, + false + ); + } + + this._playbackSpeed = playingEpisodeButton._playbackSpeed; + } + + private _loadEpisode(): void { + this._castopodAudioPlayer.dataset.episode = this.id; + + this._audio.src = this.src; + this._audio.load(); + this._audio.playbackRate = this._playbackSpeed; + for (const event of this._events) { + this._audio.addEventListener(event.name, event.onEvent, false); + } + + const img: HTMLImageElement | null = + this._castopodAudioPlayer.querySelector("img"); + + if (img) { + img.src = this.imageSrc; + img.alt = this.title; + } + + const episodeTitle: HTMLParagraphElement | null = + this._castopodAudioPlayer.querySelector('p[id="castopod-player-title"]'); + + if (episodeTitle) { + episodeTitle.title = this.title; + episodeTitle.innerHTML = this.title; + } + + const podcastTitle: HTMLParagraphElement | null = + this._castopodAudioPlayer.querySelector( + 'p[id="castopod-player-podcast"]' + ); + + if (podcastTitle) { + podcastTitle.title = this.podcast; + podcastTitle.innerHTML = this.podcast; + } + } + + static styles = css` + button { + background-color: #ffffff; + cursor: pointer; + display: inline-flex; + align-items: center; + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.25rem; + font-weight: 600; + border-width: 2px; + border-style: solid; + border-radius: 9999px; + border-color: rgba(207, 247, 243, 1); + + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + } + + button:hover { + border-color: #009486; + background-color: #ebf8f8; + } + + button:focus { + background-color: #ebf8f8; + } + + svg { + font-size: 1.5rem; + margin-right: 0.25rem; + color: #009486; + } + + @keyframes spin { + to { + transform: rotate(360deg); + } + } + + .animate-spin { + animation: spin 3s linear infinite; + } + `; + + render(): TemplateResult<1> { + return html`<button @click="${this.isPlaying ? this.pause : this.play}"> + ${this.isPlaying + ? html`<svg + class="animate-spin" + viewBox="0 0 24 24" + fill="currentColor" + width="1em" + height="1em" + > + <g> + <path fill="none" d="M0 0h24v24H0z" /> + <path + d="M13 9.17A3 3 0 1 0 15 12V2.458c4.057 1.274 7 5.064 7 9.542 0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2c.337 0 .671.017 1 .05v7.12z" + /> + </g></svg + >${this.playingLabel}` + : html`<svg + viewBox="0 0 24 24" + fill="currentColor" + width="1em" + height="1em" + > + <path fill="none" d="M0 0h24v24H0z" /> + <path + d="M7.752 5.439l10.508 6.13a.5.5 0 0 1 0 .863l-10.508 6.13A.5.5 0 0 1 7 18.128V5.871a.5.5 0 0 1 .752-.432z" + /></svg + >${this.playLabel}`} + </button>`; + } +} diff --git a/app/Resources/styles/inputRange.css b/app/Resources/styles/inputRange.css new file mode 100644 index 0000000000000000000000000000000000000000..053df1377f9bc7e0ac9b824193bcb30fdd76d7cd --- /dev/null +++ b/app/Resources/styles/inputRange.css @@ -0,0 +1,86 @@ +.wrap { + display: flex; + align-items: center; + position: relative; + width: 12.5em; + height: 5.25em; + font: 1em/1 arial, sans-serif; +} +[type="range"] { + flex: 1; + margin: 0; + padding: 0; + min-height: 1.5em; + background: transparent; + font: inherit; +} +[type="range"], +[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; +} +[type="range"]::-webkit-slider-runnable-track { + box-sizing: border-box; + border: none; + width: 12.5em; + height: 0.25em; + background: #ccc; +} +[type="range"]::-moz-range-track { + box-sizing: border-box; + border: none; + width: 12.5em; + height: 0.25em; + background: #ccc; +} +[type="range"]::-ms-track { + box-sizing: border-box; + border: none; + width: 12.5em; + height: 0.25em; + background: #ccc; +} +[type="range"]::-webkit-slider-thumb { + margin-top: -0.625em; + box-sizing: border-box; + border: none; + width: 1.5em; + height: 1.5em; + border-radius: 50%; + background: #f90; +} +[type="range"]::-moz-range-thumb { + box-sizing: border-box; + border: none; + width: 1.5em; + height: 1.5em; + border-radius: 50%; + background: #f90; +} +[type="range"]::-ms-thumb { + margin-top: 0; + box-sizing: border-box; + border: none; + width: 1.5em; + height: 1.5em; + border-radius: 50%; + background: #f90; +} +[type="range"]::-ms-tooltip { + display: none; +} +[type="range"] ~ output { + display: none; +} +.js [type="range"] ~ output { + display: block; + position: absolute; + left: 0.75em; + top: 0; + padding: 0.25em 0.5em; + border-radius: 3px; + transform: translate( + calc((var(--val) - var(--min)) / (var(--max) - var(--min)) * 11em - 50%) + ); + background: #95a; + color: #eee; +} diff --git a/app/Views/_layout.php b/app/Views/_layout.php index bf9bcded9c69b07e9498cfbed9ea434a3e240dff..5782c039f2af91c01e751659502fd20625ea9112 100644 --- a/app/Views/_layout.php +++ b/app/Views/_layout.php @@ -8,7 +8,9 @@ <meta name="description" content="Castopod is an open-source hosting platform made for podcasters who want engage and interact with their audience."/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <link rel="shortcut icon" type="image/png" href="/favicon.ico" /> + <?= service('vite')->asset('styles/index.css', 'css') ?> + <?= service('vite')->asset('js/audio-player.ts', 'js') ?> </head> <body class="flex flex-col min-h-screen mx-auto bg-gray-100"> diff --git a/app/Views/admin/_layout.php b/app/Views/admin/_layout.php index c5375af68fc8714eae9fa5bed20f4c7a5c0c43bc..16bcf98339400eeeeec398043da20de2cb22d701 100644 --- a/app/Views/admin/_layout.php +++ b/app/Views/admin/_layout.php @@ -7,8 +7,10 @@ <meta name="description" content="Castopod is an open-source hosting platform made for podcasters who want engage and interact with their audience."/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <link rel="shortcut icon" type="image/png" href="/favicon.ico" /> + <?= service('vite')->asset('styles/index.css', 'css') ?> <?= service('vite')->asset('js/admin.ts', 'js') ?> + <?= service('vite')->asset('js/audio-player.ts', 'js') ?> </head> <body class="relative bg-gray-100 holy-grail-grid"> diff --git a/app/Views/admin/contributor/list.php b/app/Views/admin/contributor/list.php index f83064d9c858230f4a6e7b1ddcc4b679e4de8920..d390902f3a439926085b829af7604885974ce90d 100644 --- a/app/Views/admin/contributor/list.php +++ b/app/Views/admin/contributor/list.php @@ -65,6 +65,7 @@ ], ], $podcast->contributors, + '', $podcast, ) ?> diff --git a/app/Views/admin/episode/embeddable_player.php b/app/Views/admin/episode/embeddable_player.php index bb42a4a3d6fe564fab07a183498695a4b9153dd8..b15060b77c09f7652308abeaa4c58d4563610afe 100644 --- a/app/Views/admin/episode/embeddable_player.php +++ b/app/Views/admin/episode/embeddable_player.php @@ -24,7 +24,7 @@ <?php endforeach; ?> </div> -<iframe name="embeddable_player" id="embeddable_player" class="w-full h-48 max-w-xl" frameborder="0" scrolling="no" style="width: 100%; overflow: hidden;" src="<?= $episode->embeddable_player_url ?>"></iframe> +<iframe name="embeddable_player" id="embeddable_player" class="w-full max-w-xl h-36" frameborder="0" scrolling="no" style="width: 100%; overflow: hidden;" src="<?= $episode->embeddable_player_url ?>"></iframe> <div class="flex items-center w-full mt-8"> <?= form_textarea( diff --git a/app/Views/admin/episode/list.php b/app/Views/admin/episode/list.php index 5780b47cb642edb7f3c041257eba5fc6f2780856..fdee95e1177f17052c369ecd5d18926152ab6f1c 100644 --- a/app/Views/admin/episode/list.php +++ b/app/Views/admin/episode/list.php @@ -5,9 +5,7 @@ <?= $this->endSection() ?> <?= $this->section('pageTitle') ?> -<?= lang('Episode.all_podcast_episodes') ?> (<?= $pager->getDetails()[ - 'total' - ] ?>) +<?= lang('Episode.all_podcast_episodes') ?> (<?= $pager->getDetails()['total'] ?>) <?= $this->endSection() ?> <?= $this->section('headerRight') ?> @@ -21,110 +19,108 @@ <?= $this->section('content') ?> <p class="mb-4 text-sm italic text-gray-700"><?= lang('Common.pageInfo', [ - 'currentPage' => $pager->getDetails()['currentPage'], - 'pageCount' => $pager->getDetails()['pageCount'], -]) ?></p> -<div class="flex flex-wrap mb-6"> - <?php if ($episodes): ?> - <?php foreach ($episodes as $episode): ?> - <article class="flex w-full max-w-lg p-4 mx-auto"> - <img - loading="lazy" - src="<?= $episode->image->thumbnail_url ?>" - alt="<?= $episode->title ?>" class="object-cover w-20 h-20 mr-2 rounded-lg" /> - <div class="flex flex-col flex-1"> - <div class="flex"> - <a class="flex-1 text-sm hover:underline" href="<?= route_to( - 'episode-view', - $podcast->id, - $episode->id, - ) ?>"> - <h2 class="inline-flex justify-between w-full font-semibold leading-none group"> - <span class="mr-1 group-hover:underline"><?= $episode->title ?></span> - <?= episode_numbering( - $episode->number, - $episode->season_number, - 'text-xs font-semibold text-gray-600', - true, - ) ?> - </h2> - </a> - <button - id="more-dropdown-<?= $episode->id ?>" - type="button" - class="inline-flex items-center p-1 outline-none focus:ring" - data-dropdown="button" - data-dropdown-target="more-dropdown-<?= $episode->id ?>-menu" - aria-haspopup="true" - aria-expanded="false"> - <?= icon('more') ?> - </button> - <nav - id="more-dropdown-<?= $episode->id ?>-menu" - class="flex flex-col py-2 text-black whitespace-no-wrap bg-white border rounded shadow" - aria-labelledby="more-dropdown-<?= $episode->id ?>" - data-dropdown="menu" - data-dropdown-placement="bottom-start" - data-dropdown-offset-x="0" - data-dropdown-offset-y="-24"> - <a class="px-4 py-1 hover:bg-gray-100" href="<?= route_to( - 'episode-edit', - $podcast->id, - $episode->id, - ) ?>"><?= lang('Episode.edit') ?></a> - <a class="px-4 py-1 hover:bg-gray-100" href="<?= route_to( - 'embeddable-player-add', - $podcast->id, - $episode->id, - ) ?>"><?= lang( - 'Episode.embeddable_player.add', -) ?></a> - <a class="px-4 py-1 hover:bg-gray-100" href="<?= route_to( - 'episode-person-manage', - $podcast->id, - $episode->id, - ) ?>"><?= lang('Person.persons') ?></a> - <a class="px-4 py-1 hover:bg-gray-100" href="<?= route_to( - 'soundbites-edit', - $podcast->id, - $episode->id, - ) ?>"><?= lang('Episode.soundbites') ?></a> - <a class="px-4 py-1 hover:bg-gray-100" href="<?= route_to( - 'episode', - $podcast->handle, - $episode->slug, - ) ?>"><?= lang('Episode.go_to_page') ?></a> - <a class="px-4 py-1 hover:bg-gray-100" href="<?= route_to( - 'episode-delete', - $podcast->id, - $episode->id, - ) ?>"><?= lang('Episode.delete') ?></a> - </nav> - </div> - <div class="mb-2 text-xs"> - <?= publication_pill( - $episode->published_at, - $episode->publication_status, - ) ?> - <span class="mx-1">•</span> - <time datetime="PT<?= $episode->audio_file_duration ?>S"> - <?= format_duration( + 'currentPage' => $pager->getDetails()['currentPage'], + 'pageCount' => $pager->getDetails()['pageCount'], + ]) ?></p> + +<?= data_table( + [ + [ + 'header' => lang('Episode.list.episode'), + 'cell' => function ($episode, $podcast) { + return '<div class="flex">' . + '<div class="relative flex-shrink-0 mr-2">'. + '<time class="absolute px-1 text-xs font-semibold text-white rounded bottom-2 right-2 bg-black/50" datetime="PT<?= $episode->audio_file_duration ?>S">' . + format_duration( $episode->audio_file_duration, - ) ?> - </time> - </div> - <audio controls preload="none" class="w-full mt-auto"> - <source src="<?= $episode->audio_file_url ?>" type="<?= $episode->audio_file_mimetype ?>"> - Your browser does not support the audio tag. - </audio> - </div> - </article> - <?php endforeach; ?> - <?php else: ?> - <p class="italic"><?= lang('Podcast.no_episode') ?></p> - <?php endif; ?> -</div> + ) . + '</time>' . + '<img loading="lazy" src="' . $episode->image->thumbnail_url . '" alt="' . $episode->title . '" class="object-cover w-20 h-20 rounded-lg" />' . + '</div>' . + '<a class="text-sm hover:underline" href="' . route_to( + 'episode-view', + $podcast->id, + $episode->id, + ) . '">' . + '<h2 class="inline-flex w-full font-semibold leading-none group">' . + episode_numbering( + $episode->number, + $episode->season_number, + 'text-xs font-semibold text-gray-600', + true, + ) . + '<span class="mx-1">-</span>' . + '<span class="mr-1 group-hover:underline">' . $episode->title . '</span>' . + '</h2>' . + '<p class="max-w-sm text-xs text-gray-600 line-clamp-2">' . $episode->description . '</p>' . + '</a>' . + '</div>'; + }, + ], + [ + 'header' => lang('Episode.list.visibility'), + 'cell' => function ($episode) { + return publication_pill( + $episode->published_at, + $episode->publication_status, + ); + }, + ], + [ + 'header' => lang('Episode.list.comments'), + 'cell' => function ($episode) { + return count($episode->comments); + }, + ], + [ + 'header' => lang('Episode.list.actions'), + 'cell' => function ($episode, $podcast) { + return '<button id="more-dropdown-<?= $episode->id ?>" type="button" class="inline-flex items-center p-1 outline-none focus:ring" data-dropdown="button" data-dropdown-target="more-dropdown-<?= $episode->id ?>-menu" aria-haspopup="true" aria-expanded="false">' . + icon('more') . + '</button>' . + '<nav id="more-dropdown-<?= $episode->id ?>-menu" class="flex flex-col py-2 text-black whitespace-no-wrap bg-white border rounded shadow" aria-labelledby="more-dropdown-<?= $episode->id ?>" data-dropdown="menu" data-dropdown-placement="bottom-start" data-dropdown-offset-x="0" data-dropdown-offset-y="-24">' . + '<a class="px-4 py-1 hover:bg-gray-100" href="' . route_to( + 'episode-edit', + $podcast->id, + $episode->id, + ) . '">' . lang('Episode.edit') . '</a>' . + '<a class="px-4 py-1 hover:bg-gray-100" href="' . route_to( + 'embeddable-player-add', + $podcast->id, + $episode->id, + ) . '">' . lang( + 'Episode.embeddable_player.add', + ) . '</a>' . + '<a class="px-4 py-1 hover:bg-gray-100" href="' . route_to( + 'episode-person-manage', + $podcast->id, + $episode->id, + ) . '">' . lang('Person.persons') . '</a>' . + '<a class="px-4 py-1 hover:bg-gray-100" href="' . route_to( + 'soundbites-edit', + $podcast->id, + $episode->id, + ) . '">' . lang('Episode.soundbites') . '</a>' . + '<a class="px-4 py-1 hover:bg-gray-100" href="' . route_to( + 'episode', + $podcast->handle, + $episode->slug, + ) . '">' . lang('Episode.go_to_page') . '</a>' . + '<a class="px-4 py-1 hover:bg-gray-100" href="' . route_to( + 'episode-delete', + $podcast->id, + $episode->id, + ) . '">' . lang('Episode.delete') . '</a>' . + '</nav>' . + '</div>'; + }, + ], + ], + $episodes, + 'mb-6', + $podcast +) ?> <?= $pager->links() ?> -<?= $this->endSection() ?> +<?= $this->endSection() ?> \ No newline at end of file diff --git a/app/Views/admin/episode/publish.php b/app/Views/admin/episode/publish.php index e1ed34bc5167b633fd0d31fdb4b7f217fd8f5842..a3c192a24c12f24e72828968fdf9f688b545de69 100644 --- a/app/Views/admin/episode/publish.php +++ b/app/Views/admin/episode/publish.php @@ -73,10 +73,7 @@ </time> </div> </a> - <audio controls preload="none" class="w-full mt-auto"> - <source src="<?= $episode->audio_file_url ?>" type="<?= $episode->audio_file_mimetype ?>"> - Your browser does not support the audio tag. - </audio> + <?= audio_player($episode->audio_file_url, $episode->audio_file_mimetype, 'mt-auto') ?> </div> </div> <footer class="flex justify-around px-6 py-3"> diff --git a/app/Views/admin/episode/publish_edit.php b/app/Views/admin/episode/publish_edit.php index 52e23326f81a88d868624d64ea336526379ca33f..d71485ddf86a941829e412b1369b2952d2c91640 100644 --- a/app/Views/admin/episode/publish_edit.php +++ b/app/Views/admin/episode/publish_edit.php @@ -91,10 +91,7 @@ </time> </div> </a> - <audio controls preload="none" class="w-full mt-auto"> - <source src="<?= $episode->audio_file_url ?>" type="<?= $episode->audio_file_mimetype ?>"> - Your browser does not support the audio tag. - </audio> + <?= audio_player($episode->audio_file_url, $episode->audio_file_mimetype, 'mt-auto') ?> </div> </div> <footer class="flex justify-around px-6 py-3"> diff --git a/app/Views/admin/episode/view.php b/app/Views/admin/episode/view.php index 47c208c2b57b50777dcc80e44ed6225aa28663c3..87f451bfb40daa82e826f117baa3ea80e34e305d 100644 --- a/app/Views/admin/episode/view.php +++ b/app/Views/admin/episode/view.php @@ -29,15 +29,14 @@ <div class="flex flex-wrap"> <div class="w-full max-w-sm mb-6 md:mr-4"> - <img + <div class="mb-6"> + <img src="<?= $episode->image->medium_url ?>" alt="Episode cover" class="object-cover w-full" - /> - <audio controls preload="auto" class="w-full mb-6"> - <source src="<?= $episode->audio_file_url ?>" type="<?= $episode->audio_file_mimetype ?>"> - Your browser does not support the audio tag. - </audio> + /> + <?= audio_player($episode->audio_file_url, $episode->audio_file_mimetype) ?> + </div> <div class="flex justify-around"> <?= button( @@ -113,7 +112,7 @@ [ 'header' => lang('Episode.soundbites_form.duration'), 'cell' => function ($soundbite): string { - return format_duration($soundbite->duration); + return $soundbite->duration . 's'; }, ], [ diff --git a/app/Views/admin/podcast/latest_episodes.php b/app/Views/admin/podcast/latest_episodes.php index 962d6a84f674b9c7b8f98361ec425057560831e2..5b367b788ba418da264591d684c7b09cca602fd3 100644 --- a/app/Views/admin/podcast/latest_episodes.php +++ b/app/Views/admin/podcast/latest_episodes.php @@ -12,10 +12,18 @@ <?php if ($episodes): ?> <div class="flex p-2 overflow-x-auto gap-x-6"> <?php foreach ($episodes as $episode): ?> - <article class="flex flex-col flex-shrink-0 w-56 overflow-hidden bg-white border shadow rounded-xl"> - <img - src="<?= $episode->image->thumbnail_url ?>" - alt="<?= $episode->title ?>" class="object-cover" /> + <article class="flex flex-col flex-shrink-0 flex-1 w-full min-w-[12rem] overflow-hidden bg-white border shadow rounded-xl"> + <div class="relative"> + <div class=""></div> + <?= publication_pill( + $episode->published_at, + $episode->publication_status, + 'absolute top-2 right-2 text-sm' + ); ?> + <img + src="<?= $episode->image->thumbnail_url ?>" + alt="<?= $episode->title ?>" class="object-cover w-full" /> + </div> <div class="flex items-start justify-between p-2"> <div class="flex flex-col min-w-0"> <a href="<?= route_to( @@ -24,29 +32,16 @@ $episode->id, ) ?>" class="text-sm font-semibold truncate hover:underline" - ><?= $episode->title ?> - </a> - <div class="text-xs"> - <?= episode_numbering( + > + <?= episode_numbering( $episode->number, $episode->season_number, 'font-semibold text-gray-600', true, - ) ?> - <?php if ($episode->published_at): ?> - <span class="mx-1">•</span> - <time - pubdate - datetime="<?= $episode->published_at->format( - DateTime::ATOM, - ) ?>" - title="<?= $episode->published_at ?>"> - <?= lang('Common.mediumDate', [ - $episode->published_at, - ]) ?> - </time> - <?php endif; ?> - </div> + ) ?> + <span class="mx-1">-</span> + <?= $episode->title ?> + </a> </div> <button type="button" @@ -100,4 +95,4 @@ <?php else: ?> <p class="italic"><?= lang('Podcast.no_episode') ?></p> <?php endif; ?> -</section> \ No newline at end of file +</section> diff --git a/app/Views/embeddable_player.php b/app/Views/embeddable_player.php index fe24b866e703988d89d3993a09510d1768e99617..3d2873638f74ea017d65fe749dc8cfb9f333f708 100644 --- a/app/Views/embeddable_player.php +++ b/app/Views/embeddable_player.php @@ -10,24 +10,25 @@ <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" /> <link rel="canonical" href="<?= $episode->link ?>" /> <?= service('vite')->asset('styles/index.css', 'css') ?> + <?= service('vite')->asset('js/embed.ts', 'js') ?> </head> -<body class="flex w-full h-screen" style="background: <?= $theme[ +<body class="flex w-full h-screen" style="background: <?= $themeData[ 'background' -] ?>; color: <?= $theme['text'] ?>;"> +] ?>; color: <?= $themeData['text'] ?>;"> <img src="<?= $episode->image - ->medium_url ?>" alt="<?= $episode->title ?>" class="flex-shrink h-full" /> - <div class="flex flex-col flex-1 min-w-0 p-4"> + ->thumbnail_url ?>" alt="<?= $episode->title ?>" class="flex-shrink w-36 h-36" /> + <div class="flex flex-col flex-1 min-w-0 px-4 py-2 h-36"> <div class="flex items-center"> <a href="<?= route_to( - 'podcast', + 'podcast-activity', $podcast->handle, - ) ?>" style="color: <?= $theme[ + ) ?>" style="color: <?= $themeData[ 'text' ] ?>;" class="mr-2 text-xs tracking-wider uppercase truncate opacity-75 hover:opacity-100" target="_blank"> <?= $podcast->title ?> </a> - <a href="https://castopod.org/" class="ml-auto text-xl text-pine-700 hover:opacity-75" title="<?= lang( + <a href="https://castopod.org/" class="ml-auto text-3xl text-pine-700 hover:opacity-75" title="<?= lang( 'Common.powered_by', [ 'castopod' => 'Castopod', @@ -36,7 +37,7 @@ <?= icon('podcasting/castopod') ?> </a> </div> - <a href="<?= $episode->link ?>" class="flex items-center mb-2" style="color: <?= $theme[ + <a href="<?= $episode->link ?>" class="flex items-center mb-2" style="color: <?= $themeData[ 'text' ] ?>;" target="_blank"> <h1 class="mr-2 text-lg font-semibold truncate opacity-100 hover:opacity-75"> @@ -49,14 +50,33 @@ true, ) ?> </a> - <audio controls preload="none" class="flex w-full mt-auto"> - <source src="<?= $episode->audio_file_analytics_url . - (isset($_SERVER['HTTP_REFERER']) - ? '?_from=' . - parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) - : '') ?>" type="<?= $episode->audio_file_mimetype ?>" /> - Your browser does not support the audio tag. - </audio> + <vm-player + id="castopod-vm-player" + theme="<?= str_starts_with($theme, 'dark') ? 'dark' : 'light' ?>" + language="${language}" + icons="castopod-icons" + class="w-full mt-auto" + style="--vm-player-box-shadow:0; --vm-player-theme: #009486; --vm-control-spacing: 4px; --vm-control-icon-size: 24px; <?= str_ends_with($theme, 'transparent') ? '--vm-controls-bg: transparent;' : '' ?>" + > + <vm-audio preload="none"> + <?php $source = logged_in() ? $episode->audio_file_url : $episode->audio_file_analytics_url . + (isset($_SERVER['HTTP_REFERER']) + ? '?_from=' . + parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) + : '') ?> + <source src="<?= $source ?>" type="<?= $episode->audio_file_mimetype ?>" /> + </vm-audio> + <vm-ui> + <vm-icon-library name="castopod-icons"></vm-icon-library> + <vm-controls full-width> + <vm-playback-control></vm-playback-control> + <vm-volume-control></vm-volume-control> + <vm-current-time></vm-current-time> + <vm-scrubber-control></vm-scrubber-control> + <vm-end-time></vm-end-time> + </vm-controls> + </vm-ui> + </vm-player> </div> </body> diff --git a/app/Views/podcast/_layout.php b/app/Views/podcast/_layout.php index 0e7ab03790d336d815e0b32226f51832bfd70104..641e71314f123b4c9bfacd69d055f6b7bc17d3cb 100644 --- a/app/Views/podcast/_layout.php +++ b/app/Views/podcast/_layout.php @@ -15,53 +15,50 @@ <?= service('vite')->asset('styles/index.css', 'css') ?> <?= service('vite')->asset('js/podcast.ts', 'js') ?> + <?= service('vite')->asset('js/audio-player.ts', 'js') ?> </head> <body class="flex w-full min-h-screen pb-20 overflow-x-hidden lg:mx-auto lg:container bg-pine-50 sm:pb-0"> <?= $this->include('podcast/_partials/header') ?> <main class="flex-shrink-0 w-full min-w-0 sm:w-auto sm:flex-1 sm:flex-shrink"> + <nav class="sticky top-0 left-0 z-50 flex items-center w-full h-12 px-2 py-1 sm:hidden bg-pine-900"> + <button + data-toggle="main-header" + data-toggle-class="sticky -translate-x-full" + class="flex-shrink-0 mr-3 overflow-hidden rounded-full focus:ring-2 focus:outline-none focus:ring-pine-50"> + <img src="<?= $podcast->image + ->thumbnail_url ?>" alt="<?= $podcast->title ?>" class="h-10"/> + </button> + <p class="flex flex-col flex-1 min-w-0 mr-2 text-white"> + <span class="text-sm font-semibold truncate"><?= $podcast->title ?></span> + <span class="text-xs">@<?= $podcast->handle ?></span> + </p> + <?= anchor_popup( + route_to('follow', $podcast->handle), + icon( + 'social/castopod', + 'mr-2 text-xl text-pink-200 group-hover:text-pink-50', + ) . lang('Podcast.follow'), + [ + 'width' => 420, + 'height' => 620, + 'class' => + 'group inline-flex mr-2 items-center px-3 py-1 text-xs tracking-wider font-semibold text-white uppercase rounded-full shadow focus:outline-none focus:ring bg-rose-600', + ], + ) ?> + <button + data-toggle="main-sidebar" + data-toggle-class="translate-x-full" + data-toggle-body-class="-ml-64" + class="p-2 text-xl rounded-full focus:outline-none focus:ring-2 focus:ring-pine-600 text-pine-200 hover:text-pine-50"><?= icon( + 'menu', + ) ?><span class="sr-only"><?= lang('Podcast.toggle_podcast_sidebar') ?></span></button> + </nav> <?= $this->renderSection('content') ?> </main> <?= $this->include('podcast/_partials/sidebar') ?> - <nav class="fixed bottom-0 left-0 z-50 flex items-center w-full px-4 py-4 sm:hidden"> - <div class="flex items-center w-full p-2 rounded-full shadow-2xl bg-pine-900"> - <button - data-toggle="main-header" - data-toggle-class="sticky -translate-x-full" - class="flex-shrink-0 mr-3 overflow-hidden rounded-full focus:ring-2 focus:outline-none focus:ring-pine-50"> - <img src="<?= $podcast->image - ->thumbnail_url ?>" alt="<?= $podcast->title ?>" class="h-14"/> - </button> - <p class="flex flex-col flex-1 min-w-0 mr-2 text-white"> - <span class="text-sm font-semibold truncate"><?= $podcast->title ?></span> - <span class="text-xs">@<?= $podcast->handle ?></span> - </p> - <?= anchor_popup( - route_to('follow', $podcast->handle), - icon( - 'social/castopod', - 'mr-2 text-xl text-pink-200 group-hover:text-pink-50', - ) . lang('Podcast.follow'), - [ - 'width' => 420, - 'height' => 620, - 'class' => - 'group inline-flex items-center px-4 py-2 text-xs tracking-wider font-semibold text-white uppercase rounded-full shadow focus:outline-none focus:ring bg-rose-600', - ], - ) ?> - <button - data-toggle="main-sidebar" - data-toggle-class="translate-x-full" - data-toggle-body-class="-ml-64" - class="p-4 text-xl rounded-full focus:outline-none focus:ring-2 focus:ring-pine-600 text-pine-200 hover:text-pine-50"><?= icon( - 'menu', - ) ?><span class="sr-only"><?= lang( - 'Podcast.toggle_podcast_sidebar', -) ?></span></button> - </div> - </nav> <button data-toggle="main-sidebar" diff --git a/app/Views/podcast/_layout_authenticated.php b/app/Views/podcast/_layout_authenticated.php index 5834aade2fcb9be6a45a16a801228f8c78167262..83914136f023071ddd706bb78f3c4d692831f5c8 100644 --- a/app/Views/podcast/_layout_authenticated.php +++ b/app/Views/podcast/_layout_authenticated.php @@ -15,6 +15,7 @@ <?= service('vite')->asset('styles/index.css', 'css') ?> <?= service('vite')->asset('js/podcast.ts', 'js') ?> + <?= service('vite')->asset('js/audio-player.ts', 'js') ?> </head> <body class="flex w-full min-h-screen pt-12 pb-20 overflow-x-hidden bg-pine-50 lg:mx-auto lg:container sm:pb-0"> @@ -66,42 +67,44 @@ <?= $this->include('podcast/_partials/header') ?> <main class="flex-shrink-0 w-full min-w-0 sm:w-auto sm:flex-1 sm:flex-shrink"> + <nav class="sticky top-0 left-0 z-50 flex items-center w-full h-12 px-2 py-1 sm:hidden bg-pine-900"> + <button + data-toggle="main-header" + data-toggle-class="sticky -translate-x-full" + class="flex-shrink-0 mr-3 overflow-hidden rounded-full focus:ring-2 focus:outline-none focus:ring-pine-50"> + <img src="<?= $podcast->image + ->thumbnail_url ?>" alt="<?= $podcast->title ?>" class="h-10"/> + </button> + <p class="flex flex-col flex-1 min-w-0 mr-2 text-white"> + <span class="text-sm font-semibold truncate"><?= $podcast->title ?></span> + <span class="text-xs">@<?= $podcast->handle ?></span> + </p> + <?= anchor_popup( + route_to('follow', $podcast->handle), + icon( + 'social/castopod', + 'mr-2 text-xl text-pink-200 group-hover:text-pink-50', + ) . lang('Podcast.follow'), + [ + 'width' => 420, + 'height' => 620, + 'class' => + 'group inline-flex mr-2 items-center px-3 py-1 text-xs tracking-wider font-semibold text-white uppercase rounded-full shadow focus:outline-none focus:ring bg-rose-600', + ], + ) ?> + <button + data-toggle="main-sidebar" + data-toggle-class="translate-x-full" + data-toggle-body-class="-ml-64" + class="p-2 text-xl rounded-full focus:outline-none focus:ring-2 focus:ring-pine-600 text-pine-200 hover:text-pine-50"><?= icon( + 'menu', + ) ?><span class="sr-only"><?= lang('Podcast.toggle_podcast_sidebar') ?></span></button> + </nav> <?= $this->renderSection('content') ?> </main> <?= $this->include('podcast/_partials/sidebar') ?> - <nav class="fixed bottom-0 left-0 z-50 flex items-center w-full px-4 py-4 sm:hidden"> - <div class="flex items-center w-full p-2 rounded-full shadow-2xl bg-pine-900"> - <button data-toggle="main-header" data-toggle-class="sticky -translate-x-full" class="flex-shrink-0 mr-3 overflow-hidden rounded-full focus:ring-2 focus:outline-none focus:ring-pine-50"> - <img src="<?= $podcast->image - ->thumbnail_url ?>" alt="<?= $podcast->title ?>" class="h-14" /> - </button> - <p class="flex flex-col flex-1 min-w-0 mr-2 text-white"> - <span class="text-sm font-semibold truncate"><?= $podcast->title ?></span> - <span class="text-xs">@<?= $podcast->handle ?></span> - </p> - <?= anchor_popup( - route_to('follow', $podcast->handle), - icon( - 'social/castopod', - 'mr-2 text-xl text-pink-200 group-hover:text-pink-50', - ) . lang('Podcast.follow'), - [ - 'width' => 420, - 'height' => 620, - 'class' => - 'group inline-flex items-center px-4 py-2 text-xs tracking-wider font-semibold text-white uppercase rounded-full shadow focus:outline-none focus:ring bg-rose-600', - ], - ) ?> - <button data-toggle="main-sidebar" data-toggle-class="translate-x-full" data-toggle-body-class="-ml-64" class="p-4 text-xl rounded-full focus:outline-none focus:ring-2 focus:ring-pine-600 text-pine-200 hover:text-pine-50"><?= icon( - 'menu', - ) ?><span class="sr-only"><?= lang( - 'Podcast.toggle_podcast_sidebar', -) ?></span></button> - </div> - </nav> - <button data-toggle="main-sidebar" data-toggle-class="translate-x-full" data-toggle-body-class="-ml-64" class="fixed z-40 hidden p-4 text-xl rounded-full shadow-2xl sm:block lg:hidden bottom-4 left-4 bg-pine-900 focus:outline-none focus:ring-2 focus:ring-pine-600 text-pine-200 hover:text-pine-50"><?= icon( 'menu', ) ?><span class="sr-only"><?= lang( diff --git a/app/Views/podcast/_partials/episode_card.php b/app/Views/podcast/_partials/episode_card.php index c64e82bde109d7b2b9801fbbbaada29538def40a..9da514f0ecd1a91af9d33c99ce5a06d926755dc2 100644 --- a/app/Views/podcast/_partials/episode_card.php +++ b/app/Views/podcast/_partials/episode_card.php @@ -1,36 +1,47 @@ -<div class="flex"> - <img - src="<?= $episode->image->thumbnail_url ?>" - alt="<?= $episode->title ?>" class="w-24 h-24"/> - <div class="flex flex-col flex-1"> - <a href="<?= $episode->link ?>" class="flex-1 px-4 py-2 bg-gray-100"> - <div class="flex items-baseline"> - <span class="flex-1 w-0 mr-2 font-semibold leading-none truncate"><?= $episode->title ?></span> - <?= episode_numbering( - $episode->number, - $episode->season_number, - 'text-xs font-semibold text-gray-600', - true, +<article class="w-full mb-4 bg-white rounded-lg shadow"> + <div class="flex p-4"> + <div class="relative mr-2"> + <time class="absolute px-1 text-xs font-semibold text-white rounded bottom-2 right-2 bg-black/50" datetime="PT<?= $episode->audio_file_duration ?>S"> + <?= format_duration( + $episode->audio_file_duration, ) ?> - </div> - <div class="text-xs text-gray-800"> - <time - itemprop="published" - datetime="<?= $episode->published_at->format(DateTime::ATOM) ?>" - title="<?= $episode->published_at ?>"> - <?= lang('Common.mediumDate', [$episode->published_at]) ?> - </time> - <span class="mx-1">•</span> - <time datetime="PT<?= $episode->audio_file_duration ?>S"> - <?= format_duration($episode->audio_file_duration) ?> + </time> + <img loading="lazy" src="<?= $episode->image + ->thumbnail_url ?>" alt="<?= $episode->title ?>" class="object-cover w-20 h-20 rounded-lg" /> + </div> + <div class="flex flex-col flex-1"> + <a class="flex justify-between text-sm" href="<?= $episode->link ?>"> + <h2 class="flex-1 font-semibold hover:underline"> + <?= episode_numbering( + $episode->number, + $episode->season_number, + 'text-xs font-semibold text-gray-600', + true, + ) ?> + <span class="mx-1">-</span> + <?= $episode->title ?> + </h2> + <time class="text-xs whitespace-nowrap" itemprop="published" datetime="<?= $episode->published_at->format(DateTime::ATOM,) ?>" title="<?= $episode->published_at ?>"> + <?= lang('Common.mediumDate', [ + $episode->published_at, + ]) ?> </time> + </a> + <div class="flex mt-auto gap-x-4"> + <?= play_episode_button($episode->id, $episode->image->thumbnail_url, $episode->title, $podcast->title, $episode->audio_file_web_url, $episode->audio_file_mimetype, 'mt-auto') ?> + <?= anchor( + route_to('episode', $podcast->handle, $episode->slug), + icon('chat', 'text-xl mr-1 text-gray-400') . + $episode->statuses_total, + [ + 'class' => + 'inline-flex items-center hover:underline', + 'title' => lang('Episode.total_statuses', [ + 'numberOfTotalStatuses' => $episode->statuses_total, + ]), + ], + ) ?> </div> - </a> - <audio controls preload="none" class="w-full mt-auto"> - <source - src="<?= $episode->audio_file_web_url ?>" - type="<?= $episode->audio_file_mimetype ?>"> - Your browser does not support the audio tag. - </audio> + </div> </div> -</div> +</article> \ No newline at end of file diff --git a/app/Views/podcast/_partials/episode_preview_card.php b/app/Views/podcast/_partials/episode_preview_card.php new file mode 100644 index 0000000000000000000000000000000000000000..15b5292c043d185cee1d75f7d9dcccc56c829fd4 --- /dev/null +++ b/app/Views/podcast/_partials/episode_preview_card.php @@ -0,0 +1,32 @@ +<div class="flex"> + <div class="relative"> + <time class="absolute px-1 text-sm font-semibold text-white bg-black/50 bottom-2 right-2" datetime="PT<?= $episode->audio_file_duration ?>S"> + <?= format_duration($episode->audio_file_duration) ?> + </time> + <img + src="<?= $episode->image->thumbnail_url ?>" + alt="<?= $episode->title ?>" class="w-24 h-24"/> + </div> + <div class="flex flex-col flex-1 px-4 py-2 border-t border-b"> + <a href="<?= $episode->link ?>" class="flex justify-between flex-1"> + <div class="flex items-baseline font-semibold"> + <?= episode_numbering( + $episode->number, + $episode->season_number, + 'text-xs font-semibold text-gray-600', + true, + ) ?> + <span class="mx-1">-</span> + <?= $episode->title ?> + </div> + <time + class="text-xs" + itemprop="published" + datetime="<?= $episode->published_at->format(DateTime::ATOM) ?>" + title="<?= $episode->published_at ?>"> + <?= lang('Common.mediumDate', [$episode->published_at]) ?> + </time> + </a> + <?= play_episode_button($episode->id, $episode->image->thumbnail_url, $episode->title, $podcast->title, $episode->audio_file_web_url, $episode->audio_file_mimetype, 'mt-auto') ?> + </div> +</div> diff --git a/app/Views/podcast/_partials/reblog.php b/app/Views/podcast/_partials/reblog.php index 6d953688117d8c977897014a9747c77515b4ae9b..bcf979ea74664bd8f2ad4bb3113f5d7d6d1c3507 100644 --- a/app/Views/podcast/_partials/reblog.php +++ b/app/Views/podcast/_partials/reblog.php @@ -35,7 +35,7 @@ </header> <div class="px-6 mb-4 status-content"><?= $status->message_html ?></div> <?php if ($status->episode_id): ?> - <?= view('podcast/_partials/episode_card', [ + <?= view('podcast/_partials/episode_preview_card', [ 'episode' => $status->episode, ]) ?> <?php elseif ($status->has_preview_card): ?> diff --git a/app/Views/podcast/_partials/reblog_authenticated.php b/app/Views/podcast/_partials/reblog_authenticated.php index c8d32585410749c08cdac2c6a198909d8fc93c7a..a4d12387654693b6d0656ec314f58a16c005488d 100644 --- a/app/Views/podcast/_partials/reblog_authenticated.php +++ b/app/Views/podcast/_partials/reblog_authenticated.php @@ -35,7 +35,7 @@ </header> <div class="px-6 mb-4 status-content"><?= $status->message_html ?></div> <?php if ($status->episode_id): ?> - <?= view('podcast/_partials/episode_card', [ + <?= view('podcast/_partials/episode_preview_card', [ 'episode' => $status->episode, ]) ?> <?php elseif ($status->has_preview_card): ?> diff --git a/app/Views/podcast/_partials/status.php b/app/Views/podcast/_partials/status.php index 641869a3f7338239f42fb2c69e540fd29a4ebca2..9d3b0f186ecb7d36185466d4da4e51526ef743b3 100644 --- a/app/Views/podcast/_partials/status.php +++ b/app/Views/podcast/_partials/status.php @@ -1,4 +1,4 @@ -<article class="relative z-10 w-full bg-white shadow-md rounded-2xl"> +<article class="relative z-10 w-full bg-white shadow rounded-2xl"> <header class="flex px-6 py-4"> <img src="<?= $status->actor ->avatar_image_url ?>" alt="<?= $status->display_name ?>" class="w-12 h-12 mr-4 rounded-full" /> @@ -28,7 +28,7 @@ </header> <div class="px-6 mb-4 status-content"><?= $status->message_html ?></div> <?php if ($status->episode_id): ?> - <?= view('podcast/_partials/episode_card', [ + <?= view('podcast/_partials/episode_preview_card', [ 'episode' => $status->episode, ]) ?> <?php elseif ($status->has_preview_card): ?> diff --git a/app/Views/podcast/_partials/status_authenticated.php b/app/Views/podcast/_partials/status_authenticated.php index a7db296ac31fef90307bdcecae92e67d7c17e32f..3a1771c900cb6fe66b865d49920aaa6bf87aa88d 100644 --- a/app/Views/podcast/_partials/status_authenticated.php +++ b/app/Views/podcast/_partials/status_authenticated.php @@ -28,7 +28,7 @@ </header> <div class="px-6 mb-4 status-content"><?= $status->message_html ?></div> <?php if ($status->episode_id): ?> - <?= view('podcast/_partials/episode_card', [ + <?= view('podcast/_partials/episode_preview_card', [ 'episode' => $status->episode, ]) ?> <?php elseif ($status->has_preview_card): ?> diff --git a/app/Views/podcast/activity.php b/app/Views/podcast/activity.php index 47106a1953a8f9374524f0c457857857f4fec679..75bdbee563a001f60edda1ab2af9b44ff8eceba1 100644 --- a/app/Views/podcast/activity.php +++ b/app/Views/podcast/activity.php @@ -18,11 +18,13 @@ <meta property="og:image:width" content="<?= config('Images')->largeSize ?>" /> <meta property="og:image:height" content="<?= config('Images')->largeSize ?>" /> <meta name="twitter:card" content="summary_large_image" /> + +<?= service('vite')->asset('styles/index.css', 'css') ?> <?= $this->endSection() ?> <?= $this->section('content') ?> -<nav class="sticky top-0 z-20 flex justify-center pt-2 text-lg bg-pine-50"> +<nav class="sticky z-20 flex justify-center pt-2 text-lg sm:top-0 top-12 bg-pine-50"> <a href="<?= route_to( 'podcast-activity', $podcast->handle, diff --git a/app/Views/podcast/activity_authenticated.php b/app/Views/podcast/activity_authenticated.php index de36b3574d93effa65da6a8f7da7b63e0d843dc2..d8404171a1c38636c19c26d86c02437c7013882e 100644 --- a/app/Views/podcast/activity_authenticated.php +++ b/app/Views/podcast/activity_authenticated.php @@ -18,11 +18,13 @@ <meta property="og:image:width" content="<?= config('Images')->largeSize ?>" /> <meta property="og:image:height" content="<?= config('Images')->largeSize ?>" /> <meta name="twitter:card" content="summary_large_image" /> + +<?= service('vite')->asset('styles/index.css', 'css') ?> <?= $this->endSection() ?> <?= $this->section('content') ?> -<nav class="sticky top-0 z-20 flex justify-center pt-2 text-lg bg-pine-50"> +<nav class="sticky z-20 flex justify-center pt-2 text-lg top-12 sm:top-0 bg-pine-50"> <a href="<?= route_to( 'podcast-activity', $podcast->handle, diff --git a/app/Views/podcast/episode.php b/app/Views/podcast/episode.php index 2f5f17d17eea5db49e76f0f7ae4bd39b08e797b3..834de56a3418380291c52eab49f05a667d6b9d14 100644 --- a/app/Views/podcast/episode.php +++ b/app/Views/podcast/episode.php @@ -113,12 +113,9 @@ </div> <?= location_link($episode->location, 'text-sm mb-4') ?> <?= person_list($episode->persons) ?> + <?= play_episode_button($episode->id, $episode->image->thumbnail_url, $episode->title, $podcast->title, $episode->audio_file_web_url, $episode->audio_file_mimetype) ?> </div> </div> - <audio controls preload="none" class="w-full mt-auto"> - <source src="<?= $episode->audio_file_web_url ?>" type="<?= $episode->audio_file_mimetype ?>"> - Your browser does not support the audio tag. - </audio> </header> <div class="tabset"> diff --git a/app/Views/podcast/episode_authenticated.php b/app/Views/podcast/episode_authenticated.php index 38fb1db1a721a30fad5a69d8771508b2de59b638..695cddd0cf36567595d6178ac9e2c54f8d792ed4 100644 --- a/app/Views/podcast/episode_authenticated.php +++ b/app/Views/podcast/episode_authenticated.php @@ -113,12 +113,9 @@ </div> <?= location_link($episode->location, 'text-sm mb-4') ?> <?= person_list($episode->persons) ?> + <?= play_episode_button($episode->id, $episode->image->thumbnail_url, $episode->title, $podcast->title, $episode->audio_file_web_url, $episode->audio_file_mimetype) ?> </div> </div> - <audio controls preload="none" class="w-full mt-auto"> - <source src="<?= $episode->audio_file_web_url ?>" type="<?= $episode->audio_file_mimetype ?>"> - Your browser does not support the audio tag. - </audio> </header> <div class="tabset"> diff --git a/app/Views/podcast/episodes.php b/app/Views/podcast/episodes.php index 6e3c3ca70c22241c3fbace4c8ed5df248214e8f3..ca97759f67678f8a9c330ea4b53e829f44207c75 100644 --- a/app/Views/podcast/episodes.php +++ b/app/Views/podcast/episodes.php @@ -18,10 +18,12 @@ <meta property="og:image:width" content="<?= config('Images')->largeSize ?>" /> <meta property="og:image:height" content="<?= config('Images')->largeSize ?>" /> <meta name="twitter:card" content="summary_large_image" /> + +<?= service('vite')->asset('styles/index.css', 'css') ?> <?= $this->endSection() ?> <?= $this->section('content') ?> -<nav class="sticky top-0 flex items-center justify-center pt-2 text-lg bg-pine-50"> +<nav class="sticky z-20 flex items-center justify-center pt-2 text-lg top-12 sm:top-0 bg-pine-50"> <a href="<?= route_to( 'podcast-activity', $podcast->handle, @@ -79,85 +81,9 @@ <?php endif; ?> </h1> <?php foreach ($episodes as $episode): ?> - <article class="w-full mb-4 bg-white rounded-lg shadow"> - <div class="flex px-4 pt-4 pb-2"> - <img loading="lazy" src="<?= $episode->image - ->thumbnail_url ?>" alt="<?= $episode->title ?>" class="object-cover w-20 h-20 mr-2 rounded-lg" /> - <div class="flex flex-col flex-1"> - <a class="text-sm" href="<?= $episode->link ?>"> - <h2 class="inline-flex justify-between w-full font-semibold leading-none group"> - <span class="mr-1 group-hover:underline"><?= $episode->title ?></span> - <?= episode_numbering( - $episode->number, - $episode->season_number, - 'text-xs font-semibold text-gray-600', - true, - ) ?> - </h2> - </a> - <div class="mb-2 text-xs"> - <time itemprop="published" datetime="<?= $episode->published_at->format( - DateTime::ATOM, - ) ?>" title="<?= $episode->published_at ?>"> - <?= lang('Common.mediumDate', [ - $episode->published_at, - ]) ?> - </time> - <span class="mx-1">•</span> - <time datetime="PT<?= $episode->audio_file_duration ?>S"> - <?= format_duration( - $episode->audio_file_duration, - ) ?> - </time> - </div> - <audio controls preload="none" class="w-full mt-auto"> - <source src="<?= $episode->audio_file_web_url ?>" type="<?= $episode->audio_file_mimetype ?>"> - Your browser does not support the audio tag. - </audio> - </div> - </div> - <div class="px-4 py-2 space-x-4 text-sm"> - <?= anchor( - route_to('episode', $podcast->handle, $episode->slug), - icon('chat', 'text-xl mr-1 text-gray-400') . - $episode->statuses_total, - [ - 'class' => - 'inline-flex items-center hover:underline', - 'title' => lang('Episode.total_statuses', [ - 'numberOfTotalStatuses' => $episode->statuses_total, - ]), - ], - ) ?> - <?= anchor( - route_to('episode', $podcast->handle, $episode->slug), - icon('repeat', 'text-xl mr-1 text-gray-400') . - $episode->reblogs_total, - [ - 'class' => - 'inline-flex items-center hover:underline', - 'title' => lang('Episode.total_reblogs', [ - 'numberOfTotalReblogs' => - $episode->reblogs_total, - ]), - ], - ) ?> - - <?= anchor( - route_to('episode', $podcast->handle, $episode->slug), - icon('heart', 'text-xl mr-1 text-gray-400') . - $episode->favourites_total, - [ - 'class' => - 'inline-flex items-center hover:underline', - 'title' => lang('Episode.total_favourites', [ - 'numberOfTotalFavourites' => - $episode->favourites_total, - ]), - ], - ) ?> - </div> - </article> + <?= view('podcast/_partials/episode_card', [ + 'episode' => $episode, + ]) ?> <?php endforeach; ?> <?php else: ?> <h1 class="px-4 mb-2 text-xl text-center"><?= lang( diff --git a/app/Views/podcast/episodes_authenticated.php b/app/Views/podcast/episodes_authenticated.php index 2fb852263a294a77b3331b9fa8ecf2835bb2ed0d..09b38ede83ea66d507246c4846a82cf05d1fe9f9 100644 --- a/app/Views/podcast/episodes_authenticated.php +++ b/app/Views/podcast/episodes_authenticated.php @@ -5,8 +5,8 @@ <title><?= $podcast->title ?></title> <meta name="description" content="<?= htmlspecialchars( - $podcast->description, -) ?>" /> + $podcast->description, + ) ?>" /> <link rel="shortcut icon" type="image/png" href="/favicon.ico" /> <link rel="canonical" href="<?= current_url() ?>" /> <meta property="og:title" content="<?= $podcast->title ?>" /> @@ -18,26 +18,28 @@ <meta property="og:image:width" content="<?= config('Images')->largeSize ?>" /> <meta property="og:image:height" content="<?= config('Images')->largeSize ?>" /> <meta name="twitter:card" content="summary_large_image" /> + +<?= service('vite')->asset('styles/index.css', 'css') ?> <?= $this->endSection() ?> <?= $this->section('content') ?> -<nav class="sticky top-0 flex items-center justify-center pt-2 text-lg bg-pine-50"> +<nav class="sticky z-20 flex items-center justify-center pt-2 text-lg top-12 sm:top-0 bg-pine-50"> <a href="<?= route_to( - 'podcast-activity', - $podcast->handle, - ) ?>" class="px-4 py-1 mr-8 rounded-full hover:bg-pine-100"><?= lang( - 'Podcast.activity', -) ?></a> + 'podcast-activity', + $podcast->handle, + ) ?>" class="px-4 py-1 mr-8 rounded-full hover:bg-pine-100"><?= lang( + 'Podcast.activity', + ) ?></a> <a href="<?= route_to( - 'podcast-episodes', - $podcast->handle, - ) ?>" class="px-4 py-1 font-semibold border-b-4 text-pine-800 border-pine-800"><?= lang( - 'Podcast.episodes', -) ?></a> - <?php if ($activeQuery): ?> + 'podcast-episodes', + $podcast->handle, + ) ?>" class="px-4 py-1 font-semibold border-b-4 text-pine-800 border-pine-800"><?= lang( + 'Podcast.episodes', + ) ?></a> + <?php if ($activeQuery) : ?> <button id="episode-lists-dropdown" type="button" class="inline-flex items-center px-2 py-1 text-sm font-semibold outline-none focus:ring" data-dropdown="button" data-dropdown-target="episode-lists-dropdown-menu" aria-label="<?= lang( - 'Common.more', - ) ?>" aria-haspopup="true" aria-expanded="false"> + 'Common.more', + ) ?>" aria-haspopup="true" aria-expanded="false"> <?= $activeQuery['label'] . ' (' . $activeQuery['number_of_episodes'] . @@ -45,13 +47,13 @@ icon('caret-down', 'ml-2 text-xl') ?> </button> <nav id="episode-lists-dropdown-menu" class="flex flex-col py-2 text-black bg-white border rounded shadow" aria-labelledby="episode-lists-dropdown" data-dropdown="menu" data-dropdown-placement="bottom-end"> - <?php foreach ($episodesNav as $link): ?> + <?php foreach ($episodesNav as $link) : ?> <?= anchor( $link['route'], $link['label'] . ' (' . $link['number_of_episodes'] . ')', [ 'class' => - 'px-2 py-1 whitespace-nowrap ' . + 'px-2 py-1 whitespace-nowrap ' . ($link['is_active'] ? 'font-semibold' : 'text-gray-600 hover:text-gray-900'), @@ -64,104 +66,29 @@ <section class="flex flex-col max-w-2xl px-6 py-8 mx-auto"> - <?php if ($episodes): ?> + <?php if ($episodes) : ?> <h1 class="mb-4 text-xl font-semibold"> - <?php if ($activeQuery['type'] == 'year'): ?> + <?php if ($activeQuery['type'] == 'year') : ?> <?= lang('Podcast.list_of_episodes_year', [ 'year' => $activeQuery['value'], 'episodeCount' => count($episodes), ]) ?> - <?php elseif ($activeQuery['type'] == 'season'): ?> + <?php elseif ($activeQuery['type'] == 'season') : ?> <?= lang('Podcast.list_of_episodes_season', [ 'seasonNumber' => $activeQuery['value'], 'episodeCount' => count($episodes), ]) ?> <?php endif; ?> </h1> - <?php foreach ($episodes as $episode): ?> - <article class="w-full mb-4 bg-white rounded-lg shadow"> - <div class="flex px-4 pt-4 pb-2"> - <img loading="lazy" src="<?= $episode->image - ->thumbnail_url ?>" alt="<?= $episode->title ?>" class="object-cover w-20 h-20 mr-2 rounded-lg" /> - <div class="flex flex-col flex-1"> - <a class="text-sm" href="<?= $episode->link ?>"> - <h2 class="inline-flex justify-between w-full font-semibold leading-none group"> - <span class="mr-1 group-hover:underline"><?= $episode->title ?></span> - <?= episode_numbering( - $episode->number, - $episode->season_number, - 'text-xs font-semibold text-gray-600', - true, - ) ?> - </h2> - </a> - <div class="mb-2 text-xs"> - <time itemprop="published" datetime="<?= $episode->published_at->format( - DateTime::ATOM, - ) ?>" title="<?= $episode->published_at ?>"> - <?= lang('Common.mediumDate', [ - $episode->published_at, - ]) ?> - </time> - <span class="mx-1">•</span> - <time datetime="PT<?= $episode->audio_file_duration ?>S"> - <?= format_duration( - $episode->audio_file_duration, - ) ?> - </time> - </div> - <audio controls preload="none" class="w-full mt-auto"> - <source src="<?= $episode->audio_file_web_url ?>" type="<?= $episode->audio_file_mimetype ?>"> - Your browser does not support the audio tag. - </audio> - </div> - </div> - <div class="px-4 py-2 space-x-4 text-sm"> - <?= anchor( - route_to('episode', $podcast->handle, $episode->slug), - icon('chat', 'text-xl mr-1 text-gray-400') . - $episode->statuses_total, - [ - 'class' => - 'inline-flex items-center hover:underline', - 'title' => lang('Episode.total_statuses', [ - 'numberOfTotalStatuses' => $episode->statuses_total, - ]), - ], - ) ?> - <?= anchor( - route_to('episode', $podcast->handle, $episode->slug), - icon('repeat', 'text-xl mr-1 text-gray-400') . - $episode->reblogs_total, - [ - 'class' => - 'inline-flex items-center hover:underline', - 'title' => lang('Episode.total_reblogs', [ - 'numberOfTotalReblogs' => - $episode->reblogs_total, - ]), - ], - ) ?> - <?= anchor( - route_to('episode', $podcast->handle, $episode->slug), - icon('heart', 'text-xl mr-1 text-gray-400') . - $episode->favourites_total, - [ - 'class' => - 'inline-flex items-center hover:underline', - 'title' => lang('Episode.total_favourites', [ - 'numberOfTotalFavourites' => - $episode->favourites_total, - ]), - ], - ) ?> - </div> - </article> + <?php foreach ($episodes as $episode) : ?> + <?= view('podcast/_partials/episode_card', [ + 'episode' => $episode, + ]) ?> <?php endforeach; ?> - <?php else: ?> + <?php else : ?> <h1 class="px-4 mb-2 text-xl text-center"><?= lang( - 'Podcast.no_episode', - ) ?></h1> + 'Podcast.no_episode', + ) ?></h1> <p class="italic text-center"><?= lang('Podcast.no_episode_hint') ?></p> <?php endif; ?> </section> diff --git a/app/Views/podcast/follow.php b/app/Views/podcast/follow.php index 227ddc8ca016b00f876f07d8ef405fa17babc76a..aef1249ad445091dc899add3626fbfda0074a093 100644 --- a/app/Views/podcast/follow.php +++ b/app/Views/podcast/follow.php @@ -8,20 +8,22 @@ <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="shortcut icon" type="image/png" href="/favicon.ico" /> <?= service('vite')->asset('styles/index.css', 'css') ?> - + <title><?= lang('Podcast.follow.title', [ 'actorDisplayName' => $actor->display_name, - ]) ?></title> + ]) ?></title> <meta name="description" content="<?= $actor->summary ?>"/> <meta property="og:title" content="<?= lang('Podcast.follow.title', [ 'actorDisplayName' => $actor->display_name, - ]) ?>"/> + ]) ?>"/> <meta property="og:locale" content="<?= service( 'request', - )->getLocale() ?>" /> + )->getLocale() ?>" /> <meta property="og:url" content="<?= current_url() ?>" /> <meta property="og:image" content="<?= $actor->avatar_image_url ?>" /> <meta property="og:description" content="<?= $actor->summary ?>" /> + + <?= service('vite')->asset('styles/index.css', 'css') ?> </head> diff --git a/package-lock.json b/package-lock.json index 9114c24b478f96a8c1c854d4a4004e61570ccb22..098dd27692248b52a27aec8e730299812165145d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@amcharts/amcharts4-geodata": "^4.1.21", "@github/markdown-toolbar-element": "^1.5.1", "@popperjs/core": "^2.9.2", + "@vime/core": "^5.0.33", "choices.js": "^9.0.1", "flatpickr": "^4.6.9", "leaflet": "^1.7.1", @@ -1809,6 +1810,18 @@ "url": "https://github.com/sindresorhus/is?sponsor=1" } }, + "node_modules/@stencil/core": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.8.1.tgz", + "integrity": "sha512-iv9J6oLO/lv7/aO45M05yw3pp1J7olY400vlOZgdMVs3s5zHfalY1ZPYM0KyqU4+7DZuadKYbd0aQZ/g2PInZw==", + "bin": { + "stencil": "bin/stencil" + }, + "engines": { + "node": ">=12.10.0", + "npm": ">=6.0.0" + } + }, "node_modules/@stylelint/postcss-css-in-js": { "version": "0.37.2", "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.2.tgz", @@ -1911,6 +1924,11 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "node_modules/@types/fscreen": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/fscreen/-/fscreen-1.0.1.tgz", + "integrity": "sha512-hV2d0BreihMGtrg+EdAFOIl/O2EL5vhAheHJUztGE/lPFZIN8ZCpGFL8hCbtyi1CfhKjDRCf47sHjP+FwJ4q0Q==" + }, "node_modules/@types/geojson": { "version": "7946.0.8", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz", @@ -2303,6 +2321,18 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@vime/core": { + "version": "5.0.33", + "resolved": "https://registry.npmjs.org/@vime/core/-/core-5.0.33.tgz", + "integrity": "sha512-mpWT/wDALAdzhowskJ1YgQl8ThSQuhgHQVAhLn2Bd3yg2Vgw9rkuLC00c98dHXNTEE/sn2tdyiu9YnJ8EwknQQ==", + "dependencies": { + "@stencil/core": "^2.5.2", + "@types/fscreen": "^1.0.1", + "fscreen": "^1.2.0", + "mitt": "^2.1.0", + "stencil-wormhole": "^3.2.2" + } + }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -6436,6 +6466,7 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, +<<<<<<< HEAD "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -6449,6 +6480,12 @@ "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } +======= + "node_modules/fscreen": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fscreen/-/fscreen-1.2.0.tgz", + "integrity": "sha512-hlq4+BU0hlPmwsFjwGGzZ+OZ9N/wq9Ljg/sq3pX+2CD7hrJsX9tJgWWK/wiNTFM212CLHWhicOoqwXyZGGetJg==" +>>>>>>> 9bcc04c (feat: add js audio player on podcast, admin and embeddable player pages + fix admon episodes ux) }, "node_modules/function-bind": { "version": "1.1.1", @@ -8875,6 +8912,11 @@ "node": ">= 6" } }, + "node_modules/mitt": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-2.1.0.tgz", + "integrity": "sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==" + }, "node_modules/modern-normalize": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/modern-normalize/-/modern-normalize-1.1.0.tgz", @@ -17295,6 +17337,11 @@ "node": ">= 0.8.0" } }, + "node_modules/stencil-wormhole": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/stencil-wormhole/-/stencil-wormhole-3.4.1.tgz", + "integrity": "sha512-ppYTcWTJnIl4ZAKwF39LTA9f/ypHfbVefsHdN2hpMQGrR57wt1TieZo9tlCM/r1Y4SFiZ5yz/cjho564C921Xw==" + }, "node_modules/stream-combiner2": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", @@ -20816,6 +20863,11 @@ "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==", "dev": true }, + "@stencil/core": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.8.1.tgz", + "integrity": "sha512-iv9J6oLO/lv7/aO45M05yw3pp1J7olY400vlOZgdMVs3s5zHfalY1ZPYM0KyqU4+7DZuadKYbd0aQZ/g2PInZw==" + }, "@stylelint/postcss-css-in-js": { "version": "0.37.2", "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.2.tgz", @@ -20901,6 +20953,11 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/fscreen": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/fscreen/-/fscreen-1.0.1.tgz", + "integrity": "sha512-hV2d0BreihMGtrg+EdAFOIl/O2EL5vhAheHJUztGE/lPFZIN8ZCpGFL8hCbtyi1CfhKjDRCf47sHjP+FwJ4q0Q==" + }, "@types/geojson": { "version": "7946.0.8", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz", @@ -21204,6 +21261,18 @@ "eslint-visitor-keys": "^2.0.0" } }, + "@vime/core": { + "version": "5.0.33", + "resolved": "https://registry.npmjs.org/@vime/core/-/core-5.0.33.tgz", + "integrity": "sha512-mpWT/wDALAdzhowskJ1YgQl8ThSQuhgHQVAhLn2Bd3yg2Vgw9rkuLC00c98dHXNTEE/sn2tdyiu9YnJ8EwknQQ==", + "requires": { + "@stencil/core": "^2.5.2", + "@types/fscreen": "^1.0.1", + "fscreen": "^1.2.0", + "mitt": "^2.1.0", + "stencil-wormhole": "^3.2.2" + } + }, "abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -24430,12 +24499,19 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, +<<<<<<< HEAD "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true +======= + "fscreen": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fscreen/-/fscreen-1.2.0.tgz", + "integrity": "sha512-hlq4+BU0hlPmwsFjwGGzZ+OZ9N/wq9Ljg/sq3pX+2CD7hrJsX9tJgWWK/wiNTFM212CLHWhicOoqwXyZGGetJg==" +>>>>>>> 9bcc04c (feat: add js audio player on podcast, admin and embeddable player pages + fix admon episodes ux) }, "function-bind": { "version": "1.1.1", @@ -25677,25 +25753,1762 @@ "dev": true }, "lint-staged": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.2.6.tgz", - "integrity": "sha512-Vti55pUnpvPE0J9936lKl0ngVeTdSZpEdTNhASbkaWX7J5R9OEifo1INBGQuGW4zmy6OG+TcWPJ3m5yuy5Q8Tg==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.2.6.tgz", + "integrity": "sha512-Vti55pUnpvPE0J9936lKl0ngVeTdSZpEdTNhASbkaWX7J5R9OEifo1INBGQuGW4zmy6OG+TcWPJ3m5yuy5Q8Tg==", + "dev": true, + "requires": { + "cli-truncate": "2.1.0", + "colorette": "^1.4.0", + "commander": "^8.2.0", + "cosmiconfig": "^7.0.1", + "debug": "^4.3.2", + "enquirer": "^2.3.6", + "execa": "^5.1.1", + "listr2": "^3.12.2", + "micromatch": "^4.0.4", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.2.0", + "string-argv": "0.3.1", + "stringify-object": "3.3.0", + "supports-color": "8.1.1" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "listr2": { + "version": "3.13.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.13.5.tgz", + "integrity": "sha512-3n8heFQDSk+NcwBn3CgxEibZGaRzx+pC64n3YjpMD1qguV4nWus3Al+Oo3KooqFKTQEJ1v7MmnbnyyNspgx3NA==", + "dev": true, + "requires": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.4.0", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "colorette": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", + "dev": true + }, + "rxjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.4.0.tgz", + "integrity": "sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==", + "dev": true, + "requires": { + "tslib": "~2.1.0" + } + }, + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + } + } + }, + "lit": { + "version": "2.0.0-rc.2", + "resolved": "https://registry.npmjs.org/lit/-/lit-2.0.0-rc.2.tgz", + "integrity": "sha512-BOCuoJR04WaTV8UqTKk09cNcQA10Aq2LCcBOiHuF7TzWH5RNDsbCBP5QM9sLBSotGTXbDug/gFO08jq6TbyEtw==", + "dev": true, + "requires": { + "@lit/reactive-element": "^1.0.0-rc.2", + "lit-element": "^3.0.0-rc.2", + "lit-html": "^2.0.0-rc.3" + } + }, + "lit-element": { + "version": "3.0.0-rc.2", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.0.0-rc.2.tgz", + "integrity": "sha512-2Z7DabJ3b5K+p5073vFjMODoaWqy5PIaI4y6ADKm+fCGc8OnX9fU9dMoUEBZjFpd/bEFR9PBp050tUtBnT9XTQ==", + "dev": true, + "requires": { + "@lit/reactive-element": "^1.0.0-rc.2", + "lit-html": "^2.0.0-rc.3" + } + }, + "lit-html": { + "version": "2.0.0-rc.3", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.0.0-rc.3.tgz", + "integrity": "sha512-Y6P8LlAyQuqvzq6l/Nc4z5/P5M/rVLYKQIRxcNwSuGajK0g4kbcBFQqZmgvqKG+ak+dHZjfm2HUw9TF5N/pkCw==", + "dev": true, + "requires": { + "@types/trusted-types": "^1.0.1" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.capitalize": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", + "integrity": "sha1-+CbJtOKoUR2E46yinbBeGk87cqk=", + "dev": true + }, + "lodash.castarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", + "integrity": "sha1-wCUTUV4wna3dTCTGDP3c9ZdtkRU=", + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", + "dev": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", + "dev": true + }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.topath": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz", + "integrity": "sha1-NhY1Hzu6YZlKCTGYlmC9AyVP0Ak=", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI=", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "longest": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-2.0.1.tgz", + "integrity": "sha1-eB4YMpaqlPbU2RbcM10NF676I/g=", + "dev": true + }, + "longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "magic-string": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.1.tgz", + "integrity": "sha512-sCuTz6pYom8Rlt4ISPFn6wuFodbKMIHUMv4Qko9P17dpxb7s52KJTmRuZZqHdGmLCK9AOcDare039nRIcfdkEg==", + "requires": { + "sourcemap-codec": "^1.4.1" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "map-obj": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.0.tgz", + "integrity": "sha512-NAq0fCmZYGz9UFEQyndp7sisrow4GroyGeKluyKC/chuITZsPyOyC1UJZPJlVFImhXdROIP5xqouRLThT3BbpQ==", + "dev": true + }, + "marked": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", + "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==" + }, + "marked-terminal": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-4.2.0.tgz", + "integrity": "sha512-DQfNRV9svZf0Dm9Cf5x5xaVJ1+XjxQW6XjFJ5HFkVyK52SDpj5PCBzS5X5r2w9nHr3mlB0T5201UMLue9fmhUw==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.1", + "cardinal": "^2.1.1", + "chalk": "^4.1.0", + "cli-table3": "^0.6.0", + "node-emoji": "^1.10.0", + "supports-hyperlinks": "^2.1.0" + }, + "dependencies": { + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } + } + }, + "mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true + }, + "mdast-util-from-markdown": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "dev": true, + "requires": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + } + }, + "mdast-util-to-markdown": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", + "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^2.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" + } + }, + "mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", + "dev": true + }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + } + }, + "merge-source-map": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz", + "integrity": "sha1-pd5GU42uhNQRTMXqArR3KmNGcB8=", + "requires": { + "source-map": "^0.5.6" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromark": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "dev": true, + "requires": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + } + }, + "mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true + }, + "mime-db": { + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", + "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==" + }, + "mime-types": { + "version": "2.1.28", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", + "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", + "requires": { + "mime-db": "1.45.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "dev": true + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "mini-svg-data-uri": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.2.3.tgz", + "integrity": "sha512-zd6KCAyXgmq6FV1mR10oKXYtvmA9vRoB6xPSTUJTbFApCtkefDnYueVR1gkof3KcdLZo1Y8mjF2DFmQMIxsHNQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + } + }, + "modern-normalize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/modern-normalize/-/modern-normalize-1.1.0.tgz", + "integrity": "sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA==", + "dev": true + }, + "modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "nanoid": { + "version": "3.1.30", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", + "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "nerf-dart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", + "integrity": "sha1-5tq3/r9a2Bbqgc9cYpxaDr3nLBo=", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "requires": { + "lodash": "^4.17.21" + } + }, + "node-fetch": { + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz", + "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } + }, + "node-releases": { + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", + "dev": true + }, + "normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true + }, + "normalize-selector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", + "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", + "dev": true + }, + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true + }, + "npm": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/npm/-/npm-7.24.2.tgz", + "integrity": "sha512-120p116CE8VMMZ+hk8IAb1inCPk4Dj3VZw29/n2g6UI77urJKVYb7FZUDW8hY+EBnfsjI/2yrobBgFyzo7YpVQ==", + "dev": true, + "requires": { + "@isaacs/string-locale-compare": "*", + "@npmcli/arborist": "*", + "@npmcli/ci-detect": "*", + "@npmcli/config": "*", + "@npmcli/map-workspaces": "*", + "@npmcli/package-json": "*", + "@npmcli/run-script": "*", + "abbrev": "*", + "ansicolors": "*", + "ansistyles": "*", + "archy": "*", + "cacache": "*", + "chalk": "*", + "chownr": "*", + "cli-columns": "*", + "cli-table3": "*", + "columnify": "*", + "fastest-levenshtein": "*", + "glob": "*", + "graceful-fs": "*", + "hosted-git-info": "*", + "ini": "*", + "init-package-json": "*", + "is-cidr": "*", + "json-parse-even-better-errors": "*", + "libnpmaccess": "*", + "libnpmdiff": "*", + "libnpmexec": "*", + "libnpmfund": "*", + "libnpmhook": "*", + "libnpmorg": "*", + "libnpmpack": "*", + "libnpmpublish": "*", + "libnpmsearch": "*", + "libnpmteam": "*", + "libnpmversion": "*", + "make-fetch-happen": "*", + "minipass": "*", + "minipass-pipeline": "*", + "mkdirp": "*", + "mkdirp-infer-owner": "*", + "ms": "*", + "node-gyp": "*", + "nopt": "*", + "npm-audit-report": "*", + "npm-install-checks": "*", + "npm-package-arg": "*", + "npm-pick-manifest": "*", + "npm-profile": "*", + "npm-registry-fetch": "*", + "npm-user-validate": "*", + "npmlog": "*", + "opener": "*", + "pacote": "*", + "parse-conflict-json": "*", + "qrcode-terminal": "*", + "read": "*", + "read-package-json": "*", + "read-package-json-fast": "*", + "readdir-scoped-modules": "*", + "rimraf": "*", + "semver": "*", + "ssri": "*", + "tar": "*", + "text-table": "*", + "tiny-relative-date": "*", + "treeverse": "*", + "validate-npm-package-name": "*", + "which": "*", + "write-file-atomic": "*" + }, + "dependencies": { + "@gar/promisify": { + "version": "1.1.2", + "bundled": true, + "dev": true + }, + "@isaacs/string-locale-compare": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "@npmcli/arborist": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "requires": { + "@isaacs/string-locale-compare": "^1.0.1", + "@npmcli/installed-package-contents": "^1.0.7", + "@npmcli/map-workspaces": "^1.0.2", + "@npmcli/metavuln-calculator": "^1.1.0", + "@npmcli/move-file": "^1.1.0", + "@npmcli/name-from-folder": "^1.0.1", + "@npmcli/node-gyp": "^1.0.1", + "@npmcli/package-json": "^1.0.1", + "@npmcli/run-script": "^1.8.2", + "bin-links": "^2.2.1", + "cacache": "^15.0.3", + "common-ancestor-path": "^1.0.1", + "json-parse-even-better-errors": "^2.3.1", + "json-stringify-nice": "^1.1.4", + "mkdirp": "^1.0.4", + "mkdirp-infer-owner": "^2.0.0", + "npm-install-checks": "^4.0.0", + "npm-package-arg": "^8.1.5", + "npm-pick-manifest": "^6.1.0", + "npm-registry-fetch": "^11.0.0", + "pacote": "^11.3.5", + "parse-conflict-json": "^1.1.1", + "proc-log": "^1.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^1.0.1", + "read-package-json-fast": "^2.0.2", + "readdir-scoped-modules": "^1.1.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "ssri": "^8.0.1", + "treeverse": "^1.0.4", + "walk-up-path": "^1.0.0" + } + }, + "@npmcli/ci-detect": { + "version": "1.3.0", + "bundled": true, + "dev": true + }, + "@npmcli/config": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "requires": { + "ini": "^2.0.0", + "mkdirp-infer-owner": "^2.0.0", + "nopt": "^5.0.0", + "semver": "^7.3.4", + "walk-up-path": "^1.0.0" + } + }, + "@npmcli/disparity-colors": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { +<<<<<<< HEAD +======= + "is-buffer": "^1.1.5" + } + } + } + }, + "is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true + }, + "is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, + "is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + }, + "is-bigint": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", + "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" + }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "dev": true, + "requires": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==" + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-ssh": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.2.tgz", + "integrity": "sha512-elEw0/0c2UscLrNG+OAorbP539E3rhliKPg+hDMWN9VwrDXfYK+4PBEykDPfxlYYtQvl84TascnQyobfQLHEhQ==", + "dev": true, + "requires": { + "protocols": "^1.1.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "dev": true, + "requires": { + "text-extensions": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "issue-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", + "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", + "dev": true, + "requires": { + "lodash.capitalize": "^4.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.uniqby": "^4.7.0" + } + }, + "java-properties": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", + "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "requires": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==" + }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + } + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "jshint": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.1.tgz", + "integrity": "sha512-vymzfR3OysF5P774x6zYv0bD4EpH6NWRxpq54wO9mA9RuY49yb1teKSICkLx2Ryx+mfzlVVNNbTBtsRtg78t7g==", + "requires": { + "cli": "~1.0.0", + "console-browserify": "1.1.x", + "exit": "0.1.x", + "htmlparser2": "3.8.x", + "lodash": "~4.17.21", + "minimatch": "~3.0.2", + "shelljs": "0.3.x", + "strip-json-comments": "1.0.x" + }, + "dependencies": { + "domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=" + }, + "htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "requires": { + "domelementtype": "1", + "domhandler": "2.3", + "domutils": "1.5", + "entities": "1.0", + "readable-stream": "1.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "strip-json-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=" + } + } + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.0.tgz", + "integrity": "sha512-o3aP+RsWDJZayj1SbHNQAI8x0v3T3SKiGoZlNYfbUP1S3omJQ6i9CnqADqkSPaOAxwua4/1YWx5CM7oiChJt2Q==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json2module": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/json2module/-/json2module-0.0.3.tgz", + "integrity": "sha1-APtfSpt638PwZHwpyxe80Zeb6bI=", + "requires": { + "rw": "^1.3.2" + } + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "junk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", + "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", + "dev": true + }, + "keyv": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.4.tgz", + "integrity": "sha512-vqNHbAc8BBsxk+7QBYLW0Y219rWcClspR6WSeoHYKG5mnsSoOH+BL1pWq02DDCVdvvuUny5rkBlzMRzoqc+GIg==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "known-css-properties": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.21.0.tgz", + "integrity": "sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw==", + "dev": true + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" + }, + "leaflet": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.7.1.tgz", + "integrity": "sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw==" + }, + "leaflet.markercluster": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/leaflet.markercluster/-/leaflet.markercluster-1.5.1.tgz", + "integrity": "sha512-dRGndfMZibkWMBD7g8h+lJW0R0keTx1GGMErre7uhqnKiYBoMxR2VPX6Sy8oGNzg+FA7FKtTuO1hGh5HtV9s2g==", + "requires": { + "jshint": "^2.13.1", + "npm-ci": "0.0.2" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lilconfig": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.3.tgz", + "integrity": "sha512-EHKqr/+ZvdKCifpNrJCKxBTgk5XupZA3y/aCPY9mxfgBzmgh93Mt/WqjjQ38oMxXuvDokaKiM3lAgvSH2sjtHg==", + "dev": true + }, + "linebreak": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/linebreak/-/linebreak-1.0.2.tgz", + "integrity": "sha512-bJwSRsJeAmaZYnkcwl5sCQNfSDAhBuXxb6L27tb+qkBRtUQSSTUa5bcgCPD6hFEkRNlpWHfK7nFMmcANU7ZP1w==", + "requires": { + "base64-js": "0.0.8", + "brfs": "^2.0.2", + "unicode-trie": "^1.0.0" + }, + "dependencies": { + "base64-js": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", + "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=" + }, + "unicode-trie": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-1.0.0.tgz", + "integrity": "sha512-v5raLKsobbFbWLMoX9+bChts/VhPPj3XpkNr/HbqkirXR1DPk8eo9IYKyvk0MQZFkaoRsFj2Rmaqgi2rfAZYtA==", + "requires": { + "pako": "^0.2.5", + "tiny-inflate": "^1.0.0" + } + } + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "lint-staged": { +<<<<<<< HEAD + "version": "10.5.4", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz", + "integrity": "sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==", "dev": true, "requires": { - "cli-truncate": "2.1.0", - "colorette": "^1.4.0", - "commander": "^8.2.0", - "cosmiconfig": "^7.0.1", - "debug": "^4.3.2", + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "commander": "^6.2.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.2.0", + "dedent": "^0.7.0", "enquirer": "^2.3.6", - "execa": "^5.1.1", - "listr2": "^3.12.2", + "execa": "^4.1.0", + "listr2": "^3.2.2", + "log-symbols": "^4.0.0", + "micromatch": "^4.0.2", +======= + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.1.2.tgz", + "integrity": "sha512-6lYpNoA9wGqkL6Hew/4n1H6lRqF3qCsujVT0Oq5Z4hiSAM7S6NksPJ3gnr7A7R52xCtiZMcEUNNQ6d6X5Bvh9w==", + "dev": true, + "requires": { + "chalk": "^4.1.1", + "cli-truncate": "^2.1.0", + "commander": "^7.2.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.3.1", + "enquirer": "^2.3.6", + "execa": "^5.0.0", + "listr2": "^3.8.2", + "log-symbols": "^4.1.0", "micromatch": "^4.0.4", +>>>>>>> 4e51bf2 (fix(persons): set person picture as optional for better ux) "normalize-path": "^3.0.0", "please-upgrade-node": "^3.2.0", "string-argv": "0.3.1", - "stringify-object": "3.3.0", - "supports-color": "8.1.1" + "stringify-object": "^3.3.0" }, "dependencies": { "braces": { @@ -25707,6 +27520,36 @@ "fill-range": "^7.0.1" } }, + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -25716,11 +27559,29 @@ "to-regex-range": "^5.0.1" } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", +<<<<<<< HEAD + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } +======= + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true +>>>>>>> 4e51bf2 (fix(persons): set person picture as optional for better ux) }, "is-number": { "version": "7.0.0", @@ -25729,24 +27590,45 @@ "dev": true }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "dev": true, "requires": { "braces": "^3.0.1", - "picomatch": "^2.2.3" + "picomatch": "^2.0.5" } }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "mimic-fn": "^2.1.0" } }, +<<<<<<< HEAD + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, +======= +>>>>>>> 4e51bf2 (fix(persons): set person picture as optional for better ux) "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -25759,42 +27641,53 @@ } }, "listr2": { - "version": "3.13.5", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.13.5.tgz", - "integrity": "sha512-3n8heFQDSk+NcwBn3CgxEibZGaRzx+pC64n3YjpMD1qguV4nWus3Al+Oo3KooqFKTQEJ1v7MmnbnyyNspgx3NA==", +<<<<<<< HEAD + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.4.3.tgz", + "integrity": "sha512-wZmkzNiuinOfwrGqAwTCcPw6aKQGTAMGXwG5xeU1WpDjJNeBA35jGBeWxR3OF+R6Yl5Y3dRG+3vE8t6PDcSNHA==", +======= + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.12.1.tgz", + "integrity": "sha512-oB1DlXlCzGPbvWhqYBZUQEPJKqsmebQWofXG6Mpbe3uIvoNl8mctBEojyF13ZyqwQ91clCWXpwsWp+t98K4FOQ==", +>>>>>>> 4e51bf2 (fix(persons): set person picture as optional for better ux) "dev": true, "requires": { + "chalk": "^4.1.0", "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", +<<<<<<< HEAD + "figures": "^3.2.0", + "indent-string": "^4.0.0", +======= + "colorette": "^1.4.0", +>>>>>>> 4e51bf2 (fix(persons): set person picture as optional for better ux) "log-update": "^4.0.0", "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.4.0", + "rxjs": "^6.6.6", "through": "^2.3.8", "wrap-ansi": "^7.0.0" +<<<<<<< HEAD }, "dependencies": { - "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } }, "rxjs": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.4.0.tgz", - "integrity": "sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==", + "version": "6.6.6", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.6.tgz", + "integrity": "sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg==", "dev": true, "requires": { - "tslib": "~2.1.0" + "tslib": "^1.9.0" } - }, - "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", - "dev": true } +======= +>>>>>>> 4e51bf2 (fix(persons): set person picture as optional for better ux) } }, "lit": { @@ -25891,12 +27784,6 @@ "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=", "dev": true }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true - }, "lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", @@ -25933,6 +27820,12 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=", + "dev": true + }, "lodash.topath": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz", @@ -26053,23 +27946,23 @@ } }, "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "strip-ansi": "^6.0.0" } }, "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^5.0.0" } }, "type-fest": { @@ -26134,12 +28027,24 @@ "sourcemap-codec": "^1.4.1" } }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", +<<<<<<< HEAD + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, +======= +>>>>>>> 4e51bf2 (fix(persons): set person picture as optional for better ux) "map-obj": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.0.tgz", @@ -26149,7 +28054,12 @@ "marked": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", +<<<<<<< HEAD + "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==", + "dev": true +======= "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==" +>>>>>>> 87ca2cf (fix(md-editor): build new markdown editor with lit + github/markdown-toolbar-element) }, "marked-terminal": { "version": "4.2.0", @@ -26221,12 +28131,20 @@ "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", "dev": true }, +<<<<<<< HEAD "mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", "dev": true }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, +======= +>>>>>>> 87ca2cf (fix(md-editor): build new markdown editor with lit + github/markdown-toolbar-element) "meow": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", @@ -26277,9 +28195,9 @@ } }, "mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", "dev": true }, "mime-db": { @@ -26302,9 +28220,9 @@ "dev": true }, "mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true }, "min-indent": { @@ -26343,6 +28261,47 @@ "kind-of": "^6.0.3" } }, +<<<<<<< HEAD +<<<<<<< HEAD + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, +======= +>>>>>>> 4e51bf2 (fix(persons): set person picture as optional for better ux) +======= + "mitt": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-2.1.0.tgz", + "integrity": "sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==" + }, +>>>>>>> 65aab48 (feat: add js audio player on podcast, admin and embeddable player pages + fix admon episodes ux) "modern-normalize": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/modern-normalize/-/modern-normalize-1.1.0.tgz", @@ -26367,9 +28326,9 @@ "dev": true }, "nanoid": { - "version": "3.1.30", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", - "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==", + "version": "3.1.23", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", + "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", "dev": true }, "natural-compare": { @@ -26396,12 +28355,12 @@ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, "node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", + "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", "dev": true, "requires": { - "lodash": "^4.17.21" + "lodash.toarray": "^4.4.0" } }, "node-fetch": { @@ -26495,9 +28454,9 @@ "dev": true }, "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", "dev": true }, "npm": { @@ -26708,6 +28667,128 @@ }, "@npmcli/move-file": { "version": "1.1.2", +======= + "@npmcli/arborist": { + "version": "2.8.3", +>>>>>>> dfa437f (fix: rename podcast name to podcast handle to clarify field usage) + "bundled": true, + "dev": true, + "requires": { + "@npmcli/installed-package-contents": "^1.0.7", + "@npmcli/map-workspaces": "^1.0.2", + "@npmcli/metavuln-calculator": "^1.1.0", + "@npmcli/move-file": "^1.1.0", + "@npmcli/name-from-folder": "^1.0.1", + "@npmcli/node-gyp": "^1.0.1", + "@npmcli/package-json": "^1.0.1", + "@npmcli/run-script": "^1.8.2", + "bin-links": "^2.2.1", + "cacache": "^15.0.3", + "common-ancestor-path": "^1.0.1", + "json-parse-even-better-errors": "^2.3.1", + "json-stringify-nice": "^1.1.4", + "mkdirp": "^1.0.4", + "mkdirp-infer-owner": "^2.0.0", + "npm-install-checks": "^4.0.0", + "npm-package-arg": "^8.1.5", + "npm-pick-manifest": "^6.1.0", + "npm-registry-fetch": "^11.0.0", + "pacote": "^11.3.5", + "parse-conflict-json": "^1.1.1", + "proc-log": "^1.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^1.0.1", + "read-package-json-fast": "^2.0.2", + "readdir-scoped-modules": "^1.1.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "ssri": "^8.0.1", + "treeverse": "^1.0.4", + "walk-up-path": "^1.0.0" + } + }, + "@npmcli/ci-detect": { + "version": "1.3.0", + "bundled": true, + "dev": true + }, + "@npmcli/config": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "requires": { + "ini": "^2.0.0", + "mkdirp-infer-owner": "^2.0.0", + "nopt": "^5.0.0", + "semver": "^7.3.4", + "walk-up-path": "^1.0.0" + } + }, + "@npmcli/disparity-colors": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { +>>>>>>> 9bcc04c (feat: add js audio player on podcast, admin and embeddable player pages + fix admon episodes ux) + "ansi-styles": "^4.3.0" + } + }, + "@npmcli/fs": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" + } + }, + "@npmcli/git": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/promise-spawn": "^1.3.2", + "lru-cache": "^6.0.0", + "mkdirp": "^1.0.4", + "npm-pick-manifest": "^6.1.1", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^2.0.2" + } + }, + "@npmcli/installed-package-contents": { + "version": "1.0.7", + "bundled": true, + "dev": true, + "requires": { + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "@npmcli/map-workspaces": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/name-from-folder": "^1.0.1", + "glob": "^7.1.6", + "minimatch": "^3.0.4", + "read-package-json-fast": "^2.0.1" + } + }, + "@npmcli/metavuln-calculator": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "cacache": "^15.0.5", + "pacote": "^11.1.11", + "semver": "^7.3.2" + } + }, + "@npmcli/move-file": { + "version": "1.1.2", "bundled": true, "dev": true, "requires": { @@ -32677,6 +34758,11 @@ } } }, + "stencil-wormhole": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/stencil-wormhole/-/stencil-wormhole-3.4.1.tgz", + "integrity": "sha512-ppYTcWTJnIl4ZAKwF39LTA9f/ypHfbVefsHdN2hpMQGrR57wt1TieZo9tlCM/r1Y4SFiZ5yz/cjho564C921Xw==" + }, "stream-combiner2": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", diff --git a/package.json b/package.json index 90e8782c32c5d528794ca4b33275fc898af32ac0..077fcc0173c22fb9d1b313c57caf0758b53ba1c6 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "@amcharts/amcharts4": "^4.10.20", "@github/markdown-toolbar-element": "^1.5.1", "@popperjs/core": "^2.9.2", + "@vime/core": "^5.0.33", "choices.js": "^9.0.1", "flatpickr": "^4.6.9", "leaflet.markercluster": "^1.5.1", diff --git a/vite.config.ts b/vite.config.ts index b2d623b932e5951f923815c27cd859bb30e85e3f..f8b3ed543f8cf044178fc82c500f573f088ba220 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -17,6 +17,8 @@ export default defineConfig({ "admin.ts": "app/Resources/js/admin.ts", "charts.ts": "app/Resources/js/charts.ts", "map.ts": "app/Resources/js/map.ts", + "audio-player.ts": "app/Resources/js/audio-player.ts", + "embed.ts": "app/Resources/js/embed.ts", "styles/index.css": "app/Resources/styles/index.css", }, },