{"id":30164,"date":"2026-07-14T12:18:32","date_gmt":"2026-07-14T16:18:32","guid":{"rendered":"https:\/\/allianceenjesus.com\/?page_id=30164"},"modified":"2026-08-01T12:26:22","modified_gmt":"2026-08-01T16:26:22","slug":"jeu-new","status":"publish","type":"page","link":"https:\/\/allianceenjesus.com\/?page_id=30164","title":{"rendered":"Jeu new"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"30164\" class=\"elementor elementor-30164\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-d7523ed elementor-section-full_width ang-section-padding-initial elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no\" data-id=\"d7523ed\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-70c7420 elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"70c7420\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap\">\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-j6jr01l elementor-section-content-middle elementor-section-height-full elementor-section-full_width ang-section-padding-initial elementor-section-height-default elementor-section-items-middle wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no\" data-id=\"j6jr01l\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-b1eae7d elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"b1eae7d\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-e239bc3 elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-spacer\" data-id=\"e239bc3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-28f8f35 animated-slow e-transform e-transform elementor-repeater-item-none elementor-repeater-item-none_hover elementor-invisible elementor-widget elementor-widget-heading\" data-id=\"28f8f35\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;flash&quot;,&quot;_animation_delay&quot;:2000,&quot;_transform_translateX_effect&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:7,&quot;sizes&quot;:[]},&quot;_transform_translateY_effect&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:156,&quot;sizes&quot;:[]},&quot;_transform_translateX_effect_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_translateX_effect_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_translateY_effect_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_translateY_effect_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_skewX_effect&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_skewX_effect_tablet&quot;:{&quot;unit&quot;:&quot;deg&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_skewX_effect_mobile&quot;:{&quot;unit&quot;:&quot;deg&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_skewY_effect&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_skewY_effect_tablet&quot;:{&quot;unit&quot;:&quot;deg&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_skewY_effect_mobile&quot;:{&quot;unit&quot;:&quot;deg&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]}}\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\"><a href=\"http:\/\/www.alliance-en-j\u00e9sus.com\" target=\"_blank\" rel=\"noopener\">Bienvenue sur <br>Alliance en J\u00e9sus<\/a><\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-2a00edd e-transform e-transform elementor-repeater-item-none elementor-repeater-item-none_hover elementor-invisible elementor-widget elementor-widget-heading\" data-id=\"2a00edd\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeIn&quot;,&quot;_transform_translateX_effect&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:0,&quot;sizes&quot;:[]},&quot;_transform_translateY_effect&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:-153,&quot;sizes&quot;:[]},&quot;_transform_rotateZ_effect&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_rotateZ_effect_tablet&quot;:{&quot;unit&quot;:&quot;deg&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_rotateZ_effect_mobile&quot;:{&quot;unit&quot;:&quot;deg&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_translateX_effect_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_translateX_effect_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_translateY_effect_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_translateY_effect_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]}}\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\"><a href=\"http:\/\/www.alliance-en-j\u00e9sus.com\" target=\"_blank\" rel=\"noopener\">Bienvenue sur <br>Alliance en J\u00e9sus<\/a><\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-2afe0c24 elementor-section-content-middle elementor-section-full_width ang-section-padding-initial elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no\" data-id=\"2afe0c24\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-532eb909 elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"532eb909\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-36b43d4e elementor-repeater-item-none elementor-repeater-item-none_hover elementor-invisible elementor-widget elementor-widget-heading\" data-id=\"36b43d4e\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;pulse&quot;}\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\"><a href=\"http:\/\/www.alliance-en-j\u00e9sus.com\" target=\"_blank\" rel=\"noopener\">Une Alliance Eternelle<\/a><\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3554af0 animated-slow elementor-repeater-item-none elementor-repeater-item-none_hover elementor-invisible elementor-widget elementor-widget-text-editor\" data-id=\"3554af0\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;slideInRight&quot;,&quot;_animation_delay&quot;:200}\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span style=\"color: #ff9900;\"><u><a style=\"color: #ff9900;\" title=\"Accueil\" href=\"https:\/\/xn--alliance-en-jsus-nqb.com\/index.php\/accueil\/\" target=\"_blank\" rel=\"noopener\">Parce que Le Seigneur<\/a> t&rsquo;aime<\/u><\/span> et te consid\u00e8re comme la prunelle de ses yeux, viens et approche toi de L&rsquo;ETERNEL DIEU.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-1a0b86a elementor-section-boxed ang-section-padding-initial elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no\" data-id=\"1a0b86a\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-941c3db elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"941c3db\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-dd5c8fb elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-spacer\" data-id=\"dd5c8fb\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-f3aeeec elementor-section-boxed ang-section-padding-initial elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no elementor-invisible\" data-id=\"f3aeeec\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;animation&quot;:&quot;fadeIn&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-12247d2 elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"12247d2\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-3e2a670 animated-slow elementor-repeater-item-none elementor-repeater-item-none_hover elementor-invisible elementor-widget elementor-widget-heading\" data-id=\"3e2a670\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeIn&quot;,&quot;_animation_delay&quot;:400}\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Louanges et adorations :<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-0c045b3 animated-slow elementor-section-boxed ang-section-padding-initial elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no elementor-invisible\" data-id=\"0c045b3\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;animation&quot;:&quot;fadeInDown&quot;,&quot;animation_delay&quot;:200}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-5886539 elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"5886539\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap\">\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-abb886f elementor-section-full_width animated-slow ang-section-padding-initial elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no elementor-invisible\" data-id=\"abb886f\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;animation&quot;:&quot;fadeIn&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-no\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-1110b70 elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"1110b70\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-96ced09 elementor-widget__width-inherit e-transform elementor-arrows-position-inside elementor-pagination-position-outside elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-image-carousel\" data-id=\"96ced09\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;image_spacing_custom&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:14,&quot;sizes&quot;:[]},&quot;_transform_translateX_effect&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:0,&quot;sizes&quot;:[]},&quot;_transform_translateY_effect&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:15,&quot;sizes&quot;:[]},&quot;navigation&quot;:&quot;both&quot;,&quot;autoplay&quot;:&quot;yes&quot;,&quot;pause_on_hover&quot;:&quot;yes&quot;,&quot;pause_on_interaction&quot;:&quot;yes&quot;,&quot;autoplay_speed&quot;:5000,&quot;infinite&quot;:&quot;yes&quot;,&quot;speed&quot;:500,&quot;image_spacing_custom_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;image_spacing_custom_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_translateX_effect_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_translateX_effect_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_translateY_effect_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_translateY_effect_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]}}\" data-widget_type=\"image-carousel.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-image-carousel-wrapper swiper\" role=\"region\" aria-roledescription=\"carousel\" aria-label=\"Carrousel d\u2019images\" dir=\"ltr\">\n\t\t\t<div class=\"elementor-image-carousel swiper-wrapper\" aria-live=\"off\">\n\t\t\t\t\t\t\t\t<div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"1 sur 3\"><figure class=\"swiper-slide-inner\"><img decoding=\"async\" class=\"swiper-slide-image\" src=\"https:\/\/allianceenjesus.com\/wp-content\/uploads\/2022\/03\/images-6-6.jpg\" alt=\"images (6)\" \/><\/figure><\/div><div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"2 sur 3\"><figure class=\"swiper-slide-inner\"><img decoding=\"async\" class=\"swiper-slide-image\" src=\"https:\/\/allianceenjesus.com\/wp-content\/uploads\/2022\/03\/images-7-1-2.jpg\" alt=\"images (7) (1)\" \/><\/figure><\/div><div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"3 sur 3\"><figure class=\"swiper-slide-inner\"><img decoding=\"async\" class=\"swiper-slide-image\" src=\"https:\/\/allianceenjesus.com\/wp-content\/uploads\/2022\/03\/images-8-4.jpg\" alt=\"images (8)\" \/><\/figure><\/div>\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-swiper-button elementor-swiper-button-prev\" role=\"button\" tabindex=\"0\">\n\t\t\t\t\t\t<i aria-hidden=\"true\" class=\"eicon-chevron-left\"><\/i>\t\t\t\t\t<\/div>\n\t\t\t\t\t<div class=\"elementor-swiper-button elementor-swiper-button-next\" role=\"button\" tabindex=\"0\">\n\t\t\t\t\t\t<i aria-hidden=\"true\" class=\"eicon-chevron-right\"><\/i>\t\t\t\t\t<\/div>\n\t\t\t\t\n\t\t\t\t\t\t\t\t\t<div class=\"swiper-pagination\"><\/div>\n\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-66f7555 elementor-section-boxed ang-section-padding-initial elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no\" data-id=\"66f7555\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-1f90a72 elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"1f90a72\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-8eacd35 elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-spacer\" data-id=\"8eacd35\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-8ccd90c elementor-section-full_width animated-slow ang-section-padding-initial elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no elementor-invisible\" data-id=\"8ccd90c\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;animation&quot;:&quot;bounce&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-6fc320e elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"6fc320e\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-7266b74 elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-text-editor\" data-id=\"7266b74\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Rejoignez-nous dans cette gr\u00e2ce de pouvoir louer et glorifier l&rsquo;ETERNEL DIEU et soyez fortifi\u00e9s par les messages d&rsquo;encouragements ! L&rsquo;Eglise Evang\u00e9lique de la Guyane vous re\u00e7oit dans ses sept Eglises pour partager notre communion Chr\u00e9tienne.\u00a0\u00a0<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t<div class=\"elementor-element elementor-element-7db05be e-flex e-con-boxed elementor-repeater-item-default_padding elementor-repeater-item-none elementor-repeater-item-none_hover wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-column-slider-no wpr-equal-height-no e-con e-parent\" data-id=\"7db05be\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;ang_container_spacing_size&quot;:&quot;default_padding&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-c7484e7 elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-html\" data-id=\"c7484e7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div id=\"bibleTetris\">\r\n<canvas id=\"tetrisCanvas\" width=\"300\" height=\"600\"><\/canvas>\r\n\r\n<div id=\"infoTetris\">\r\n<h2>\u271d\ufe0f Bible Blocks<\/h2>\r\n<p>Score : <span id=\"tScore\">0<\/span><\/p>\r\n<p>Niveau : <span id=\"tLevel\">1<\/span><\/p>\r\n<p>Lignes : <span id=\"tLines\">0<\/span><\/p>\r\n\r\n<p id=\"verse\">\r\n\"Je puis tout par celui qui me fortifie.\"<br>\r\nPhilippiens 4:13\r\n<\/p>\r\n\r\n<button id=\"startTetris\">Jouer<\/button>\r\n<\/div>\r\n<\/div>\r\n\r\n<style>\r\n#bibleTetris{\r\ndisplay:flex;\r\ngap:20px;\r\njustify-content:center;\r\nalign-items:center;\r\nfont-family:Arial;\r\nbackground:#102030;\r\npadding:20px;\r\ncolor:white;\r\n}\r\n\r\n#tetrisCanvas{\r\nbackground:#000;\r\nborder:4px solid gold;\r\n}\r\n\r\n#infoTetris{\r\nbackground:#1c3557;\r\npadding:20px;\r\nborder-radius:15px;\r\ntext-align:center;\r\nmax-width:220px;\r\n}\r\n\r\n#startTetris{\r\nbackground:gold;\r\nborder:0;\r\npadding:12px;\r\nborder-radius:8px;\r\ncursor:pointer;\r\nfont-size:18px;\r\n}\r\n\r\n@media(max-width:700px){\r\n#bibleTetris{\r\nflex-direction:column;\r\n}\r\n}\r\n<\/style>\r\n\r\n\r\n<script>\r\n(function(){\r\n\r\nconst canvas=document.getElementById(\"tetrisCanvas\");\r\nconst ctx=canvas.getContext(\"2d\");\r\n\r\nconst size=30;\r\nconst rows=20;\r\nconst cols=10;\r\n\r\nlet board=[];\r\nlet piece=null;\r\nlet timer=null;\r\n\r\nlet score=0;\r\nlet lines=0;\r\nlet level=1;\r\n\r\n\r\nfunction resetBoard(){\r\n\r\nboard=[];\r\n\r\nfor(let y=0;y<rows;y++){\r\nboard[y]=[];\r\n\r\nfor(let x=0;x<cols;x++){\r\nboard[y][x]=0;\r\n}\r\n}\r\n\r\n}\r\n\r\n\r\nconst shapes=[\r\n\r\n[[1,1,1,1]],\r\n\r\n[[1,1],[1,1]],\r\n\r\n[[0,1,0],[1,1,1]],\r\n\r\n[[1,0,0],[1,1,1]],\r\n\r\n[[0,0,1],[1,1,1]],\r\n\r\n[[1,1,0],[0,1,1]],\r\n\r\n[[0,1,1],[1,1,0]]\r\n\r\n];\r\n\r\n\r\nconst colors=[\r\n\"#00ffff\",\r\n\"#ffff00\",\r\n\"#ff00ff\",\r\n\"#00ff00\",\r\n\"#ff8800\",\r\n\"#8888ff\",\r\n\"#ff3333\"\r\n];\r\n\r\n\r\nfunction newPiece(){\r\n\r\nlet i=Math.floor(Math.random()*shapes.length);\r\n\r\nreturn {\r\n\r\nshape:shapes[i],\r\n\r\ncolor:colors[i],\r\n\r\nx:3,\r\n\r\ny:0\r\n\r\n};\r\n\r\n}\r\n\r\n\r\nfunction draw(){\r\n\r\nctx.clearRect(0,0,300,600);\r\n\r\n\r\nfor(let y=0;y<rows;y++){\r\n\r\nfor(let x=0;x<cols;x++){\r\n\r\nif(board[y][x]){\r\n\r\nctx.fillStyle=board[y][x];\r\nctx.fillRect(x*size,y*size,size,size);\r\n\r\n}\r\n\r\nctx.strokeStyle=\"#222\";\r\nctx.strokeRect(x*size,y*size,size,size);\r\n\r\n}\r\n\r\n}\r\n\r\n\r\nif(piece){\r\n\r\npiece.shape.forEach((r,y)=>{\r\n\r\nr.forEach((v,x)=>{\r\n\r\nif(v){\r\n\r\nctx.fillStyle=piece.color;\r\n\r\nctx.fillRect(\r\n(piece.x+x)*size,\r\n(piece.y+y)*size,\r\nsize,\r\nsize\r\n);\r\n\r\n}\r\n\r\n});\r\n\r\n});\r\n\r\n}\r\n\r\n}\r\n\r\n\r\nfunction hit(){\r\n\r\nfor(let y=0;y<piece.shape.length;y++){\r\n\r\nfor(let x=0;x<piece.shape[y].length;x++){\r\n\r\nif(piece.shape[y][x]){\r\n\r\nlet nx=piece.x+x;\r\nlet ny=piece.y+y;\r\n\r\nif(\r\nnx<0||\r\nnx>=cols||\r\nny>=rows||\r\n(board[ny]&&board[ny][nx])\r\n)\r\nreturn true;\r\n\r\n}\r\n\r\n}\r\n\r\n}\r\n\r\nreturn false;\r\n\r\n}\r\n\r\n\r\n\r\nfunction merge(){\r\n\r\npiece.shape.forEach((r,y)=>{\r\n\r\nr.forEach((v,x)=>{\r\n\r\nif(v)\r\nboard[piece.y+y][piece.x+x]=piece.color;\r\n\r\n});\r\n\r\n});\r\n\r\nclearLines();\r\n\r\npiece=newPiece();\r\n\r\n}\r\n\r\n\r\n\r\nfunction clearLines(){\r\n\r\nfor(let y=rows-1;y>=0;y--){\r\n\r\nif(board[y].every(v=>v)){\r\n\r\nboard.splice(y,1);\r\nboard.unshift(new Array(cols).fill(0));\r\n\r\nscore+=100;\r\nlines++;\r\n\r\n}\r\n\r\n}\r\n\r\nlevel=Math.floor(lines\/10)+1;\r\n\r\ndocument.getElementById(\"tScore\").innerHTML=score;\r\ndocument.getElementById(\"tLines\").innerHTML=lines;\r\ndocument.getElementById(\"tLevel\").innerHTML=level;\r\n\r\n}\r\n\r\n\r\n\r\nfunction down(){\r\n\r\npiece.y++;\r\n\r\nif(hit()){\r\n\r\npiece.y--;\r\nmerge();\r\n\r\n}\r\n\r\n}\r\n\r\n\r\n\r\ndocument.addEventListener(\"keydown\",function(e){\r\n\r\nif(!piece)return;\r\n\r\n\r\nif(e.key===\"ArrowLeft\"){\r\n\r\npiece.x--;\r\n\r\nif(hit())piece.x++;\r\n\r\n}\r\n\r\n\r\nif(e.key===\"ArrowRight\"){\r\n\r\npiece.x++;\r\n\r\nif(hit())piece.x--;\r\n\r\n}\r\n\r\n\r\nif(e.key===\"ArrowDown\"){\r\n\r\ndown();\r\n\r\n}\r\n\r\n\r\nif(e.key===\"ArrowUp\"){\r\n\r\nlet old=piece.shape;\r\n\r\npiece.shape=piece.shape[0].map((_,i)=>\r\npiece.shape.map(r=>r[i]).reverse()\r\n);\r\n\r\nif(hit())\r\npiece.shape=old;\r\n\r\n}\r\n\r\n});\r\n\r\n\r\n\r\nfunction loop(){\r\n\r\ndraw();\r\n\r\n}\r\n\r\n\r\n\r\ndocument.getElementById(\"startTetris\").onclick=function(){\r\n\r\nresetBoard();\r\n\r\nscore=0;\r\nlines=0;\r\nlevel=1;\r\n\r\npiece=newPiece();\r\n\r\n\r\nif(timer)\r\nclearInterval(timer);\r\n\r\n\r\ntimer=setInterval(function(){\r\n\r\ndown();\r\ndraw();\r\n\r\n},700);\r\n\r\n\r\n};\r\n\r\n\r\n\r\ndraw();\r\n\r\n\r\n})();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-2ce192c elementor-section-boxed ang-section-padding-initial elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no\" data-id=\"2ce192c\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-8eb8c8f elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"8eb8c8f\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-6a458a7 elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-spacer\" data-id=\"6a458a7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-d3f6e90 elementor-section-boxed ang-section-padding-initial elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no\" data-id=\"d3f6e90\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-7d44ab9 elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"7d44ab9\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-692c640 elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-spacer\" data-id=\"692c640\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-64da3fc animated-slow elementor-section-full_width ang-section-padding-initial elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no elementor-invisible\" data-id=\"64da3fc\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;animation&quot;:&quot;bounce&quot;,&quot;animation_delay&quot;:500}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-04f7e40 elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"04f7e40\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-90ec09b elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-text-editor\" data-id=\"90ec09b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Nous vous invitons \u00e0 prendre part \u00e0 nos conf\u00e9rences et s\u00e9minaires tout au long de l&rsquo;ann\u00e9e. Contactez-nous pour plus de renseignement et nous nous ferons un immense plaisir de vous r\u00e9pondre.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<section class=\"elementor-section elementor-inner-section elementor-element elementor-element-58925fed elementor-section-boxed ang-section-padding-initial elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no\" data-id=\"58925fed\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t\t<div class=\"elementor-background-overlay\"><\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-inner-column elementor-element elementor-element-7d4bbf6 elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"7d4bbf6\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-9e6f260 elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-heading\" data-id=\"9e6f260\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-xl\">BAPTEME<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-2d4a487 animated-slow elementor-repeater-item-none elementor-repeater-item-none_hover elementor-invisible elementor-widget elementor-widget-image-box\" data-id=\"2d4a487\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;zoomIn&quot;,&quot;_animation_delay&quot;:300}\" data-widget_type=\"image-box.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"elementor-image-box-wrapper\"><div class=\"elementor-image-box-content\"><h2 class=\"elementor-image-box-title\">Celui qui croira sera baptis\u00e9 au nom du P\u00e8re, du Fils et du Saint-Esprit.<\/h2><p class=\"elementor-image-box-description\">Cet acte symbolise notre mort au p\u00e9ch\u00e9 et une vie nouvelle en JESUS-CHRIST.<\/p><\/div><\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-035f777 elementor-repeater-item-none elementor-repeater-item-none_hover elementor-invisible elementor-widget elementor-widget-heading\" data-id=\"035f777\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;headShake&quot;}\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">Fuyez le jugement \u00e0 venir et la col\u00e8re de DIEU.<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9a76257 elementor-align-left elementor-tablet-align-left elementor-mobile-align-justify elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-button\" data-id=\"9a76257\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"button.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<div class=\"elementor-button-wrapper\">\n\t\t\t\t\t<a class=\"elementor-button elementor-button-link elementor-size-sm\" href=\"#\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\">ACCES RAPIDE<\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/a>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-f6717ef animated-slow elementor-section-boxed ang-section-padding-initial elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no elementor-invisible\" data-id=\"f6717ef\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;animation&quot;:&quot;swing&quot;,&quot;animation_delay&quot;:200}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-727cd58 elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"727cd58\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-43a556e animated-slow external_elementor-repeater-item-none_external elementor-repeater-item-none elementor-repeater-item-none_hover elementor-invisible elementor-widget elementor-widget-image\" data-id=\"43a556e\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeIn&quot;,&quot;_animation_delay&quot;:1500}\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"275\" height=\"183\" src=\"https:\/\/allianceenjesus.com\/wp-content\/uploads\/2022\/03\/alliance-en-jesus-1-1.jpg\" class=\"attachment-large size-large wp-image-3707\" alt=\"\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-df14b24 elementor-section-boxed ang-section-padding-initial elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no\" data-id=\"df14b24\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-4c946b9 elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"4c946b9\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-3ce6178 elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-spacer\" data-id=\"3ce6178\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-268005c elementor-section-boxed ang-section-padding-initial elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no elementor-repeater-item-none elementor-repeater-item-none_hover wpr-column-slider-no wpr-equal-height-no\" data-id=\"268005c\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-8603f28 elementor-repeater-item-none elementor-repeater-item-none_hover\" data-id=\"8603f28\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-f32f6ca elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-spacer\" data-id=\"f32f6ca\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t<div class=\"elementor-element elementor-element-f24e148 e-flex e-con-boxed elementor-repeater-item-default_padding elementor-repeater-item-none elementor-repeater-item-none_hover wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-column-slider-no wpr-equal-height-no e-con e-parent\" data-id=\"f24e148\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;ang_container_spacing_size&quot;:&quot;default_padding&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b99fee7 elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-html\" data-id=\"b99fee7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"fr\">\r\n<head>\r\n\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n\r\n<title>Planning des Absences<\/title>\r\n\r\n<style>\r\n\r\n*{\r\nbox-sizing:border-box;\r\nfont-family:Arial,sans-serif;\r\n}\r\n\r\nbody{\r\nmargin:0;\r\nbackground:#f2f5f9;\r\ncolor:#333;\r\n}\r\n\r\nheader{\r\nbackground:#1e3a8a;\r\ncolor:white;\r\npadding:20px;\r\ntext-align:center;\r\n}\r\n\r\n.container{\r\nwidth:95%;\r\nmargin:20px auto;\r\n}\r\n\r\n.panel{\r\nbackground:white;\r\npadding:20px;\r\nborder-radius:12px;\r\nmargin-bottom:20px;\r\nbox-shadow:0 3px 10px #ccc;\r\n}\r\n\r\n\r\ninput,select,button{\r\npadding:10px;\r\nmargin:5px;\r\nborder-radius:6px;\r\nborder:1px solid #ccc;\r\n}\r\n\r\n\r\nbutton{\r\ncursor:pointer;\r\nbackground:#1e3a8a;\r\ncolor:white;\r\n}\r\n\r\nbutton:hover{\r\nopacity:.8;\r\n}\r\n\r\n\r\n.calendar{\r\n\r\ndisplay:grid;\r\ngrid-template-columns:repeat(7,1fr);\r\ngap:5px;\r\n\r\n}\r\n\r\n\r\n.day{\r\n\r\nmin-height:110px;\r\nbackground:white;\r\nborder-radius:8px;\r\npadding:8px;\r\nborder:1px solid #ddd;\r\n\r\n}\r\n\r\n\r\n.day h4{\r\n\r\nmargin:0;\r\ntext-align:right;\r\n\r\n}\r\n\r\n\r\n.absence{\r\n\r\npadding:5px;\r\nmargin-top:5px;\r\nborder-radius:5px;\r\ncolor:white;\r\nfont-size:12px;\r\n\r\n}\r\n\r\n\r\n.conge{\r\nbackground:#16a34a;\r\n}\r\n\r\n.maladie{\r\nbackground:#dc2626;\r\n}\r\n\r\n.teletravail{\r\nbackground:#2563eb;\r\n}\r\n\r\n.autre{\r\nbackground:#9333ea;\r\n}\r\n\r\n\r\n\r\n.stats{\r\n\r\ndisplay:flex;\r\ngap:20px;\r\nflex-wrap:wrap;\r\n\r\n}\r\n\r\n\r\n.card{\r\n\r\nbackground:white;\r\npadding:15px;\r\nborder-radius:10px;\r\nflex:1;\r\nmin-width:200px;\r\nbox-shadow:0 2px 8px #ccc;\r\n\r\n}\r\n\r\n\r\n\r\ntable{\r\n\r\nwidth:100%;\r\nborder-collapse:collapse;\r\n\r\n}\r\n\r\n\r\nth,td{\r\n\r\nborder:1px solid #ddd;\r\npadding:10px;\r\n\r\n}\r\n\r\n\r\nth{\r\n\r\nbackground:#1e3a8a;\r\ncolor:white;\r\n\r\n}\r\n\r\n\r\n@media(max-width:700px){\r\n\r\n.calendar{\r\n\r\ngrid-template-columns:repeat(2,1fr);\r\n\r\n}\r\n\r\n}\r\n\r\n<\/style>\r\n\r\n<\/head>\r\n\r\n\r\n<body>\r\n\r\n\r\n<header>\r\n<h1>\ud83d\udcc5 Planning des Absences des Membres<\/h1>\r\n<\/header>\r\n\r\n\r\n<div class=\"container\">\r\n\r\n\r\n<div class=\"panel\">\r\n\r\n<h2>Ajouter une absence<\/h2>\r\n\r\n<input id=\"nom\" placeholder=\"Nom du membre\">\r\n\r\n<input id=\"eglise\" placeholder=\"\u00c9glise\">\r\n\r\n<input id=\"fonction\" placeholder=\"Fonction\">\r\n\r\n<input id=\"service\" placeholder=\"Service\">\r\n\r\n\r\n<select id=\"type\">\r\n\r\n<option value=\"conge\">Cong\u00e9<\/option>\r\n<option value=\"maladie\">Maladie<\/option>\r\n<option value=\"teletravail\">T\u00e9l\u00e9travail<\/option>\r\n<option value=\"autre\">Autre<\/option>\r\n\r\n<\/select>\r\n\r\n\r\n<input type=\"date\" id=\"debut\">\r\n\r\n<input type=\"date\" id=\"fin\">\r\n\r\n\r\n<button onclick=\"ajouterAbsence()\">\r\nAjouter\r\n<\/button>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n\r\n\r\n<div class=\"panel\">\r\n\r\n<h2>Recherche<\/h2>\r\n\r\n<input id=\"recherche\"\r\nplaceholder=\"Rechercher un membre...\"\r\nonkeyup=\"afficher()\">\r\n\r\n<\/div>\r\n\r\n\r\n\r\n<div class=\"panel\">\r\n\r\n<h2>\ud83d\udd0e Filtres<\/h2>\r\n\r\n\r\n<input id=\"filtreEglise\"\r\nplaceholder=\"Filtrer par \u00c9glise\"\r\nonkeyup=\"afficher()\">\r\n\r\n\r\n\r\n<input id=\"filtreFonction\"\r\nplaceholder=\"Filtrer par Fonction\"\r\nonkeyup=\"afficher()\">\r\n\r\n\r\n\r\n<input id=\"filtreService\"\r\nplaceholder=\"Filtrer par Service\"\r\nonkeyup=\"afficher()\">\r\n\r\n\r\n\r\n<button onclick=\"resetFiltres()\">\r\nR\u00e9initialiser\r\n<\/button>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"panel\">\r\n\r\n<h2>Calendrier<\/h2>\r\n\r\n<div class=\"calendar\" id=\"calendar\"><\/div>\r\n\r\n<\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"panel\">\r\n\r\n<h2>Liste des absences<\/h2>\r\n\r\n\r\n<div class=\"table-wrapper\"><table>\r\n\r\n<thead>\r\n\r\n<tr>\r\n\r\n<th>Membre<\/th>\r\n<th>\u00c9glise<\/th>\r\n<th>Fonction<\/th>\r\n<th>Service<\/th>\r\n<th>Type<\/th>\r\n<th>D\u00e9but<\/th>\r\n<th>Fin<\/th>\r\n<th>Dur\u00e9e<\/th>\r\n<th>Action<\/th>\r\n\r\n<\/tr>\r\n\r\n<\/thead>\r\n\r\n<tbody id=\"tableau\"><\/tbody>\r\n\r\n<\/table><\/div>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<div class=\"panel\">\r\n\r\n<h2>Statistiques<\/h2>\r\n\r\n\r\n<div class=\"stats\">\r\n\r\n<div class=\"card\">\r\n\r\n<h3>Total absences<\/h3>\r\n<p id=\"total\">0<\/p>\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"card\">\r\n\r\n<h3>Jours cumul\u00e9s<\/h3>\r\n<p id=\"jours\">0<\/p>\r\n\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n\r\n\r\n<\/div>\r\n\r\n\r\n\r\n<script>\r\n\r\n\r\nlet absences=[];\r\n\r\n\r\ntry{\r\n\r\nabsences=JSON.parse(localStorage.getItem(\"absences\")) || [];\r\n\r\n}\r\ncatch(e){\r\n\r\nabsences=[];\r\n\r\n}\r\n\r\n\r\n\r\nconst types={\r\n\r\nconge:\"Cong\u00e9\",\r\nmaladie:\"Maladie\",\r\nteletravail:\"T\u00e9l\u00e9travail\",\r\nautre:\"Autre\"\r\n\r\n};\r\n\r\n\r\n\r\n\r\n\r\nfunction sauvegarder(){\r\n\r\nlocalStorage.setItem(\r\n\"absences\",\r\nJSON.stringify(absences)\r\n);\r\n\r\n}\r\n\r\n\r\n\r\n\r\n\r\nfunction ajouterAbsence(){\r\n\r\n\r\nlet absence={\r\n\r\nnom:nom.value.trim(),\r\n\r\neglise:eglise.value.trim(),\r\n\r\nfonction:fonction.value.trim(),\r\n\r\nservice:service.value.trim(),\r\n\r\ntype:type.value,\r\n\r\ndebut:debut.value,\r\n\r\nfin:fin.value\r\n\r\n};\r\n\r\n\r\n\r\nif(!absence.nom || !absence.debut || !absence.fin){\r\n\r\nalert(\"Veuillez remplir les champs obligatoires\");\r\n\r\nreturn;\r\n\r\n}\r\n\r\n\r\n\r\nif(new Date(absence.fin)<new Date(absence.debut)){\r\n\r\nalert(\"La fin doit \u00eatre apr\u00e8s le d\u00e9but\");\r\n\r\nreturn;\r\n\r\n}\r\n\r\n\r\n\r\nabsences.push(absence);\r\n\r\nsauvegarder();\r\n\r\n\r\nnom.value=\"\";\r\neglise.value=\"\";\r\nfonction.value=\"\";\r\nservice.value=\"\";\r\ndebut.value=\"\";\r\nfin.value=\"\";\r\n\r\n\r\nafficher();\r\n\r\n\r\n}\r\n\r\n\r\n\r\n\r\n\r\nfunction joursEntre(a,b){\r\n\r\nlet debut=new Date(a);\r\nlet fin=new Date(b);\r\n\r\n\r\ndebut.setHours(0,0,0,0);\r\nfin.setHours(0,0,0,0);\r\n\r\n\r\nreturn Math.round(\r\n(fin-debut)\/(1000*60*60*24)\r\n)+1;\r\n\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\nfunction afficher(){\r\n\r\n\r\nlet recherche=\r\ndocument.getElementById(\"recherche\").value.toLowerCase();\r\n\r\n\r\nlet fe=\r\nfiltreEglise.value.toLowerCase();\r\n\r\n\r\nlet ff=\r\nfiltreFonction.value.toLowerCase();\r\n\r\n\r\nlet fs=\r\nfiltreService.value.toLowerCase();\r\n\r\n\r\n\r\nlet tableau=document.getElementById(\"tableau\");\r\n\r\ntableau.innerHTML=\"\";\r\n\r\n\r\nlet totalJours=0;\r\n\r\n\r\n\r\nabsences.forEach((a,index)=>{\r\n\r\n\r\nif(\r\n\r\na.nom.toLowerCase().includes(recherche)\r\n\r\n&& a.eglise.toLowerCase().includes(fe)\r\n\r\n&& a.fonction.toLowerCase().includes(ff)\r\n\r\n&& a.service.toLowerCase().includes(fs)\r\n\r\n){\r\n\r\n\r\nlet duree=joursEntre(a.debut,a.fin);\r\n\r\ntotalJours+=duree;\r\n\r\n\r\ntableau.innerHTML+=`\r\n\r\n<tr>\r\n\r\n<td>${a.nom}<\/td>\r\n<td>${a.eglise}<\/td>\r\n<td>${a.fonction}<\/td>\r\n<td>${a.service}<\/td>\r\n<td>${types[a.type]}<\/td>\r\n<td>${a.debut}<\/td>\r\n<td>${a.fin}<\/td>\r\n<td>${duree} jour(s)<\/td>\r\n\r\n<td>\r\n<button onclick=\"supprimer(${index})\">\r\nSupprimer\r\n<\/button>\r\n<\/td>\r\n\r\n<\/tr>\r\n\r\n`;\r\n\r\n}\r\n\r\n\r\n});\r\n\r\n\r\ntotal.innerHTML=absences.length;\r\n\r\njours.innerHTML=totalJours;\r\n\r\n\r\ngenererCalendrier();\r\n\r\n\r\n}\r\n\r\n\r\n\r\n\r\nfunction supprimer(i){\r\n\r\nabsences.splice(i,1);\r\n\r\nsauvegarder();\r\n\r\nafficher();\r\n\r\n}\r\n\r\n\r\n\r\n\r\n\r\nfunction resetFiltres(){\r\n\r\nfiltreEglise.value=\"\";\r\nfiltreFonction.value=\"\";\r\nfiltreService.value=\"\";\r\n\r\nafficher();\r\n\r\n}\r\n\r\n\r\n\r\n\r\n\r\nfunction genererCalendrier(){\r\n\r\n\r\nlet cal=document.getElementById(\"calendar\");\r\n\r\ncal.innerHTML=\"\";\r\n\r\n\r\nlet aujourd=new Date();\r\n\r\nlet mois=aujourd.getMonth();\r\n\r\nlet annee=aujourd.getFullYear();\r\n\r\n\r\nlet nbjours=new Date(\r\nannee,\r\nmois+1,\r\n0\r\n).getDate();\r\n\r\n\r\n\r\nfor(let i=1;i<=nbjours;i++){\r\n\r\n\r\nlet div=document.createElement(\"div\");\r\n\r\ndiv.className=\"day\";\r\n\r\n\r\nlet contenu=\"<h4>\"+i+\"<\/h4>\";\r\n\r\n\r\n\r\nabsences.forEach(a=>{\r\n\r\n\r\nlet date=new Date(\r\nannee,\r\nmois,\r\ni\r\n);\r\n\r\n\r\nlet debut=new Date(a.debut);\r\nlet fin=new Date(a.fin);\r\n\r\n\r\ndate.setHours(0,0,0,0);\r\ndebut.setHours(0,0,0,0);\r\nfin.setHours(0,0,0,0);\r\n\r\n\r\n\r\nif(date>=debut && date<=fin){\r\n\r\n\r\ncontenu+=`\r\n\r\n<div class=\"absence ${a.type}\">\r\n${a.nom}\r\n<\/div>\r\n\r\n`;\r\n\r\n}\r\n\r\n\r\n});\r\n\r\n\r\ndiv.innerHTML=contenu;\r\n\r\ncal.appendChild(div);\r\n\r\n\r\n}\r\n\r\n\r\n\r\n}\r\n\r\n\r\n\r\n\r\nafficher();\r\n\r\n\r\n<\/script>\r\n\r\n\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-a060924 e-flex e-con-boxed elementor-repeater-item-default_padding elementor-repeater-item-none elementor-repeater-item-none_hover wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-column-slider-no wpr-equal-height-no e-con e-parent\" data-id=\"a060924\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;ang_container_spacing_size&quot;:&quot;default_padding&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-9a555f7 elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-html\" data-id=\"9a555f7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"fr\">\r\n\r\n<head>\r\n\r\n<meta charset=\"UTF-8\">\r\n\r\n<meta name=\"viewport\"\r\n      content=\"width=device-width, initial-scale=1.0\">\r\n\r\n<title>Exploration de J\u00e9rusalem<\/title>\r\n\r\n<!-- Leaflet CSS -->\r\n<link\r\n    rel=\"stylesheet\"\r\n    href=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.css\"\r\n>\r\n\r\n<style>\r\n\r\n* {\r\n    box-sizing: border-box;\r\n}\r\n\r\nhtml,\r\nbody {\r\n    margin: 0;\r\n    padding: 0;\r\n    width: 100%;\r\n    min-height: 100%;\r\n    font-family: Arial, sans-serif;\r\n    background: #0f172a;\r\n}\r\n\r\n#jeu {\r\n    width: 100%;\r\n    max-width: 1500px;\r\n    margin: auto;\r\n    color: white;\r\n    background: #111827;\r\n}\r\n\r\n\/* ==============================\r\n   HEADER\r\n============================== *\/\r\n\r\n.header {\r\n    text-align: center;\r\n    padding: 20px;\r\n    background:\r\n        linear-gradient(\r\n            135deg,\r\n            #172554,\r\n            #4c1d95\r\n        );\r\n}\r\n\r\n.header h1 {\r\n    margin: 0 0 8px 0;\r\n}\r\n\r\n.header p {\r\n    margin: 0;\r\n    color: #dbeafe;\r\n}\r\n\r\n\/* ==============================\r\n   BARRES\r\n============================== *\/\r\n\r\n.barre {\r\n    display: flex;\r\n    flex-wrap: wrap;\r\n    justify-content: center;\r\n    gap: 8px;\r\n    padding: 12px;\r\n    background: #020617;\r\n}\r\n\r\n.barre strong {\r\n    width: 100%;\r\n    text-align: center;\r\n}\r\n\r\n\/* ==============================\r\n   BOUTONS\r\n============================== *\/\r\n\r\nbutton {\r\n    padding: 10px 14px;\r\n    border: 2px solid #475569;\r\n    border-radius: 8px;\r\n    background: #1e293b;\r\n    color: white;\r\n    font-weight: bold;\r\n    cursor: pointer;\r\n    user-select: none;\r\n}\r\n\r\nbutton:hover {\r\n    background: #334155;\r\n}\r\n\r\nbutton.active {\r\n    background: #2563eb;\r\n    border-color: #93c5fd;\r\n}\r\n\r\n\/* ==============================\r\n   INFORMATIONS\r\n============================== *\/\r\n\r\n#infos {\r\n    padding: 12px;\r\n    text-align: center;\r\n    background: #172554;\r\n}\r\n\r\n#message {\r\n    padding: 10px;\r\n    text-align: center;\r\n    background: #312e81;\r\n}\r\n\r\n\/* ==============================\r\n   CARTE\r\n============================== *\/\r\n\r\n#map {\r\n    width: 100%;\r\n    height: 650px;\r\n    min-height: 500px;\r\n    background: #dbeafe;\r\n}\r\n\r\n\/* ==============================\r\n   JOUEUR\r\n============================== *\/\r\n\r\n.joueur {\r\n    width: 44px;\r\n    height: 44px;\r\n\r\n    display: flex;\r\n    align-items: center;\r\n    justify-content: center;\r\n\r\n    font-size: 30px;\r\n\r\n    filter:\r\n        drop-shadow(\r\n            0 3px 4px\r\n            rgba(0, 0, 0, 0.7)\r\n        );\r\n}\r\n\r\n\/* ==============================\r\n   COMMANDES\r\n============================== *\/\r\n\r\n.commandes {\r\n    display: flex;\r\n    justify-content: center;\r\n    padding: 20px;\r\n    background: #111827;\r\n}\r\n\r\n.pave {\r\n    display: grid;\r\n\r\n    grid-template-columns:\r\n        65px\r\n        65px\r\n        65px\r\n        65px\r\n        65px;\r\n\r\n    grid-template-rows:\r\n        60px\r\n        60px\r\n        60px;\r\n\r\n    gap: 7px;\r\n}\r\n\r\n.commande {\r\n    width: 65px;\r\n    height: 60px;\r\n    padding: 0;\r\n    font-size: 21px;\r\n    touch-action: none;\r\n}\r\n\r\n.tourner-gauche {\r\n    grid-column: 1;\r\n    grid-row: 2;\r\n}\r\n\r\n.avancer {\r\n    grid-column: 3;\r\n    grid-row: 1;\r\n}\r\n\r\n.gauche {\r\n    grid-column: 2;\r\n    grid-row: 2;\r\n}\r\n\r\n.stop {\r\n    grid-column: 3;\r\n    grid-row: 2;\r\n}\r\n\r\n.droite {\r\n    grid-column: 4;\r\n    grid-row: 2;\r\n}\r\n\r\n.reculer {\r\n    grid-column: 3;\r\n    grid-row: 3;\r\n}\r\n\r\n.tourner-droite {\r\n    grid-column: 5;\r\n    grid-row: 2;\r\n}\r\n\r\n.commande:active {\r\n    background: #f59e0b;\r\n    color: #111827;\r\n}\r\n\r\n\/* ==============================\r\n   MOBILE\r\n============================== *\/\r\n\r\n@media (max-width: 600px) {\r\n\r\n    #map {\r\n        height: 550px;\r\n    }\r\n\r\n    .pave {\r\n        grid-template-columns:\r\n            55px\r\n            55px\r\n            55px\r\n            55px\r\n            55px;\r\n\r\n        grid-template-rows:\r\n            55px\r\n            55px\r\n            55px;\r\n\r\n        gap: 5px;\r\n    }\r\n\r\n    .commande {\r\n        width: 55px;\r\n        height: 55px;\r\n    }\r\n\r\n}\r\n\r\n<\/style>\r\n\r\n<\/head>\r\n\r\n\r\n<body>\r\n\r\n<div id=\"jeu\">\r\n\r\n\r\n<!-- ==============================\r\n     TITRE\r\n============================== -->\r\n\r\n<div class=\"header\">\r\n\r\n<h1>\r\n\ud83d\uddfa\ufe0f Exploration de J\u00e9rusalem\r\n<\/h1>\r\n\r\n<p>\r\nExplorez J\u00e9rusalem et d\u00e9couvrez ses lieux bibliques.\r\n<\/p>\r\n\r\n<\/div>\r\n\r\n\r\n<!-- ==============================\r\n     TRANSPORT\r\n============================== -->\r\n\r\n<div class=\"barre\">\r\n\r\n<strong>\r\n\ud83d\ude97 Choisissez votre moyen de transport\r\n<\/strong>\r\n\r\n<button\r\n    class=\"transport active\"\r\n    data-mode=\"walk\"\r\n>\r\n\ud83d\udeb6 Marche\r\n<\/button>\r\n\r\n<button\r\n    class=\"transport\"\r\n    data-mode=\"bike\"\r\n>\r\n\ud83d\udeb2 V\u00e9lo\r\n<\/button>\r\n\r\n<button\r\n    class=\"transport\"\r\n    data-mode=\"motorcycle\"\r\n>\r\n\ud83c\udfcd\ufe0f Moto\r\n<\/button>\r\n\r\n<button\r\n    class=\"transport\"\r\n    data-mode=\"car\"\r\n>\r\n\ud83d\ude97 Voiture\r\n<\/button>\r\n\r\n<\/div>\r\n\r\n\r\n<!-- ==============================\r\n     VUES\r\n============================== -->\r\n\r\n<div class=\"barre\">\r\n\r\n<strong>\r\n\ud83d\uddfa\ufe0f Choisissez votre vue\r\n<\/strong>\r\n\r\n<button\r\n    class=\"vue active\"\r\n    data-view=\"plan\"\r\n>\r\n\ud83d\uddfa\ufe0f Plan\r\n<\/button>\r\n\r\n<button\r\n    class=\"vue\"\r\n    data-view=\"satellite\"\r\n>\r\n\ud83d\udef0\ufe0f Satellite\r\n<\/button>\r\n\r\n<button\r\n    class=\"vue\"\r\n    data-view=\"hybride\"\r\n>\r\n\ud83d\udef0\ufe0f Hybride\r\n<\/button>\r\n\r\n<button\r\n    class=\"vue\"\r\n    data-view=\"detail\"\r\n>\r\n\ud83d\udd0e Vue d\u00e9taill\u00e9e\r\n<\/button>\r\n\r\n<button\r\n    class=\"vue\"\r\n    data-view=\"global\"\r\n>\r\n\ud83c\udf0d Vue globale\r\n<\/button>\r\n\r\n<\/div>\r\n\r\n\r\n<!-- ==============================\r\n     INFORMATIONS\r\n============================== -->\r\n\r\n<div id=\"infos\">\r\n\r\nMode :\r\n<strong id=\"mode\">Marche<\/strong>\r\n\r\n&nbsp; | &nbsp;\r\n\r\nDirection :\r\n<strong id=\"direction\">Nord<\/strong>\r\n\r\n<\/div>\r\n\r\n\r\n<div id=\"message\">\r\n\u2705 Carte pr\u00eate. Utilisez les fl\u00e8ches pour vous d\u00e9placer.\r\n<\/div>\r\n\r\n\r\n<!-- ==============================\r\n     CARTE\r\n============================== -->\r\n\r\n<div id=\"map\"><\/div>\r\n\r\n\r\n<!-- ==============================\r\n     COMMANDES\r\n============================== -->\r\n\r\n<div class=\"commandes\">\r\n\r\n<div class=\"pave\">\r\n\r\n<button\r\n    class=\"commande tourner-gauche\"\r\n    id=\"tournerGauche\"\r\n>\r\n1\ufe0f\u20e3\r\n<\/button>\r\n\r\n<button\r\n    class=\"commande avancer\"\r\n    id=\"haut\"\r\n>\r\n\u2b06\ufe0f\r\n<\/button>\r\n\r\n<button\r\n    class=\"commande gauche\"\r\n    id=\"gauche\"\r\n>\r\n\u2b05\ufe0f\r\n<\/button>\r\n\r\n<button\r\n    class=\"commande stop\"\r\n    id=\"stop\"\r\n>\r\n\u23f9\ufe0f\r\n<\/button>\r\n\r\n<button\r\n    class=\"commande droite\"\r\n    id=\"droite\"\r\n>\r\n\u27a1\ufe0f\r\n<\/button>\r\n\r\n<button\r\n    class=\"commande reculer\"\r\n    id=\"bas\"\r\n>\r\n\u2b07\ufe0f\r\n<\/button>\r\n\r\n<button\r\n    class=\"commande tourner-droite\"\r\n    id=\"tournerDroite\"\r\n>\r\n2\ufe0f\u20e3\r\n<\/button>\r\n\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n\r\n<!-- ==============================\r\n     LEAFLET JS\r\n============================== -->\r\n\r\n<script\r\n    src=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.js\"\r\n><\/script>\r\n\r\n\r\n<script>\r\n\r\n\/* ==================================================\r\n   POSITION DE DEPART\r\n================================================== *\/\r\n\r\nconst DEPART_LAT = 31.7767;\r\n\r\nconst DEPART_LNG = 35.2345;\r\n\r\n\r\n\/* ==================================================\r\n   POSITION DU JOUEUR\r\n================================================== *\/\r\n\r\nlet lat = DEPART_LAT;\r\n\r\nlet lng = DEPART_LNG;\r\n\r\n\r\n\/* ==================================================\r\n   ORIENTATION\r\n\r\n   0   = Nord\r\n   90  = Est\r\n   180 = Sud\r\n   270 = Ouest\r\n================================================== *\/\r\n\r\nlet angle = 0;\r\n\r\n\r\n\/* ==================================================\r\n   MODE ACTUEL\r\n================================================== *\/\r\n\r\nlet mode = \"walk\";\r\n\r\n\r\n\/* ==================================================\r\n   MODES DE TRANSPORT\r\n\r\n   IMPORTANT :\r\n\r\n   Tous utilisent le m\u00eame syst\u00e8me\r\n   de d\u00e9placement.\r\n\r\n   La diff\u00e9rence est uniquement\r\n   la vitesse.\r\n================================================== *\/\r\n\r\nconst modes = {\r\n\r\n    walk: {\r\n\r\n        nom: \"Marche\",\r\n\r\n        emoji: \"\ud83d\udeb6\",\r\n\r\n        vitesse: 0.000015\r\n\r\n    },\r\n\r\n    bike: {\r\n\r\n        nom: \"V\u00e9lo\",\r\n\r\n        emoji: \"\ud83d\udeb2\",\r\n\r\n        vitesse: 0.000025\r\n\r\n    },\r\n\r\n    motorcycle: {\r\n\r\n        nom: \"Moto\",\r\n\r\n        emoji: \"\ud83c\udfcd\ufe0f\",\r\n\r\n        vitesse: 0.000040\r\n\r\n    },\r\n\r\n    car: {\r\n\r\n        nom: \"Voiture\",\r\n\r\n        emoji: \"\ud83d\ude97\",\r\n\r\n        vitesse: 0.000035\r\n\r\n    }\r\n\r\n};\r\n\r\n\r\n\/* ==================================================\r\n   ETAT DES TOUCHES\r\n================================================== *\/\r\n\r\nconst touches = {\r\n\r\n    haut: false,\r\n\r\n    bas: false,\r\n\r\n    gauche: false,\r\n\r\n    droite: false\r\n\r\n};\r\n\r\n\r\n\/* ==================================================\r\n   CREATION DE LA CARTE\r\n\r\n   J\u00e9rusalem\r\n================================================== *\/\r\n\r\nconst map = L.map(\r\n    \"map\",\r\n    {\r\n        center: [\r\n            DEPART_LAT,\r\n            DEPART_LNG\r\n        ],\r\n\r\n        zoom: 15,\r\n\r\n        zoomControl: true\r\n    }\r\n);\r\n\r\n\r\n\/* ==================================================\r\n   COUCHE PLAN\r\n================================================== *\/\r\n\r\nconst plan = L.tileLayer(\r\n\r\n    \"https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png\",\r\n\r\n    {\r\n\r\n        maxZoom: 19,\r\n\r\n        attribution:\r\n        \"&copy; OpenStreetMap contributors\"\r\n\r\n    }\r\n\r\n);\r\n\r\n\r\n\/* Ajouter la couche au d\u00e9marrage *\/\r\n\r\nplan.addTo(map);\r\n\r\n\r\n\/* ==================================================\r\n   COUCHE SATELLITE\r\n================================================== *\/\r\n\r\nconst satellite = L.tileLayer(\r\n\r\n    \"https:\/\/server.arcgisonline.com\/ArcGIS\/rest\/services\/World_Imagery\/MapServer\/tile\/{z}\/{y}\/{x}\",\r\n\r\n    {\r\n\r\n        maxZoom: 19,\r\n\r\n        attribution:\r\n        \"&copy; Esri\"\r\n\r\n    }\r\n\r\n);\r\n\r\n\r\n\/* ==================================================\r\n   CREATION DE L'ICONE\r\n================================================== *\/\r\n\r\nfunction creerIcone() {\r\n\r\n    return L.divIcon({\r\n\r\n        className: \"\",\r\n\r\n        html:\r\n\r\n        `\r\n        <div\r\n            class=\"joueur\"\r\n            style=\"transform:rotate(${angle}deg)\"\r\n        >\r\n            ${modes[mode].emoji}\r\n        <\/div>\r\n        `,\r\n\r\n        iconSize: [\r\n            44,\r\n            44\r\n        ],\r\n\r\n        iconAnchor: [\r\n            22,\r\n            22\r\n        ]\r\n\r\n    });\r\n\r\n}\r\n\r\n\r\n\/* ==================================================\r\n   CREER LE JOUEUR\r\n================================================== *\/\r\n\r\nconst joueur = L.marker(\r\n\r\n    [\r\n        lat,\r\n        lng\r\n    ],\r\n\r\n    {\r\n\r\n        icon:\r\n        creerIcone(),\r\n\r\n        zIndexOffset:\r\n        10000\r\n\r\n    }\r\n\r\n).addTo(map);\r\n\r\n\r\n\/* ==================================================\r\n   ACTUALISER LE JOUEUR\r\n================================================== *\/\r\n\r\nfunction actualiserJoueur() {\r\n\r\n    joueur.setLatLng(\r\n\r\n        [\r\n            lat,\r\n            lng\r\n        ]\r\n\r\n    );\r\n\r\n    joueur.setIcon(\r\n\r\n        creerIcone()\r\n\r\n    );\r\n\r\n}\r\n\r\n\r\n\/* ==================================================\r\n   DIRECTION\r\n================================================== *\/\r\n\r\nfunction afficherDirection() {\r\n\r\n    let direction = \"Nord\";\r\n\r\n\r\n    if (\r\n        angle >= 45 &&\r\n        angle < 135\r\n    ) {\r\n\r\n        direction = \"Est\";\r\n\r\n    }\r\n\r\n    else if (\r\n        angle >= 135 &&\r\n        angle < 225\r\n    ) {\r\n\r\n        direction = \"Sud\";\r\n\r\n    }\r\n\r\n    else if (\r\n        angle >= 225 &&\r\n        angle < 315\r\n    ) {\r\n\r\n        direction = \"Ouest\";\r\n\r\n    }\r\n\r\n\r\n    document\r\n        .getElementById(\"direction\")\r\n        .textContent = direction;\r\n\r\n}\r\n\r\n\r\n\/* ==================================================\r\n   DEPLACEMENT\r\n\r\n   \u2b06\ufe0f = AVANCER\r\n   \u2b07\ufe0f = RECULER\r\n   \u2b05\ufe0f = ALLER A GAUCHE\r\n   \u27a1\ufe0f = ALLER A DROITE\r\n\r\n   1 = TOURNER GAUCHE\r\n   2 = TOURNER DROITE\r\n\r\n   Identique pour :\r\n   Marche\r\n   V\u00e9lo\r\n   Moto\r\n   Voiture\r\n================================================== *\/\r\n\r\nfunction deplacer() {\r\n\r\n    const vitesse =\r\n        modes[mode].vitesse;\r\n\r\n\r\n    let dLat = 0;\r\n\r\n    let dLng = 0;\r\n\r\n\r\n    \/* ==========================\r\n       AVANCER\r\n    ========================== *\/\r\n\r\n    if (touches.haut) {\r\n\r\n        const radians =\r\n            angle *\r\n            Math.PI \/\r\n            180;\r\n\r\n\r\n        dLat +=\r\n            Math.cos(radians)\r\n            *\r\n            vitesse;\r\n\r\n\r\n        dLng +=\r\n            Math.sin(radians)\r\n            *\r\n            vitesse;\r\n\r\n    }\r\n\r\n\r\n    \/* ==========================\r\n       RECULER\r\n    ========================== *\/\r\n\r\n    if (touches.bas) {\r\n\r\n        const radians =\r\n            angle *\r\n            Math.PI \/\r\n            180;\r\n\r\n\r\n        dLat -=\r\n            Math.cos(radians)\r\n            *\r\n            vitesse;\r\n\r\n\r\n        dLng -=\r\n            Math.sin(radians)\r\n            *\r\n            vitesse;\r\n\r\n    }\r\n\r\n\r\n    \/* ==========================\r\n       ALLER A GAUCHE\r\n\r\n       SANS TOURNER\r\n    ========================== *\/\r\n\r\n    if (touches.gauche) {\r\n\r\n        const radians =\r\n\r\n            (\r\n                angle - 90\r\n            )\r\n            *\r\n            Math.PI \/\r\n            180;\r\n\r\n\r\n        dLat +=\r\n            Math.cos(radians)\r\n            *\r\n            vitesse;\r\n\r\n\r\n        dLng +=\r\n            Math.sin(radians)\r\n            *\r\n            vitesse;\r\n\r\n    }\r\n\r\n\r\n    \/* ==========================\r\n       ALLER A DROITE\r\n\r\n       SANS TOURNER\r\n    ========================== *\/\r\n\r\n    if (touches.droite) {\r\n\r\n        const radians =\r\n\r\n            (\r\n                angle + 90\r\n            )\r\n            *\r\n            Math.PI \/\r\n            180;\r\n\r\n\r\n        dLat +=\r\n            Math.cos(radians)\r\n            *\r\n            vitesse;\r\n\r\n\r\n        dLng +=\r\n            Math.sin(radians)\r\n            *\r\n            vitesse;\r\n\r\n    }\r\n\r\n\r\n    \/* ==========================\r\n       AUCUN MOUVEMENT\r\n    ========================== *\/\r\n\r\n    if (\r\n\r\n        dLat === 0 &&\r\n\r\n        dLng === 0\r\n\r\n    ) {\r\n\r\n        return;\r\n\r\n    }\r\n\r\n\r\n    \/* ==========================\r\n       NOUVELLE POSITION\r\n    ========================== *\/\r\n\r\n    lat += dLat;\r\n\r\n    lng += dLng;\r\n\r\n\r\n    \/* ==========================\r\n       ACTUALISATION\r\n    ========================== *\/\r\n\r\n    actualiserJoueur();\r\n\r\n\r\n    \/* ==========================\r\n       SUIVRE LE JOUEUR\r\n    ========================== *\/\r\n\r\n    map.panTo(\r\n\r\n        [\r\n            lat,\r\n            lng\r\n        ],\r\n\r\n        {\r\n            animate: false\r\n        }\r\n\r\n    );\r\n\r\n}\r\n\r\n\r\n\/* ==================================================\r\n   TOURNER GAUCHE\r\n\r\n   TOUCHE 1\r\n================================================== *\/\r\n\r\nfunction tournerGauche() {\r\n\r\n    angle -= 10;\r\n\r\n\r\n    angle =\r\n        (\r\n            angle + 360\r\n        )\r\n        % 360;\r\n\r\n\r\n    actualiserJoueur();\r\n\r\n\r\n    afficherDirection();\r\n\r\n}\r\n\r\n\r\n\/* ==================================================\r\n   TOURNER DROITE\r\n\r\n   TOUCHE 2\r\n================================================== *\/\r\n\r\nfunction tournerDroite() {\r\n\r\n    angle += 10;\r\n\r\n\r\n    angle =\r\n        (\r\n            angle + 360\r\n        )\r\n        % 360;\r\n\r\n\r\n    actualiserJoueur();\r\n\r\n\r\n    afficherDirection();\r\n\r\n}\r\n\r\n\r\n\/* ==================================================\r\n   STOP\r\n================================================== *\/\r\n\r\nfunction arreter() {\r\n\r\n    touches.haut = false;\r\n\r\n    touches.bas = false;\r\n\r\n    touches.gauche = false;\r\n\r\n    touches.droite = false;\r\n\r\n}\r\n\r\n\r\n\/* ==================================================\r\n   CLAVIER\r\n================================================== *\/\r\n\r\ndocument.addEventListener(\r\n\r\n    \"keydown\",\r\n\r\n    function(e) {\r\n\r\n\r\n        \/* Bloquer le d\u00e9filement *\/\r\n\r\n        if (\r\n\r\n            e.key === \"ArrowUp\" ||\r\n\r\n            e.key === \"ArrowDown\" ||\r\n\r\n            e.key === \"ArrowLeft\" ||\r\n\r\n            e.key === \"ArrowRight\"\r\n\r\n        ) {\r\n\r\n            e.preventDefault();\r\n\r\n        }\r\n\r\n\r\n        \/* HAUT *\/\r\n\r\n        if (\r\n            e.key === \"ArrowUp\"\r\n        ) {\r\n\r\n            touches.haut = true;\r\n\r\n        }\r\n\r\n\r\n        \/* BAS *\/\r\n\r\n        if (\r\n            e.key === \"ArrowDown\"\r\n        ) {\r\n\r\n            touches.bas = true;\r\n\r\n        }\r\n\r\n\r\n        \/* GAUCHE *\/\r\n\r\n        if (\r\n            e.key === \"ArrowLeft\"\r\n        ) {\r\n\r\n            touches.gauche = true;\r\n\r\n        }\r\n\r\n\r\n        \/* DROITE *\/\r\n\r\n        if (\r\n            e.key === \"ArrowRight\"\r\n        ) {\r\n\r\n            touches.droite = true;\r\n\r\n        }\r\n\r\n\r\n        \/* TOURNER GAUCHE *\/\r\n\r\n        if (\r\n            e.key === \"1\"\r\n        ) {\r\n\r\n            tournerGauche();\r\n\r\n        }\r\n\r\n\r\n        \/* TOURNER DROITE *\/\r\n\r\n        if (\r\n            e.key === \"2\"\r\n        ) {\r\n\r\n            tournerDroite();\r\n\r\n        }\r\n\r\n\r\n        \/* STOP *\/\r\n\r\n        if (\r\n            e.code === \"Space\"\r\n        ) {\r\n\r\n            arreter();\r\n\r\n        }\r\n\r\n    }\r\n\r\n);\r\n\r\n\r\n\/* ==================================================\r\n   RELACHEMENT\r\n================================================== *\/\r\n\r\ndocument.addEventListener(\r\n\r\n    \"keyup\",\r\n\r\n    function(e) {\r\n\r\n\r\n        if (\r\n            e.key === \"ArrowUp\"\r\n        ) {\r\n\r\n            touches.haut = false;\r\n\r\n        }\r\n\r\n\r\n        if (\r\n            e.key === \"ArrowDown\"\r\n        ) {\r\n\r\n            touches.bas = false;\r\n\r\n        }\r\n\r\n\r\n        if (\r\n            e.key === \"ArrowLeft\"\r\n        ) {\r\n\r\n            touches.gauche = false;\r\n\r\n        }\r\n\r\n\r\n        if (\r\n            e.key === \"ArrowRight\"\r\n        ) {\r\n\r\n            touches.droite = false;\r\n\r\n        }\r\n\r\n    }\r\n\r\n);\r\n\r\n\r\n\/* ==================================================\r\n   BOUTONS DE DEPLACEMENT\r\n\r\n   Fonctionne avec souris\r\n   et \u00e9cran tactile.\r\n================================================== *\/\r\n\r\nfunction boutonMaintenu(\r\n\r\n    id,\r\n\r\n    touche\r\n\r\n) {\r\n\r\n    const bouton =\r\n        document.getElementById(id);\r\n\r\n\r\n    \/* Souris *\/\r\n\r\n    bouton.addEventListener(\r\n\r\n        \"mousedown\",\r\n\r\n        function(e) {\r\n\r\n            e.preventDefault();\r\n\r\n            touches[touche] = true;\r\n\r\n        }\r\n\r\n    );\r\n\r\n\r\n    bouton.addEventListener(\r\n\r\n        \"mouseup\",\r\n\r\n        function() {\r\n\r\n            touches[touche] = false;\r\n\r\n        }\r\n\r\n    );\r\n\r\n\r\n    bouton.addEventListener(\r\n\r\n        \"mouseleave\",\r\n\r\n        function() {\r\n\r\n            touches[touche] = false;\r\n\r\n        }\r\n\r\n    );\r\n\r\n\r\n    \/* Tactile *\/\r\n\r\n    bouton.addEventListener(\r\n\r\n        \"touchstart\",\r\n\r\n        function(e) {\r\n\r\n            e.preventDefault();\r\n\r\n            touches[touche] = true;\r\n\r\n        },\r\n\r\n        {\r\n            passive: false\r\n        }\r\n\r\n    );\r\n\r\n\r\n    bouton.addEventListener(\r\n\r\n        \"touchend\",\r\n\r\n        function(e) {\r\n\r\n            e.preventDefault();\r\n\r\n            touches[touche] = false;\r\n\r\n        },\r\n\r\n        {\r\n            passive: false\r\n        }\r\n\r\n    );\r\n\r\n}\r\n\r\n\r\n\/* Activer les boutons *\/\r\n\r\nboutonMaintenu(\r\n    \"haut\",\r\n    \"haut\"\r\n);\r\n\r\nboutonMaintenu(\r\n    \"bas\",\r\n    \"bas\"\r\n);\r\n\r\nboutonMaintenu(\r\n    \"gauche\",\r\n    \"gauche\"\r\n);\r\n\r\nboutonMaintenu(\r\n    \"droite\",\r\n    \"droite\"\r\n);\r\n\r\n\r\n\/* ==================================================\r\n   BOUTON 1\r\n================================================== *\/\r\n\r\ndocument\r\n    .getElementById(\"tournerGauche\")\r\n    .addEventListener(\r\n        \"click\",\r\n        tournerGauche\r\n    );\r\n\r\n\r\n\/* ==================================================\r\n   BOUTON 2\r\n================================================== *\/\r\n\r\ndocument\r\n    .getElementById(\"tournerDroite\")\r\n    .addEventListener(\r\n        \"click\",\r\n        tournerDroite\r\n    );\r\n\r\n\r\n\/* ==================================================\r\n   BOUTON STOP\r\n================================================== *\/\r\n\r\ndocument\r\n    .getElementById(\"stop\")\r\n    .addEventListener(\r\n        \"click\",\r\n        arreter\r\n    );\r\n\r\n\r\n\/* ==================================================\r\n   CHANGEMENT DE TRANSPORT\r\n================================================== *\/\r\n\r\ndocument\r\n    .querySelectorAll(\".transport\")\r\n    .forEach(\r\n\r\n        function(button) {\r\n\r\n            button.addEventListener(\r\n\r\n                \"click\",\r\n\r\n                function() {\r\n\r\n\r\n                    \/* Arr\u00eat *\/\r\n\r\n                    arreter();\r\n\r\n\r\n                    \/* D\u00e9sactiver les autres *\/\r\n\r\n                    document\r\n                        .querySelectorAll(\".transport\")\r\n                        .forEach(\r\n\r\n                            function(b) {\r\n\r\n                                b.classList.remove(\r\n                                    \"active\"\r\n                                );\r\n\r\n                            }\r\n\r\n                        );\r\n\r\n\r\n                    \/* Activer *\/\r\n\r\n                    button.classList.add(\r\n                        \"active\"\r\n                    );\r\n\r\n\r\n                    \/* Changer le mode *\/\r\n\r\n                    mode =\r\n                        button.dataset.mode;\r\n\r\n\r\n                    \/* Afficher *\/\r\n\r\n                    document\r\n                        .getElementById(\"mode\")\r\n                        .textContent =\r\n                        modes[mode].nom;\r\n\r\n\r\n                    \/* Changer l'ic\u00f4ne *\/\r\n\r\n                    actualiserJoueur();\r\n\r\n                }\r\n\r\n            );\r\n\r\n        }\r\n\r\n    );\r\n\r\n\r\n\/* ==================================================\r\n   CHANGEMENT DE VUE\r\n================================================== *\/\r\n\r\ndocument\r\n    .querySelectorAll(\".vue\")\r\n    .forEach(\r\n\r\n        function(button) {\r\n\r\n            button.addEventListener(\r\n\r\n                \"click\",\r\n\r\n                function() {\r\n\r\n\r\n                    \/* D\u00e9sactiver *\/\r\n\r\n                    document\r\n                        .querySelectorAll(\".vue\")\r\n                        .forEach(\r\n\r\n                            function(b) {\r\n\r\n                                b.classList.remove(\r\n                                    \"active\"\r\n                                );\r\n\r\n                            }\r\n\r\n                        );\r\n\r\n\r\n                    \/* Activer *\/\r\n\r\n                    button.classList.add(\r\n                        \"active\"\r\n                    );\r\n\r\n\r\n                    const vue =\r\n                        button.dataset.view;\r\n\r\n\r\n                    \/* Retirer les couches *\/\r\n\r\n                    if (\r\n                        map.hasLayer(plan)\r\n                    ) {\r\n\r\n                        map.removeLayer(plan);\r\n\r\n                    }\r\n\r\n\r\n                    if (\r\n                        map.hasLayer(satellite)\r\n                    ) {\r\n\r\n                        map.removeLayer(satellite);\r\n\r\n                    }\r\n\r\n\r\n                    \/* PLAN *\/\r\n\r\n                    if (\r\n                        vue === \"plan\"\r\n                    ) {\r\n\r\n                        plan.addTo(map);\r\n\r\n                    }\r\n\r\n\r\n                    \/* SATELLITE *\/\r\n\r\n                    if (\r\n                        vue === \"satellite\"\r\n                    ) {\r\n\r\n                        satellite.addTo(map);\r\n\r\n                    }\r\n\r\n\r\n                    \/* HYBRIDE *\/\r\n\r\n                    if (\r\n                        vue === \"hybride\"\r\n                    ) {\r\n\r\n                        satellite.addTo(map);\r\n\r\n                        plan.setOpacity(0.45);\r\n\r\n                        plan.addTo(map);\r\n\r\n                    }\r\n\r\n\r\n                    \/* DETAIL *\/\r\n\r\n                    if (\r\n                        vue === \"detail\"\r\n                    ) {\r\n\r\n                        plan.addTo(map);\r\n\r\n                        map.setZoom(19);\r\n\r\n                    }\r\n\r\n\r\n                    \/* GLOBAL *\/\r\n\r\n                    if (\r\n                        vue === \"global\"\r\n                    ) {\r\n\r\n                        plan.addTo(map);\r\n\r\n                        map.setView(\r\n\r\n                            [\r\n                                DEPART_LAT,\r\n                                DEPART_LNG\r\n                            ],\r\n\r\n                            11\r\n\r\n                        );\r\n\r\n                    }\r\n\r\n                }\r\n\r\n            );\r\n\r\n        }\r\n\r\n    );\r\n\r\n\r\n\/* ==================================================\r\n   CORRECTION TAILLE CARTE\r\n================================================== *\/\r\n\r\nsetTimeout(\r\n\r\n    function() {\r\n\r\n        map.invalidateSize();\r\n\r\n    },\r\n\r\n    500\r\n\r\n);\r\n\r\n\r\n\/* ==================================================\r\n   BOUCLE DU JEU\r\n================================================== *\/\r\n\r\nfunction boucle() {\r\n\r\n    deplacer();\r\n\r\n    requestAnimationFrame(\r\n        boucle\r\n    );\r\n\r\n}\r\n\r\n\r\n\/* ==================================================\r\n   DEMARRAGE\r\n================================================== *\/\r\n\r\nboucle();\r\n\r\n\r\n<\/script>\r\n\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-e7c2190 e-flex e-con-boxed elementor-repeater-item-default_padding elementor-repeater-item-none elementor-repeater-item-none_hover wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-column-slider-no wpr-equal-height-no e-con e-parent\" data-id=\"e7c2190\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;ang_container_spacing_size&quot;:&quot;default_padding&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-db91e63 elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-html\" data-id=\"db91e63\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t```html\r\n<!DOCTYPE html>\r\n<html lang=\"fr\">\r\n\r\n<head>\r\n\r\n<meta charset=\"UTF-8\">\r\n\r\n<meta name=\"viewport\"\r\ncontent=\"width=device-width, initial-scale=1.0\">\r\n\r\n<title>\r\nJeu des livres de la Bible\r\n<\/title>\r\n\r\n\r\n<style>\r\n\r\n\/* =====================================================\r\n   STYLE GENERAL\r\n===================================================== *\/\r\n\r\n* {\r\n    box-sizing: border-box;\r\n}\r\n\r\nbody {\r\n\r\n    margin: 0;\r\n\r\n    font-family:\r\n    Arial,\r\n    Helvetica,\r\n    sans-serif;\r\n\r\n    background:\r\n    linear-gradient(\r\n        135deg,\r\n        #17365d,\r\n        #3f72af,\r\n        #6fa3d2\r\n    );\r\n\r\n    min-height: 100vh;\r\n\r\n    padding: 20px;\r\n\r\n}\r\n\r\n\r\n.container {\r\n\r\n    max-width: 1500px;\r\n\r\n    margin: auto;\r\n\r\n    background: white;\r\n\r\n    border-radius: 25px;\r\n\r\n    padding: 25px;\r\n\r\n    box-shadow:\r\n    0 10px 40px\r\n    rgba(0,0,0,0.3);\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   TITRE\r\n===================================================== *\/\r\n\r\nh1 {\r\n\r\n    text-align: center;\r\n\r\n    color: #17365d;\r\n\r\n    margin-top: 0;\r\n\r\n    font-size: 34px;\r\n\r\n}\r\n\r\n\r\n.instructions {\r\n\r\n    text-align: center;\r\n\r\n    font-size: 18px;\r\n\r\n    color: #555;\r\n\r\n    margin-bottom: 20px;\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   MODES\r\n===================================================== *\/\r\n\r\n.game-selection {\r\n\r\n    background: #f1f4f7;\r\n\r\n    border: 3px solid #d4dce4;\r\n\r\n    border-radius: 18px;\r\n\r\n    padding: 18px;\r\n\r\n    margin-bottom: 20px;\r\n\r\n    text-align: center;\r\n\r\n}\r\n\r\n\r\n.game-selection h2 {\r\n\r\n    margin-top: 0;\r\n\r\n    color: #17365d;\r\n\r\n}\r\n\r\n\r\n.mode-buttons {\r\n\r\n    display: flex;\r\n\r\n    justify-content: center;\r\n\r\n    gap: 12px;\r\n\r\n    flex-wrap: wrap;\r\n\r\n}\r\n\r\n\r\n.mode-button {\r\n\r\n    padding: 12px 20px;\r\n\r\n    border: 2px solid #4682b4;\r\n\r\n    border-radius: 12px;\r\n\r\n    background: white;\r\n\r\n    color: #17365d;\r\n\r\n    font-size: 16px;\r\n\r\n    font-weight: bold;\r\n\r\n    cursor: pointer;\r\n\r\n}\r\n\r\n\r\n.mode-button.active {\r\n\r\n    background: #17365d;\r\n\r\n    color: white;\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   SCORE\r\n===================================================== *\/\r\n\r\n.score-area {\r\n\r\n    display: flex;\r\n\r\n    justify-content: center;\r\n\r\n    gap: 20px;\r\n\r\n    flex-wrap: wrap;\r\n\r\n    margin-bottom: 15px;\r\n\r\n}\r\n\r\n\r\n.score-box {\r\n\r\n    background:\r\n    linear-gradient(\r\n        135deg,\r\n        #ffd86b,\r\n        #e8b83f\r\n    );\r\n\r\n    padding: 12px 30px;\r\n\r\n    border-radius: 15px;\r\n\r\n    font-size: 22px;\r\n\r\n    font-weight: bold;\r\n\r\n}\r\n\r\n\r\n.placed-box {\r\n\r\n    background:\r\n    linear-gradient(\r\n        135deg,\r\n        #cce6ff,\r\n        #80b9e8\r\n    );\r\n\r\n    padding: 12px 30px;\r\n\r\n    border-radius: 15px;\r\n\r\n    font-size: 22px;\r\n\r\n    font-weight: bold;\r\n\r\n}\r\n\r\n\r\n#message {\r\n\r\n    text-align: center;\r\n\r\n    min-height: 35px;\r\n\r\n    font-size: 18px;\r\n\r\n    font-weight: bold;\r\n\r\n    margin-bottom: 15px;\r\n\r\n}\r\n\r\n\r\n.good {\r\n\r\n    color: #16803c;\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   ZONE DE JEU\r\n===================================================== *\/\r\n\r\n.game-area {\r\n\r\n    display: grid;\r\n\r\n    grid-template-columns:\r\n    1fr 2fr;\r\n\r\n    gap: 25px;\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   ZONE DES LIVRES DISPONIBLES\r\n===================================================== *\/\r\n\r\n.books-area {\r\n\r\n    background: #f1f4f7;\r\n\r\n    border: 3px solid #d4dce4;\r\n\r\n    border-radius: 20px;\r\n\r\n    padding: 20px;\r\n\r\n    min-height: 650px;\r\n\r\n    transition: 0.2s;\r\n\r\n}\r\n\r\n\r\n.books-area h2 {\r\n\r\n    text-align: center;\r\n\r\n    color: #17365d;\r\n\r\n    margin-top: 0;\r\n\r\n}\r\n\r\n\r\n.books-help {\r\n\r\n    text-align: center;\r\n\r\n    color: #555;\r\n\r\n    margin-bottom: 20px;\r\n\r\n}\r\n\r\n\r\n.books-area.drop-active {\r\n\r\n    box-shadow:\r\n    0 0 0 6px\r\n    rgba(52,152,219,0.65);\r\n\r\n    transform:\r\n    scale(1.01);\r\n\r\n}\r\n\r\n\r\n.books-area.drop-active::after {\r\n\r\n    content:\r\n    \"\ud83d\udcda Rel\u00e2cher pour remettre le livre dans la liste\";\r\n\r\n    position: absolute;\r\n\r\n    top: 50%;\r\n\r\n    left: 50%;\r\n\r\n    transform:\r\n    translate(-50%,-50%);\r\n\r\n    background:\r\n    rgba(255,255,255,0.95);\r\n\r\n    padding: 15px 25px;\r\n\r\n    border-radius: 12px;\r\n\r\n    font-size: 18px;\r\n\r\n    font-weight: bold;\r\n\r\n    color: #17365d;\r\n\r\n    pointer-events: none;\r\n\r\n    z-index: 100;\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   LISTE DES LIVRES\r\n===================================================== *\/\r\n\r\n#books {\r\n\r\n    display: grid;\r\n\r\n    grid-template-columns:\r\n    repeat(2,1fr);\r\n\r\n    gap: 10px;\r\n\r\n    min-height: 350px;\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   LIVRE\r\n===================================================== *\/\r\n\r\n.book {\r\n\r\n    background:\r\n    linear-gradient(\r\n        135deg,\r\n        #ffffff,\r\n        #e5edf5\r\n    );\r\n\r\n    border: 2px solid #4682b4;\r\n\r\n    border-radius: 10px;\r\n\r\n    padding: 13px 8px;\r\n\r\n    text-align: center;\r\n\r\n    font-weight: bold;\r\n\r\n    cursor: grab;\r\n\r\n    user-select: none;\r\n\r\n    touch-action: none;\r\n\r\n}\r\n\r\n\r\n.book-in-zone {\r\n\r\n    display: flex;\r\n\r\n    align-items: center;\r\n\r\n    background: white;\r\n\r\n    border: 2px solid #999;\r\n\r\n    border-radius: 10px;\r\n\r\n    padding: 10px;\r\n\r\n    margin-bottom: 8px;\r\n\r\n    font-weight: bold;\r\n\r\n    cursor: grab;\r\n\r\n    user-select: none;\r\n\r\n    touch-action: none;\r\n\r\n}\r\n\r\n\r\n.book.dragging,\r\n.book-in-zone.dragging {\r\n\r\n    opacity: 0.35;\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   TESTAMENTS\r\n===================================================== *\/\r\n\r\n.testaments {\r\n\r\n    display: grid;\r\n\r\n    grid-template-columns:\r\n    1fr 1fr;\r\n\r\n    gap: 20px;\r\n\r\n}\r\n\r\n\r\n.testaments.single {\r\n\r\n    grid-template-columns:\r\n    1fr;\r\n\r\n}\r\n\r\n\r\n.testament {\r\n\r\n    position: relative;\r\n\r\n    border-radius: 20px;\r\n\r\n    padding: 15px;\r\n\r\n    min-height: 650px;\r\n\r\n    transition: 0.2s;\r\n\r\n}\r\n\r\n\r\n.ancien {\r\n\r\n    background:\r\n    linear-gradient(\r\n        135deg,\r\n        #fff5c7,\r\n        #ffe28a\r\n    );\r\n\r\n    border: 4px solid #d3a52c;\r\n\r\n}\r\n\r\n\r\n.nouveau {\r\n\r\n    background:\r\n    linear-gradient(\r\n        135deg,\r\n        #dceeff,\r\n        #a7d1f3\r\n    );\r\n\r\n    border: 4px solid #4385bd;\r\n\r\n}\r\n\r\n\r\n.testament.drop-active {\r\n\r\n    transform:\r\n    scale(1.01);\r\n\r\n    box-shadow:\r\n    0 0 0 6px\r\n    rgba(255,152,0,0.65);\r\n\r\n}\r\n\r\n\r\n.testament.drop-active::after {\r\n\r\n    content:\r\n    \"\ud83d\udcd6 D\u00e9poser le livre ici\";\r\n\r\n    position: absolute;\r\n\r\n    top: 50%;\r\n\r\n    left: 50%;\r\n\r\n    transform:\r\n    translate(-50%,-50%);\r\n\r\n    background:\r\n    rgba(255,255,255,0.95);\r\n\r\n    padding: 15px 25px;\r\n\r\n    border-radius: 12px;\r\n\r\n    font-size: 20px;\r\n\r\n    font-weight: bold;\r\n\r\n    color: #17365d;\r\n\r\n    pointer-events: none;\r\n\r\n    z-index: 100;\r\n\r\n}\r\n\r\n\r\n.testament h2 {\r\n\r\n    text-align: center;\r\n\r\n    margin-top: 5px;\r\n\r\n}\r\n\r\n\r\n.ancien h2 {\r\n\r\n    color: #8a6500;\r\n\r\n}\r\n\r\n\r\n.nouveau h2 {\r\n\r\n    color: #205987;\r\n\r\n}\r\n\r\n\r\n.testament-description {\r\n\r\n    text-align: center;\r\n\r\n    color: #555;\r\n\r\n    margin-bottom: 15px;\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   LISTE DANS LE TESTAMENT\r\n===================================================== *\/\r\n\r\n.book-list {\r\n\r\n    min-height: 500px;\r\n\r\n    padding: 10px;\r\n\r\n    border-radius: 15px;\r\n\r\n    background:\r\n    rgba(255,255,255,0.35);\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   LIVRE CORRECT\r\n===================================================== *\/\r\n\r\n.book-in-zone.correct {\r\n\r\n    background: #b9efc7;\r\n\r\n    border: 3px solid #16803c;\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   PLACEHOLDER\r\n===================================================== *\/\r\n\r\n.drag-placeholder {\r\n\r\n    height: 48px;\r\n\r\n    margin-bottom: 8px;\r\n\r\n    border: 2px dashed #777;\r\n\r\n    border-radius: 10px;\r\n\r\n    background:\r\n    rgba(255,255,255,0.4);\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   FIN\r\n===================================================== *\/\r\n\r\n#end {\r\n\r\n    display: none;\r\n\r\n    text-align: center;\r\n\r\n    margin-top: 25px;\r\n\r\n    padding: 25px;\r\n\r\n    background: #d8f5df;\r\n\r\n    border: 3px solid #16803c;\r\n\r\n    border-radius: 20px;\r\n\r\n}\r\n\r\n\r\n#final {\r\n\r\n    font-size: 30px;\r\n\r\n    font-weight: bold;\r\n\r\n    color: #11652f;\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   BOUTON\r\n===================================================== *\/\r\n\r\n.restart-button {\r\n\r\n    display: block;\r\n\r\n    margin: 25px auto 5px;\r\n\r\n    padding: 14px 35px;\r\n\r\n    border: none;\r\n\r\n    border-radius: 12px;\r\n\r\n    background: #17365d;\r\n\r\n    color: white;\r\n\r\n    font-size: 18px;\r\n\r\n    font-weight: bold;\r\n\r\n    cursor: pointer;\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   RESPONSIVE\r\n===================================================== *\/\r\n\r\n@media(max-width:1100px) {\r\n\r\n    .game-area {\r\n\r\n        grid-template-columns: 1fr;\r\n\r\n    }\r\n\r\n}\r\n\r\n\r\n@media(max-width:750px) {\r\n\r\n    .testaments {\r\n\r\n        grid-template-columns: 1fr;\r\n\r\n    }\r\n\r\n}\r\n\r\n\r\n@media(max-width:500px) {\r\n\r\n    body {\r\n\r\n        padding: 8px;\r\n\r\n    }\r\n\r\n\r\n    .container {\r\n\r\n        padding: 12px;\r\n\r\n    }\r\n\r\n\r\n    #books {\r\n\r\n        grid-template-columns: 1fr;\r\n\r\n    }\r\n\r\n\r\n    h1 {\r\n\r\n        font-size: 26px;\r\n\r\n    }\r\n\r\n}\r\n\r\n<\/style>\r\n\r\n<\/head>\r\n\r\n\r\n<body>\r\n\r\n\r\n<div class=\"container\">\r\n\r\n\r\n<h1>\r\n\ud83d\udcd6 Les livres de la Bible\r\n<\/h1>\r\n\r\n\r\n<div class=\"instructions\">\r\n\r\n\ud83d\uddb1\ufe0f Fais glisser un livre avec la souris.\r\n\r\n<br>\r\n\r\n\ud83d\udcf1 Sur t\u00e9l\u00e9phone ou tablette,\r\nfais glisser avec ton doigt.\r\n\r\n<br><br>\r\n\r\nTu peux d\u00e9placer les livres autant de fois que n\u00e9cessaire.\r\n\r\n<br>\r\n\r\nPour retirer un livre d'un Testament,\r\nfais-le glisser vers la zone\r\n<strong>\ud83d\udcda Livres disponibles<\/strong>.\r\n\r\n<\/div>\r\n\r\n\r\n\r\n<!-- =====================================================\r\n     MODES\r\n===================================================== -->\r\n\r\n<div class=\"game-selection\">\r\n\r\n\r\n<h2>\r\n\ud83c\udfae Choisis ton jeu\r\n<\/h2>\r\n\r\n\r\n<div class=\"mode-buttons\">\r\n\r\n\r\n<button\r\nclass=\"mode-button active\"\r\ndata-mode=\"all\">\r\n\r\n\ud83d\udcd6 Toute la Bible\r\n<br>\r\n66 livres\r\n\r\n<\/button>\r\n\r\n\r\n<button\r\nclass=\"mode-button\"\r\ndata-mode=\"ancien\">\r\n\r\n\ud83d\udcdc Ancien Testament\r\n<br>\r\n39 livres\r\n\r\n<\/button>\r\n\r\n\r\n<button\r\nclass=\"mode-button\"\r\ndata-mode=\"nouveau\">\r\n\r\n\u271d\ufe0f Nouveau Testament\r\n<br>\r\n27 livres\r\n\r\n<\/button>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n\r\n<!-- =====================================================\r\n     SCORE\r\n===================================================== -->\r\n\r\n<div class=\"score-area\">\r\n\r\n\r\n<div class=\"score-box\">\r\n\r\n\ud83c\udfc6 Score :\r\n<span id=\"score\">0<\/span>\r\n\/\r\n<span id=\"maxScore\">66<\/span>\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"placed-box\">\r\n\r\n\ud83d\udcda Livres plac\u00e9s :\r\n<span id=\"placed\">0<\/span>\r\n\/\r\n<span id=\"maxPlaced\">66<\/span>\r\n\r\n<\/div>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n<div id=\"message\">\r\n\r\nCommence par d\u00e9placer un livre.\r\n\r\n<\/div>\r\n\r\n\r\n\r\n<!-- =====================================================\r\n     ZONE DE JEU\r\n===================================================== -->\r\n\r\n<div class=\"game-area\">\r\n\r\n\r\n\r\n<!-- =====================================================\r\n     LIVRES DISPONIBLES\r\n===================================================== -->\r\n\r\n<div\r\nclass=\"books-area\"\r\nid=\"booksArea\">\r\n\r\n\r\n<h2>\r\n\ud83d\udcda Livres disponibles\r\n<\/h2>\r\n\r\n\r\n<div class=\"books-help\">\r\n\r\nListe alphab\u00e9tique\r\n\r\n<br><br>\r\n\r\nGlisse un livre vers le Testament.\r\n\r\n<br>\r\n\r\nPour retirer un livre plac\u00e9,\r\nglisse-le ici.\r\n\r\n<\/div>\r\n\r\n\r\n<div id=\"books\">\r\n\r\n<\/div>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n\r\n<!-- =====================================================\r\n     TESTAMENTS\r\n===================================================== -->\r\n\r\n<div\r\nclass=\"testaments\"\r\nid=\"testaments\">\r\n\r\n\r\n\r\n<!-- ANCIEN -->\r\n\r\n<div\r\nclass=\"testament ancien\"\r\nid=\"ancienZone\"\r\ndata-testament=\"ancien\">\r\n\r\n\r\n<h2>\r\n\ud83d\udcdc Ancien Testament\r\n<\/h2>\r\n\r\n\r\n<div class=\"testament-description\">\r\n\r\n39 livres\r\n\r\n<\/div>\r\n\r\n\r\n<div\r\nclass=\"book-list\"\r\nid=\"ancienList\">\r\n\r\n<\/div>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n\r\n<!-- NOUVEAU -->\r\n\r\n<div\r\nclass=\"testament nouveau\"\r\nid=\"nouveauZone\"\r\ndata-testament=\"nouveau\">\r\n\r\n\r\n<h2>\r\n\u271d\ufe0f Nouveau Testament\r\n<\/h2>\r\n\r\n\r\n<div class=\"testament-description\">\r\n\r\n27 livres\r\n\r\n<\/div>\r\n\r\n\r\n<div\r\nclass=\"book-list\"\r\nid=\"nouveauList\">\r\n\r\n<\/div>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n\r\n<!-- =====================================================\r\n     FIN\r\n===================================================== -->\r\n\r\n<div id=\"end\">\r\n\r\n\r\n<h2>\r\n\ud83c\udf89 F\u00e9licitations !\r\n<\/h2>\r\n\r\n\r\n<p>\r\nTu as termin\u00e9 le jeu.\r\n<\/p>\r\n\r\n\r\n<div id=\"final\">\r\n\r\n\ud83c\udfc6 Score final\r\n\r\n<\/div>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n\r\n<button\r\nclass=\"restart-button\"\r\nonclick=\"restartGame()\">\r\n\r\n\ud83d\udd04 Recommencer\r\n\r\n<\/button>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n\r\n<script>\r\n\r\n\/* =====================================================\r\n   DONNEES\r\n===================================================== *\/\r\n\r\nconst booksData = [\r\n\r\n\/* ANCIEN TESTAMENT *\/\r\n\r\n[\"1 Chroniques\",\"ancien\",10],\r\n[\"1 Rois\",\"ancien\",6],\r\n[\"1 Samuel\",\"ancien\",7],\r\n[\"2 Chroniques\",\"ancien\",11],\r\n[\"2 Rois\",\"ancien\",8],\r\n[\"2 Samuel\",\"ancien\",8],\r\n[\"Abdias\",\"ancien\",37],\r\n[\"Agg\u00e9e\",\"ancien\",35],\r\n[\"Amos\",\"ancien\",30],\r\n[\"Cantique des cantiques\",\"ancien\",21],\r\n[\"Daniel\",\"ancien\",26],\r\n[\"Deut\u00e9ronome\",\"ancien\",4],\r\n[\"Eccl\u00e9siaste\",\"ancien\",20],\r\n[\"\u00c9sa\u00efe\",\"ancien\",22],\r\n[\"Esdras\",\"ancien\",13],\r\n[\"Esther\",\"ancien\",15],\r\n[\"\u00c9z\u00e9chiel\",\"ancien\",25],\r\n[\"Exode\",\"ancien\",1],\r\n[\"Gen\u00e8se\",\"ancien\",0],\r\n[\"Habacuc\",\"ancien\",32],\r\n[\"J\u00e9r\u00e9mie\",\"ancien\",23],\r\n[\"Job\",\"ancien\",16],\r\n[\"Jo\u00ebl\",\"ancien\",27],\r\n[\"Jonas\",\"ancien\",29],\r\n[\"Josu\u00e9\",\"ancien\",5],\r\n[\"Juges\",\"ancien\",6],\r\n[\"Lamentations\",\"ancien\",24],\r\n[\"L\u00e9vitique\",\"ancien\",2],\r\n[\"Malachie\",\"ancien\",38],\r\n[\"Mich\u00e9e\",\"ancien\",31],\r\n[\"Nahum\",\"ancien\",33],\r\n[\"N\u00e9h\u00e9mie\",\"ancien\",14],\r\n[\"Nombres\",\"ancien\",3],\r\n[\"Os\u00e9e\",\"ancien\",26],\r\n[\"Psaumes\",\"ancien\",17],\r\n[\"Proverbes\",\"ancien\",18],\r\n[\"Ruth\",\"ancien\",7],\r\n[\"Sophonie\",\"ancien\",34],\r\n[\"Zacharie\",\"ancien\",37],\r\n\r\n\/* NOUVEAU TESTAMENT *\/\r\n\r\n[\"1 Corinthiens\",\"nouveau\",6],\r\n[\"1 Jean\",\"nouveau\",22],\r\n[\"1 Pierre\",\"nouveau\",20],\r\n[\"1 Thessaloniciens\",\"nouveau\",12],\r\n[\"1 Timoth\u00e9e\",\"nouveau\",14],\r\n[\"2 Corinthiens\",\"nouveau\",7],\r\n[\"2 Jean\",\"nouveau\",23],\r\n[\"2 Pierre\",\"nouveau\",21],\r\n[\"2 Thessaloniciens\",\"nouveau\",13],\r\n[\"2 Timoth\u00e9e\",\"nouveau\",15],\r\n[\"3 Jean\",\"nouveau\",24],\r\n[\"Actes\",\"nouveau\",4],\r\n[\"Apocalypse\",\"nouveau\",26],\r\n[\"Colossiens\",\"nouveau\",11],\r\n[\"\u00c9ph\u00e9siens\",\"nouveau\",8],\r\n[\"Galates\",\"nouveau\",7],\r\n[\"H\u00e9breux\",\"nouveau\",18],\r\n[\"Jacques\",\"nouveau\",19],\r\n[\"Jude\",\"nouveau\",25],\r\n[\"Luc\",\"nouveau\",2],\r\n[\"Marc\",\"nouveau\",1],\r\n[\"Matthieu\",\"nouveau\",0],\r\n[\"Phil\u00e9mon\",\"nouveau\",17],\r\n[\"Philippiens\",\"nouveau\",9],\r\n[\"Romains\",\"nouveau\",5],\r\n[\"Tite\",\"nouveau\",16]\r\n\r\n];\r\n\r\n\r\n\/* =====================================================\r\n   ELEMENTS\r\n===================================================== *\/\r\n\r\nconst booksArea =\r\ndocument.getElementById(\r\n    \"books\"\r\n);\r\n\r\n\r\nconst booksContainer =\r\ndocument.getElementById(\r\n    \"booksArea\"\r\n);\r\n\r\n\r\nconst testaments =\r\ndocument.getElementById(\r\n    \"testaments\"\r\n);\r\n\r\n\r\nconst ancienZone =\r\ndocument.getElementById(\r\n    \"ancienZone\"\r\n);\r\n\r\n\r\nconst nouveauZone =\r\ndocument.getElementById(\r\n    \"nouveauZone\"\r\n);\r\n\r\n\r\nconst ancienList =\r\ndocument.getElementById(\r\n    \"ancienList\"\r\n);\r\n\r\n\r\nconst nouveauList =\r\ndocument.getElementById(\r\n    \"nouveauList\"\r\n);\r\n\r\n\r\nconst scoreDisplay =\r\ndocument.getElementById(\r\n    \"score\"\r\n);\r\n\r\n\r\nconst placedDisplay =\r\ndocument.getElementById(\r\n    \"placed\"\r\n);\r\n\r\n\r\nconst maxScoreDisplay =\r\ndocument.getElementById(\r\n    \"maxScore\"\r\n);\r\n\r\n\r\nconst maxPlacedDisplay =\r\ndocument.getElementById(\r\n    \"maxPlaced\"\r\n);\r\n\r\n\r\nconst message =\r\ndocument.getElementById(\r\n    \"message\"\r\n);\r\n\r\n\r\nconst end =\r\ndocument.getElementById(\r\n    \"end\"\r\n);\r\n\r\n\r\nconst final =\r\ndocument.getElementById(\r\n    \"final\"\r\n);\r\n\r\n\r\nlet currentMode =\r\n\"all\";\r\n\r\n\r\nlet draggedElement =\r\nnull;\r\n\r\n\r\nlet placeholder =\r\nnull;\r\n\r\n\r\n\/* =====================================================\r\n   INFORMATIONS MODES\r\n===================================================== *\/\r\n\r\nconst modeInfo = {\r\n\r\n    all: 66,\r\n\r\n    ancien: 39,\r\n\r\n    nouveau: 27\r\n\r\n};\r\n\r\n\r\n\/* =====================================================\r\n   CREER LA LISTE DES LIVRES\r\n===================================================== *\/\r\n\r\nfunction createBooks() {\r\n\r\n\r\n    booksArea.innerHTML =\r\n    \"\";\r\n\r\n\r\n    let list =\r\n    booksData.filter(\r\n    book => {\r\n\r\n\r\n        if (\r\n            currentMode ===\r\n            \"all\"\r\n        ) {\r\n\r\n            return true;\r\n\r\n        }\r\n\r\n\r\n        return (\r\n            book[1]\r\n            ===\r\n            currentMode\r\n        );\r\n\r\n    });\r\n\r\n\r\n    \/* TRI ALPHABETIQUE *\/\r\n\r\n    list.sort(\r\n    (\r\n        a,\r\n        b\r\n    ) => {\r\n\r\n\r\n        return a[0].localeCompare(\r\n            b[0],\r\n            \"fr\"\r\n        );\r\n\r\n\r\n    });\r\n\r\n\r\n    list.forEach(\r\n    data => {\r\n\r\n\r\n        const book =\r\n        document.createElement(\r\n            \"div\"\r\n        );\r\n\r\n\r\n        book.className =\r\n        \"book\";\r\n\r\n\r\n        book.textContent =\r\n        data[0];\r\n\r\n\r\n        book.dataset.name =\r\n        data[0];\r\n\r\n\r\n        book.dataset.testament =\r\n        data[1];\r\n\r\n\r\n        book.dataset.position =\r\n        data[2];\r\n\r\n\r\n        booksArea.appendChild(\r\n            book\r\n        );\r\n\r\n\r\n        book.addEventListener(\r\n            \"pointerdown\",\r\n            startDrag\r\n        );\r\n\r\n\r\n    });\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   CONFIGURATION DU MODE\r\n===================================================== *\/\r\n\r\nfunction configureMode() {\r\n\r\n\r\n    if (\r\n        currentMode ===\r\n        \"ancien\"\r\n    ) {\r\n\r\n\r\n        ancienZone.style.display =\r\n        \"block\";\r\n\r\n\r\n        nouveauZone.style.display =\r\n        \"none\";\r\n\r\n\r\n        testaments.classList.add(\r\n            \"single\"\r\n        );\r\n\r\n\r\n    }\r\n\r\n    else if (\r\n        currentMode ===\r\n        \"nouveau\"\r\n    ) {\r\n\r\n\r\n        ancienZone.style.display =\r\n        \"none\";\r\n\r\n\r\n        nouveauZone.style.display =\r\n        \"block\";\r\n\r\n\r\n        testaments.classList.add(\r\n            \"single\"\r\n        );\r\n\r\n\r\n    }\r\n\r\n    else {\r\n\r\n\r\n        ancienZone.style.display =\r\n        \"block\";\r\n\r\n\r\n        nouveauZone.style.display =\r\n        \"block\";\r\n\r\n\r\n        testaments.classList.remove(\r\n            \"single\"\r\n        );\r\n\r\n\r\n    }\r\n\r\n\r\n    const max =\r\n    modeInfo[\r\n        currentMode\r\n    ];\r\n\r\n\r\n    maxScoreDisplay.textContent =\r\n    max;\r\n\r\n\r\n    maxPlacedDisplay.textContent =\r\n    max;\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   CHANGEMENT DE MODE\r\n===================================================== *\/\r\n\r\ndocument\r\n.querySelectorAll(\r\n    \".mode-button\"\r\n)\r\n.forEach(\r\nbutton => {\r\n\r\n\r\n    button.addEventListener(\r\n        \"click\",\r\n        function() {\r\n\r\n\r\n            currentMode =\r\n            this.dataset.mode;\r\n\r\n\r\n            document\r\n            .querySelectorAll(\r\n                \".mode-button\"\r\n            )\r\n            .forEach(\r\n            b => {\r\n\r\n\r\n                b.classList.remove(\r\n                    \"active\"\r\n                );\r\n\r\n\r\n            });\r\n\r\n\r\n            this.classList.add(\r\n                \"active\"\r\n            );\r\n\r\n\r\n            restartGame();\r\n\r\n\r\n        }\r\n    );\r\n\r\n\r\n});\r\n\r\n\r\n\/* =====================================================\r\n   DEBUT DU GLISSEMENT\r\n===================================================== *\/\r\n\r\nfunction startDrag(event) {\r\n\r\n\r\n    event.preventDefault();\r\n\r\n\r\n    draggedElement =\r\n    event.currentTarget;\r\n\r\n\r\n    draggedElement.classList.add(\r\n        \"dragging\"\r\n    );\r\n\r\n\r\n    placeholder =\r\n    document.createElement(\r\n        \"div\"\r\n    );\r\n\r\n\r\n    placeholder.className =\r\n    \"drag-placeholder\";\r\n\r\n\r\n    placeholder.style.height =\r\n    draggedElement.offsetHeight\r\n    +\r\n    \"px\";\r\n\r\n\r\n    draggedElement.parentNode.insertBefore(\r\n        placeholder,\r\n        draggedElement.nextSibling\r\n    );\r\n\r\n\r\n    document.addEventListener(\r\n        \"pointermove\",\r\n        moveDrag,\r\n        {\r\n            passive: false\r\n        }\r\n    );\r\n\r\n\r\n    document.addEventListener(\r\n        \"pointerup\",\r\n        endDrag,\r\n        {\r\n            once: true\r\n        }\r\n    );\r\n\r\n\r\n    message.textContent =\r\n    \"D\u00e9place le livre vers la zone souhait\u00e9e.\";\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   OBTENIR LA LISTE\r\n===================================================== *\/\r\n\r\nfunction getListFromZone(\r\nzone\r\n) {\r\n\r\n\r\n    if (\r\n        zone ===\r\n        ancienZone\r\n    ) {\r\n\r\n        return ancienList;\r\n\r\n    }\r\n\r\n\r\n    if (\r\n        zone ===\r\n        nouveauZone\r\n    ) {\r\n\r\n        return nouveauList;\r\n\r\n    }\r\n\r\n\r\n    return null;\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   DEPLACEMENT PENDANT LE GLISSEMENT\r\n===================================================== *\/\r\n\r\nfunction moveDrag(event) {\r\n\r\n\r\n    if (\r\n        !draggedElement\r\n    ) {\r\n\r\n        return;\r\n\r\n    }\r\n\r\n\r\n    event.preventDefault();\r\n\r\n\r\n    const element =\r\n    document.elementFromPoint(\r\n        event.clientX,\r\n        event.clientY\r\n    );\r\n\r\n\r\n    if (\r\n        !element\r\n    ) {\r\n\r\n        return;\r\n\r\n    }\r\n\r\n\r\n    \/* =================================================\r\n       DEPOT VERS LA LISTE DES LIVRES\r\n    ================================================= *\/\r\n\r\n    if (\r\n        element.closest(\r\n            \"#booksArea\"\r\n        )\r\n    ) {\r\n\r\n\r\n        booksContainer.classList.add(\r\n            \"drop-active\"\r\n        );\r\n\r\n\r\n        ancienZone.classList.remove(\r\n            \"drop-active\"\r\n        );\r\n\r\n\r\n        nouveauZone.classList.remove(\r\n            \"drop-active\"\r\n        );\r\n\r\n\r\n        booksArea.appendChild(\r\n            placeholder\r\n        );\r\n\r\n\r\n        return;\r\n\r\n    }\r\n\r\n\r\n    \/* =================================================\r\n       DEPOT VERS UN TESTAMENT\r\n    ================================================= *\/\r\n\r\n    const zone =\r\n    element.closest(\r\n        \".testament\"\r\n    );\r\n\r\n\r\n    if (\r\n        !zone\r\n    ) {\r\n\r\n        return;\r\n\r\n    }\r\n\r\n\r\n    \/* ================================================\r\n       VERIFIER LE BON TESTAMENT\r\n    ================================================ *\/\r\n\r\n    if (\r\n        draggedElement.dataset.testament\r\n        !==\r\n        zone.dataset.testament\r\n    ) {\r\n\r\n\r\n        return;\r\n\r\n    }\r\n\r\n\r\n    \/* ================================================\r\n       MODE UNIQUE\r\n    ================================================ *\/\r\n\r\n    if (\r\n        currentMode !==\r\n        \"all\"\r\n        &&\r\n        currentMode\r\n        !==\r\n        draggedElement.dataset.testament\r\n    ) {\r\n\r\n\r\n        return;\r\n\r\n    }\r\n\r\n\r\n    booksContainer.classList.remove(\r\n        \"drop-active\"\r\n    );\r\n\r\n\r\n    ancienZone.classList.remove(\r\n        \"drop-active\"\r\n    );\r\n\r\n\r\n    nouveauZone.classList.remove(\r\n        \"drop-active\"\r\n    );\r\n\r\n\r\n    zone.classList.add(\r\n        \"drop-active\"\r\n    );\r\n\r\n\r\n    const list =\r\n    getListFromZone(\r\n        zone\r\n    );\r\n\r\n\r\n    if (\r\n        !list\r\n    ) {\r\n\r\n        return;\r\n\r\n    }\r\n\r\n\r\n    \/* ================================================\r\n       POSITION AVANT\/APRES UN AUTRE LIVRE\r\n    ================================================ *\/\r\n\r\n    const target =\r\n    element.closest(\r\n        \".book-in-zone\"\r\n    );\r\n\r\n\r\n    if (\r\n        target\r\n        &&\r\n        target !==\r\n        draggedElement\r\n        &&\r\n        target !==\r\n        placeholder\r\n        &&\r\n        target.parentElement ===\r\n        list\r\n    ) {\r\n\r\n\r\n        const rect =\r\n        target.getBoundingClientRect();\r\n\r\n\r\n        const middle =\r\n        rect.top\r\n        +\r\n        rect.height \/\r\n        2;\r\n\r\n\r\n        if (\r\n            event.clientY\r\n            <\r\n            middle\r\n        ) {\r\n\r\n\r\n            list.insertBefore(\r\n                placeholder,\r\n                target\r\n            );\r\n\r\n\r\n        }\r\n\r\n        else {\r\n\r\n\r\n            list.insertBefore(\r\n                placeholder,\r\n                target.nextSibling\r\n            );\r\n\r\n\r\n        }\r\n\r\n\r\n    }\r\n\r\n    else {\r\n\r\n\r\n        list.appendChild(\r\n            placeholder\r\n        );\r\n\r\n\r\n    }\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   FIN DU GLISSEMENT\r\n===================================================== *\/\r\n\r\nfunction endDrag() {\r\n\r\n\r\n    document.removeEventListener(\r\n        \"pointermove\",\r\n        moveDrag\r\n    );\r\n\r\n\r\n    booksContainer.classList.remove(\r\n        \"drop-active\"\r\n    );\r\n\r\n\r\n    ancienZone.classList.remove(\r\n        \"drop-active\"\r\n    );\r\n\r\n\r\n    nouveauZone.classList.remove(\r\n        \"drop-active\"\r\n    );\r\n\r\n\r\n    if (\r\n        !draggedElement\r\n    ) {\r\n\r\n        return;\r\n\r\n    }\r\n\r\n\r\n    if (\r\n        placeholder\r\n        &&\r\n        placeholder.parentNode\r\n    ) {\r\n\r\n\r\n        placeholder.parentNode.insertBefore(\r\n            draggedElement,\r\n            placeholder\r\n        );\r\n\r\n\r\n        placeholder.remove();\r\n\r\n\r\n    }\r\n\r\n\r\n    \/* =================================================\r\n       LIVRE DANS LA LISTE\r\n    ================================================= *\/\r\n\r\n    if (\r\n        draggedElement.parentElement\r\n        ===\r\n        booksArea\r\n    ) {\r\n\r\n\r\n        draggedElement.className =\r\n        \"book\";\r\n\r\n\r\n    }\r\n\r\n\r\n    \/* =================================================\r\n       LIVRE DANS UN TESTAMENT\r\n    ================================================= *\/\r\n\r\n    else {\r\n\r\n\r\n        draggedElement.className =\r\n        \"book-in-zone\";\r\n\r\n\r\n    }\r\n\r\n\r\n    draggedElement =\r\n    null;\r\n\r\n\r\n    placeholder =\r\n    null;\r\n\r\n\r\n    updateGame();\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   CALCUL SCORE\r\n===================================================== *\/\r\n\r\nfunction updateGame() {\r\n\r\n\r\n    let score =\r\n    0;\r\n\r\n\r\n    let placed =\r\n    0;\r\n\r\n\r\n    \/* ANCIEN *\/\r\n\r\n    if (\r\n        currentMode ===\r\n        \"all\"\r\n        ||\r\n        currentMode ===\r\n        \"ancien\"\r\n    ) {\r\n\r\n\r\n        const books =\r\n        ancienList.querySelectorAll(\r\n            \".book-in-zone\"\r\n        );\r\n\r\n\r\n        books.forEach(\r\n        (\r\n            book,\r\n            index\r\n        ) => {\r\n\r\n\r\n            placed++;\r\n\r\n\r\n            if (\r\n                Number(\r\n                    book.dataset.position\r\n                )\r\n                ===\r\n                index\r\n            ) {\r\n\r\n\r\n                score++;\r\n\r\n\r\n                book.classList.add(\r\n                    \"correct\"\r\n                );\r\n\r\n\r\n            }\r\n\r\n            else {\r\n\r\n\r\n                book.classList.remove(\r\n                    \"correct\"\r\n                );\r\n\r\n\r\n            }\r\n\r\n\r\n        });\r\n\r\n\r\n    }\r\n\r\n\r\n    \/* NOUVEAU *\/\r\n\r\n    if (\r\n        currentMode ===\r\n        \"all\"\r\n        ||\r\n        currentMode ===\r\n        \"nouveau\"\r\n    ) {\r\n\r\n\r\n        const books =\r\n        nouveauList.querySelectorAll(\r\n            \".book-in-zone\"\r\n        );\r\n\r\n\r\n        books.forEach(\r\n        (\r\n            book,\r\n            index\r\n        ) => {\r\n\r\n\r\n            placed++;\r\n\r\n\r\n            if (\r\n                Number(\r\n                    book.dataset.position\r\n                )\r\n                ===\r\n                index\r\n            ) {\r\n\r\n\r\n                score++;\r\n\r\n\r\n                book.classList.add(\r\n                    \"correct\"\r\n                );\r\n\r\n\r\n            }\r\n\r\n            else {\r\n\r\n\r\n                book.classList.remove(\r\n                    \"correct\"\r\n                );\r\n\r\n\r\n            }\r\n\r\n\r\n        });\r\n\r\n\r\n    }\r\n\r\n\r\n    scoreDisplay.textContent =\r\n    score;\r\n\r\n\r\n    placedDisplay.textContent =\r\n    placed;\r\n\r\n\r\n    \/* FIN *\/\r\n\r\n    if (\r\n        score\r\n        ===\r\n        modeInfo[\r\n            currentMode\r\n        ]\r\n    ) {\r\n\r\n\r\n        finishGame();\r\n\r\n\r\n    }\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   FIN DU JEU\r\n===================================================== *\/\r\n\r\nfunction finishGame() {\r\n\r\n\r\n    const max =\r\n    modeInfo[\r\n        currentMode\r\n    ];\r\n\r\n\r\n    message.textContent =\r\n    \"\ud83c\udf89 F\u00e9licitations ! Tous les livres sont dans le bon ordre !\";\r\n\r\n\r\n    message.className =\r\n    \"good\";\r\n\r\n\r\n    end.style.display =\r\n    \"block\";\r\n\r\n\r\n    final.textContent =\r\n\r\n    \"\ud83c\udfc6 Score final : \"\r\n    +\r\n    max\r\n    +\r\n    \" \/ \"\r\n    +\r\n    max;\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   RECOMMENCER\r\n===================================================== *\/\r\n\r\nfunction restartGame() {\r\n\r\n\r\n    ancienList.innerHTML =\r\n    \"\";\r\n\r\n\r\n    nouveauList.innerHTML =\r\n    \"\";\r\n\r\n\r\n    scoreDisplay.textContent =\r\n    \"0\";\r\n\r\n\r\n    placedDisplay.textContent =\r\n    \"0\";\r\n\r\n\r\n    end.style.display =\r\n    \"none\";\r\n\r\n\r\n    message.className =\r\n    \"\";\r\n\r\n\r\n    message.textContent =\r\n    \"Commence par d\u00e9placer un livre.\";\r\n\r\n\r\n    createBooks();\r\n\r\n\r\n    configureMode();\r\n\r\n\r\n}\r\n\r\n\r\n\/* =====================================================\r\n   LANCEMENT\r\n===================================================== *\/\r\n\r\nrestartGame();\r\n\r\n<\/script>\r\n\r\n<\/body>\r\n\r\n<\/html>\r\n```\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-8a33623 e-flex e-con-boxed elementor-repeater-item-default_padding elementor-repeater-item-none elementor-repeater-item-none_hover wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-column-slider-no wpr-equal-height-no e-con e-parent\" data-id=\"8a33623\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;ang_container_spacing_size&quot;:&quot;default_padding&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3842fad elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-html\" data-id=\"3842fad\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t```html\r\n<!DOCTYPE html>\r\n<html lang=\"fr\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n\r\n<title>La Bible en BD \u2014 \u00c9vangile selon Matthieu<\/title>\r\n\r\n<style>\r\n\r\n* {\r\n    box-sizing: border-box;\r\n}\r\n\r\nbody {\r\n    margin: 0;\r\n    font-family: Arial, Helvetica, sans-serif;\r\n    background: #f3f1ed;\r\n    color: #222;\r\n}\r\n\r\n\/* EN-T\u00caTE *\/\r\n\r\nheader {\r\n    background: #2c211b;\r\n    color: white;\r\n    padding: 30px 20px;\r\n    text-align: center;\r\n}\r\n\r\nheader h1 {\r\n    margin: 0;\r\n    font-size: 2.3em;\r\n}\r\n\r\nheader p {\r\n    margin-top: 10px;\r\n    font-size: 1.1em;\r\n}\r\n\r\n\/* NAVIGATION *\/\r\n\r\nnav {\r\n    background: #5b4030;\r\n    padding: 12px;\r\n    text-align: center;\r\n}\r\n\r\nnav a {\r\n    color: white;\r\n    text-decoration: none;\r\n    margin: 0 12px;\r\n    font-weight: bold;\r\n}\r\n\r\nnav a:hover {\r\n    text-decoration: underline;\r\n}\r\n\r\n\/* CONTENU *\/\r\n\r\n.container {\r\n    max-width: 1200px;\r\n    margin: auto;\r\n    padding: 25px;\r\n}\r\n\r\n\/* INTRODUCTION *\/\r\n\r\n.introduction {\r\n    background: white;\r\n    padding: 25px;\r\n    border-radius: 12px;\r\n    margin-bottom: 25px;\r\n    box-shadow: 0 3px 10px rgba(0,0,0,0.1);\r\n}\r\n\r\n.introduction h2 {\r\n    color: #5b4030;\r\n}\r\n\r\n\/* RECHERCHE *\/\r\n\r\n.search-box {\r\n    text-align: center;\r\n    margin-bottom: 25px;\r\n}\r\n\r\n.search-box input {\r\n    width: 80%;\r\n    max-width: 600px;\r\n    padding: 14px;\r\n    border: 1px solid #ccc;\r\n    border-radius: 8px;\r\n    font-size: 16px;\r\n}\r\n\r\n\/* LISTE DES \u00c9PISODES *\/\r\n\r\n.episodes {\r\n    display: grid;\r\n    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\r\n    gap: 15px;\r\n    margin-bottom: 30px;\r\n}\r\n\r\n.episode-button {\r\n    background: white;\r\n    border: none;\r\n    padding: 18px;\r\n    border-radius: 10px;\r\n    cursor: pointer;\r\n    box-shadow: 0 3px 8px rgba(0,0,0,0.1);\r\n    text-align: left;\r\n}\r\n\r\n.episode-button:hover {\r\n    background: #eee7df;\r\n}\r\n\r\n.episode-button strong {\r\n    display: block;\r\n    color: #5b4030;\r\n    margin-bottom: 6px;\r\n}\r\n\r\n\/* BD *\/\r\n\r\n.comic {\r\n    background: white;\r\n    padding: 25px;\r\n    border-radius: 12px;\r\n    box-shadow: 0 3px 12px rgba(0,0,0,0.1);\r\n}\r\n\r\n.comic h2 {\r\n    text-align: center;\r\n    color: #5b4030;\r\n}\r\n\r\n.reference {\r\n    text-align: center;\r\n    font-style: italic;\r\n    color: #666;\r\n    margin-bottom: 25px;\r\n}\r\n\r\n\/* CASES *\/\r\n\r\n.comic-grid {\r\n    display: grid;\r\n    grid-template-columns: repeat(2, 1fr);\r\n    gap: 20px;\r\n}\r\n\r\n.panel {\r\n    border: 4px solid #222;\r\n    border-radius: 8px;\r\n    overflow: hidden;\r\n    background: #fafafa;\r\n}\r\n\r\n.panel-image {\r\n    height: 280px;\r\n    background: #ddd;\r\n    display: flex;\r\n    align-items: center;\r\n    justify-content: center;\r\n    color: #666;\r\n    text-align: center;\r\n    padding: 20px;\r\n}\r\n\r\n.panel-text {\r\n    padding: 18px;\r\n    background: white;\r\n}\r\n\r\n.narration {\r\n    font-style: italic;\r\n    color: #555;\r\n    margin-bottom: 12px;\r\n}\r\n\r\n.dialogue {\r\n    font-weight: bold;\r\n    color: #222;\r\n}\r\n\r\n\/* BOUTONS *\/\r\n\r\n.controls {\r\n    display: flex;\r\n    justify-content: space-between;\r\n    margin-top: 25px;\r\n}\r\n\r\n.controls button {\r\n    padding: 12px 22px;\r\n    background: #5b4030;\r\n    color: white;\r\n    border: none;\r\n    border-radius: 7px;\r\n    cursor: pointer;\r\n}\r\n\r\n.controls button:hover {\r\n    background: #3f2d22;\r\n}\r\n\r\n\/* PIED DE PAGE *\/\r\n\r\nfooter {\r\n    margin-top: 40px;\r\n    background: #2c211b;\r\n    color: white;\r\n    text-align: center;\r\n    padding: 25px;\r\n}\r\n\r\n\/* MOBILE *\/\r\n\r\n@media (max-width: 700px) {\r\n\r\n    .comic-grid {\r\n        grid-template-columns: 1fr;\r\n    }\r\n\r\n    header h1 {\r\n        font-size: 1.7em;\r\n    }\r\n\r\n    .search-box input {\r\n        width: 100%;\r\n    }\r\n\r\n}\r\n\r\n<\/style>\r\n\r\n<\/head>\r\n\r\n\r\n<body>\r\n\r\n\r\n<header>\r\n\r\n<h1>\ud83d\udcd6 La Bible en BD<\/h1>\r\n\r\n<p>L'\u00c9vangile selon Matthieu<\/p>\r\n\r\n<\/header>\r\n\r\n\r\n<nav>\r\n\r\n<a href=\"#accueil\">Accueil<\/a>\r\n\r\n<a href=\"#episodes\">\u00c9pisodes<\/a>\r\n\r\n<a href=\"#bd\">Lire la BD<\/a>\r\n\r\n<\/nav>\r\n\r\n\r\n<div class=\"container\">\r\n\r\n\r\n<section class=\"introduction\" id=\"accueil\">\r\n\r\n<h2>\u271d\ufe0f L'\u00c9vangile selon Matthieu<\/h2>\r\n\r\n<p>\r\n\r\nBienvenue dans cette adaptation en bande dessin\u00e9e\r\nde l'\u00c9vangile selon Matthieu.\r\n\r\n<\/p>\r\n\r\n<p>\r\n\r\nCette s\u00e9rie pr\u00e9sente les principaux \u00e9v\u00e9nements racont\u00e9s\r\ndans le livre de Matthieu, depuis la g\u00e9n\u00e9alogie et la\r\nnaissance de J\u00e9sus jusqu'\u00e0 sa r\u00e9surrection et \u00e0 la\r\nGrande Mission donn\u00e9e aux disciples.\r\n\r\n<\/p>\r\n\r\n<p>\r\n\r\nChaque \u00e9pisode indique les r\u00e9f\u00e9rences bibliques\r\ncorrespondantes afin de permettre au lecteur de\r\nretrouver le passage dans le texte biblique.\r\n\r\n<\/p>\r\n\r\n<\/section>\r\n\r\n\r\n<div class=\"search-box\">\r\n\r\n<input\r\ntype=\"text\"\r\nid=\"search\"\r\nplaceholder=\"\ud83d\udd0e Rechercher un \u00e9pisode...\"\r\nonkeyup=\"searchEpisodes()\"\r\n>\r\n\r\n<\/div>\r\n\r\n\r\n<section id=\"episodes\">\r\n\r\n<h2>\ud83d\udcda Les \u00e9pisodes<\/h2>\r\n\r\n<div class=\"episodes\" id=\"episodeList\">\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(0)\">\r\n\r\n<strong>\u00c9pisode 1<\/strong>\r\n\r\nLa g\u00e9n\u00e9alogie et la naissance de J\u00e9sus\r\n\r\n<small>Matthieu 1<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(1)\">\r\n\r\n<strong>\u00c9pisode 2<\/strong>\r\n\r\nLes mages et la fuite en \u00c9gypte\r\n\r\n<small>Matthieu 2<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(2)\">\r\n\r\n<strong>\u00c9pisode 3<\/strong>\r\n\r\nJean-Baptiste et le bapt\u00eame de J\u00e9sus\r\n\r\n<small>Matthieu 3<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(3)\">\r\n\r\n<strong>\u00c9pisode 4<\/strong>\r\n\r\nLa tentation de J\u00e9sus\r\n\r\n<small>Matthieu 4<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(4)\">\r\n\r\n<strong>\u00c9pisode 5<\/strong>\r\n\r\nL'appel des premiers disciples\r\n\r\n<small>Matthieu 4<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(5)\">\r\n\r\n<strong>\u00c9pisode 6<\/strong>\r\n\r\nLe Sermon sur la montagne\r\n\r\n<small>Matthieu 5\u20137<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(6)\">\r\n\r\n<strong>\u00c9pisode 7<\/strong>\r\n\r\nLes miracles de J\u00e9sus\r\n\r\n<small>Matthieu 8\u20139<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(7)\">\r\n\r\n<strong>\u00c9pisode 8<\/strong>\r\n\r\nL'envoi des douze disciples\r\n\r\n<small>Matthieu 10<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(8)\">\r\n\r\n<strong>\u00c9pisode 9<\/strong>\r\n\r\nLes paraboles du Royaume\r\n\r\n<small>Matthieu 13<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(9)\">\r\n\r\n<strong>\u00c9pisode 10<\/strong>\r\n\r\nLa confession de Pierre\r\n\r\n<small>Matthieu 16<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(10)\">\r\n\r\n<strong>\u00c9pisode 11<\/strong>\r\n\r\nLa Transfiguration\r\n\r\n<small>Matthieu 17<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(11)\">\r\n\r\n<strong>\u00c9pisode 12<\/strong>\r\n\r\nL'entr\u00e9e \u00e0 J\u00e9rusalem\r\n\r\n<small>Matthieu 21<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(12)\">\r\n\r\n<strong>\u00c9pisode 13<\/strong>\r\n\r\nLa derni\u00e8re C\u00e8ne\r\n\r\n<small>Matthieu 26<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(13)\">\r\n\r\n<strong>\u00c9pisode 14<\/strong>\r\n\r\nGeths\u00e9mani et l'arrestation\r\n\r\n<small>Matthieu 26<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(14)\">\r\n\r\n<strong>\u00c9pisode 15<\/strong>\r\n\r\nLa crucifixion\r\n\r\n<small>Matthieu 27<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(15)\">\r\n\r\n<strong>\u00c9pisode 16<\/strong>\r\n\r\nLa r\u00e9surrection\r\n\r\n<small>Matthieu 28<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<button class=\"episode-button\"\r\nonclick=\"loadEpisode(16)\">\r\n\r\n<strong>\u00c9pisode 17<\/strong>\r\n\r\nLa Grande Mission\r\n\r\n<small>Matthieu 28<\/small>\r\n\r\n<\/button>\r\n\r\n\r\n<\/div>\r\n\r\n<\/section>\r\n\r\n\r\n<section class=\"comic\" id=\"bd\">\r\n\r\n<h2 id=\"episodeTitle\">\r\n\u00c9pisode 1 \u2014 La naissance de J\u00e9sus\r\n<\/h2>\r\n\r\n<div class=\"reference\" id=\"episodeReference\">\r\n\r\nMatthieu 1:1\u201325\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"comic-grid\" id=\"comicGrid\">\r\n\r\n\r\n<div class=\"panel\">\r\n\r\n<div class=\"panel-image\">\r\n\r\n\ud83d\uddbc\ufe0f Illustration de la g\u00e9n\u00e9alogie de J\u00e9sus\r\n\r\n<\/div>\r\n\r\n<div class=\"panel-text\">\r\n\r\n<div class=\"narration\">\r\n\r\nVoici la g\u00e9n\u00e9alogie de J\u00e9sus-Christ,\r\nfils de David, fils d'Abraham.\r\n\r\n<\/div>\r\n\r\n<div class=\"dialogue\">\r\n\r\nUne histoire de g\u00e9n\u00e9rations conduit\r\njusqu'\u00e0 la naissance de J\u00e9sus.\r\n\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"panel\">\r\n\r\n<div class=\"panel-image\">\r\n\r\n\ud83d\uddbc\ufe0f Illustration de Joseph et de l'ange\r\n\r\n<\/div>\r\n\r\n<div class=\"panel-text\">\r\n\r\n<div class=\"narration\">\r\n\r\nJoseph apprend que Marie attend un enfant\r\npar l'action de l'Esprit Saint.\r\n\r\n<\/div>\r\n\r\n<div class=\"dialogue\">\r\n\r\n\u00ab Joseph, fils de David, ne crains pas\r\nde prendre avec toi Marie, ta femme. \u00bb\r\n\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"panel\">\r\n\r\n<div class=\"panel-image\">\r\n\r\n\ud83d\uddbc\ufe0f Illustration de la naissance de J\u00e9sus\r\n\r\n<\/div>\r\n\r\n<div class=\"panel-text\">\r\n\r\n<div class=\"narration\">\r\n\r\nMarie donne naissance \u00e0 son fils premier-n\u00e9.\r\n\r\n<\/div>\r\n\r\n<div class=\"dialogue\">\r\n\r\n\u00ab Elle enfantera un fils,\r\net tu lui donneras le nom de J\u00e9sus. \u00bb\r\n\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"panel\">\r\n\r\n<div class=\"panel-image\">\r\n\r\n\ud83d\uddbc\ufe0f Illustration de J\u00e9sus enfant\r\n\r\n<\/div>\r\n\r\n<div class=\"panel-text\">\r\n\r\n<div class=\"narration\">\r\n\r\nL'enfant re\u00e7oit le nom annonc\u00e9 par l'ange.\r\n\r\n<\/div>\r\n\r\n<div class=\"dialogue\">\r\n\r\n\u00ab Il sauvera son peuple de ses p\u00e9ch\u00e9s. \u00bb\r\n\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"controls\">\r\n\r\n<button onclick=\"previousEpisode()\">\r\n\r\n\u2b05\ufe0f \u00c9pisode pr\u00e9c\u00e9dent\r\n\r\n<\/button>\r\n\r\n\r\n<button onclick=\"nextEpisode()\">\r\n\r\n\u00c9pisode suivant \u27a1\ufe0f\r\n\r\n<\/button>\r\n\r\n<\/div>\r\n\r\n\r\n<\/section>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n<footer>\r\n\r\n<p>\r\n\r\n\ud83d\udcd6 La Bible en BD \u2014 \u00c9vangile selon Matthieu\r\n\r\n<\/p>\r\n\r\n<p>\r\n\r\nProjet d'adaptation p\u00e9dagogique et illustr\u00e9e.\r\n\r\n<\/p>\r\n\r\n<\/footer>\r\n\r\n\r\n<script>\r\n\r\n\r\nconst episodes = [\r\n\r\n{\r\n\r\ntitle: \"\u00c9pisode 1 \u2014 La g\u00e9n\u00e9alogie et la naissance de J\u00e9sus\",\r\n\r\nreference: \"Matthieu 1:1\u201325\",\r\n\r\npanels: [\r\n\r\n[\"\ud83d\uddbc\ufe0f G\u00e9n\u00e9alogie de J\u00e9sus\",\r\n\"Voici la g\u00e9n\u00e9alogie de J\u00e9sus-Christ, fils de David, fils d'Abraham.\"],\r\n\r\n[\"\ud83d\uddbc\ufe0f Joseph et l'ange\",\r\n\"Joseph re\u00e7oit en songe l'annonce concernant l'enfant \u00e0 venir.\"],\r\n\r\n[\"\ud83d\uddbc\ufe0f La naissance de J\u00e9sus\",\r\n\"Marie donne naissance \u00e0 son fils premier-n\u00e9.\"],\r\n\r\n[\"\ud83d\uddbc\ufe0f Le nom de J\u00e9sus\",\r\n\"Tu lui donneras le nom de J\u00e9sus, car il sauvera son peuple de ses p\u00e9ch\u00e9s.\"]\r\n]\r\n\r\n},\r\n\r\n{\r\n\r\ntitle: \"\u00c9pisode 2 \u2014 Les mages et la fuite en \u00c9gypte\",\r\n\r\nreference: \"Matthieu 2:1\u201323\",\r\n\r\npanels: [\r\n\r\n[\"\ud83d\uddbc\ufe0f Les mages\",\r\n\"Des mages venus d'Orient arrivent \u00e0 J\u00e9rusalem.\"],\r\n\r\n[\"\ud83d\uddbc\ufe0f H\u00e9rode\",\r\n\"Le roi H\u00e9rode cherche \u00e0 savoir o\u00f9 se trouve l'enfant.\"],\r\n\r\n[\"\ud83d\uddbc\ufe0f L'adoration\",\r\n\"Les mages trouvent l'enfant et lui rendent hommage.\"],\r\n\r\n[\"\ud83d\uddbc\ufe0f La fuite en \u00c9gypte\",\r\n\"Joseph re\u00e7oit en songe l'ordre de partir avec l'enfant et sa m\u00e8re.\"]\r\n]\r\n\r\n},\r\n\r\n{\r\n\r\ntitle: \"\u00c9pisode 3 \u2014 Jean-Baptiste et le bapt\u00eame de J\u00e9sus\",\r\n\r\nreference: \"Matthieu 3:1\u201317\",\r\n\r\npanels: [\r\n\r\n[\"\ud83d\uddbc\ufe0f Jean-Baptiste\",\r\n\"Jean-Baptiste proclame : Repentez-vous, car le royaume des cieux est proche.\"],\r\n\r\n[\"\ud83d\uddbc\ufe0f Le bapt\u00eame\",\r\n\"J\u00e9sus vient aupr\u00e8s de Jean pour \u00eatre baptis\u00e9.\"],\r\n\r\n[\"\ud83d\uddbc\ufe0f Le Jourdain\",\r\n\"J\u00e9sus sort de l'eau apr\u00e8s son bapt\u00eame.\"],\r\n\r\n[\"\ud83d\uddbc\ufe0f La voix du ciel\",\r\n\"Une voix venant des cieux d\u00e9clare que J\u00e9sus est le Fils bien-aim\u00e9.\"]\r\n]\r\n\r\n},\r\n\r\n{\r\n\r\ntitle: \"\u00c9pisode 4 \u2014 La tentation de J\u00e9sus\",\r\n\r\nreference: \"Matthieu 4:1\u201311\",\r\n\r\npanels: [\r\n\r\n[\"\ud83d\uddbc\ufe0f Le d\u00e9sert\",\r\n\"J\u00e9sus est conduit dans le d\u00e9sert.\"],\r\n\r\n[\"\ud83d\uddbc\ufe0f La premi\u00e8re tentation\",\r\n\"J\u00e9sus r\u00e9pond \u00e0 la tentation en s'appuyant sur l'\u00c9criture.\"],\r\n\r\n[\"\ud83d\uddbc\ufe0f La deuxi\u00e8me tentation\",\r\n\"J\u00e9sus refuse de mettre Dieu \u00e0 l'\u00e9preuve.\"],\r\n\r\n[\"\ud83d\uddbc\ufe0f La victoire\",\r\n\"Apr\u00e8s les tentations, des anges viennent aupr\u00e8s de J\u00e9sus.\"]\r\n]\r\n\r\n}\r\n\r\n];\r\n\r\n\r\nlet currentEpisode = 0;\r\n\r\n\r\nfunction loadEpisode(index) {\r\n\r\nif (index < 0) {\r\n\r\nindex = episodes.length - 1;\r\n\r\n}\r\n\r\nif (index >= episodes.length) {\r\n\r\nindex = 0;\r\n\r\n}\r\n\r\ncurrentEpisode = index;\r\n\r\nconst episode = episodes[index];\r\n\r\ndocument.getElementById(\"episodeTitle\")\r\n.innerText = episode.title;\r\n\r\ndocument.getElementById(\"episodeReference\")\r\n.innerText = episode.reference;\r\n\r\nconst grid =\r\ndocument.getElementById(\"comicGrid\");\r\n\r\ngrid.innerHTML = \"\";\r\n\r\nepisode.panels.forEach(panel => {\r\n\r\nconst div =\r\ndocument.createElement(\"div\");\r\n\r\ndiv.className = \"panel\";\r\n\r\ndiv.innerHTML = `\r\n\r\n<div class=\"panel-image\">\r\n\r\n${panel[0]}\r\n\r\n<\/div>\r\n\r\n<div class=\"panel-text\">\r\n\r\n<div class=\"narration\">\r\n\r\n${panel[1]}\r\n\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n`;\r\n\r\ngrid.appendChild(div);\r\n\r\n});\r\n\r\nwindow.location.hash = \"bd\";\r\n\r\n}\r\n\r\n\r\nfunction nextEpisode() {\r\n\r\nloadEpisode(currentEpisode + 1);\r\n\r\n}\r\n\r\n\r\nfunction previousEpisode() {\r\n\r\nloadEpisode(currentEpisode - 1);\r\n\r\n}\r\n\r\n\r\nfunction searchEpisodes() {\r\n\r\nconst search =\r\ndocument.getElementById(\"search\")\r\n.value\r\n.toLowerCase();\r\n\r\nconst buttons =\r\ndocument.querySelectorAll(\r\n\".episode-button\"\r\n);\r\n\r\nbuttons.forEach(button => {\r\n\r\nconst text =\r\nbutton.innerText.toLowerCase();\r\n\r\nif (text.includes(search)) {\r\n\r\nbutton.style.display = \"\";\r\n\r\n} else {\r\n\r\nbutton.style.display = \"none\";\r\n\r\n}\r\n\r\n});\r\n\r\n}\r\n\r\n\r\n<\/script>\r\n\r\n\r\n<\/body>\r\n\r\n<\/html>\r\n```\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-fcf4aef e-flex e-con-boxed elementor-repeater-item-default_padding elementor-repeater-item-none elementor-repeater-item-none_hover wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-column-slider-no wpr-equal-height-no e-con e-parent\" data-id=\"fcf4aef\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;ang_container_spacing_size&quot;:&quot;default_padding&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-c336ef7 elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-html\" data-id=\"c336ef7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"fr\">\r\n\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n\r\n<title>Catalogue Films - Wikidata<\/title>\r\n\r\n<style>\r\n\r\n*{\r\n    box-sizing:border-box;\r\n}\r\n\r\nbody{\r\n    margin:0;\r\n    font-family:Arial,Helvetica,sans-serif;\r\n    background:#0b0b0d;\r\n    color:#fff;\r\n}\r\n\r\n.app{\r\n    max-width:1400px;\r\n    margin:auto;\r\n    padding:25px;\r\n}\r\n\r\nheader{\r\n    text-align:center;\r\n    margin-bottom:25px;\r\n}\r\n\r\nheader h1{\r\n    margin:0 0 10px;\r\n}\r\n\r\nheader p{\r\n    opacity:.7;\r\n}\r\n\r\n.search-box{\r\n    background:#1d1d1d;\r\n    border-radius:14px;\r\n    padding:20px;\r\n    margin-bottom:20px;\r\n}\r\n\r\n.search-grid{\r\n    display:grid;\r\n    grid-template-columns:\r\n        2fr .6fr .6fr .8fr 1fr 1fr 1fr auto;\r\n    gap:10px;\r\n}\r\n\r\ninput,\r\nselect{\r\n    width:100%;\r\n    padding:12px;\r\n    border-radius:8px;\r\n    border:1px solid #444;\r\n    background:#111;\r\n    color:#fff;\r\n}\r\n\r\nbutton{\r\n    padding:12px 18px;\r\n    border:0;\r\n    border-radius:8px;\r\n    background:#f0c400;\r\n    color:#111;\r\n    font-weight:bold;\r\n    cursor:pointer;\r\n}\r\n\r\nbutton:hover{\r\n    opacity:.85;\r\n}\r\n\r\nbutton:disabled{\r\n    opacity:.4;\r\n    cursor:not-allowed;\r\n}\r\n\r\n.options{\r\n    display:grid;\r\n    grid-template-columns:\r\n        1.4fr 1fr 1fr auto auto;\r\n    gap:10px;\r\n    margin-top:15px;\r\n    align-items:stretch;\r\n}\r\n\r\n.toggle-filter{\r\n    display:flex;\r\n    align-items:center;\r\n    gap:10px;\r\n    padding:12px;\r\n    border-radius:8px;\r\n    border:1px solid #444;\r\n    background:#111;\r\n    cursor:pointer;\r\n    user-select:none;\r\n}\r\n\r\n.toggle-filter input{\r\n    width:18px;\r\n    height:18px;\r\n    accent-color:#f0c400;\r\n    cursor:pointer;\r\n}\r\n\r\n.toggle-filter span{\r\n    font-size:14px;\r\n}\r\n\r\n.page-options{\r\n    display:grid;\r\n    grid-template-columns:\r\n        1fr 1fr auto auto;\r\n    gap:10px;\r\n    margin-top:15px;\r\n}\r\n\r\n.status{\r\n    margin:20px 0;\r\n    text-align:center;\r\n    min-height:25px;\r\n}\r\n\r\n.progress{\r\n    width:100%;\r\n    height:8px;\r\n    background:#333;\r\n    border-radius:10px;\r\n    overflow:hidden;\r\n    margin-top:15px;\r\n}\r\n\r\n.progress-bar{\r\n    width:0%;\r\n    height:100%;\r\n    background:#f0c400;\r\n    transition:width .2s;\r\n}\r\n\r\n\/* =========================================================\r\n   GRILLE DE RESULTATS - STYLE \"SITE DE CINEMA\"\r\n========================================================= *\/\r\n\r\n.results{\r\n    display:grid;\r\n    grid-template-columns:\r\n        repeat(\r\n            auto-fill,\r\n            minmax(220px,1fr)\r\n        );\r\n    gap:24px;\r\n}\r\n\r\n.card{\r\n    position:relative;\r\n    background:#1a1a1d;\r\n    border-radius:14px;\r\n    overflow:hidden;\r\n    box-shadow:0 4px 14px rgba(0,0,0,.4);\r\n    transition:transform .25s ease, box-shadow .25s ease;\r\n    display:flex;\r\n    flex-direction:column;\r\n}\r\n\r\n.card:hover{\r\n    transform:translateY(-6px);\r\n    box-shadow:0 14px 30px rgba(0,0,0,.6);\r\n}\r\n\r\n.poster-wrap{\r\n    position:relative;\r\n    width:100%;\r\n    aspect-ratio:2\/3;\r\n    background:#222;\r\n    overflow:hidden;\r\n}\r\n\r\n.poster{\r\n    width:100%;\r\n    height:100%;\r\n    object-fit:cover;\r\n    display:block;\r\n    transition:transform .35s ease;\r\n}\r\n\r\n.card:hover .poster{\r\n    transform:scale(1.06);\r\n}\r\n\r\n.poster-placeholder{\r\n    width:100%;\r\n    height:100%;\r\n    display:flex;\r\n    align-items:center;\r\n    justify-content:center;\r\n    font-size:46px;\r\n    background:\r\n        linear-gradient(\r\n            145deg,\r\n            #2a2a30,\r\n            #17171a\r\n        );\r\n    color:rgba(255,255,255,.25);\r\n}\r\n\r\n.year-badge{\r\n    position:absolute;\r\n    top:10px;\r\n    left:10px;\r\n    background:rgba(0,0,0,.65);\r\n    backdrop-filter:blur(3px);\r\n    padding:4px 10px;\r\n    border-radius:20px;\r\n    font-size:12px;\r\n    font-weight:bold;\r\n    letter-spacing:.3px;\r\n}\r\n\r\n.religious-badge{\r\n    position:absolute;\r\n    top:10px;\r\n    right:10px;\r\n    background:rgba(240,196,0,.9);\r\n    color:#111;\r\n    padding:4px 10px;\r\n    border-radius:20px;\r\n    font-size:11px;\r\n    font-weight:bold;\r\n}\r\n\r\n.poster-overlay{\r\n    position:absolute;\r\n    inset:0;\r\n    background:\r\n        linear-gradient(\r\n            to top,\r\n            rgba(0,0,0,.92) 0%,\r\n            rgba(0,0,0,.15) 55%,\r\n            rgba(0,0,0,0) 100%\r\n        );\r\n    opacity:0;\r\n    transition:opacity .25s ease;\r\n    display:flex;\r\n    align-items:flex-end;\r\n    padding:14px;\r\n}\r\n\r\n.card:hover .poster-overlay{\r\n    opacity:1;\r\n}\r\n\r\n.overlay-btn{\r\n    display:inline-block;\r\n    width:100%;\r\n    text-align:center;\r\n    padding:10px;\r\n    background:#f0c400;\r\n    color:#111;\r\n    font-weight:bold;\r\n    text-decoration:none;\r\n    border-radius:8px;\r\n    font-size:13px;\r\n}\r\n\r\n.card-content{\r\n    padding:14px 16px 16px;\r\n    flex:1;\r\n    display:flex;\r\n    flex-direction:column;\r\n    gap:6px;\r\n}\r\n\r\n.card h3{\r\n    margin:0;\r\n    font-size:15px;\r\n    line-height:1.3;\r\n    display:-webkit-box;\r\n    -webkit-line-clamp:2;\r\n    -webkit-box-orient:vertical;\r\n    overflow:hidden;\r\n}\r\n\r\n.meta-line{\r\n    font-size:12.5px;\r\n    color:rgba(255,255,255,.65);\r\n    line-height:1.5;\r\n    display:-webkit-box;\r\n    -webkit-line-clamp:2;\r\n    -webkit-box-orient:vertical;\r\n    overflow:hidden;\r\n}\r\n\r\n.meta-line b{\r\n    color:rgba(255,255,255,.9);\r\n}\r\n\r\n.card-links{\r\n    margin-top:auto;\r\n    display:flex;\r\n    gap:8px;\r\n    padding-top:8px;\r\n}\r\n\r\n.link-primary,\r\n.link-secondary{\r\n    text-decoration:none;\r\n    text-align:center;\r\n    border-radius:7px;\r\n    font-size:12.5px;\r\n    font-weight:bold;\r\n    padding:9px 6px;\r\n}\r\n\r\n.link-primary{\r\n    flex:2;\r\n    background:#f0c400;\r\n    color:#111;\r\n}\r\n\r\n.link-secondary{\r\n    flex:1;\r\n    background:#2c2c30;\r\n    color:#fff;\r\n}\r\n\r\n.link-primary:hover,\r\n.link-secondary:hover{\r\n    opacity:.85;\r\n}\r\n\r\n.pagination{\r\n    display:flex;\r\n    justify-content:center;\r\n    align-items:center;\r\n    gap:15px;\r\n    margin-top:30px;\r\n}\r\n\r\n@media(max-width:1000px){\r\n\r\n    .search-grid{\r\n        grid-template-columns:\r\n            repeat(3,1fr);\r\n    }\r\n\r\n    .options{\r\n        grid-template-columns:\r\n            repeat(2,1fr);\r\n    }\r\n\r\n}\r\n\r\n@media(max-width:600px){\r\n\r\n    .search-grid,\r\n    .options,\r\n    .page-options{\r\n        grid-template-columns:1fr;\r\n    }\r\n\r\n}\r\n\r\n<\/style>\r\n\r\n<\/head>\r\n\r\n\r\n<body>\r\n\r\n\r\n<div class=\"app\">\r\n\r\n\r\n<header>\r\n\r\n<h1>\r\n\ud83c\udfac Catalogue Films - Wikidata\r\n<\/h1>\r\n\r\n<p>\r\nRecherche directe dans Wikidata \u2014 aucune base locale\r\n<\/p>\r\n\r\n<\/header>\r\n\r\n\r\n<section class=\"search-box\">\r\n\r\n\r\n<div class=\"search-grid\">\r\n\r\n\r\n<input\r\n    id=\"search\"\r\n    type=\"search\"\r\n    placeholder=\"Mot ou partie de mot : chr\u00e9tien, Bible, spirituel...\"\r\n>\r\n\r\n\r\n<input\r\n    id=\"day\"\r\n    type=\"number\"\r\n    placeholder=\"Jour\"\r\n    min=\"1\"\r\n    max=\"31\"\r\n>\r\n\r\n\r\n<input\r\n    id=\"month\"\r\n    type=\"number\"\r\n    placeholder=\"Mois\"\r\n    min=\"1\"\r\n    max=\"12\"\r\n>\r\n\r\n\r\n<input\r\n    id=\"year\"\r\n    type=\"number\"\r\n    placeholder=\"Ann\u00e9e\"\r\n    min=\"1800\"\r\n    max=\"2100\"\r\n>\r\n\r\n\r\n<select id=\"titleFilter\">\r\n\r\n<option value=\"all\">\r\nTous les films\r\n<\/option>\r\n\r\n<option value=\"with\">\r\nAvec un titre\r\n<\/option>\r\n\r\n<option value=\"without\">\r\nSans titre\r\n<\/option>\r\n\r\n<\/select>\r\n\r\n\r\n<select id=\"dateFilter\">\r\n\r\n<option value=\"all\">\r\nToutes les dates\r\n<\/option>\r\n\r\n<option value=\"with\">\r\nAvec date de sortie\r\n<\/option>\r\n\r\n<option value=\"without\">\r\nSans date de sortie\r\n<\/option>\r\n\r\n<\/select>\r\n\r\n\r\n<select id=\"sort\">\r\n\r\n<option value=\"newest\">\r\nPlus r\u00e9cents\r\n<\/option>\r\n\r\n<option value=\"oldest\">\r\nPlus anciens\r\n<\/option>\r\n\r\n<option value=\"title\">\r\nTitre A-Z\r\n<\/option>\r\n\r\n<\/select>\r\n\r\n\r\n<button id=\"searchButton\">\r\n\ud83d\udd0e Rechercher\r\n<\/button>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"options\">\r\n\r\n\r\n<label\r\n    class=\"toggle-filter\"\r\n    for=\"religiousFilter\"\r\n>\r\n\r\n<input\r\n    type=\"checkbox\"\r\n    id=\"religiousFilter\"\r\n>\r\n\r\n<span>\r\n\u271d\ufe0f Films chr\u00e9tiens \/ religieux uniquement\r\n<\/span>\r\n\r\n<\/label>\r\n\r\n\r\n<select id=\"typeFilter\">\r\n\r\n<option value=\"film\">\r\nFilms uniquement\r\n<\/option>\r\n\r\n<option value=\"all\">\r\nFilms et \u0153uvres audiovisuelles\r\n<\/option>\r\n\r\n<\/select>\r\n\r\n\r\n<select id=\"pageSize\">\r\n\r\n<option value=\"20\" selected>\r\n20 r\u00e9sultats\r\n<\/option>\r\n\r\n<option value=\"50\">\r\n50 r\u00e9sultats\r\n<\/option>\r\n\r\n<option value=\"100\">\r\n100 r\u00e9sultats\r\n<\/option>\r\n\r\n<\/select>\r\n\r\n\r\n<button\r\n    id=\"cancelButton\"\r\n    disabled\r\n>\r\n\u23f9 Annuler\r\n<\/button>\r\n\r\n\r\n<button id=\"resetButton\">\r\n\ud83e\uddf9 R\u00e9initialiser\r\n<\/button>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"page-options\">\r\n\r\n\r\n<input\r\n    id=\"pageInput\"\r\n    type=\"number\"\r\n    min=\"1\"\r\n    value=\"1\"\r\n    placeholder=\"Num\u00e9ro de page\"\r\n>\r\n\r\n\r\n<button id=\"pageButton\">\r\n\ud83d\udcc4 Aller \u00e0 la page\r\n<\/button>\r\n\r\n\r\n<button id=\"exportButton\">\r\n\u2b07\ufe0f Exporter CSV\r\n<\/button>\r\n\r\n\r\n<button id=\"reloadButton\">\r\n\ud83d\udd04 Rechercher\r\n<\/button>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"progress\">\r\n\r\n<div\r\n    id=\"progressBar\"\r\n    class=\"progress-bar\"\r\n>\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n\r\n<\/section>\r\n\r\n\r\n<div\r\n    id=\"status\"\r\n    class=\"status\"\r\n>\r\nPr\u00eat.\r\n<\/div>\r\n\r\n\r\n<div\r\n    id=\"results\"\r\n    class=\"results\"\r\n>\r\n<\/div>\r\n\r\n\r\n<div class=\"pagination\">\r\n\r\n\r\n<button id=\"previousButton\">\r\n\u25c0 Pr\u00e9c\u00e9dent\r\n<\/button>\r\n\r\n\r\n<span id=\"pageInfo\">\r\nPage 1\r\n<\/span>\r\n\r\n\r\n<button id=\"nextButton\">\r\nSuivant \u25b6\r\n<\/button>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n<\/div>\r\n\r\n\r\n\r\n<script>\r\n\r\n\r\n\/* =========================================================\r\n   CONFIGURATION\r\n========================================================= *\/\r\n\r\nconst WIKIDATA_ENDPOINT =\r\n\r\n    \"https:\/\/query.wikidata.org\/sparql\";\r\n\r\n\r\n\/*\r\nQID utilis\u00e9s pour rep\u00e9rer les films chr\u00e9tiens \/ religieux :\r\n\r\n- Q115122793 : genre \"Christian film\"\r\n- Q7717463   : genre \"Bible film\"\r\n- Q5043      : sujet principal \"Christianisme\"\r\n- Q1845      : sujet principal \"Bible\"\r\n- Q302       : sujet principal \"J\u00e9sus\"\r\n- Q9174      : sujet principal \"religion\"\r\n*\/\r\n\r\nconst RELIGIOUS_GENRE_IDS =\r\n\r\n    [\"wd:Q115122793\", \"wd:Q7717463\"];\r\n\r\n\r\nconst RELIGIOUS_SUBJECT_IDS =\r\n\r\n    [\"wd:Q5043\", \"wd:Q1845\", \"wd:Q302\", \"wd:Q9174\"];\r\n\r\n\r\n\/* =========================================================\r\n   VARIABLES\r\n========================================================= *\/\r\n\r\nlet currentPage = 1;\r\n\r\nlet currentResults = [];\r\n\r\nlet abortController = null;\r\n\r\nlet isLoading = false;\r\n\r\n\r\n\/* =========================================================\r\n   ELEMENTS\r\n========================================================= *\/\r\n\r\nconst searchInput =\r\n    document.getElementById(\"search\");\r\n\r\nconst dayInput =\r\n    document.getElementById(\"day\");\r\n\r\nconst monthInput =\r\n    document.getElementById(\"month\");\r\n\r\nconst yearInput =\r\n    document.getElementById(\"year\");\r\n\r\nconst titleFilter =\r\n    document.getElementById(\"titleFilter\");\r\n\r\nconst dateFilter =\r\n    document.getElementById(\"dateFilter\");\r\n\r\nconst sortSelect =\r\n    document.getElementById(\"sort\");\r\n\r\nconst typeFilter =\r\n    document.getElementById(\"typeFilter\");\r\n\r\nconst religiousFilter =\r\n    document.getElementById(\"religiousFilter\");\r\n\r\nconst pageSizeSelect =\r\n    document.getElementById(\"pageSize\");\r\n\r\nconst statusElement =\r\n    document.getElementById(\"status\");\r\n\r\nconst resultsElement =\r\n    document.getElementById(\"results\");\r\n\r\nconst progressBar =\r\n    document.getElementById(\"progressBar\");\r\n\r\nconst cancelButton =\r\n    document.getElementById(\"cancelButton\");\r\n\r\n\r\n\/* =========================================================\r\n   CONSTRUIRE LA REQUETE\r\n========================================================= *\/\r\n\r\nfunction buildListQuery(){\r\n\r\n    const search =\r\n        searchInput.value.trim();\r\n\r\n    const day =\r\n        dayInput.value.trim();\r\n\r\n    const month =\r\n        monthInput.value.trim();\r\n\r\n    const year =\r\n        yearInput.value.trim();\r\n\r\n    const pageSize =\r\n        Number(\r\n            pageSizeSelect.value\r\n        ) || 20;\r\n\r\n    const offset =\r\n        (\r\n            currentPage - 1\r\n        ) *\r\n        pageSize;\r\n\r\n\r\n    \/*\r\n    ---------------------------------------------------------\r\n    LABEL\r\n\r\n    On r\u00e9cup\u00e8re un label fran\u00e7ais ET un label anglais\r\n    s\u00e9par\u00e9ment puis on garde le premier disponible\r\n    (COALESCE), en priorit\u00e9 le fran\u00e7ais.\r\n\r\n    Cela \u00e9vite d'avoir DEUX fiches pour le m\u00eame film\r\n    (une en fran\u00e7ais, une en anglais) comme cela pouvait\r\n    arriver avant.\r\n    ---------------------------------------------------------\r\n    *\/\r\n\r\n    const labelCondition = `\r\n\r\n        OPTIONAL{\r\n\r\n            ?item\r\n                rdfs:label\r\n                ?labelFr .\r\n\r\n            FILTER(\r\n                LANG(?labelFr) = \"fr\"\r\n            )\r\n\r\n        }\r\n\r\n        OPTIONAL{\r\n\r\n            ?item\r\n                rdfs:label\r\n                ?labelEn .\r\n\r\n            FILTER(\r\n                LANG(?labelEn) = \"en\"\r\n            )\r\n\r\n        }\r\n\r\n        BIND(\r\n\r\n            COALESCE(?labelFr, ?labelEn)\r\n\r\n            AS ?itemLabel\r\n\r\n        )\r\n\r\n        FILTER(\r\n            BOUND(?itemLabel)\r\n        )\r\n\r\n    `;\r\n\r\n\r\n    let searchCondition = \"\";\r\n\r\n\r\n    if(search){\r\n\r\n        const safeSearch =\r\n            search\r\n            .replace(\r\n                \/\"\/g,\r\n                '\\\\\"'\r\n            );\r\n\r\n\r\n        searchCondition = `\r\n\r\n            FILTER(\r\n\r\n                CONTAINS(\r\n                    LCASE(STR(?labelFr)),\r\n                    LCASE(\"${safeSearch}\")\r\n                )\r\n\r\n                ||\r\n\r\n                CONTAINS(\r\n                    LCASE(STR(?labelEn)),\r\n                    LCASE(\"${safeSearch}\")\r\n                )\r\n\r\n            )\r\n\r\n        `;\r\n\r\n    }\r\n\r\n\r\n    \/*\r\n    ---------------------------------------------------------\r\n    FILTRE TYPE\r\n    ---------------------------------------------------------\r\n    *\/\r\n\r\n    let typeCondition = `\r\n\r\n        ?item\r\n\r\n            wdt:P31\r\n\r\n            wd:Q11424 .\r\n\r\n    `;\r\n\r\n\r\n    if(\r\n\r\n        typeFilter.value ===\r\n        \"all\"\r\n\r\n    ){\r\n\r\n        typeCondition = `\r\n\r\n            {\r\n\r\n                ?item\r\n                    wdt:P31\r\n                    wd:Q11424 .\r\n\r\n            }\r\n\r\n            UNION\r\n\r\n            {\r\n\r\n                ?item\r\n                    wdt:P31\r\n                    ?type .\r\n\r\n                ?type\r\n                    wdt:P279*\r\n                    wd:Q11424 .\r\n\r\n            }\r\n\r\n        `;\r\n\r\n    }\r\n\r\n\r\n    \/*\r\n    ---------------------------------------------------------\r\n    FILTRE THEMATIQUE : chr\u00e9tien \/ religieux\r\n\r\n    Un film correspond si :\r\n      - son genre (P136) est \"Christian film\" ou \"Bible film\"\r\n      OU\r\n      - son sujet principal (P921) est Christianisme, Bible,\r\n        J\u00e9sus ou religion\r\n    ---------------------------------------------------------\r\n    *\/\r\n\r\n    let religiousCondition = \"\";\r\n\r\n\r\n    if(\r\n\r\n        religiousFilter.checked\r\n\r\n    ){\r\n\r\n        religiousCondition = `\r\n\r\n            {\r\n\r\n                ?item\r\n                    wdt:P136\r\n                    ?religiousGenre .\r\n\r\n                VALUES ?religiousGenre {\r\n\r\n                    ${RELIGIOUS_GENRE_IDS.join(\" \")}\r\n\r\n                }\r\n\r\n            }\r\n\r\n            UNION\r\n\r\n            {\r\n\r\n                ?item\r\n                    wdt:P921\r\n                    ?religiousSubject .\r\n\r\n                VALUES ?religiousSubject {\r\n\r\n                    ${RELIGIOUS_SUBJECT_IDS.join(\" \")}\r\n\r\n                }\r\n\r\n            }\r\n\r\n        `;\r\n\r\n    }\r\n\r\n\r\n    \/*\r\n    ---------------------------------------------------------\r\n    DATE \u2014 jour \/ mois \/ ann\u00e9e\r\n\r\n    Se d\u00e9clenche d\u00e8s qu'AU MOINS UN des trois champs est\r\n    renseign\u00e9.\r\n    ---------------------------------------------------------\r\n    *\/\r\n\r\n    const hasDateFilter =\r\n\r\n        day ||\r\n        month ||\r\n        year;\r\n\r\n\r\n    let dateVariable = `\r\n\r\n        OPTIONAL{\r\n\r\n            ?item\r\n\r\n                wdt:P577\r\n\r\n                ?date .\r\n\r\n        }\r\n\r\n    `;\r\n\r\n\r\n    if(\r\n\r\n        dateFilter.value ===\r\n        \"with\"\r\n\r\n        ||\r\n\r\n        hasDateFilter\r\n\r\n    ){\r\n\r\n        dateVariable = `\r\n\r\n            ?item\r\n\r\n                wdt:P577\r\n\r\n                ?date .\r\n\r\n        `;\r\n\r\n    }\r\n\r\n\r\n    if(\r\n\r\n        dateFilter.value ===\r\n        \"without\"\r\n\r\n    ){\r\n\r\n        dateVariable = `\r\n\r\n            FILTER NOT EXISTS{\r\n\r\n                ?item\r\n\r\n                    wdt:P577\r\n\r\n                    ?anyDate .\r\n\r\n            }\r\n\r\n        `;\r\n\r\n    }\r\n\r\n\r\n    let dateFilterCondition = \"\";\r\n\r\n\r\n    if(\r\n\r\n        hasDateFilter\r\n\r\n        &&\r\n\r\n        dateFilter.value !==\r\n        \"without\"\r\n\r\n    ){\r\n\r\n        const conditions = [];\r\n\r\n\r\n        if(day){\r\n\r\n            conditions.push(\r\n\r\n                `DAY(?date) = ${Number(day)}`\r\n\r\n            );\r\n\r\n        }\r\n\r\n\r\n        if(month){\r\n\r\n            conditions.push(\r\n\r\n                `MONTH(?date) = ${Number(month)}`\r\n\r\n            );\r\n\r\n        }\r\n\r\n\r\n        if(year){\r\n\r\n            conditions.push(\r\n\r\n                `YEAR(?date) = ${Number(year)}`\r\n\r\n            );\r\n\r\n        }\r\n\r\n\r\n        dateFilterCondition = `\r\n\r\n            FILTER(\r\n\r\n                ${conditions.join(\" && \")}\r\n\r\n            )\r\n\r\n        `;\r\n\r\n    }\r\n\r\n\r\n    \/*\r\n    ---------------------------------------------------------\r\n    TRI\r\n    ---------------------------------------------------------\r\n    *\/\r\n\r\n    let order =\r\n\r\n        \"DESC(?date)\";\r\n\r\n\r\n    if(\r\n\r\n        sortSelect.value ===\r\n        \"oldest\"\r\n\r\n    ){\r\n\r\n        order =\r\n\r\n            \"ASC(?date)\";\r\n\r\n    }\r\n\r\n\r\n    if(\r\n\r\n        sortSelect.value ===\r\n        \"title\"\r\n\r\n    ){\r\n\r\n        order =\r\n\r\n            \"LCASE(STR(?itemLabel))\";\r\n\r\n    }\r\n\r\n\r\n    \/*\r\n    ---------------------------------------------------------\r\n    REQUETE LEGERE\r\n\r\n    Cette premi\u00e8re requ\u00eate se contente de trouver LES FILMS\r\n    qui correspondent aux filtres (titre, date, religieux...)\r\n    et applique directement la pagination.\r\n\r\n    Elle ne va PAS chercher l'affiche, le r\u00e9alisateur, le\r\n    casting, etc. \u2014 ces informations sont beaucoup plus\r\n    co\u00fbteuses \u00e0 joindre et ne sont utiles que pour les films\r\n    r\u00e9ellement affich\u00e9s sur la page en cours. Les r\u00e9cup\u00e9rer\r\n    ici, pour potentiellement des dizaines de milliers de\r\n    films avant pagination, est ce qui provoquait les\r\n    timeouts (\"Wikidata est temporairement charg\u00e9\").\r\n\r\n    Une seconde requ\u00eate cibl\u00e9e (buildDetailsQuery) s'occupe\r\n    de l'enrichissement, uniquement pour les films de cette\r\n    page.\r\n    ---------------------------------------------------------\r\n    *\/\r\n\r\n    return `\r\n\r\n        SELECT DISTINCT\r\n\r\n            ?item\r\n\r\n            ?itemLabel\r\n\r\n            ?date\r\n\r\n\r\n        WHERE{\r\n\r\n\r\n            ${typeCondition}\r\n\r\n\r\n            ${religiousCondition}\r\n\r\n\r\n            ${labelCondition}\r\n\r\n\r\n            ${searchCondition}\r\n\r\n\r\n            ${dateVariable}\r\n\r\n\r\n            ${dateFilterCondition}\r\n\r\n        }\r\n\r\n\r\n        ORDER BY\r\n\r\n            ${order}\r\n\r\n\r\n        LIMIT\r\n\r\n            ${pageSize}\r\n\r\n\r\n        OFFSET\r\n\r\n            ${offset}\r\n\r\n    `;\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   REQUETE D'ENRICHISSEMENT\r\n\r\n   Va chercher affiche, r\u00e9alisateur(s), casting, site\r\n   officiel et IMDb, mais UNIQUEMENT pour la liste d'items\r\n   pass\u00e9e en argument (donc au maximum \"pageSize\" films,\r\n   ceux affich\u00e9s sur la page en cours).\r\n\r\n   C'est le fait de restreindre avec VALUES ?item {...} qui\r\n   rend cette requ\u00eate rapide : plus besoin de scanner toute\r\n   la classe des films.\r\n========================================================= *\/\r\n\r\nfunction buildDetailsQuery(\r\n\r\n    itemUris\r\n\r\n){\r\n\r\n    const values =\r\n\r\n        itemUris\r\n\r\n        .map(\r\n\r\n            uri => `<${uri}>`\r\n\r\n        )\r\n\r\n        .join(\" \");\r\n\r\n\r\n    return `\r\n\r\n        SELECT\r\n\r\n            ?item\r\n\r\n            (SAMPLE(?poster) AS ?poster)\r\n\r\n            (SAMPLE(?image) AS ?image)\r\n\r\n            (GROUP_CONCAT(DISTINCT ?directorLabel; separator=\", \") AS ?directors)\r\n\r\n            (GROUP_CONCAT(DISTINCT ?castLabel; separator=\", \") AS ?cast)\r\n\r\n            (SAMPLE(?website) AS ?website)\r\n\r\n            (SAMPLE(?imdb) AS ?imdb)\r\n\r\n\r\n        WHERE{\r\n\r\n            VALUES ?item { ${values} }\r\n\r\n            OPTIONAL{\r\n\r\n                ?item wdt:P3383 ?poster .\r\n\r\n            }\r\n\r\n            OPTIONAL{\r\n\r\n                ?item wdt:P18 ?image .\r\n\r\n            }\r\n\r\n            OPTIONAL{\r\n\r\n                ?item wdt:P57 ?director .\r\n\r\n                ?director rdfs:label ?directorLabel .\r\n\r\n                FILTER(LANG(?directorLabel) IN (\"fr\",\"en\"))\r\n\r\n            }\r\n\r\n            OPTIONAL{\r\n\r\n                ?item wdt:P161 ?cast .\r\n\r\n                ?cast rdfs:label ?castLabel .\r\n\r\n                FILTER(LANG(?castLabel) IN (\"fr\",\"en\"))\r\n\r\n            }\r\n\r\n            OPTIONAL{\r\n\r\n                ?item wdt:P856 ?website .\r\n\r\n            }\r\n\r\n            OPTIONAL{\r\n\r\n                ?item wdt:P345 ?imdbId .\r\n\r\n                BIND(\r\n\r\n                    CONCAT(\r\n                        \"https:\/\/www.imdb.com\/title\/\",\r\n                        ?imdbId\r\n                    )\r\n\r\n                    AS ?imdb\r\n\r\n                )\r\n\r\n            }\r\n\r\n        }\r\n\r\n\r\n        GROUP BY\r\n\r\n            ?item\r\n\r\n    `;\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   REQUETE AVEC RETRY\r\n========================================================= *\/\r\n\r\nasync function fetchWikidata(\r\n\r\n    query,\r\n\r\n    attempt = 0\r\n\r\n){\r\n\r\n    \/*\r\n    ---------------------------------------------------------\r\n    POST plut\u00f4t que GET.\r\n\r\n    Les requ\u00eates sont devenues plus longues (affiche,\r\n    r\u00e9alisateur, casting, filtre religieux...). En GET,\r\n    la requ\u00eate part dans l'URL, qui peut d\u00e9passer la\r\n    limite accept\u00e9e par le serveur\/proxy de Wikidata et\r\n    provoquer un \u00e9chec r\u00e9seau (\"Failed to fetch\") avant\r\n    m\u00eame qu'une r\u00e9ponse HTTP soit re\u00e7ue.\r\n\r\n    En POST, la requ\u00eate part dans le corps de la requ\u00eate :\r\n    plus de limite de longueur.\r\n    ---------------------------------------------------------\r\n    *\/\r\n\r\n    const response =\r\n\r\n        await fetch(\r\n\r\n            WIKIDATA_ENDPOINT,\r\n\r\n            {\r\n\r\n                method:\"POST\",\r\n\r\n                headers:{\r\n\r\n                    \"Content-Type\":\r\n                        \"application\/x-www-form-urlencoded\",\r\n\r\n                    \"Accept\":\r\n                        \"application\/sparql-results+json\"\r\n\r\n                },\r\n\r\n                body:\r\n\r\n                    \"query=\"\r\n\r\n                    +\r\n\r\n                    encodeURIComponent(\r\n\r\n                        query\r\n\r\n                    ),\r\n\r\n                signal:\r\n\r\n                    abortController.signal\r\n\r\n            }\r\n\r\n        );\r\n\r\n\r\n    if(\r\n\r\n        [\r\n\r\n            429,\r\n\r\n            502,\r\n\r\n            503,\r\n\r\n            504\r\n\r\n        ]\r\n\r\n        .includes(\r\n\r\n            response.status\r\n\r\n        )\r\n\r\n    ){\r\n\r\n        if(\r\n\r\n            attempt < 3\r\n\r\n        ){\r\n\r\n            const delay =\r\n\r\n                (\r\n\r\n                    attempt + 1\r\n\r\n                )\r\n\r\n                *\r\n\r\n                2500;\r\n\r\n\r\n            statusElement.textContent =\r\n\r\n                \"\u23f3 Wikidata est temporairement charg\u00e9. \"\r\n\r\n                +\r\n\r\n                \"Nouvelle tentative dans \"\r\n\r\n                +\r\n\r\n                (\r\n\r\n                    delay \/ 1000\r\n\r\n                )\r\n\r\n                +\r\n\r\n                \" secondes...\";\r\n\r\n\r\n            await new Promise(\r\n\r\n                resolve =>\r\n\r\n                    setTimeout(\r\n\r\n                        resolve,\r\n\r\n                        delay\r\n\r\n                    )\r\n\r\n            );\r\n\r\n\r\n            return fetchWikidata(\r\n\r\n                query,\r\n\r\n                attempt + 1\r\n\r\n            );\r\n\r\n        }\r\n\r\n    }\r\n\r\n\r\n    if(\r\n\r\n        !response.ok\r\n\r\n    ){\r\n\r\n        throw new Error(\r\n\r\n            \"Erreur HTTP \"\r\n\r\n            +\r\n\r\n            response.status\r\n\r\n        );\r\n\r\n    }\r\n\r\n\r\n    return response.json();\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   RECHERCHE\r\n========================================================= *\/\r\n\r\nasync function searchWikidata(){\r\n\r\n    if(\r\n\r\n        isLoading\r\n\r\n    ){\r\n\r\n        return;\r\n\r\n    }\r\n\r\n\r\n    isLoading =\r\n\r\n        true;\r\n\r\n\r\n    abortController =\r\n\r\n        new AbortController();\r\n\r\n\r\n    cancelButton.disabled =\r\n\r\n        false;\r\n\r\n\r\n    progressBar.style.width =\r\n\r\n        \"15%\";\r\n\r\n\r\n    resultsElement.innerHTML =\r\n\r\n        \"\";\r\n\r\n\r\n    statusElement.textContent =\r\n\r\n        \"\u23f3 Pr\u00e9paration de la recherche...\";\r\n\r\n\r\n    try{\r\n\r\n\r\n        \/*\r\n        -----------------------------------------------------\r\n        ETAPE 1 : requ\u00eate l\u00e9g\u00e8re (liste + pagination)\r\n        -----------------------------------------------------\r\n        *\/\r\n\r\n        const listQuery =\r\n\r\n            buildListQuery();\r\n\r\n\r\n        progressBar.style.width =\r\n\r\n            \"25%\";\r\n\r\n\r\n        statusElement.textContent =\r\n\r\n            \"\u23f3 Recherche des films...\";\r\n\r\n\r\n        const listData =\r\n\r\n            await fetchWikidata(\r\n\r\n                listQuery\r\n\r\n            );\r\n\r\n\r\n        const listRows =\r\n\r\n            listData\r\n            .results\r\n            .bindings;\r\n\r\n\r\n        progressBar.style.width =\r\n\r\n            \"50%\";\r\n\r\n\r\n        if(\r\n\r\n            titleFilter.value ===\r\n            \"without\"\r\n\r\n        ){\r\n\r\n            currentResults = [];\r\n\r\n            statusElement.textContent =\r\n\r\n                \"\u26a0\ufe0f Wikidata ne permet pas de r\u00e9cup\u00e9rer \"\r\n\r\n                +\r\n\r\n                \"fiablement les films sans titre dans \"\r\n\r\n                +\r\n\r\n                \"cette requ\u00eate l\u00e9g\u00e8re.\";\r\n\r\n            renderResults();\r\n\r\n            return;\r\n\r\n        }\r\n\r\n\r\n        if(\r\n\r\n            listRows.length ===\r\n            0\r\n\r\n        ){\r\n\r\n            currentResults = [];\r\n\r\n            progressBar.style.width =\r\n\r\n                \"100%\";\r\n\r\n            statusElement.textContent =\r\n\r\n                \"\u274c Aucun r\u00e9sultat.\";\r\n\r\n            renderResults();\r\n\r\n            return;\r\n\r\n        }\r\n\r\n\r\n        \/*\r\n        -----------------------------------------------------\r\n        ETAPE 2 : enrichissement, uniquement pour les films\r\n        de cette page (affiche, r\u00e9alisateur, casting, liens)\r\n        -----------------------------------------------------\r\n        *\/\r\n\r\n        statusElement.textContent =\r\n\r\n            \"\u23f3 R\u00e9cup\u00e9ration des affiches et informations...\";\r\n\r\n\r\n        const itemUris =\r\n\r\n            listRows.map(\r\n\r\n                row => row.item.value\r\n\r\n            );\r\n\r\n\r\n        const detailsQuery =\r\n\r\n            buildDetailsQuery(\r\n\r\n                itemUris\r\n\r\n            );\r\n\r\n\r\n        const detailsData =\r\n\r\n            await fetchWikidata(\r\n\r\n                detailsQuery\r\n\r\n            );\r\n\r\n\r\n        const detailsByUri = {};\r\n\r\n\r\n        detailsData\r\n\r\n            .results\r\n\r\n            .bindings\r\n\r\n            .forEach(\r\n\r\n                row => {\r\n\r\n                    detailsByUri[row.item.value] = row;\r\n\r\n                }\r\n\r\n            );\r\n\r\n\r\n        progressBar.style.width =\r\n\r\n            \"80%\";\r\n\r\n\r\n        currentResults =\r\n\r\n            listRows.map(\r\n\r\n                row =>\r\n\r\n                    convertResult(\r\n\r\n                        row,\r\n\r\n                        detailsByUri[row.item.value]\r\n\r\n                    )\r\n\r\n            );\r\n\r\n\r\n        progressBar.style.width =\r\n\r\n            \"100%\";\r\n\r\n\r\n        statusElement.textContent =\r\n\r\n            \"\u2705 \"\r\n\r\n            +\r\n\r\n            currentResults.length\r\n\r\n            +\r\n\r\n            \" r\u00e9sultat(s) trouv\u00e9(s).\";\r\n\r\n\r\n        renderResults();\r\n\r\n\r\n    }\r\n\r\n    catch(\r\n\r\n        error\r\n\r\n    ){\r\n\r\n        if(\r\n\r\n            error.name ===\r\n            \"AbortError\"\r\n\r\n        ){\r\n\r\n            statusElement.textContent =\r\n\r\n                \"\u23f9 Recherche annul\u00e9e.\";\r\n\r\n        }\r\n\r\n        else{\r\n\r\n            console.error(\r\n\r\n                \"Wikidata :\",\r\n\r\n                error\r\n\r\n            );\r\n\r\n\r\n            statusElement.textContent =\r\n\r\n                \"\u274c Impossible d'interroger Wikidata : \"\r\n\r\n                +\r\n\r\n                error.message;\r\n\r\n        }\r\n\r\n    }\r\n\r\n    finally{\r\n\r\n\r\n        isLoading =\r\n\r\n            false;\r\n\r\n\r\n        cancelButton.disabled =\r\n\r\n            true;\r\n\r\n\r\n        abortController =\r\n\r\n            null;\r\n\r\n    }\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   CONVERSION\r\n========================================================= *\/\r\n\r\nfunction convertResult(\r\n\r\n    listRow,\r\n\r\n    detailsRow\r\n\r\n){\r\n\r\n    \/*\r\n    -----------------------------------------------------\r\n    detailsRow peut \u00eatre absent si, pour une raison\r\n    quelconque, la requ\u00eate d'enrichissement n'a rien\r\n    renvoy\u00e9 pour ce film pr\u00e9cis (rare, mais on s'en\r\n    prot\u00e8ge avec un objet vide par d\u00e9faut).\r\n    -----------------------------------------------------\r\n    *\/\r\n\r\n    const details =\r\n\r\n        detailsRow\r\n\r\n        ||\r\n\r\n        {};\r\n\r\n\r\n    const poster =\r\n\r\n        details.poster\r\n\r\n        ?\r\n\r\n        details.poster.value\r\n\r\n        :\r\n\r\n        (\r\n\r\n            details.image\r\n\r\n            ?\r\n\r\n            details.image.value\r\n\r\n            :\r\n\r\n            \"\"\r\n\r\n        );\r\n\r\n\r\n    const website =\r\n\r\n        details.website\r\n\r\n        ?\r\n\r\n        details.website.value\r\n\r\n        :\r\n\r\n        \"\";\r\n\r\n\r\n    const imdb =\r\n\r\n        details.imdb\r\n\r\n        ?\r\n\r\n        details.imdb.value\r\n\r\n        :\r\n\r\n        \"\";\r\n\r\n\r\n    const uri =\r\n\r\n        listRow.item\r\n\r\n        ?\r\n\r\n        listRow.item.value\r\n\r\n        :\r\n\r\n        \"\";\r\n\r\n\r\n    \/*\r\n    -----------------------------------------------------\r\n    LIEN PRINCIPAL\r\n\r\n    Priorit\u00e9 : site officiel du film > IMDb > fiche\r\n    Wikidata (toujours disponible en dernier recours).\r\n    -----------------------------------------------------\r\n    *\/\r\n\r\n    const primaryLink =\r\n\r\n        website\r\n\r\n        ||\r\n\r\n        imdb\r\n\r\n        ||\r\n\r\n        uri;\r\n\r\n\r\n    return {\r\n\r\n        uri,\r\n\r\n        title:\r\n\r\n            listRow.itemLabel\r\n\r\n            ?\r\n\r\n            listRow.itemLabel.value\r\n\r\n            :\r\n\r\n            \"\",\r\n\r\n        poster,\r\n\r\n        directors:\r\n\r\n            details.directors\r\n\r\n            ?\r\n\r\n            details.directors.value\r\n\r\n            :\r\n\r\n            \"\",\r\n\r\n        cast:\r\n\r\n            details.cast\r\n\r\n            ?\r\n\r\n            details.cast.value\r\n\r\n            :\r\n\r\n            \"\",\r\n\r\n        date:\r\n\r\n            listRow.date\r\n\r\n            ?\r\n\r\n            listRow.date.value\r\n\r\n            :\r\n\r\n            \"\",\r\n\r\n        website,\r\n\r\n        imdb,\r\n\r\n        primaryLink\r\n\r\n    };\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   AFFICHAGE\r\n========================================================= *\/\r\n\r\nfunction renderResults(){\r\n\r\n    resultsElement.innerHTML =\r\n\r\n        \"\";\r\n\r\n\r\n    currentResults.forEach(\r\n\r\n        film => {\r\n\r\n\r\n            const card =\r\n\r\n                document\r\n                .createElement(\r\n                    \"article\"\r\n                );\r\n\r\n\r\n            card.className =\r\n\r\n                \"card\";\r\n\r\n\r\n            const year =\r\n\r\n                film.date\r\n\r\n                ?\r\n\r\n                new Date(film.date)\r\n                    .getFullYear()\r\n\r\n                :\r\n\r\n                \"\";\r\n\r\n\r\n            const castList =\r\n\r\n                film.cast\r\n\r\n                ?\r\n\r\n                film.cast\r\n                    .split(\", \")\r\n                    .slice(0, 4)\r\n                    .join(\", \")\r\n\r\n                :\r\n\r\n                \"\";\r\n\r\n\r\n            const posterBlock =\r\n\r\n                film.poster\r\n\r\n                ?\r\n\r\n                `<img decoding=\"async\"\r\n                    class=\"poster\"\r\n                    src=\"${film.poster}\"\r\n                    alt=\"${escapeHTML(film.title)}\"\r\n                    loading=\"lazy\"\r\n                >`\r\n\r\n                :\r\n\r\n                `<div class=\"poster-placeholder\">\ud83c\udfac<\/div>`;\r\n\r\n\r\n            card.innerHTML = `\r\n\r\n                <div class=\"poster-wrap\">\r\n\r\n                    ${posterBlock}\r\n\r\n                    ${\r\n\r\n                        year\r\n\r\n                        ?\r\n\r\n                        `<div class=\"year-badge\">${year}<\/div>`\r\n\r\n                        :\r\n\r\n                        \"\"\r\n\r\n                    }\r\n\r\n                    ${\r\n\r\n                        religiousFilter.checked\r\n\r\n                        ?\r\n\r\n                        `<div class=\"religious-badge\">\u271d\ufe0f Religieux<\/div>`\r\n\r\n                        :\r\n\r\n                        \"\"\r\n\r\n                    }\r\n\r\n                    <a\r\n\r\n                        class=\"poster-overlay\"\r\n\r\n                        href=\"${film.primaryLink}\"\r\n\r\n                        target=\"_blank\"\r\n\r\n                        rel=\"noopener\"\r\n\r\n                    >\r\n\r\n                        <span class=\"overlay-btn\">\r\n                            \u25b6 Voir le film\r\n                        <\/span>\r\n\r\n                    <\/a>\r\n\r\n                <\/div>\r\n\r\n\r\n                <div class=\"card-content\">\r\n\r\n                    <h3>\r\n                        ${escapeHTML(\r\n\r\n                            film.title\r\n\r\n                            ||\r\n\r\n                            \"Titre non renseign\u00e9\"\r\n\r\n                        )}\r\n                    <\/h3>\r\n\r\n                    ${\r\n\r\n                        film.directors\r\n\r\n                        ?\r\n\r\n                        `<div class=\"meta-line\">\r\n                            <b>R\u00e9alisation :<\/b>\r\n                            ${escapeHTML(film.directors)}\r\n                        <\/div>`\r\n\r\n                        :\r\n\r\n                        \"\"\r\n\r\n                    }\r\n\r\n                    ${\r\n\r\n                        castList\r\n\r\n                        ?\r\n\r\n                        `<div class=\"meta-line\">\r\n                            <b>Avec :<\/b>\r\n                            ${escapeHTML(castList)}\r\n                        <\/div>`\r\n\r\n                        :\r\n\r\n                        \"\"\r\n\r\n                    }\r\n\r\n                    <div class=\"meta-line\">\r\n                        \ud83d\udcc5 ${formatDate(film.date)}\r\n                    <\/div>\r\n\r\n                    <div class=\"card-links\">\r\n\r\n                        <a\r\n\r\n                            class=\"link-primary\"\r\n\r\n                            href=\"${film.primaryLink}\"\r\n\r\n                            target=\"_blank\"\r\n\r\n                            rel=\"noopener\"\r\n\r\n                        >\r\n                            \u25b6 Voir le film\r\n                        <\/a>\r\n\r\n                        <a\r\n\r\n                            class=\"link-secondary\"\r\n\r\n                            href=\"${film.uri}\"\r\n\r\n                            target=\"_blank\"\r\n\r\n                            rel=\"noopener\"\r\n\r\n                        >\r\n                            Wikidata\r\n                        <\/a>\r\n\r\n                    <\/div>\r\n\r\n                <\/div>\r\n\r\n            `;\r\n\r\n\r\n            resultsElement.appendChild(\r\n\r\n                card\r\n\r\n            );\r\n\r\n        }\r\n\r\n    );\r\n\r\n\r\n    updatePagination();\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   PAGINATION\r\n========================================================= *\/\r\n\r\nfunction updatePagination(){\r\n\r\n    const pageSize =\r\n\r\n        Number(\r\n\r\n            pageSizeSelect.value\r\n\r\n        );\r\n\r\n\r\n    document\r\n\r\n        .getElementById(\r\n            \"pageInfo\"\r\n        )\r\n\r\n        .textContent =\r\n\r\n            \"Page \"\r\n\r\n            +\r\n\r\n            currentPage;\r\n\r\n\r\n    document\r\n\r\n        .getElementById(\r\n            \"previousButton\"\r\n        )\r\n\r\n        .disabled =\r\n\r\n            currentPage <=\r\n            1;\r\n\r\n\r\n    document\r\n\r\n        .getElementById(\r\n            \"nextButton\"\r\n        )\r\n\r\n        .disabled =\r\n\r\n            currentResults.length <\r\n            pageSize;\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   DATE\r\n========================================================= *\/\r\n\r\nfunction formatDate(\r\n\r\n    date\r\n\r\n){\r\n\r\n    if(\r\n\r\n        !date\r\n\r\n    ){\r\n\r\n        return \"Date non renseign\u00e9e\";\r\n\r\n    }\r\n\r\n\r\n    const d =\r\n\r\n        new Date(\r\n\r\n            date\r\n\r\n        );\r\n\r\n\r\n    if(\r\n\r\n        isNaN(\r\n\r\n            d\r\n\r\n        )\r\n\r\n    ){\r\n\r\n        return date;\r\n\r\n    }\r\n\r\n\r\n    return d.toLocaleDateString(\r\n\r\n        \"fr-FR\"\r\n\r\n    );\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   SECURITE\r\n========================================================= *\/\r\n\r\nfunction escapeHTML(\r\n\r\n    value\r\n\r\n){\r\n\r\n    const div =\r\n\r\n        document\r\n        .createElement(\r\n            \"div\"\r\n        );\r\n\r\n\r\n    div.textContent =\r\n\r\n        value\r\n\r\n        ?\r\n\r\n        String(\r\n\r\n            value\r\n\r\n        )\r\n\r\n        :\r\n\r\n        \"\";\r\n\r\n\r\n    return div.innerHTML;\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   ANNULER\r\n========================================================= *\/\r\n\r\ncancelButton\r\n\r\n.addEventListener(\r\n\r\n    \"click\",\r\n\r\n    function(){\r\n\r\n        if(\r\n\r\n            abortController\r\n\r\n        ){\r\n\r\n            abortController.abort();\r\n\r\n        }\r\n\r\n    }\r\n\r\n);\r\n\r\n\r\n\/* =========================================================\r\n   RECHERCHE\r\n========================================================= *\/\r\n\r\ndocument\r\n\r\n.getElementById(\r\n    \"searchButton\"\r\n)\r\n\r\n.addEventListener(\r\n\r\n    \"click\",\r\n\r\n    function(){\r\n\r\n        currentPage =\r\n\r\n            1;\r\n\r\n        searchWikidata();\r\n\r\n    }\r\n\r\n);\r\n\r\n\r\n\/* =========================================================\r\n   ENTER\r\n========================================================= *\/\r\n\r\nsearchInput\r\n\r\n.addEventListener(\r\n\r\n    \"keydown\",\r\n\r\n    function(\r\n\r\n        event\r\n\r\n    ){\r\n\r\n        if(\r\n\r\n            event.key ===\r\n            \"Enter\"\r\n\r\n        ){\r\n\r\n            currentPage =\r\n\r\n                1;\r\n\r\n            searchWikidata();\r\n\r\n        }\r\n\r\n    }\r\n\r\n);\r\n\r\n\r\n\/* =========================================================\r\n   SUIVANT\r\n========================================================= *\/\r\n\r\ndocument\r\n\r\n.getElementById(\r\n    \"nextButton\"\r\n)\r\n\r\n.addEventListener(\r\n\r\n    \"click\",\r\n\r\n    function(){\r\n\r\n        currentPage++;\r\n\r\n        searchWikidata();\r\n\r\n    }\r\n\r\n);\r\n\r\n\r\n\/* =========================================================\r\n   PRECEDENT\r\n========================================================= *\/\r\n\r\ndocument\r\n\r\n.getElementById(\r\n    \"previousButton\"\r\n)\r\n\r\n.addEventListener(\r\n\r\n    \"click\",\r\n\r\n    function(){\r\n\r\n        if(\r\n\r\n            currentPage >\r\n            1\r\n\r\n        ){\r\n\r\n            currentPage--;\r\n\r\n            searchWikidata();\r\n\r\n        }\r\n\r\n    }\r\n\r\n);\r\n\r\n\r\n\/* =========================================================\r\n   PAGE DIRECTE\r\n========================================================= *\/\r\n\r\ndocument\r\n\r\n.getElementById(\r\n    \"pageButton\"\r\n)\r\n\r\n.addEventListener(\r\n\r\n    \"click\",\r\n\r\n    function(){\r\n\r\n        const page =\r\n\r\n            Number(\r\n\r\n                document\r\n\r\n                .getElementById(\r\n                    \"pageInput\"\r\n                )\r\n\r\n                .value\r\n\r\n            );\r\n\r\n\r\n        if(\r\n\r\n            page >= 1\r\n\r\n        ){\r\n\r\n            currentPage =\r\n\r\n                page;\r\n\r\n            searchWikidata();\r\n\r\n        }\r\n\r\n    }\r\n\r\n);\r\n\r\n\r\n\/* =========================================================\r\n   RECHERCHE PAGE\r\n========================================================= *\/\r\n\r\ndocument\r\n\r\n.getElementById(\r\n    \"reloadButton\"\r\n)\r\n\r\n.addEventListener(\r\n\r\n    \"click\",\r\n\r\n    searchWikidata\r\n\r\n);\r\n\r\n\r\n\/* =========================================================\r\n   RESET\r\n========================================================= *\/\r\n\r\ndocument\r\n\r\n.getElementById(\r\n    \"resetButton\"\r\n)\r\n\r\n.addEventListener(\r\n\r\n    \"click\",\r\n\r\n    function(){\r\n\r\n        if(\r\n\r\n            isLoading\r\n\r\n            &&\r\n\r\n            abortController\r\n\r\n        ){\r\n\r\n            abortController.abort();\r\n\r\n        }\r\n\r\n\r\n        searchInput.value = \"\";\r\n\r\n        dayInput.value = \"\";\r\n\r\n        monthInput.value = \"\";\r\n\r\n        yearInput.value = \"\";\r\n\r\n        titleFilter.value = \"all\";\r\n\r\n        dateFilter.value = \"all\";\r\n\r\n        typeFilter.value = \"film\";\r\n\r\n        religiousFilter.checked = false;\r\n\r\n        sortSelect.value = \"newest\";\r\n\r\n        pageSizeSelect.value = \"20\";\r\n\r\n        currentPage = 1;\r\n\r\n        currentResults = [];\r\n\r\n        resultsElement.innerHTML = \"\";\r\n\r\n        progressBar.style.width = \"0%\";\r\n\r\n        statusElement.textContent =\r\n\r\n            \"Filtres r\u00e9initialis\u00e9s.\";\r\n\r\n    }\r\n\r\n);\r\n\r\n\r\n\/* =========================================================\r\n   EXPORT CSV\r\n========================================================= *\/\r\n\r\ndocument\r\n\r\n.getElementById(\r\n    \"exportButton\"\r\n)\r\n\r\n.addEventListener(\r\n\r\n    \"click\",\r\n\r\n    function(){\r\n\r\n        if(\r\n\r\n            currentResults.length ===\r\n            0\r\n\r\n        ){\r\n\r\n            alert(\r\n\r\n                \"Aucun r\u00e9sultat \u00e0 exporter.\"\r\n\r\n            );\r\n\r\n            return;\r\n\r\n        }\r\n\r\n\r\n        const header = [\r\n\r\n            \"Titre\",\r\n\r\n            \"R\u00e9alisateur(s)\",\r\n\r\n            \"Casting\",\r\n\r\n            \"Date\",\r\n\r\n            \"Lien\",\r\n\r\n            \"Wikidata\"\r\n\r\n        ];\r\n\r\n\r\n        const rows =\r\n\r\n            currentResults.map(\r\n\r\n                film => [\r\n\r\n                    film.title,\r\n\r\n                    film.directors,\r\n\r\n                    film.cast,\r\n\r\n                    film.date,\r\n\r\n                    film.primaryLink,\r\n\r\n                    film.uri\r\n\r\n                ]\r\n\r\n            );\r\n\r\n\r\n        const csv =\r\n\r\n            [\r\n\r\n                header,\r\n\r\n                ...rows\r\n\r\n            ]\r\n\r\n            .map(\r\n\r\n                row =>\r\n\r\n                    row\r\n\r\n                    .map(\r\n\r\n                        value =>\r\n\r\n                            '\"' +\r\n\r\n                            String(\r\n\r\n                                value\r\n\r\n                                ||\r\n\r\n                                \"\"\r\n\r\n                            )\r\n\r\n                            .replace(\r\n\r\n                                \/\"\/g,\r\n\r\n                                '\"\"'\r\n\r\n                            )\r\n\r\n                            +\r\n\r\n                            '\"'\r\n\r\n                    )\r\n\r\n                    .join(\";\")\r\n\r\n            )\r\n\r\n            .join(\"\\n\");\r\n\r\n\r\n        const blob =\r\n\r\n            new Blob(\r\n\r\n                [\r\n\r\n                    \"\\ufeff\" +\r\n\r\n                    csv\r\n\r\n                ],\r\n\r\n                {\r\n\r\n                    type:\r\n\r\n                        \"text\/csv;charset=utf-8\"\r\n\r\n                }\r\n\r\n            );\r\n\r\n\r\n        const url =\r\n\r\n            URL.createObjectURL(\r\n\r\n                blob\r\n\r\n            );\r\n\r\n\r\n        const link =\r\n\r\n            document\r\n            .createElement(\r\n                \"a\"\r\n            );\r\n\r\n\r\n        link.href =\r\n\r\n            url;\r\n\r\n\r\n        link.download =\r\n\r\n            \"films-wikidata.csv\";\r\n\r\n\r\n        link.click();\r\n\r\n\r\n        URL.revokeObjectURL(\r\n\r\n            url\r\n\r\n        );\r\n\r\n    }\r\n\r\n);\r\n\r\n\r\n\/* =========================================================\r\n   LANCEMENT\r\n\r\n   IMPORTANT :\r\n\r\n   On ne lance PAS automatiquement une requ\u00eate vide.\r\n\r\n   L'utilisateur choisit ses crit\u00e8res et lance la recherche.\r\n\r\n========================================================= *\/\r\n\r\nstatusElement.textContent =\r\n\r\n    \"Pr\u00eat. Entrez un terme ou lancez une recherche.\";\r\n\r\n<\/script>\r\n\r\n<\/body>\r\n\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-b8c6a5a e-flex e-con-boxed elementor-repeater-item-default_padding elementor-repeater-item-none elementor-repeater-item-none_hover wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-column-slider-no wpr-equal-height-no e-con e-parent\" data-id=\"b8c6a5a\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;ang_container_spacing_size&quot;:&quot;default_padding&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d66ed5e elementor-repeater-item-none elementor-repeater-item-none_hover elementor-widget elementor-widget-html\" data-id=\"d66ed5e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"fr\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n<title>Catalogue Films - Wikidata<\/title>\r\n\r\n<style>\r\n\r\n* { box-sizing: border-box; }\r\n\r\nbody {\r\n    margin: 0;\r\n    font-family: Arial, Helvetica, sans-serif;\r\n    background: #0b0b0d;\r\n    color: #fff;\r\n}\r\n\r\n.app {\r\n    max-width: 1400px;\r\n    margin: auto;\r\n    padding: 25px;\r\n}\r\n\r\nheader { text-align: center; margin-bottom: 25px; }\r\nheader h1 { margin: 0 0 10px; }\r\nheader p { opacity: .7; }\r\n\r\n.search-box {\r\n    background: #1d1d1d;\r\n    border-radius: 14px;\r\n    padding: 20px;\r\n    margin-bottom: 20px;\r\n}\r\n\r\n.field-row {\r\n    display: grid;\r\n    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\r\n    gap: 12px;\r\n    margin-bottom: 16px;\r\n}\r\n\r\n.field-row:last-child { margin-bottom: 0; }\r\n\r\n.field-row.search-row {\r\n    grid-template-columns: 3fr 1.4fr auto;\r\n}\r\n\r\n.field label {\r\n    display: block;\r\n    font-size: 11.5px;\r\n    text-transform: uppercase;\r\n    letter-spacing: .4px;\r\n    opacity: .55;\r\n    margin-bottom: 5px;\r\n}\r\n\r\ninput, select {\r\n    width: 100%;\r\n    padding: 12px;\r\n    border-radius: 8px;\r\n    border: 1px solid #444;\r\n    background: #111;\r\n    color: #fff;\r\n    font-size: 14px;\r\n}\r\n\r\nbutton {\r\n    padding: 12px 18px;\r\n    border: 0;\r\n    border-radius: 8px;\r\n    background: #f0c400;\r\n    color: #111;\r\n    font-weight: bold;\r\n    cursor: pointer;\r\n}\r\n\r\nbutton:hover { opacity: .85; }\r\nbutton:disabled { opacity: .4; cursor: not-allowed; }\r\n\r\n.toggle-filter {\r\n    display: flex;\r\n    align-items: center;\r\n    gap: 10px;\r\n    padding: 12px;\r\n    border-radius: 8px;\r\n    border: 1px solid #444;\r\n    background: #111;\r\n    cursor: pointer;\r\n    user-select: none;\r\n}\r\n\r\n.toggle-filter input {\r\n    width: 18px;\r\n    height: 18px;\r\n    accent-color: #f0c400;\r\n    cursor: pointer;\r\n}\r\n\r\n.toggle-filter span { font-size: 13.5px; }\r\n\r\n.lexical-box {\r\n    border: 1px solid #444;\r\n    border-radius: 8px;\r\n    padding: 12px;\r\n    background: #111;\r\n}\r\n\r\n.lexical-box legend {\r\n    font-size: 11.5px;\r\n    text-transform: uppercase;\r\n    letter-spacing: .4px;\r\n    opacity: .65;\r\n    padding: 0 6px;\r\n}\r\n\r\n.lexical-options {\r\n    display: flex;\r\n    flex-wrap: wrap;\r\n    gap: 12px;\r\n    margin-top: 6px;\r\n}\r\n\r\n.lexical-options label {\r\n    display: flex;\r\n    align-items: center;\r\n    gap: 6px;\r\n    font-size: 13px;\r\n    cursor: pointer;\r\n}\r\n\r\n.lexical-options input {\r\n    width: 16px;\r\n    height: 16px;\r\n    accent-color: #f0c400;\r\n    cursor: pointer;\r\n}\r\n\r\n.status { margin: 20px 0; text-align: center; min-height: 25px; }\r\n\r\n.progress {\r\n    width: 100%;\r\n    height: 8px;\r\n    background: #333;\r\n    border-radius: 10px;\r\n    overflow: hidden;\r\n    margin-top: 15px;\r\n}\r\n\r\n.progress-bar {\r\n    width: 0%;\r\n    height: 100%;\r\n    background: #f0c400;\r\n    transition: width .2s;\r\n}\r\n\r\n.results {\r\n    display: grid;\r\n    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));\r\n    gap: 24px;\r\n}\r\n\r\n.card {\r\n    position: relative;\r\n    background: #1a1a1d;\r\n    border-radius: 14px;\r\n    overflow: hidden;\r\n    box-shadow: 0 4px 14px rgba(0,0,0,.4);\r\n    transition: transform .25s ease, box-shadow .25s ease;\r\n    display: flex;\r\n    flex-direction: column;\r\n}\r\n\r\n.card:hover {\r\n    transform: translateY(-6px);\r\n    box-shadow: 0 14px 30px rgba(0,0,0,.6);\r\n}\r\n\r\n.poster-wrap {\r\n    position: relative;\r\n    width: 100%;\r\n    aspect-ratio: 2\/3;\r\n    background: #222;\r\n    overflow: hidden;\r\n}\r\n\r\n.poster {\r\n    width: 100%;\r\n    height: 100%;\r\n    object-fit: cover;\r\n    display: block;\r\n    transition: transform .35s ease;\r\n}\r\n\r\n.card:hover .poster { transform: scale(1.06); }\r\n\r\n.year-badge {\r\n    position: absolute;\r\n    top: 10px;\r\n    left: 10px;\r\n    background: rgba(0,0,0,.65);\r\n    backdrop-filter: blur(3px);\r\n    padding: 4px 10px;\r\n    border-radius: 20px;\r\n    font-size: 12px;\r\n    font-weight: bold;\r\n}\r\n\r\n.religious-badge {\r\n    position: absolute;\r\n    top: 10px;\r\n    right: 10px;\r\n    background: rgba(240,196,0,.9);\r\n    color: #111;\r\n    padding: 4px 10px;\r\n    border-radius: 20px;\r\n    font-size: 11px;\r\n    font-weight: bold;\r\n}\r\n\r\n.poster-overlay {\r\n    position: absolute;\r\n    inset: 0;\r\n    background: linear-gradient(to top, rgba(0,0,0,.92) 0%, rgba(0,0,0,.15) 55%, rgba(0,0,0,0) 100%);\r\n    opacity: 0;\r\n    transition: opacity .25s ease;\r\n    display: flex;\r\n    align-items: flex-end;\r\n    padding: 14px;\r\n}\r\n\r\n.card:hover .poster-overlay { opacity: 1; }\r\n\r\n.overlay-btn {\r\n    display: inline-block;\r\n    width: 100%;\r\n    text-align: center;\r\n    padding: 10px;\r\n    background: #f0c400;\r\n    color: #111;\r\n    font-weight: bold;\r\n    text-decoration: none;\r\n    border-radius: 8px;\r\n    font-size: 13px;\r\n}\r\n\r\n.card-content {\r\n    padding: 14px 16px 16px;\r\n    flex: 1;\r\n    display: flex;\r\n    flex-direction: column;\r\n    gap: 6px;\r\n}\r\n\r\n.card h3 {\r\n    margin: 0;\r\n    font-size: 15px;\r\n    line-height: 1.3;\r\n    display: -webkit-box;\r\n    -webkit-line-clamp: 2;\r\n    -webkit-box-orient: vertical;\r\n    overflow: hidden;\r\n}\r\n\r\n.meta-line {\r\n    font-size: 12.5px;\r\n    color: rgba(255,255,255,.65);\r\n    line-height: 1.5;\r\n    display: -webkit-box;\r\n    -webkit-line-clamp: 2;\r\n    -webkit-box-orient: vertical;\r\n    overflow: hidden;\r\n}\r\n\r\n.meta-line b { color: rgba(255,255,255,.9); }\r\n\r\n.card-links {\r\n    margin-top: auto;\r\n    display: flex;\r\n    gap: 8px;\r\n    padding-top: 8px;\r\n}\r\n\r\n.link-primary, .link-secondary {\r\n    text-decoration: none;\r\n    text-align: center;\r\n    border-radius: 7px;\r\n    font-size: 12.5px;\r\n    font-weight: bold;\r\n    padding: 9px 6px;\r\n}\r\n\r\n.link-primary { flex: 2; background: #f0c400; color: #111; }\r\n.link-secondary { flex: 1; background: #2c2c30; color: #fff; }\r\n.link-primary:hover, .link-secondary:hover { opacity: .85; }\r\n\r\n.pagination {\r\n    display: flex;\r\n    justify-content: center;\r\n    align-items: center;\r\n    gap: 15px;\r\n    margin-top: 30px;\r\n    flex-wrap: wrap;\r\n}\r\n\r\n@media (max-width: 700px) {\r\n    .field-row.search-row { grid-template-columns: 1fr; }\r\n}\r\n\r\n<\/style>\r\n<\/head>\r\n\r\n<body>\r\n<div class=\"app\">\r\n\r\n<header>\r\n<h1>\ud83c\udfac Catalogue Films - Wikidata<\/h1>\r\n<p>Recherche directe dans Wikidata \u2014 aucune base locale<\/p>\r\n<\/header>\r\n\r\n<section class=\"search-box\">\r\n\r\n<div class=\"field-row search-row\">\r\n\r\n<div class=\"field\">\r\n<label for=\"search\">Recherche libre<\/label>\r\n<input id=\"search\" type=\"search\" placeholder=\"Mot ou partie de mot...\">\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label for=\"searchCategory\">Rechercher dans<\/label>\r\n<select id=\"searchCategory\">\r\n<option value=\"title\" selected>Titre<\/option>\r\n<option value=\"director\">R\u00e9alisateur<\/option>\r\n<option value=\"cast\">Acteur<\/option>\r\n<option value=\"all\">Titre + r\u00e9alisateur + acteur<\/option>\r\n<\/select>\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label>&nbsp;<\/label>\r\n<button id=\"searchButton\">\ud83d\udd0e Rechercher<\/button>\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"field-row\">\r\n\r\n<div class=\"field\">\r\n<label for=\"dateFilter\">Date de sortie<\/label>\r\n<select id=\"dateFilter\">\r\n<option value=\"all\">Toutes les dates<\/option>\r\n<option value=\"with\">Avec date de sortie<\/option>\r\n<option value=\"without\">Sans date de sortie<\/option>\r\n<\/select>\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label for=\"day\">Derniers jours<\/label>\r\n<input id=\"day\" type=\"number\" placeholder=\"Ex : 7\" min=\"1\">\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label for=\"month\">Derniers mois<\/label>\r\n<input id=\"month\" type=\"number\" placeholder=\"Ex : 7\" min=\"1\">\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label for=\"year\">Ann\u00e9e (2026) ou N derni\u00e8res ann\u00e9es (3)<\/label>\r\n<input id=\"year\" type=\"number\" placeholder=\"Ex : 2026 ou 3\" min=\"1\">\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label for=\"yearFrom\">Ann\u00e9e de (fourchette)<\/label>\r\n<input id=\"yearFrom\" type=\"number\" placeholder=\"De\" min=\"1\">\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label for=\"yearTo\">Ann\u00e9e \u00e0 (fourchette)<\/label>\r\n<input id=\"yearTo\" type=\"number\" placeholder=\"\u00c0\" min=\"1\">\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"field-row\">\r\n\r\n<div class=\"field\">\r\n<label for=\"dateFrom\">Date pr\u00e9cise de d\u00e9but<\/label>\r\n<input id=\"dateFrom\" type=\"date\">\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label for=\"dateTo\">Date pr\u00e9cise de fin<\/label>\r\n<input id=\"dateTo\" type=\"date\">\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"field-row\">\r\n\r\n<div class=\"field\">\r\n<label for=\"titleFilter\">Titre<\/label>\r\n<select id=\"titleFilter\">\r\n<option value=\"all\">Tous les films<\/option>\r\n<option value=\"with\">Avec un titre<\/option>\r\n<option value=\"without\">Sans titre<\/option>\r\n<\/select>\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label for=\"typeFilter\">Type<\/label>\r\n<select id=\"typeFilter\">\r\n<option value=\"film\">Films uniquement<\/option>\r\n<option value=\"all\">Films et \u0153uvres audiovisuelles<\/option>\r\n<\/select>\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label for=\"language\">Langue du titre<\/label>\r\n<select id=\"language\">\r\n<option value=\"fr\" selected>\ud83c\uddeb\ud83c\uddf7 Fran\u00e7ais<\/option>\r\n<option value=\"en\">\ud83c\uddec\ud83c\udde7 Anglais<\/option>\r\n<option value=\"es\">\ud83c\uddea\ud83c\uddf8 Espagnol<\/option>\r\n<option value=\"de\">\ud83c\udde9\ud83c\uddea Allemand<\/option>\r\n<option value=\"it\">\ud83c\uddee\ud83c\uddf9 Italien<\/option>\r\n<option value=\"pt\">\ud83c\uddf5\ud83c\uddf9 Portugais<\/option>\r\n<option value=\"nl\">\ud83c\uddf3\ud83c\uddf1 N\u00e9erlandais<\/option>\r\n<option value=\"ar\">\ud83c\uddf8\ud83c\udde6 Arabe<\/option>\r\n<\/select>\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label for=\"sort\">Tri<\/label>\r\n<select id=\"sort\">\r\n<option value=\"newest\">Plus r\u00e9cents<\/option>\r\n<option value=\"oldest\">Plus anciens<\/option>\r\n<option value=\"title\">Titre A-Z<\/option>\r\n<\/select>\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label for=\"pageSize\">R\u00e9sultats par page<\/label>\r\n<select id=\"pageSize\">\r\n<option value=\"20\" selected>20<\/option>\r\n<option value=\"50\">50<\/option>\r\n<option value=\"100\">100<\/option>\r\n<\/select>\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label for=\"maxResults\">Nombre maxi de r\u00e9sultats<\/label>\r\n<input id=\"maxResults\" type=\"number\" placeholder=\"Illimit\u00e9\" min=\"1\">\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"field-row\">\r\n\r\n<label class=\"toggle-filter\" for=\"religiousFilter\">\r\n<input type=\"checkbox\" id=\"religiousFilter\" checked>\r\n<span>\u271d\ufe0f Films chr\u00e9tiens \/ religieux (genre \/ sujet Wikidata)<\/span>\r\n<\/label>\r\n\r\n<fieldset class=\"lexical-box\">\r\n<legend>\u00c9largir la recherche (mots-cl\u00e9s dans le titre)<\/legend>\r\n<div class=\"lexical-options\">\r\n<label><input type=\"checkbox\" class=\"lexicalKeyword\" value=\"chr\u00e9tien,christian\"> Chr\u00e9tien<\/label>\r\n<label><input type=\"checkbox\" class=\"lexicalKeyword\" value=\"religieux,religious\"> Religieux<\/label>\r\n<label><input type=\"checkbox\" class=\"lexicalKeyword\" value=\"biblique,biblical,bible\"> Biblique<\/label>\r\n<label><input type=\"checkbox\" class=\"lexicalKeyword\" value=\"spirituel,spiritual\"> Spirituel<\/label>\r\n<\/div>\r\n<input\r\n    id=\"lexicalCustom\"\r\n    type=\"text\"\r\n    placeholder=\"Autres mots-cl\u00e9s, s\u00e9par\u00e9s par une virgule (ex : messe, pri\u00e8re)\"\r\n    style=\"margin-top:8px;\"\r\n>\r\n<\/fieldset>\r\n\r\n<div class=\"field\">\r\n<label>&nbsp;<\/label>\r\n<button id=\"cancelButton\" disabled>\u23f9 Annuler<\/button>\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label>&nbsp;<\/label>\r\n<button id=\"resetButton\">\ud83e\uddf9 R\u00e9initialiser<\/button>\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"field-row\">\r\n\r\n<div class=\"field\">\r\n<label for=\"pageInput\">Aller \u00e0 la page<\/label>\r\n<input id=\"pageInput\" type=\"number\" min=\"1\" value=\"1\">\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label>&nbsp;<\/label>\r\n<button id=\"pageButton\">\ud83d\udcc4 Aller \u00e0 la page<\/button>\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label>&nbsp;<\/label>\r\n<button id=\"exportButton\">\u2b07\ufe0f Exporter CSV<\/button>\r\n<\/div>\r\n\r\n<div class=\"field\">\r\n<label>&nbsp;<\/label>\r\n<button id=\"reloadButton\">\ud83d\udd04 Rechercher<\/button>\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n\r\n<div class=\"progress\"><div id=\"progressBar\" class=\"progress-bar\"><\/div><\/div>\r\n\r\n<\/section>\r\n\r\n<div id=\"status\" class=\"status\">Pr\u00eat.<\/div>\r\n\r\n<div id=\"results\" class=\"results\"><\/div>\r\n\r\n<div class=\"pagination\">\r\n<button id=\"previousButton\">\u25c0 Pr\u00e9c\u00e9dent<\/button>\r\n<span id=\"pageInfo\">Page 1 \/ 1<\/span>\r\n<button id=\"nextButton\">Suivant \u25b6<\/button>\r\n<\/div>\r\n\r\n<\/div>\r\n\r\n\r\n<script>\r\n\r\n\/* =========================================================\r\n   CONFIGURATION\r\n========================================================= *\/\r\n\r\nconst WIKIDATA_ENDPOINT = \"https:\/\/query.wikidata.org\/sparql\";\r\n\r\n\/\/ Genre \"Christian film\" \/ \"Bible film\"\r\nconst RELIGIOUS_GENRE_IDS = [\"wd:Q115122793\", \"wd:Q7717463\"];\r\n\r\n\/\/ Sujet principal : Christianisme \/ Bible \/ J\u00e9sus \/ religion\r\nconst RELIGIOUS_SUBJECT_IDS = [\"wd:Q5043\", \"wd:Q1845\", \"wd:Q302\", \"wd:Q9174\"];\r\n\r\n\/\/ Plafond de comptage : au-del\u00e0, on affiche \"N+ r\u00e9sultats\"\r\n\/\/ plut\u00f4t que de lancer un COUNT potentiellement tr\u00e8s co\u00fbteux\r\n\/\/ sur toute la base.\r\nconst COUNT_CAP = 3000;\r\n\r\n\/\/ Image utilis\u00e9e quand un film n'a pas d'affiche sur Wikidata.\r\n\/\/ G\u00e9n\u00e9r\u00e9e en SVG (pas de d\u00e9pendance r\u00e9seau, toujours disponible).\r\nconst DEFAULT_POSTER =\r\n    \"data:image\/svg+xml,\" +\r\n    encodeURIComponent(\r\n        '<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 400 600\">' +\r\n        '<defs><linearGradient id=\"g\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">' +\r\n        '<stop offset=\"0\" stop-color=\"#34343e\"\/>' +\r\n        '<stop offset=\"1\" stop-color=\"#131316\"\/>' +\r\n        '<\/linearGradient><\/defs>' +\r\n        '<rect width=\"400\" height=\"600\" fill=\"url(#g)\"\/>' +\r\n        '<circle cx=\"200\" cy=\"248\" r=\"74\" fill=\"none\" stroke=\"#f0c400\" stroke-width=\"6\" opacity=\"0.9\"\/>' +\r\n        '<polygon points=\"184,210 184,286 250,248\" fill=\"#f0c400\" opacity=\"0.95\"\/>' +\r\n        '<text x=\"200\" y=\"412\" text-anchor=\"middle\" font-family=\"Arial, Helvetica, sans-serif\" ' +\r\n        'font-size=\"42\" font-weight=\"bold\" letter-spacing=\"10\" fill=\"#ffffff\" opacity=\"0.9\">FILM<\/text>' +\r\n        '<\/svg>'\r\n    );\r\n\r\n\/* =========================================================\r\n   VARIABLES\r\n========================================================= *\/\r\n\r\nlet currentPage = 1;\r\nlet totalPages = 1;\r\nlet totalKnown = true;\r\nlet hasNextPageUnknown = false;\r\nlet currentResults = [];\r\nlet abortController = null;\r\nlet isLoading = false;\r\n\r\n\/* =========================================================\r\n   ELEMENTS\r\n========================================================= *\/\r\n\r\nconst searchInput = document.getElementById(\"search\");\r\nconst searchCategory = document.getElementById(\"searchCategory\");\r\nconst dayInput = document.getElementById(\"day\");\r\nconst monthInput = document.getElementById(\"month\");\r\nconst yearInput = document.getElementById(\"year\");\r\nconst yearFromInput = document.getElementById(\"yearFrom\");\r\nconst yearToInput = document.getElementById(\"yearTo\");\r\nconst dateFromInput = document.getElementById(\"dateFrom\");\r\nconst dateToInput = document.getElementById(\"dateTo\");\r\nconst titleFilter = document.getElementById(\"titleFilter\");\r\nconst dateFilter = document.getElementById(\"dateFilter\");\r\nconst sortSelect = document.getElementById(\"sort\");\r\nconst typeFilter = document.getElementById(\"typeFilter\");\r\nconst religiousFilter = document.getElementById(\"religiousFilter\");\r\nconst lexicalCustomInput = document.getElementById(\"lexicalCustom\");\r\nconst languageSelect = document.getElementById(\"language\");\r\nconst pageSizeSelect = document.getElementById(\"pageSize\");\r\nconst maxResultsInput = document.getElementById(\"maxResults\");\r\nconst statusElement = document.getElementById(\"status\");\r\nconst resultsElement = document.getElementById(\"results\");\r\nconst progressBar = document.getElementById(\"progressBar\");\r\nconst cancelButton = document.getElementById(\"cancelButton\");\r\nconst pageInput = document.getElementById(\"pageInput\");\r\nconst previousButton = document.getElementById(\"previousButton\");\r\nconst nextButton = document.getElementById(\"nextButton\");\r\nconst pageInfo = document.getElementById(\"pageInfo\");\r\n\r\n\/* =========================================================\r\n   BLOC DE CONDITIONS PARTAGE\r\n   (utilis\u00e9 \u00e0 la fois par la requ\u00eate de comptage et par la\r\n   requ\u00eate de liste, pour ne jamais les laisser diverger)\r\n========================================================= *\/\r\n\r\n\/* =========================================================\r\n   UTILITAIRES DATE (fen\u00eatres glissantes \"N derniers jours \/\r\n   mois \/ ann\u00e9es\")\r\n========================================================= *\/\r\n\r\nfunction daysAgo(n) {\r\n    const d = new Date();\r\n    d.setDate(d.getDate() - n);\r\n    return d;\r\n}\r\n\r\nfunction monthsAgo(n) {\r\n    const d = new Date();\r\n    d.setMonth(d.getMonth() - n);\r\n    return d;\r\n}\r\n\r\nfunction yearsAgo(n) {\r\n    const d = new Date();\r\n    d.setFullYear(d.getFullYear() - n);\r\n    return d;\r\n}\r\n\r\nfunction buildWhereClause() {\r\n\r\n    const search = searchInput.value.trim();\r\n    const day = dayInput.value.trim();\r\n    const month = monthInput.value.trim();\r\n    const year = yearInput.value.trim();\r\n    const yearFrom = yearFromInput.value.trim();\r\n    const yearTo = yearToInput.value.trim();\r\n    const language = languageSelect.value || \"fr\";\r\n\r\n    \/\/ --- LABEL (langue choisie, fran\u00e7ais par d\u00e9faut) ---\r\n    const labelCondition = `\r\n        ?item rdfs:label ?itemLabel .\r\n        FILTER(LANG(?itemLabel) = \"${language}\")\r\n    `;\r\n\r\n    \/\/ --- TYPE ---\r\n    let typeCondition = `?item wdt:P31 wd:Q11424 .`;\r\n\r\n    if (typeFilter.value === \"all\") {\r\n        typeCondition = `\r\n            { ?item wdt:P31 wd:Q11424 . }\r\n            UNION\r\n            { ?item wdt:P31 ?type . ?type wdt:P279* wd:Q11424 . }\r\n        `;\r\n    }\r\n\r\n    \/\/ --- THEME RELIGIEUX (filtre structur\u00e9 + mots-cl\u00e9s) ---\r\n    const lexicalKeywords =\r\n        Array.from(document.querySelectorAll(\".lexicalKeyword:checked\"))\r\n            .flatMap(cb => cb.value.split(\",\"));\r\n\r\n    const customKeywordsRaw = lexicalCustomInput.value.trim();\r\n\r\n    if (customKeywordsRaw) {\r\n        customKeywordsRaw\r\n            .split(\",\")\r\n            .map(word => word.trim())\r\n            .filter(Boolean)\r\n            .forEach(word => lexicalKeywords.push(word));\r\n    }\r\n\r\n    const hasLexicalFilter = lexicalKeywords.length > 0;\r\n\r\n    let religiousCondition = \"\";\r\n\r\n    if (religiousFilter.checked || hasLexicalFilter) {\r\n\r\n        const branches = [];\r\n\r\n        if (religiousFilter.checked) {\r\n            branches.push(`\r\n                {\r\n                    ?item wdt:P136 ?religiousGenre .\r\n                    VALUES ?religiousGenre { ${RELIGIOUS_GENRE_IDS.join(\" \")} }\r\n                }\r\n            `);\r\n            branches.push(`\r\n                {\r\n                    ?item wdt:P921 ?religiousSubject .\r\n                    VALUES ?religiousSubject { ${RELIGIOUS_SUBJECT_IDS.join(\" \")} }\r\n                }\r\n            `);\r\n        }\r\n\r\n        if (hasLexicalFilter) {\r\n            const lexicalOr = lexicalKeywords\r\n                .map(word => `CONTAINS(LCASE(STR(?itemLabel)), LCASE(\"${word.replace(\/\"\/g, '\\\\\"')}\"))`)\r\n                .join(\" || \");\r\n\r\n            branches.push(`{ FILTER(${lexicalOr}) }`);\r\n        }\r\n\r\n        religiousCondition = branches.join(\" UNION \");\r\n    }\r\n\r\n    \/\/ --- RECHERCHE PAR CATEGORIE ---\r\n    let searchCondition = \"\";\r\n\r\n    if (search) {\r\n\r\n        const safeSearch = search.replace(\/\"\/g, '\\\\\"');\r\n        const category = searchCategory.value || \"title\";\r\n\r\n        const titleMatch = `CONTAINS(LCASE(STR(?itemLabel)), LCASE(\"${safeSearch}\"))`;\r\n\r\n        const directorBlock = `\r\n            ?item wdt:P57 ?searchDirector .\r\n            ?searchDirector rdfs:label ?searchDirectorLabel .\r\n            FILTER(LANG(?searchDirectorLabel) IN (\"fr\",\"en\"))\r\n            FILTER(CONTAINS(LCASE(STR(?searchDirectorLabel)), LCASE(\"${safeSearch}\")))\r\n        `;\r\n\r\n        const castBlock = `\r\n            ?item wdt:P161 ?searchCast .\r\n            ?searchCast rdfs:label ?searchCastLabel .\r\n            FILTER(LANG(?searchCastLabel) IN (\"fr\",\"en\"))\r\n            FILTER(CONTAINS(LCASE(STR(?searchCastLabel)), LCASE(\"${safeSearch}\")))\r\n        `;\r\n\r\n        if (category === \"title\") {\r\n            searchCondition = `FILTER(${titleMatch})`;\r\n        }\r\n        else if (category === \"director\") {\r\n            searchCondition = directorBlock;\r\n        }\r\n        else if (category === \"cast\") {\r\n            searchCondition = castBlock;\r\n        }\r\n        else {\r\n            searchCondition = `\r\n                { FILTER(${titleMatch}) }\r\n                UNION\r\n                { ${directorBlock} }\r\n                UNION\r\n                { ${castBlock} }\r\n            `;\r\n        }\r\n    }\r\n\r\n    \/\/ --- DATE ---\r\n    \/\/ Priorit\u00e9 : fourchette pr\u00e9cise (jour+mois+ann\u00e9e exacts) >\r\n    \/\/            fourchette d'ann\u00e9es > champs jour\/mois\/ann\u00e9e.\r\n    const dateFrom = dateFromInput.value;\r\n    const dateTo = dateToInput.value;\r\n\r\n    const hasFullDateRange = Boolean(dateFrom || dateTo);\r\n    const hasYearRange = Boolean(yearFrom || yearTo);\r\n    const hasRollingFilter = Boolean(day || month || year);\r\n\r\n    const hasDateFilter = hasFullDateRange || hasYearRange || hasRollingFilter;\r\n\r\n    let dateVariable = `OPTIONAL{ ?item wdt:P577 ?date . }`;\r\n\r\n    if (dateFilter.value === \"with\" || hasDateFilter) {\r\n        dateVariable = `?item wdt:P577 ?date .`;\r\n    }\r\n\r\n    if (dateFilter.value === \"without\") {\r\n        dateVariable = `FILTER NOT EXISTS{ ?item wdt:P577 ?anyDate . }`;\r\n    }\r\n\r\n    let dateFilterCondition = \"\";\r\n\r\n    if (hasDateFilter && dateFilter.value !== \"without\") {\r\n\r\n        const conditions = [];\r\n\r\n        if (hasFullDateRange) {\r\n\r\n            \/\/ Fourchette de dates pr\u00e9cises (ex : 05\/05\/2024 -> 31\/07\/2026)\r\n            if (dateFrom) conditions.push(`?date >= \"${dateFrom}T00:00:00Z\"^^xsd:dateTime`);\r\n            if (dateTo) conditions.push(`?date <= \"${dateTo}T23:59:59Z\"^^xsd:dateTime`);\r\n        }\r\n        else if (hasYearRange) {\r\n\r\n            \/\/ Fourchette d'ann\u00e9es (ex : 2022 -> 2026)\r\n            if (yearFrom) conditions.push(`YEAR(?date) >= ${Number(yearFrom)}`);\r\n            if (yearTo) conditions.push(`YEAR(?date) <= ${Number(yearTo)}`);\r\n        }\r\n        else {\r\n\r\n            const now = new Date();\r\n            const nowIso = now.toISOString();\r\n\r\n            \/\/ \"Jour\" = N derniers jours (fen\u00eatre glissante)\r\n            if (day) {\r\n                conditions.push(`?date >= \"${daysAgo(Number(day)).toISOString()}\"^^xsd:dateTime`);\r\n                conditions.push(`?date <= \"${nowIso}\"^^xsd:dateTime`);\r\n            }\r\n\r\n            \/\/ \"Mois\" = N derniers mois (fen\u00eatre glissante)\r\n            if (month) {\r\n                conditions.push(`?date >= \"${monthsAgo(Number(month)).toISOString()}\"^^xsd:dateTime`);\r\n                conditions.push(`?date <= \"${nowIso}\"^^xsd:dateTime`);\r\n            }\r\n\r\n            \/\/ \"Ann\u00e9e\" : un nombre qui ressemble \u00e0 une vraie ann\u00e9e\r\n            \/\/ (>= 100) est trait\u00e9 comme une ann\u00e9e pr\u00e9cise (ex : 2026).\r\n            \/\/ Un petit nombre (< 100) est trait\u00e9 comme \"N derni\u00e8res\r\n            \/\/ ann\u00e9es\" (ex : 3 -> 3 derni\u00e8res ann\u00e9es).\r\n            if (year) {\r\n\r\n                const yearNumber = Number(year);\r\n\r\n                if (yearNumber >= 100) {\r\n                    conditions.push(`YEAR(?date) = ${yearNumber}`);\r\n                }\r\n                else {\r\n                    conditions.push(`?date >= \"${yearsAgo(yearNumber).toISOString()}\"^^xsd:dateTime`);\r\n                    conditions.push(`?date <= \"${nowIso}\"^^xsd:dateTime`);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (conditions.length) {\r\n            dateFilterCondition = `FILTER(${conditions.join(\" && \")})`;\r\n        }\r\n    }\r\n\r\n    return `\r\n        ${typeCondition}\r\n        ${labelCondition}\r\n        ${religiousCondition}\r\n        ${searchCondition}\r\n        ${dateVariable}\r\n        ${dateFilterCondition}\r\n    `;\r\n}\r\n\r\n\/* =========================================================\r\n   REQUETE DE COMPTAGE\r\n\r\n   Compte les films correspondant aux filtres, plafonn\u00e9 \u00e0\r\n   COUNT_CAP pour rester rapide m\u00eame sur une recherche large.\r\n========================================================= *\/\r\n\r\nfunction buildCountQuery() {\r\n\r\n    const where = buildWhereClause();\r\n\r\n    return `\r\n        PREFIX xsd: <http:\/\/www.w3.org\/2001\/XMLSchema#>\r\n        SELECT (COUNT(*) AS ?count) WHERE {\r\n            SELECT DISTINCT ?item WHERE{ ${where} }\r\n            LIMIT ${COUNT_CAP}\r\n        }\r\n    `;\r\n}\r\n\r\n\/* =========================================================\r\n   REQUETE DE LISTE (l\u00e9g\u00e8re, pagination r\u00e9elle)\r\n========================================================= *\/\r\n\r\nfunction buildListQuery(limit, offset) {\r\n\r\n    const where = buildWhereClause();\r\n\r\n    let order = \"DESC(?date)\";\r\n    if (sortSelect.value === \"oldest\") order = \"ASC(?date)\";\r\n    if (sortSelect.value === \"title\") order = \"LCASE(STR(?itemLabel))\";\r\n\r\n    return `\r\n        PREFIX xsd: <http:\/\/www.w3.org\/2001\/XMLSchema#>\r\n        SELECT DISTINCT ?item ?itemLabel ?date\r\n        WHERE{ ${where} }\r\n        ORDER BY ${order}\r\n        LIMIT ${limit}\r\n        OFFSET ${offset}\r\n    `;\r\n}\r\n\r\n\/* =========================================================\r\n   REQUETE D'ENRICHISSEMENT\r\n   (affiche, r\u00e9alisateur, casting, liens \u2014 uniquement pour\r\n   les films de la page affich\u00e9e)\r\n========================================================= *\/\r\n\r\nfunction buildDetailsQuery(itemUris) {\r\n\r\n    const values = itemUris.map(uri => `<${uri}>`).join(\" \");\r\n\r\n    return `\r\n        SELECT ?item\r\n               (SAMPLE(?poster) AS ?poster)\r\n               (SAMPLE(?image) AS ?image)\r\n               (GROUP_CONCAT(DISTINCT ?directorLabel; separator=\", \") AS ?directors)\r\n               (GROUP_CONCAT(DISTINCT ?castLabel; separator=\", \") AS ?cast)\r\n               (SAMPLE(?website) AS ?website)\r\n               (SAMPLE(?imdb) AS ?imdb)\r\n        WHERE{\r\n            VALUES ?item { ${values} }\r\n            OPTIONAL{ ?item wdt:P3383 ?poster . }\r\n            OPTIONAL{ ?item wdt:P18 ?image . }\r\n            OPTIONAL{\r\n                ?item wdt:P57 ?director .\r\n                ?director rdfs:label ?directorLabel .\r\n                FILTER(LANG(?directorLabel) IN (\"fr\",\"en\"))\r\n            }\r\n            OPTIONAL{\r\n                ?item wdt:P161 ?cast .\r\n                ?cast rdfs:label ?castLabel .\r\n                FILTER(LANG(?castLabel) IN (\"fr\",\"en\"))\r\n            }\r\n            OPTIONAL{ ?item wdt:P856 ?website . }\r\n            OPTIONAL{\r\n                ?item wdt:P345 ?imdbId .\r\n                BIND(CONCAT(\"https:\/\/www.imdb.com\/title\/\", ?imdbId) AS ?imdb)\r\n            }\r\n        }\r\n        GROUP BY ?item\r\n    `;\r\n}\r\n\r\n\/* =========================================================\r\n   REQUETE AVEC RETRY (POST, pour \u00e9viter les URL trop longues)\r\n========================================================= *\/\r\n\r\nasync function fetchWikidata(query, attempt = 0) {\r\n\r\n    const response = await fetch(WIKIDATA_ENDPOINT, {\r\n        method: \"POST\",\r\n        headers: {\r\n            \"Content-Type\": \"application\/x-www-form-urlencoded\",\r\n            \"Accept\": \"application\/sparql-results+json\"\r\n        },\r\n        body: \"query=\" + encodeURIComponent(query),\r\n        signal: abortController.signal\r\n    });\r\n\r\n    if ([429, 502, 503, 504].includes(response.status)) {\r\n\r\n        if (attempt < 3) {\r\n\r\n            const delay = (attempt + 1) * 2500;\r\n\r\n            statusElement.textContent =\r\n                \"\u23f3 Wikidata est temporairement charg\u00e9. Nouvelle tentative dans \"\r\n                + (delay \/ 1000) + \" secondes...\";\r\n\r\n            await new Promise(resolve => setTimeout(resolve, delay));\r\n\r\n            return fetchWikidata(query, attempt + 1);\r\n        }\r\n    }\r\n\r\n    if (!response.ok) {\r\n        throw new Error(\"Erreur HTTP \" + response.status);\r\n    }\r\n\r\n    return response.json();\r\n}\r\n\r\n\/* =========================================================\r\n   RECHERCHE (comptage -> liste -> enrichissement)\r\n========================================================= *\/\r\n\r\nasync function searchWikidata() {\r\n\r\n    if (isLoading) return;\r\n\r\n    isLoading = true;\r\n    abortController = new AbortController();\r\n    cancelButton.disabled = false;\r\n    progressBar.style.width = \"10%\";\r\n    resultsElement.innerHTML = \"\";\r\n    statusElement.textContent = \"\u23f3 Pr\u00e9paration de la recherche...\";\r\n\r\n    try {\r\n\r\n        if (titleFilter.value === \"without\") {\r\n            currentResults = [];\r\n            totalPages = 1;\r\n            statusElement.textContent =\r\n                \"\u26a0\ufe0f Wikidata ne permet pas de r\u00e9cup\u00e9rer fiablement les films \"\r\n                + \"sans titre dans cette requ\u00eate l\u00e9g\u00e8re.\";\r\n            renderResults();\r\n            return;\r\n        }\r\n\r\n        const pageSize = Number(pageSizeSelect.value) || 20;\r\n\r\n        const maxResultsRaw = maxResultsInput.value.trim();\r\n        const maxResults = maxResultsRaw ? Math.max(1, Number(maxResultsRaw)) : null;\r\n\r\n        \/* --- ETAPE 1 : comptage total (si possible) --- *\/\r\n\r\n        statusElement.textContent = \"\u23f3 Comptage des r\u00e9sultats...\";\r\n        progressBar.style.width = \"20%\";\r\n\r\n        let rawCount = null;\r\n        let cappedAtLimit = false;\r\n        let effectiveTotal = null;\r\n\r\n        try {\r\n            const countData = await fetchWikidata(buildCountQuery());\r\n            rawCount = Number(countData.results.bindings[0]?.count?.value || 0);\r\n            cappedAtLimit = rawCount >= COUNT_CAP;\r\n        }\r\n        catch (countError) {\r\n\r\n            if (countError.name === \"AbortError\") {\r\n                throw countError;\r\n            }\r\n\r\n            \/*\r\n            -------------------------------------------------\r\n            Le comptage peut \u00e9chouer (timeout, 500...) sur une\r\n            recherche trop large et peu s\u00e9lective (ex. \"tous\r\n            les films en fran\u00e7ais\", sans aucun filtre). Dans\r\n            ce cas on NE FAIT PAS \u00e9chouer toute la recherche :\r\n            on bascule sur l'ancien mode \"page par page sans\r\n            total connu\".\r\n            -------------------------------------------------\r\n            *\/\r\n\r\n            console.warn(\"Comptage indisponible, repli sans total exact :\", countError);\r\n\r\n            rawCount = null;\r\n        }\r\n\r\n        totalKnown = rawCount !== null;\r\n\r\n        if (totalKnown) {\r\n\r\n            effectiveTotal = maxResults ? Math.min(rawCount, maxResults) : rawCount;\r\n            totalPages = Math.max(1, Math.ceil(effectiveTotal \/ pageSize));\r\n\r\n            if (currentPage > totalPages) {\r\n                currentPage = totalPages;\r\n            }\r\n\r\n            if (effectiveTotal === 0) {\r\n                currentResults = [];\r\n                progressBar.style.width = \"100%\";\r\n                statusElement.textContent = \"\u274c Aucun r\u00e9sultat.\";\r\n                renderResults();\r\n                return;\r\n            }\r\n        }\r\n        else {\r\n            totalPages = Math.max(totalPages, currentPage);\r\n        }\r\n\r\n        \/* --- ETAPE 2 : liste des films de la page courante --- *\/\r\n\r\n        statusElement.textContent = \"\u23f3 Recherche des films...\";\r\n        progressBar.style.width = \"40%\";\r\n\r\n        const offset = (currentPage - 1) * pageSize;\r\n\r\n        let limit = pageSize;\r\n\r\n        if (maxResults) {\r\n            limit = Math.min(pageSize, Math.max(0, maxResults - offset));\r\n        }\r\n\r\n        \/\/ Si le total est inconnu, on demande un r\u00e9sultat de plus\r\n        \/\/ pour savoir s'il existe une page suivante.\r\n        const fetchLimit = totalKnown ? limit : limit + 1;\r\n\r\n        const listData = await fetchWikidata(buildListQuery(fetchLimit, offset));\r\n        let listRows = listData.results.bindings;\r\n\r\n        if (!totalKnown) {\r\n            hasNextPageUnknown = listRows.length > limit;\r\n            listRows = listRows.slice(0, limit);\r\n            totalPages = hasNextPageUnknown ? currentPage + 1 : currentPage;\r\n        }\r\n\r\n        progressBar.style.width = \"60%\";\r\n\r\n        if (listRows.length === 0) {\r\n            currentResults = [];\r\n            progressBar.style.width = \"100%\";\r\n            statusElement.textContent = \"\u274c Aucun r\u00e9sultat sur cette page.\";\r\n            renderResults();\r\n            return;\r\n        }\r\n\r\n        \/* --- ETAPE 3 : enrichissement (affiche, casting, liens) --- *\/\r\n\r\n        statusElement.textContent = \"\u23f3 R\u00e9cup\u00e9ration des affiches et informations...\";\r\n\r\n        const itemUris = listRows.map(row => row.item.value);\r\n        const detailsData = await fetchWikidata(buildDetailsQuery(itemUris));\r\n\r\n        const detailsByUri = {};\r\n        detailsData.results.bindings.forEach(row => {\r\n            detailsByUri[row.item.value] = row;\r\n        });\r\n\r\n        progressBar.style.width = \"90%\";\r\n\r\n        currentResults = listRows.map(row => convertResult(row, detailsByUri[row.item.value]));\r\n\r\n        progressBar.style.width = \"100%\";\r\n\r\n        let statusMessage;\r\n\r\n        if (totalKnown) {\r\n\r\n            statusMessage = \"\u2705 \" + effectiveTotal + \" r\u00e9sultat(s) trouv\u00e9(s)\";\r\n\r\n            if (cappedAtLimit && !maxResults) {\r\n                statusMessage += \" (au moins \" + COUNT_CAP + \" \u2014 affinez la recherche pour un compte exact)\";\r\n            }\r\n        }\r\n        else {\r\n            statusMessage =\r\n                \"\u2705 \" + listRows.length + \" r\u00e9sultat(s) affich\u00e9(s) \"\r\n                + \"(recherche trop large pour calculer un total exact \u2014 \"\r\n                + \"affinez avec un filtre pour l'obtenir)\";\r\n        }\r\n\r\n        statusElement.textContent = statusMessage + \".\";\r\n\r\n        renderResults();\r\n\r\n    }\r\n    catch (error) {\r\n\r\n        if (error.name === \"AbortError\") {\r\n            statusElement.textContent = \"\u23f9 Recherche annul\u00e9e.\";\r\n        }\r\n        else {\r\n            console.error(\"Wikidata :\", error);\r\n            statusElement.textContent = \"\u274c Impossible d'interroger Wikidata : \" + error.message;\r\n        }\r\n    }\r\n    finally {\r\n        isLoading = false;\r\n        cancelButton.disabled = true;\r\n        abortController = null;\r\n    }\r\n}\r\n\r\n\/* =========================================================\r\n   CONVERSION (fusion ligne liste + ligne d\u00e9tails)\r\n========================================================= *\/\r\n\r\nfunction convertResult(listRow, detailsRow) {\r\n\r\n    const details = detailsRow || {};\r\n\r\n    const poster = details.poster\r\n        ? details.poster.value\r\n        : (details.image ? details.image.value : \"\");\r\n\r\n    const website = details.website ? details.website.value : \"\";\r\n    const imdb = details.imdb ? details.imdb.value : \"\";\r\n    const uri = listRow.item ? listRow.item.value : \"\";\r\n\r\n    \/\/ Priorit\u00e9 : site officiel > IMDb > fiche Wikidata\r\n    const primaryLink = website || imdb || uri;\r\n\r\n    return {\r\n        uri,\r\n        title: listRow.itemLabel ? listRow.itemLabel.value : \"\",\r\n        poster,\r\n        directors: details.directors ? details.directors.value : \"\",\r\n        cast: details.cast ? details.cast.value : \"\",\r\n        date: listRow.date ? listRow.date.value : \"\",\r\n        website,\r\n        imdb,\r\n        primaryLink\r\n    };\r\n}\r\n\r\n\/* =========================================================\r\n   AFFICHAGE\r\n========================================================= *\/\r\n\r\nfunction renderResults() {\r\n\r\n    resultsElement.innerHTML = \"\";\r\n\r\n    const isReligiousSearch =\r\n        religiousFilter.checked\r\n        || document.querySelectorAll(\".lexicalKeyword:checked\").length > 0;\r\n\r\n    currentResults.forEach(film => {\r\n\r\n        const card = document.createElement(\"article\");\r\n        card.className = \"card\";\r\n\r\n        const year = film.date ? new Date(film.date).getFullYear() : \"\";\r\n\r\n        const castList = film.cast\r\n            ? film.cast.split(\", \").slice(0, 4).join(\", \")\r\n            : \"\";\r\n\r\n        card.innerHTML = `\r\n\r\n            <div class=\"poster-wrap\">\r\n\r\n                <img decoding=\"async\" class=\"poster\" src=\"${film.poster || DEFAULT_POSTER}\"\r\n                     alt=\"${escapeHTML(film.title)}\" loading=\"lazy\">\r\n\r\n                ${year ? `<div class=\"year-badge\">${year}<\/div>` : \"\"}\r\n\r\n                ${isReligiousSearch ? `<div class=\"religious-badge\">\u271d\ufe0f Religieux<\/div>` : \"\"}\r\n\r\n                <a class=\"poster-overlay\" href=\"${film.primaryLink}\" target=\"_blank\" rel=\"noopener\">\r\n                    <span class=\"overlay-btn\">\u25b6 Voir le film<\/span>\r\n                <\/a>\r\n\r\n            <\/div>\r\n\r\n            <div class=\"card-content\">\r\n\r\n                <h3>${escapeHTML(film.title || \"Titre non renseign\u00e9\")}<\/h3>\r\n\r\n                ${film.directors ? `<div class=\"meta-line\"><b>R\u00e9alisation :<\/b> ${escapeHTML(film.directors)}<\/div>` : \"\"}\r\n\r\n                ${castList ? `<div class=\"meta-line\"><b>Avec :<\/b> ${escapeHTML(castList)}<\/div>` : \"\"}\r\n\r\n                <div class=\"meta-line\">\ud83d\udcc5 ${formatDate(film.date)}<\/div>\r\n\r\n                <div class=\"card-links\">\r\n                    <a class=\"link-primary\" href=\"${film.primaryLink}\" target=\"_blank\" rel=\"noopener\">\u25b6 Voir le film<\/a>\r\n                    <a class=\"link-secondary\" href=\"${film.uri}\" target=\"_blank\" rel=\"noopener\">Wikidata<\/a>\r\n                <\/div>\r\n\r\n            <\/div>\r\n        `;\r\n\r\n        resultsElement.appendChild(card);\r\n    });\r\n\r\n    updatePagination();\r\n}\r\n\r\n\/* =========================================================\r\n   PAGINATION\r\n========================================================= *\/\r\n\r\nfunction updatePagination() {\r\n\r\n    if (totalKnown) {\r\n        pageInfo.textContent = \"Page \" + currentPage + \" \/ \" + totalPages;\r\n        previousButton.disabled = currentPage <= 1;\r\n        nextButton.disabled = currentPage >= totalPages;\r\n        pageInput.max = totalPages;\r\n    }\r\n    else {\r\n        pageInfo.textContent = \"Page \" + currentPage + \" (total non calcul\u00e9)\";\r\n        previousButton.disabled = currentPage <= 1;\r\n        nextButton.disabled = !hasNextPageUnknown;\r\n        pageInput.removeAttribute(\"max\");\r\n    }\r\n}\r\n\r\n\/* =========================================================\r\n   DATE \/ SECURITE\r\n========================================================= *\/\r\n\r\nfunction formatDate(date) {\r\n\r\n    if (!date) return \"Date non renseign\u00e9e\";\r\n\r\n    const d = new Date(date);\r\n\r\n    if (isNaN(d)) return date;\r\n\r\n    return d.toLocaleDateString(\"fr-FR\");\r\n}\r\n\r\nfunction escapeHTML(value) {\r\n    const div = document.createElement(\"div\");\r\n    div.textContent = value ? String(value) : \"\";\r\n    return div.innerHTML;\r\n}\r\n\r\n\/* =========================================================\r\n   EVENEMENTS\r\n========================================================= *\/\r\n\r\ncancelButton.addEventListener(\"click\", function () {\r\n    if (abortController) abortController.abort();\r\n});\r\n\r\ndocument.getElementById(\"searchButton\").addEventListener(\"click\", function () {\r\n    currentPage = 1;\r\n    searchWikidata();\r\n});\r\n\r\nsearchInput.addEventListener(\"keydown\", function (event) {\r\n    if (event.key === \"Enter\") {\r\n        currentPage = 1;\r\n        searchWikidata();\r\n    }\r\n});\r\n\r\nnextButton.addEventListener(\"click\", function () {\r\n    if (currentPage < totalPages) {\r\n        currentPage++;\r\n        searchWikidata();\r\n    }\r\n});\r\n\r\npreviousButton.addEventListener(\"click\", function () {\r\n    if (currentPage > 1) {\r\n        currentPage--;\r\n        searchWikidata();\r\n    }\r\n});\r\n\r\ndocument.getElementById(\"pageButton\").addEventListener(\"click\", function () {\r\n    let page = Number(pageInput.value);\r\n    if (page < 1) page = 1;\r\n    if (page > totalPages) page = totalPages;\r\n    currentPage = page;\r\n    searchWikidata();\r\n});\r\n\r\ndocument.getElementById(\"reloadButton\").addEventListener(\"click\", searchWikidata);\r\n\r\ndocument.getElementById(\"resetButton\").addEventListener(\"click\", function () {\r\n\r\n    if (isLoading && abortController) abortController.abort();\r\n\r\n    searchInput.value = \"\";\r\n    searchCategory.value = \"title\";\r\n    dayInput.value = \"\";\r\n    monthInput.value = \"\";\r\n    yearInput.value = \"\";\r\n    yearFromInput.value = \"\";\r\n    yearToInput.value = \"\";\r\n    dateFromInput.value = \"\";\r\n    dateToInput.value = \"\";\r\n    titleFilter.value = \"all\";\r\n    dateFilter.value = \"all\";\r\n    typeFilter.value = \"film\";\r\n    languageSelect.value = \"fr\";\r\n    religiousFilter.checked = true;\r\n\r\n    document.querySelectorAll(\".lexicalKeyword\").forEach(cb => { cb.checked = false; });\r\n    lexicalCustomInput.value = \"\";\r\n\r\n    sortSelect.value = \"newest\";\r\n    pageSizeSelect.value = \"20\";\r\n    maxResultsInput.value = \"\";\r\n\r\n    currentPage = 1;\r\n    totalPages = 1;\r\n    totalKnown = true;\r\n    hasNextPageUnknown = false;\r\n    currentResults = [];\r\n\r\n    resultsElement.innerHTML = \"\";\r\n    progressBar.style.width = \"0%\";\r\n    pageInput.value = 1;\r\n    pageInfo.textContent = \"Page 1 \/ 1\";\r\n\r\n    statusElement.textContent = \"Filtres r\u00e9initialis\u00e9s.\";\r\n});\r\n\r\ndocument.getElementById(\"exportButton\").addEventListener(\"click\", function () {\r\n\r\n    if (currentResults.length === 0) {\r\n        alert(\"Aucun r\u00e9sultat \u00e0 exporter.\");\r\n        return;\r\n    }\r\n\r\n    const header = [\"Titre\", \"R\u00e9alisateur(s)\", \"Casting\", \"Date\", \"Lien\", \"Wikidata\"];\r\n\r\n    const rows = currentResults.map(film => [\r\n        film.title, film.directors, film.cast, film.date, film.primaryLink, film.uri\r\n    ]);\r\n\r\n    const csv = [header, ...rows]\r\n        .map(row => row.map(value =>\r\n            '\"' + String(value || \"\").replace(\/\"\/g, '\"\"') + '\"'\r\n        ).join(\";\"))\r\n        .join(\"\\n\");\r\n\r\n    const blob = new Blob([\"\\ufeff\" + csv], { type: \"text\/csv;charset=utf-8\" });\r\n    const url = URL.createObjectURL(blob);\r\n    const link = document.createElement(\"a\");\r\n    link.href = url;\r\n    link.download = \"films-wikidata.csv\";\r\n    link.click();\r\n    URL.revokeObjectURL(url);\r\n});\r\n\r\n\/* On ne lance pas de requ\u00eate automatique au chargement. *\/\r\n\r\nstatusElement.textContent = \"Pr\u00eat. Entrez un terme ou lancez une recherche.\";\r\n\r\n<\/script>\r\n\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Bienvenue sur Alliance en J\u00e9sus Bienvenue sur Alliance en J\u00e9sus Une Alliance Eternelle Parce que Le Seigneur t&rsquo;aime et te consid\u00e8re comme la prunelle de ses yeux, viens et approche toi de L&rsquo;ETERNEL DIEU. Louanges et adorations : Rejoignez-nous dans cette gr\u00e2ce de pouvoir louer et glorifier l&rsquo;ETERNEL DIEU et soyez fortifi\u00e9s par les messages d&rsquo;encouragements ! L&rsquo;Eglise Evang\u00e9lique de la Guyane vous re\u00e7oit dans ses sept Eglises pour partager notre communion Chr\u00e9tienne.\u00a0\u00a0 \u271d\ufe0f Bible Blocks Score : 0 Niveau : 1 Lignes : 0 \u00ab\u00a0Je puis tout par celui qui me fortifie.\u00a0\u00bb Philippiens 4:13 Jouer Nous vous invitons \u00e0 prendre part \u00e0 nos conf\u00e9rences et s\u00e9minaires tout au long de l&rsquo;ann\u00e9e. Contactez-nous pour plus de renseignement et nous nous ferons un immense plaisir de vous r\u00e9pondre. BAPTEME Celui qui croira sera baptis\u00e9 au nom du P\u00e8re, du Fils et du Saint-Esprit. Cet acte symbolise notre mort au p\u00e9ch\u00e9 et une vie nouvelle en JESUS-CHRIST. Fuyez le jugement \u00e0 venir et la col\u00e8re de DIEU. ACCES RAPIDE Planning des Absences \ud83d\udcc5 Planning des Absences des Membres Ajouter une absence Cong\u00e9MaladieT\u00e9l\u00e9travailAutre Ajouter Recherche \ud83d\udd0e Filtres R\u00e9initialiser Calendrier Liste des absences Membre \u00c9glise Fonction Service Type D\u00e9but Fin Dur\u00e9e Action Statistiques Total absences 0 Jours cumul\u00e9s 0 Exploration de J\u00e9rusalem \ud83d\uddfa\ufe0f Exploration de J\u00e9rusalem Explorez J\u00e9rusalem et d\u00e9couvrez ses lieux bibliques. \ud83d\ude97 Choisissez votre moyen de transport \ud83d\udeb6 Marche \ud83d\udeb2 V\u00e9lo \ud83c\udfcd\ufe0f Moto \ud83d\ude97 Voiture \ud83d\uddfa\ufe0f Choisissez votre vue \ud83d\uddfa\ufe0f Plan \ud83d\udef0\ufe0f Satellite \ud83d\udef0\ufe0f Hybride \ud83d\udd0e Vue d\u00e9taill\u00e9e \ud83c\udf0d Vue globale Mode : Marche &nbsp; | &nbsp; Direction : Nord \u2705 Carte pr\u00eate. Utilisez les fl\u00e8ches pour vous d\u00e9placer. 1\ufe0f\u20e3 \u2b06\ufe0f \u2b05\ufe0f \u23f9\ufe0f \u27a1\ufe0f \u2b07\ufe0f 2\ufe0f\u20e3 \u00ab\u00a0`html Jeu des livres de la Bible \ud83d\udcd6 Les livres de la Bible \ud83d\uddb1\ufe0f Fais glisser un livre avec la souris. \ud83d\udcf1 Sur t\u00e9l\u00e9phone ou tablette, fais glisser avec ton doigt. Tu peux d\u00e9placer les livres autant de fois que n\u00e9cessaire. Pour retirer un livre d&rsquo;un Testament, fais-le glisser vers la zone \ud83d\udcda Livres disponibles. \ud83c\udfae Choisis ton jeu \ud83d\udcd6 Toute la Bible 66 livres \ud83d\udcdc Ancien Testament 39 livres \u271d\ufe0f Nouveau Testament 27 livres \ud83c\udfc6 Score : 0 \/ 66 \ud83d\udcda Livres plac\u00e9s : 0 \/ 66 Commence par d\u00e9placer un livre. \ud83d\udcda Livres disponibles Liste alphab\u00e9tique Glisse un livre vers le Testament. Pour retirer un livre plac\u00e9, glisse-le ici. \ud83d\udcdc Ancien Testament 39 livres \u271d\ufe0f Nouveau Testament 27 livres \ud83c\udf89 F\u00e9licitations ! Tu as termin\u00e9 le jeu. \ud83c\udfc6 Score final \ud83d\udd04 Recommencer \u00ab\u00a0` \u00ab\u00a0`html La Bible en BD \u2014 \u00c9vangile selon Matthieu \ud83d\udcd6 La Bible en BD L&rsquo;\u00c9vangile selon Matthieu Accueil \u00c9pisodes Lire la BD \u271d\ufe0f L&rsquo;\u00c9vangile selon Matthieu Bienvenue dans cette adaptation en bande dessin\u00e9e de l&rsquo;\u00c9vangile selon Matthieu. Cette s\u00e9rie pr\u00e9sente les principaux \u00e9v\u00e9nements racont\u00e9s dans le livre de Matthieu, depuis la g\u00e9n\u00e9alogie et la naissance de J\u00e9sus jusqu&rsquo;\u00e0 sa r\u00e9surrection et \u00e0 la Grande Mission donn\u00e9e aux disciples. Chaque \u00e9pisode indique les r\u00e9f\u00e9rences bibliques correspondantes afin de permettre au lecteur de retrouver le passage dans le texte biblique. \ud83d\udcda Les \u00e9pisodes \u00c9pisode 1 La g\u00e9n\u00e9alogie et la naissance de J\u00e9sus Matthieu 1 \u00c9pisode 2 Les mages et la fuite en \u00c9gypte Matthieu 2 \u00c9pisode 3 Jean-Baptiste et le bapt\u00eame de J\u00e9sus Matthieu 3 \u00c9pisode 4 La tentation de J\u00e9sus Matthieu 4 \u00c9pisode 5 L&rsquo;appel des premiers disciples Matthieu 4 \u00c9pisode 6 Le Sermon sur la montagne Matthieu 5\u20137 \u00c9pisode 7 Les miracles de J\u00e9sus Matthieu 8\u20139 \u00c9pisode 8 L&rsquo;envoi des douze disciples Matthieu 10 \u00c9pisode 9 Les paraboles du Royaume Matthieu 13 \u00c9pisode 10 La confession de Pierre Matthieu 16 \u00c9pisode 11 La Transfiguration Matthieu 17 \u00c9pisode 12 L&rsquo;entr\u00e9e \u00e0 J\u00e9rusalem Matthieu 21 \u00c9pisode 13 La derni\u00e8re C\u00e8ne Matthieu 26 \u00c9pisode 14 Geths\u00e9mani et l&rsquo;arrestation Matthieu 26 \u00c9pisode 15 La crucifixion Matthieu 27 \u00c9pisode 16 La r\u00e9surrection Matthieu 28 \u00c9pisode 17 La Grande Mission Matthieu 28 \u00c9pisode 1 \u2014 La naissance de J\u00e9sus Matthieu 1:1\u201325 \ud83d\uddbc\ufe0f Illustration de la g\u00e9n\u00e9alogie de J\u00e9sus Voici la g\u00e9n\u00e9alogie de J\u00e9sus-Christ, fils de David, fils d&rsquo;Abraham. Une histoire de g\u00e9n\u00e9rations conduit jusqu&rsquo;\u00e0 la naissance de J\u00e9sus. \ud83d\uddbc\ufe0f Illustration de Joseph et de l&rsquo;ange Joseph apprend que Marie attend un enfant par l&rsquo;action de l&rsquo;Esprit Saint. \u00ab Joseph, fils de David, ne crains pas de prendre avec toi Marie, ta femme. \u00bb \ud83d\uddbc\ufe0f Illustration de la naissance de J\u00e9sus Marie donne naissance \u00e0 son fils premier-n\u00e9. \u00ab Elle enfantera un fils, et tu lui donneras le nom de J\u00e9sus. \u00bb \ud83d\uddbc\ufe0f Illustration de J\u00e9sus enfant L&rsquo;enfant re\u00e7oit le nom annonc\u00e9 par l&rsquo;ange. \u00ab Il sauvera son peuple de ses p\u00e9ch\u00e9s. \u00bb \u2b05\ufe0f \u00c9pisode pr\u00e9c\u00e9dent \u00c9pisode suivant \u27a1\ufe0f \ud83d\udcd6 La Bible en BD \u2014 \u00c9vangile selon Matthieu Projet d&rsquo;adaptation p\u00e9dagogique et illustr\u00e9e. \u00ab\u00a0` Catalogue Films &#8211; Wikidata \ud83c\udfac Catalogue Films &#8211; Wikidata Recherche directe dans Wikidata \u2014 aucune base locale Tous les films Avec un titre Sans titre Toutes les dates Avec date de sortie Sans date de sortie Plus r\u00e9cents Plus anciens Titre A-Z \ud83d\udd0e Rechercher \u271d\ufe0f Films chr\u00e9tiens \/ religieux uniquement Films uniquement Films et \u0153uvres audiovisuelles 20 r\u00e9sultats 50 r\u00e9sultats 100 r\u00e9sultats \u23f9 Annuler \ud83e\uddf9 R\u00e9initialiser \ud83d\udcc4 Aller \u00e0 la page \u2b07\ufe0f Exporter CSV \ud83d\udd04 Rechercher Pr\u00eat. \u25c0 Pr\u00e9c\u00e9dent Page 1 Suivant \u25b6 Catalogue Films &#8211; Wikidata \ud83c\udfac Catalogue Films &#8211; Wikidata Recherche directe dans Wikidata \u2014 aucune base locale Recherche libre Rechercher dans TitreR\u00e9alisateurActeurTitre + r\u00e9alisateur + acteur &nbsp; \ud83d\udd0e Rechercher Date de sortie Toutes les datesAvec date de sortieSans date de sortie Derniers jours Derniers mois Ann\u00e9e (2026) ou N derni\u00e8res ann\u00e9es (3) Ann\u00e9e de (fourchette) Ann\u00e9e \u00e0 (fourchette) Date pr\u00e9cise de d\u00e9but Date pr\u00e9cise de fin Titre Tous les filmsAvec un titreSans titre Type Films uniquementFilms et \u0153uvres audiovisuelles Langue du titre \ud83c\uddeb\ud83c\uddf7 Fran\u00e7ais\ud83c\uddec\ud83c\udde7 Anglais\ud83c\uddea\ud83c\uddf8 Espagnol\ud83c\udde9\ud83c\uddea Allemand\ud83c\uddee\ud83c\uddf9 Italien\ud83c\uddf5\ud83c\uddf9 Portugais\ud83c\uddf3\ud83c\uddf1 N\u00e9erlandais\ud83c\uddf8\ud83c\udde6 Arabe Tri Plus r\u00e9centsPlus anciensTitre A-Z R\u00e9sultats par page 2050100 Nombre maxi de r\u00e9sultats \u271d\ufe0f Films chr\u00e9tiens \/ religieux (genre \/ sujet Wikidata) \u00c9largir la recherche (mots-cl\u00e9s dans le titre) Chr\u00e9tien Religieux Biblique Spirituel &nbsp; \u23f9 Annuler &nbsp; \ud83e\uddf9 R\u00e9initialiser Aller \u00e0 la page &nbsp; \ud83d\udcc4 Aller \u00e0 la page<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"site-sidebar-layout":"no-sidebar","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"unboxed","site-sidebar-style":"unboxed","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"enabled","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":"","_members_access_role":[],"_members_access_error":""},"class_list":["post-30164","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/allianceenjesus.com\/index.php?rest_route=\/wp\/v2\/pages\/30164","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/allianceenjesus.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/allianceenjesus.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/allianceenjesus.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/allianceenjesus.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=30164"}],"version-history":[{"count":235,"href":"https:\/\/allianceenjesus.com\/index.php?rest_route=\/wp\/v2\/pages\/30164\/revisions"}],"predecessor-version":[{"id":31792,"href":"https:\/\/allianceenjesus.com\/index.php?rest_route=\/wp\/v2\/pages\/30164\/revisions\/31792"}],"wp:attachment":[{"href":"https:\/\/allianceenjesus.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=30164"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}