{
    "id": 113220,
    "date": "2024-11-27T10:38:27",
    "date_gmt": "2024-11-27T09:38:27",
    "guid": {
        "rendered": "https:\/\/togo-en.yearbook-media.com\/?page_id=113220"
    },
    "modified": "2025-04-29T12:02:10",
    "modified_gmt": "2025-04-29T10:02:10",
    "slug": "electricite",
    "status": "publish",
    "type": "page",
    "link": "https:\/\/togo-en.yearbook-media.com\/fr\/electricite\/",
    "title": {
        "rendered": "Togo &#8211; Electricit\u00e9"
    },
    "content": {
        "rendered": "<div data-elementor-type=\"wp-page\" data-elementor-id=\"113220\" class=\"elementor elementor-113220\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-50e2a5c9 ToBeHidden e-flex e-con-boxed e-con e-child\" data-id=\"50e2a5c9\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-d84655d e-con-full droppable e-flex e-con e-child\" data-id=\"d84655d\" data-element_type=\"container\" id=\"Ele1A\">\n\t\t\t\t<div class=\"elementor-element elementor-element-531135ba elementor-widget__width-inherit elementor-widget elementor-widget-text-editor\" data-id=\"531135ba\" data-element_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>\t\t<div data-elementor-type=\"page\" data-elementor-id=\"83347\" class=\"elementor elementor-83347\" data-elementor-post-type=\"elementor_library\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6442de91 e-con-full OrdiMobileConteneurClass e-flex e-con e-child\" data-id=\"6442de91\" data-element_type=\"container\" id=\"testIdTest\">\n\t\t\t\t<div class=\"elementor-element elementor-element-57de103 elementor-widget elementor-widget-text-editor\" data-id=\"57de103\" data-element_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><style>.elementor-249678 .elementor-element.elementor-element-6da64a60{--display:flex;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--justify-content:space-around;--align-items:center;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:50px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-6da64a60.e-con{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-45f807e0{--display:flex;--min-height:0px;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:-100px;--margin-bottom:62px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:3;}.elementor-249678 .elementor-element.elementor-element-45f807e0.e-con{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-61dcced4{--display:flex;--margin-top:0px;--margin-bottom:-11px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-6c65b106{--display:flex;--margin-top:0px;--margin-bottom:-30px;--margin-left:-25px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-eb74aa8{--display:flex;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-eb74aa8:not(.elementor-motion-effects-element-type-background), .elementor-249678 .elementor-element.elementor-element-eb74aa8 > .elementor-motion-effects-container > .elementor-motion-effects-layer{background-color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-1c762c45{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--flex-wrap:nowrap;--margin-top:-3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-5be6a53a{--display:flex;--align-items:flex-start;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-5be6a53a.e-con{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-75917e71{--display:flex;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-widget-image .widget-image-caption{color:var( --e-global-color-text );font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-249678 .elementor-element.elementor-element-6be76773 > .elementor-widget-container{margin:38px 5px -38px -40px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-6be76773.elementor-element{--align-self:flex-start;}.elementor-249678 .elementor-element.elementor-element-6be76773{text-align:right;}.elementor-249678 .elementor-element.elementor-element-6be76773 img{width:17px;}.elementor-249678 .elementor-element.elementor-element-5ad25a69{--display:flex;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-5ad25a69.e-con{--align-self:flex-end;}.elementor-249678 .elementor-element.elementor-element-52dec736 > .elementor-widget-container{margin:45px -18px -55px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-52dec736{z-index:101;text-align:right;}.elementor-249678 .elementor-element.elementor-element-469b1a7c{--display:flex;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:-25px;--margin-bottom:90px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-469b1a7c:not(.elementor-motion-effects-element-type-background), .elementor-249678 .elementor-element.elementor-element-469b1a7c > .elementor-motion-effects-container > .elementor-motion-effects-layer{background-color:#9FC5F3;}.elementor-249678 .elementor-element.elementor-element-3f5f9124{--display:flex;--min-height:30px;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:center;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:1px;--margin-bottom:-6px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:99;}.elementor-249678 .elementor-element.elementor-element-3f5f9124.e-con{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-48a37689{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:flex-start;--margin-top:3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-widget-text-editor{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );color:var( --e-global-color-text );}.elementor-widget-text-editor.elementor-drop-cap-view-stacked .elementor-drop-cap{background-color:var( --e-global-color-primary );}.elementor-widget-text-editor.elementor-drop-cap-view-framed .elementor-drop-cap, .elementor-widget-text-editor.elementor-drop-cap-view-default .elementor-drop-cap{color:var( --e-global-color-primary );border-color:var( --e-global-color-primary );}.elementor-249678 .elementor-element.elementor-element-4b68287 > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249678 .elementor-element.elementor-element-4b68287.elementor-element{--align-self:flex-start;}.elementor-249678 .elementor-element.elementor-element-4b68287{text-align:start;font-family:\"Roboto\", Sans-serif;font-size:12px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-79a46db6{--display:flex;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-47d25f98 > .elementor-widget-container{margin:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-47d25f98{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:18px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-3aa42503{--display:flex;--flex-direction:row;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:flex-end;--align-items:flex-end;--margin-top:4px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-12d5dc39 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-12d5dc39.elementor-element{--align-self:flex-start;}.elementor-249678 .elementor-element.elementor-element-12d5dc39{text-align:end;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-21535e15{--display:flex;--justify-content:flex-start;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--flex-wrap:wrap;--margin-top:-2px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-21535e15.e-con{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-de420c1{--display:flex;--min-height:30px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-2f60f3f > .elementor-widget-container{margin:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-2f60f3f.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-2f60f3f{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:500;line-height:1.1em;color:#FB5E2A;}.elementor-249678 .elementor-element.elementor-element-6b485447 > .elementor-widget-container{margin:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-6b485447.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-6b485447{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-78e1d9f5{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:center;--gap:010px 9px;--row-gap:010px;--column-gap:9px;--flex-wrap:wrap;--margin-top:-14px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:100;}.elementor-249678 .elementor-element.elementor-element-78e1d9f5.e-con{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-cf3602e{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-7a1bb33 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-7a1bb33.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-7a1bb33{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-6bf72a5{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-1a57dd9 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-1a57dd9.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-1a57dd9{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-34d8bbba{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-32bd35c6 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-32bd35c6.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-32bd35c6{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-5a9252c3{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-8722042 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-8722042.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-8722042{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-19ecc2b3{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-6071d405 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-6071d405.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-6071d405{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-3617569c{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-4b013e71 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-4b013e71.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-4b013e71{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-7450a6f8{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-30970f89 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-30970f89.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-30970f89{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-6aac67a6{--display:flex;--margin-top:-46px;--margin-bottom:-20px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:2;}.elementor-249678 .elementor-element.elementor-element-40d299c{width:100%;max-width:100%;}.elementor-249678 .elementor-element.elementor-element-40d299c.elementor-element{--align-self:flex-end;}.elementor-249678 .elementor-element.elementor-element-1fd15d20{width:100%;max-width:100%;}.elementor-249678 .elementor-element.elementor-element-1fd15d20.elementor-element{--align-self:flex-end;}.elementor-249678 .elementor-element.elementor-element-54e4e530{--display:flex;--justify-content:center;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-531f3cb1{width:100%;max-width:100%;font-family:\"Roboto\", Sans-serif;font-size:10px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249678 .elementor-element.elementor-element-531f3cb1 > .elementor-widget-container{margin:-37px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-531f3cb1.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-3a352c3f > .elementor-widget-container{margin:7px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-3a352c3f.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-3a352c3f{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:15px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249678 .elementor-element.elementor-element-7abb0aba > .elementor-widget-container{margin:7px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-7abb0aba.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-7abb0aba{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:15px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249678 .elementor-element.elementor-element-68e2b2ca > .elementor-widget-container{margin:-110px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-68e2b2ca.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-68e2b2ca{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:18px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249678 .elementor-element.elementor-element-8d50d33{--display:flex;--margin-top:-85px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-8d50d33.e-con{--align-self:center;}.elementor-widget-form .elementor-field-group > label, .elementor-widget-form .elementor-field-subgroup label{color:var( --e-global-color-text );}.elementor-widget-form .elementor-field-group > label{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .elementor-field-type-html{color:var( --e-global-color-text );font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .elementor-field-group .elementor-field{color:var( --e-global-color-text );}.elementor-widget-form .elementor-field-group .elementor-field, .elementor-widget-form .elementor-field-subgroup label{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .elementor-button{font-family:var( --e-global-typography-accent-font-family ), Sans-serif;font-weight:var( --e-global-typography-accent-font-weight );}.elementor-widget-form .e-form__buttons__wrapper__button-next{background-color:var( --e-global-color-accent );}.elementor-widget-form .elementor-button[type=\"submit\"]{background-color:var( --e-global-color-accent );}.elementor-widget-form .e-form__buttons__wrapper__button-previous{background-color:var( --e-global-color-accent );}.elementor-widget-form .elementor-message{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .e-form__indicators__indicator, .elementor-widget-form .e-form__indicators__indicator__label{font-family:var( --e-global-typography-accent-font-family ), Sans-serif;font-weight:var( --e-global-typography-accent-font-weight );}.elementor-widget-form{--e-form-steps-indicator-inactive-primary-color:var( --e-global-color-text );--e-form-steps-indicator-active-primary-color:var( --e-global-color-accent );--e-form-steps-indicator-completed-primary-color:var( --e-global-color-accent );--e-form-steps-indicator-progress-color:var( --e-global-color-accent );--e-form-steps-indicator-progress-background-color:var( --e-global-color-text );--e-form-steps-indicator-progress-meter-color:var( --e-global-color-text );}.elementor-widget-form .e-form__indicators__indicator__progress__meter{font-family:var( --e-global-typography-accent-font-family ), Sans-serif;font-weight:var( --e-global-typography-accent-font-weight );}.elementor-249678 .elementor-element.elementor-element-6ae6ef83{width:var( --container-widget-width, 75% );max-width:75%;--container-widget-width:75%;--container-widget-flex-grow:0;z-index:120;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group{padding-right:calc( 10px\/2 );padding-left:calc( 10px\/2 );margin-bottom:6px;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-form-fields-wrapper{margin-left:calc( -10px\/2 );margin-right:calc( -10px\/2 );margin-bottom:-6px;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group > label, .elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{color:#7B88A3;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-type-html{padding-bottom:0px;color:#7A7A7A;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field{color:#484848;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field, .elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:01px 01px 01px 01px;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:01px 01px 01px 01px;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-message.elementor-message-success{color:#00FF2700;}.elementor-249678 .elementor-element.elementor-element-66fd4d36{--display:flex;--min-height:58px;--gap:0px 0px;--row-gap:0px;--column-gap:0px;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:8px 8px 8px 8px;--margin-top:12px;--margin-bottom:10px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:151;}.elementor-249678 .elementor-element.elementor-element-66fd4d36.e-con{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4{width:auto;max-width:auto;z-index:120;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 > .elementor-widget-container{margin:2px 0px 2px 1px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group{padding-right:calc( 0px\/2 );padding-left:calc( 0px\/2 );margin-bottom:0px;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-form-fields-wrapper{margin-left:calc( -0px\/2 );margin-right:calc( -0px\/2 );margin-bottom:-0px;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group > label, .elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-type-html{padding-bottom:0px;color:#FFFFFF;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field{color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field, .elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:600;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-message.elementor-message-success{color:#00FF2700;}.elementor-249678 .elementor-element.elementor-element-4a59cf88 > .elementor-widget-container{margin:-3px 0px -24px 0px;}.elementor-249678 .elementor-element.elementor-element-4a59cf88.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-4a59cf88{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-17d3ad0c{--display:flex;--gap:0px 0px;--row-gap:0px;--column-gap:0px;border-style:none;--border-style:none;--border-radius:8px 8px 8px 8px;--margin-top:-4px;--margin-bottom:05px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:151;}.elementor-249678 .elementor-element.elementor-element-17d3ad0c.e-con{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-177c9b71{width:auto;max-width:auto;z-index:5;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249678 .elementor-element.elementor-element-177c9b71 > .elementor-widget-container{margin:2px 0px 2px 1px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-177c9b71.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-group{padding-right:calc( 0px\/2 );padding-left:calc( 0px\/2 );margin-bottom:0px;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-form-fields-wrapper{margin-left:calc( -0px\/2 );margin-right:calc( -0px\/2 );margin-bottom:-0px;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-group > label, .elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{color:#000000;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:400;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-type-html{padding-bottom:0px;color:#FFFFFF;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field{color:#000000;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field, .elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:16px;font-weight:600;line-height:1.1em;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-message.elementor-message-success{color:#00FF2700;}.elementor-249678 .elementor-element.elementor-element-5bafe1f3{--display:flex;--min-height:0px;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--gap:0px 0px;--row-gap:0px;--column-gap:0px;--overlay-opacity:1;--margin-top:230px;--margin-bottom:-220px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:10;}.elementor-249678 .elementor-element.elementor-element-5bafe1f3::before, .elementor-249678 .elementor-element.elementor-element-5bafe1f3 > .elementor-background-video-container::before, .elementor-249678 .elementor-element.elementor-element-5bafe1f3 > .e-con-inner > .elementor-background-video-container::before, .elementor-249678 .elementor-element.elementor-element-5bafe1f3 > .elementor-background-slideshow::before, .elementor-249678 .elementor-element.elementor-element-5bafe1f3 > .e-con-inner > .elementor-background-slideshow::before, .elementor-249678 .elementor-element.elementor-element-5bafe1f3 > .elementor-motion-effects-container > .elementor-motion-effects-layer::before{--background-overlay:'';background-size:cover;}.elementor-249678 .elementor-element.elementor-element-5bafe1f3.e-con{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-432cc2a1{--display:flex;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-446e8565 > .elementor-widget-container{margin:0px 3px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-446e8565.elementor-element{--align-self:flex-end;}.elementor-249678 .elementor-element.elementor-element-446e8565{z-index:5;text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249678 .elementor-element.elementor-element-60df49d0 > .elementor-widget-container{margin:35px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-60df49d0.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-60df49d0{z-index:5;text-align:center;font-family:\"Roboto\", Sans-serif;font-size:15px;font-weight:500;line-height:1.1em;color:#6185C0;}.elementor-249678 .elementor-element.elementor-element-62ef38f0{--display:flex;--flex-direction:row;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:space-between;--align-items:flex-start;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:-287px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-f4f51cb > .elementor-widget-container{margin:0px 3px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-f4f51cb.elementor-element{--align-self:flex-end;}.elementor-249678 .elementor-element.elementor-element-f4f51cb{z-index:5;text-align:left;font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249678 .elementor-element.elementor-element-f214306 > .elementor-widget-container{margin:0px 0px 0px 3px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-f214306.elementor-element{--align-self:flex-end;}.elementor-249678 .elementor-element.elementor-element-f214306{z-index:5;text-align:start;font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249678 .elementor-element.elementor-element-1c5a5ed5{--display:flex;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--justify-content:flex-start;--align-items:center;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-1c5a5ed5.e-con{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-4740d3e8{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:space-between;--margin-top:5px;--margin-bottom:5px;--margin-left:010px;--margin-right:10px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-e964c6b > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-e964c6b.elementor-element{--align-self:flex-end;}.elementor-249678 .elementor-element.elementor-element-e964c6b{z-index:5;text-align:left;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249678 .elementor-element.elementor-element-30eb836c > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-30eb836c{z-index:101;text-align:right;}.elementor-249678 .elementor-element.elementor-element-342c88b1{--display:flex;--min-height:180px;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--justify-content:center;--align-items:center;--overflow:hidden;border-style:solid;--border-style:solid;border-width:4px 4px 4px 4px;--border-top-width:4px;--border-right-width:4px;--border-bottom-width:4px;--border-left-width:4px;border-color:#00FF19;--border-color:#00FF19;--border-radius:0px 0px 0px 0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-342c88b1:not(.elementor-motion-effects-element-type-background), .elementor-249678 .elementor-element.elementor-element-342c88b1 > .elementor-motion-effects-container > .elementor-motion-effects-layer{background-color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-3c7e790f > .elementor-widget-container{padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-3c7e790f{font-family:\"Roboto\", Sans-serif;font-weight:500;color:#6185C0;}.elementor-249678 .elementor-element.elementor-element-51f00578{width:auto;max-width:auto;z-index:5;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249678 .elementor-element.elementor-element-51f00578 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-51f00578.elementor-element{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-group{padding-right:calc( 0px\/2 );padding-left:calc( 0px\/2 );margin-bottom:0px;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-form-fields-wrapper{margin-left:calc( -0px\/2 );margin-right:calc( -0px\/2 );margin-bottom:-0px;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-group > label, .elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{color:#000000;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:400;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-type-html{padding-bottom:0px;color:#FFFFFF;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field{color:#213864;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field, .elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:15.5px;font-weight:600;line-height:1.1em;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249678 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249678 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249678 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249678 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-message.elementor-message-success{color:#00FF2700;}@media(max-width:1001px){.elementor-249678 .elementor-element.elementor-element-6ae6ef83{z-index:11;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field, .elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{font-size:10px;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-button{font-size:12px;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4{z-index:11;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field, .elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{font-size:10px;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-button{font-size:12px;}.elementor-249678 .elementor-element.elementor-element-177c9b71{z-index:11;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field, .elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{font-size:10px;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-button{font-size:12px;}.elementor-249678 .elementor-element.elementor-element-51f00578{z-index:11;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field, .elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{font-size:10px;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-button{font-size:12px;}}@media(min-width:1001px){.elementor-249678 .elementor-element.elementor-element-6da64a60{--width:500px;}.elementor-249678 .elementor-element.elementor-element-45f807e0{--width:100%;}.elementor-249678 .elementor-element.elementor-element-6c65b106{--width:500px;}.elementor-249678 .elementor-element.elementor-element-75917e71{--width:10px;}.elementor-249678 .elementor-element.elementor-element-5ad25a69{--width:100%;}.elementor-249678 .elementor-element.elementor-element-469b1a7c{--width:500px;}.elementor-249678 .elementor-element.elementor-element-48a37689{--width:22%;}.elementor-249678 .elementor-element.elementor-element-79a46db6{--width:50%;}.elementor-249678 .elementor-element.elementor-element-3aa42503{--width:22%;}.elementor-249678 .elementor-element.elementor-element-78e1d9f5{--width:100%;}.elementor-249678 .elementor-element.elementor-element-cf3602e{--width:103px;}.elementor-249678 .elementor-element.elementor-element-6bf72a5{--width:103px;}.elementor-249678 .elementor-element.elementor-element-34d8bbba{--width:103px;}.elementor-249678 .elementor-element.elementor-element-5a9252c3{--width:103px;}.elementor-249678 .elementor-element.elementor-element-19ecc2b3{--width:103px;}.elementor-249678 .elementor-element.elementor-element-3617569c{--width:103px;}.elementor-249678 .elementor-element.elementor-element-7450a6f8{--width:103px;}.elementor-249678 .elementor-element.elementor-element-8d50d33{--width:100%;}.elementor-249678 .elementor-element.elementor-element-66fd4d36{--width:390px;}.elementor-249678 .elementor-element.elementor-element-17d3ad0c{--width:100%;}.elementor-249678 .elementor-element.elementor-element-5bafe1f3{--width:150%;}.elementor-249678 .elementor-element.elementor-element-62ef38f0{--width:95%;}.elementor-249678 .elementor-element.elementor-element-1c5a5ed5{--width:100%;}.elementor-249678 .elementor-element.elementor-element-4740d3e8{--width:100%;}}@media(max-width:1000px){.elementor-249678 .elementor-element.elementor-element-6da64a60{--width:390px;--margin-top:105px;--margin-bottom:-75px;--margin-left:0px;--margin-right:0px;}.elementor-249678 .elementor-element.elementor-element-45f807e0{--min-height:150px;--flex-direction:column;--container-widget-width:100%;--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--margin-top:-47px;--margin-bottom:-32px;--margin-left:0px;--margin-right:0px;--z-index:3;}.elementor-249678 .elementor-element.elementor-element-61dcced4{--width:25%;}.elementor-249678 .elementor-element.elementor-element-6c65b106{--width:100%;--flex-direction:row;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:center;--align-items:center;--flex-wrap:nowrap;--margin-top:3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249678 .elementor-element.elementor-element-6c65b106.e-con{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-eb74aa8{--width:75%;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--align-items:center;}.elementor-249678 .elementor-element.elementor-element-eb74aa8.e-con{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-1c762c45{--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249678 .elementor-element.elementor-element-6be76773 > .elementor-widget-container{margin:-3px 40px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-5ad25a69{--width:100%;--justify-content:flex-end;--align-items:flex-end;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-52dec736 > .elementor-widget-container{margin:40px 55px -30px 0px;}.elementor-249678 .elementor-element.elementor-element-52dec736{z-index:100;}.elementor-249678 .elementor-element.elementor-element-469b1a7c{--width:78%;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--flex-wrap:nowrap;--margin-top:-103px;--margin-bottom:-7px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-469b1a7c.e-con{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-3f5f9124{--justify-content:center;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249678 .elementor-element.elementor-element-48a37689{--width:25%;--margin-top:2px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-4b68287 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-4b68287{font-size:8px;}.elementor-249678 .elementor-element.elementor-element-79a46db6{--width:46%;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-47d25f98 > .elementor-widget-container{margin:0px -20px 0px -20px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-47d25f98{font-size:12px;}.elementor-249678 .elementor-element.elementor-element-3aa42503{--width:25%;--margin-top:4px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-12d5dc39 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-12d5dc39{font-size:7px;}.elementor-249678 .elementor-element.elementor-element-21535e15{--margin-top:-15px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249678 .elementor-element.elementor-element-de420c1{--min-height:15px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-2f60f3f{width:100%;max-width:100%;font-size:10px;}.elementor-249678 .elementor-element.elementor-element-2f60f3f > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-6b485447{width:100%;max-width:100%;font-size:10px;}.elementor-249678 .elementor-element.elementor-element-6b485447 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-78e1d9f5{--width:100%;--gap:6px 4px;--row-gap:6px;--column-gap:4px;--flex-wrap:wrap;--margin-top:-12px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249678 .elementor-element.elementor-element-cf3602e{--width:61px;--min-height:15px;}.elementor-249678 .elementor-element.elementor-element-7a1bb33{font-size:9px;}.elementor-249678 .elementor-element.elementor-element-6bf72a5{--width:61px;--min-height:15px;}.elementor-249678 .elementor-element.elementor-element-1a57dd9{font-size:9px;}.elementor-249678 .elementor-element.elementor-element-34d8bbba{--width:61px;--min-height:15px;}.elementor-249678 .elementor-element.elementor-element-32bd35c6{font-size:9px;}.elementor-249678 .elementor-element.elementor-element-5a9252c3{--width:61px;--min-height:15px;}.elementor-249678 .elementor-element.elementor-element-8722042{font-size:9px;}.elementor-249678 .elementor-element.elementor-element-19ecc2b3{--width:61px;--min-height:15px;}.elementor-249678 .elementor-element.elementor-element-6071d405{font-size:9px;}.elementor-249678 .elementor-element.elementor-element-3617569c{--width:61px;--min-height:15px;}.elementor-249678 .elementor-element.elementor-element-4b013e71{font-size:9px;}.elementor-249678 .elementor-element.elementor-element-7450a6f8{--width:61px;--min-height:15px;}.elementor-249678 .elementor-element.elementor-element-30970f89{font-size:9px;}.elementor-249678 .elementor-element.elementor-element-6aac67a6{--width:96%;--min-height:250px;--margin-top:-56px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-40d299c > .elementor-widget-container{margin:5px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-1fd15d20 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-54e4e530{--margin-top:3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249678 .elementor-element.elementor-element-54e4e530.e-con{--order:-99999 \/* order start hack *\/;}.elementor-249678 .elementor-element.elementor-element-531f3cb1 > .elementor-widget-container{margin:-30px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-3a352c3f > .elementor-widget-container{margin:-181px 0px 1px 0px;}.elementor-249678 .elementor-element.elementor-element-3a352c3f{text-align:center;font-size:10px;line-height:1.2em;}.elementor-249678 .elementor-element.elementor-element-7abb0aba > .elementor-widget-container{margin:-180px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-7abb0aba{text-align:center;font-size:14px;line-height:1.2em;}.elementor-249678 .elementor-element.elementor-element-68e2b2ca > .elementor-widget-container{margin:-110px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-68e2b2ca{font-size:10px;}.elementor-249678 .elementor-element.elementor-element-8d50d33{--width:184px;--margin-top:-156px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249678 .elementor-element.elementor-element-8d50d33.e-con{--align-self:center;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83{width:var( --container-widget-width, 100% );max-width:100%;--container-widget-width:100%;--container-widget-flex-grow:0;z-index:120;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group > label{font-size:12px;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field, .elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{font-size:8px;}.elementor-249678 .elementor-element.elementor-element-6ae6ef83 .elementor-button{font-size:10.5px;}.elementor-249678 .elementor-element.elementor-element-66fd4d36{--width:85%;--min-height:42px;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--align-items:center;--margin-top:10px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:151;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 > .elementor-widget-container{margin:2px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4{z-index:120;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group > label{font-size:12px;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-type-html{font-size:12px;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field, .elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{font-size:10px;}.elementor-249678 .elementor-element.elementor-element-4ea8e2b4 .elementor-button{font-size:10.5px;}.elementor-249678 .elementor-element.elementor-element-4a59cf88 > .elementor-widget-container{margin:2px 0px -10px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-4a59cf88{font-size:7.5px;}.elementor-249678 .elementor-element.elementor-element-17d3ad0c{--width:85%;--min-height:42px;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--align-items:center;--margin-top:2px;--margin-bottom:-20px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:251;}.elementor-249678 .elementor-element.elementor-element-177c9b71 > .elementor-widget-container{margin:2px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-177c9b71{z-index:120;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-group > label{font-size:12px;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-type-html{font-size:12px;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field, .elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{font-size:12px;}.elementor-249678 .elementor-element.elementor-element-177c9b71 .elementor-button{font-size:10.5px;}.elementor-249678 .elementor-element.elementor-element-5bafe1f3{--min-height:150px;--margin-top:-149px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249678 .elementor-element.elementor-element-446e8565 > .elementor-widget-container{margin:-133px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-446e8565.elementor-element{--align-self:flex-start;}.elementor-249678 .elementor-element.elementor-element-446e8565{text-align:left;font-size:10px;}.elementor-249678 .elementor-element.elementor-element-f4f51cb > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249678 .elementor-element.elementor-element-f4f51cb.elementor-element{--align-self:flex-start;}.elementor-249678 .elementor-element.elementor-element-f4f51cb{text-align:center;font-size:10px;}.elementor-249678 .elementor-element.elementor-element-f214306 > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249678 .elementor-element.elementor-element-f214306.elementor-element{--align-self:flex-start;}.elementor-249678 .elementor-element.elementor-element-f214306{text-align:center;font-size:10px;}.elementor-249678 .elementor-element.elementor-element-1c5a5ed5{--width:390px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-e964c6b > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249678 .elementor-element.elementor-element-e964c6b.elementor-element{--align-self:flex-start;}.elementor-249678 .elementor-element.elementor-element-e964c6b{text-align:center;font-size:10px;}.elementor-249678 .elementor-element.elementor-element-30eb836c > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-30eb836c{z-index:100;}.elementor-249678 .elementor-element.elementor-element-342c88b1{--min-height:112px;--margin-top:5px;--margin-bottom:5px;--margin-left:5px;--margin-right:5px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249678 .elementor-element.elementor-element-3c7e790f{text-align:center;font-size:15px;}.elementor-249678 .elementor-element.elementor-element-51f00578 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249678 .elementor-element.elementor-element-51f00578{z-index:120;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-group > label{font-size:12px;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-type-html{font-size:12px;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field, .elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{font-size:12px;}.elementor-249678 .elementor-element.elementor-element-51f00578 .elementor-button{font-size:10.5px;}}<\/style>\t\t<div data-elementor-type=\"loop-item\" data-elementor-id=\"249678\" class=\"elementor elementor-249678 elementor-bc-flex-widget e-loop-item e-loop-item-113220 post-113220 page type-page status-publish\" data-elementor-post-type=\"elementor_library\" data-custom-edit-handle=\"1\">\n\t\t\t<div class=\"elementor-element elementor-element-6da64a60 e-con-full OrdiMobileConteneurClass e-flex e-con e-child\" data-id=\"6da64a60\" data-element_type=\"container\" id=\"testIdTest\">\n\t\t<div class=\"elementor-element elementor-element-45f807e0 e-con-full UploadFileConteneur AdUploadedTitle elementor-hidden-tablet elementor-hidden-mobile elementor-hidden-desktop e-flex e-con e-child\" data-id=\"45f807e0\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-61dcced4 e-con-full e-flex e-con e-child\" data-id=\"61dcced4\" data-element_type=\"container\">\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-6c65b106 e-con-full e-flex e-con e-child\" data-id=\"6c65b106\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-eb74aa8 e-con-full e-flex e-con e-child\" data-id=\"eb74aa8\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1c762c45 e-con-full e-flex e-con e-child\" data-id=\"1c762c45\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-5be6a53a e-con-full e-flex e-con e-child\" data-id=\"5be6a53a\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-75917e71 e-con-full e-flex e-con e-child\" data-id=\"75917e71\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6be76773 AnnonceDragIcone elementor-widget elementor-widget-image\" data-id=\"6be76773\" data-element_type=\"widget\" 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 decoding=\"async\" src=\"https:\/\/via-agency.media\/wp-content\/uploads\/2025\/05\/arrow-drag-64-bleu.png\" title=\"\" alt=\"\" loading=\"lazy\" \/>\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<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-5ad25a69 e-con-full CroixResetAnnonceContainer e-flex e-con e-child\" data-id=\"5ad25a69\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-52dec736 elementor-widget elementor-widget-image\" data-id=\"52dec736\" data-element_type=\"widget\" id=\"CroixResetAnnonce\" 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\t<a href=\"#\">\n\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-transparent.png\" title=\"\" alt=\"\" loading=\"lazy\" \/>\t\t\t\t\t\t\t\t<\/a>\n\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<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-469b1a7c e-con-full UploadFileConteneur e-flex e-con e-child\" data-id=\"469b1a7c\" data-element_type=\"container\" id=\"UploadFileConteneur\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t<div class=\"elementor-element elementor-element-3f5f9124 e-con-full ChoisirEspacePublicitaireDisponibiliteConteneur e-flex e-con e-child\" data-id=\"3f5f9124\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-48a37689 e-con-full e-flex e-con e-child\" data-id=\"48a37689\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4b68287 PositionEspacePublicitaire elementor-widget elementor-widget-text-editor\" data-id=\"4b68287\" data-element_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\tPosition\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-79a46db6 e-con-full e-flex e-con e-child\" data-id=\"79a46db6\" data-element_type=\"container\" id=\"ChoixEspacePublicitaireTitre\">\n\t\t\t\t<div class=\"elementor-element elementor-element-47d25f98 elementor-widget elementor-widget-text-editor\" data-id=\"47d25f98\" data-element_type=\"widget\" id=\"ChoixEspacePublicitaireTexte\" 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\tChoix d&rsquo;espace publicitaire\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-3aa42503 e-con-full e-flex e-con e-child\" data-id=\"3aa42503\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-12d5dc39 ReferenceEspacePublicitaire elementor-widget elementor-widget-text-editor\" data-id=\"12d5dc39\" data-element_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>R\u00e9f\u00e9rence<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-21535e15 e-con-full EspPubFormatMainContainer e-flex e-con e-child\" data-id=\"21535e15\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-de420c1 e-con-full e-flex e-con e-child\" data-id=\"de420c1\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2f60f3f elementor-widget-mobile__width-inherit SelectionFormatTitre elementor-widget elementor-widget-text-editor\" data-id=\"2f60f3f\" data-element_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 style=\"text-align: center;\">Merci de s\u00e9lectionner un format d&rsquo;annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6b485447 elementor-widget-mobile__width-inherit elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile SelectionFormatTitreBlancOLD elementor-widget elementor-widget-text-editor\" data-id=\"6b485447\" data-element_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 style=\"text-align: center;\">Vous pouvez changer de format d&rsquo;annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-78e1d9f5 e-con-full EspPubFormatListe e-flex e-con e-child\" data-id=\"78e1d9f5\" data-element_type=\"container\">\n\t\t<a class=\"elementor-element elementor-element-cf3602e e-con-full EspPubFormatContainer FormatIdCreation e-flex e-con e-child\" data-id=\"cf3602e\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-7a1bb33 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"7a1bb33\" data-element_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\tCr\u00e9ation\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-6bf72a5 e-con-full EspPubFormatContainer FormatIdPopUp e-flex e-con e-child\" data-id=\"6bf72a5\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-1a57dd9 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"1a57dd9\" data-element_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\tPop-up\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-34d8bbba e-con-full EspPubFormatContainer FormatIdBanniere e-flex e-con e-child\" data-id=\"34d8bbba\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-32bd35c6 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"32bd35c6\" data-element_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\tBanni\u00e8re\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-5a9252c3 e-con-full EspPubFormatContainer FormatIdVideo e-flex e-con e-child\" data-id=\"5a9252c3\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8722042 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"8722042\" data-element_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\tVid\u00e9o\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-19ecc2b3 e-con-full EspPubFormatContainer FormatIdCommunique e-flex e-con e-child\" data-id=\"19ecc2b3\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6071d405 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"6071d405\" data-element_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\tCommuniqu\u00e9\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-3617569c e-con-full EspPubFormatContainer FormatIdInterview e-flex e-con e-child\" data-id=\"3617569c\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4b013e71 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"4b013e71\" data-element_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\tInterview\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-7450a6f8 e-con-full EspPubFormatContainer FormatIdParrainage e-flex e-con e-child\" data-id=\"7450a6f8\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-30970f89 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"30970f89\" data-element_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\tParrainage\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-6aac67a6 e-con-full HTMLUploadfileConteneur e-flex e-con e-child\" data-id=\"6aac67a6\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-40d299c elementor-widget__width-inherit HTMLUploadfileClass elementor-widget elementor-widget-html\" data-id=\"40d299c\" data-element_type=\"widget\" id=\"HTMLUploadfile\" 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=\"en\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <meta name=\"google\" content=\"notranslate\">\r\n    \r\n    <script data-jetpack-boost=\"ignore\" src=\"https:\/\/code.jquery.com\/jquery-3.6.0.min.js\"><\/script>\r\n    <script data-jetpack-boost=\"ignore\" src=\"https:\/\/code.jquery.com\/ui\/1.12.1\/jquery-ui.min.js\"><\/script>\r\n\r\n<script data-jetpack-boost=\"ignore\">\r\n\/\/ Lazy loading des biblioth\u00e8ques - charg\u00e9es uniquement au besoin\r\nwindow.VIALibraries = {\r\n    mammothLoaded: false,\r\n    pdfLoaded: false,\r\n    \r\n    loadMammoth: function(callback) {\r\n        if (this.mammothLoaded) { callback(); return; }\r\n        var script = document.createElement('script');\r\n        script.src = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/mammoth\/1.4.0\/mammoth.browser.min.js';\r\n        script.onload = function() { \r\n            window.VIALibraries.mammothLoaded = true; \r\n            callback(); \r\n        };\r\n        document.head.appendChild(script);\r\n    },\r\n    \r\n    loadPdfJs: function(callback) {\r\n        if (this.pdfLoaded) { callback(); return; }\r\n        var script = document.createElement('script');\r\n        script.src = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.11.174\/pdf.min.js';\r\n        script.onload = function() {\r\n            window.VIALibraries.pdfLoaded = true;\r\n            pdfjsLib.GlobalWorkerOptions.workerSrc = '\/\/cdn.jsdelivr.net\/npm\/pdfjs-dist@latest\/build\/pdf.worker.min.js';\r\n            callback();\r\n        };\r\n        document.head.appendChild(script);\r\n    }\r\n};\r\n<\/script>\r\n\r\n<\/head>\r\n<body>\r\n    <div id=\"PopUpMessageAchattest\" class=\"draggable\" draggable=\"true\" style=\"justify-content: center; align-items: flex-start;\">\r\n        <div id=\"drop_file_zone_achat\" class=\"drop_file_zone_achat_class\" ondrop=\"uploadFile_achat(event)\" ondragover=\"return false\">\r\n        <div id=\"drag_upload_file_achat\">\r\n            <p><input class=\"button-2_achat\" type=\"button\" value=\"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\" onclick=\"fileExplorer_achat(event);\" \/><\/p>\r\n                <input type=\"file\" id=\"selectfile_achat\" \/>\r\n        <\/div>\r\n        <\/div>\r\n        <div class=\"img-content\"><\/div>\r\n    <\/div>\r\n<\/body>\r\n<\/html>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1fd15d20 elementor-widget__width-inherit HTMLUploadfileClass elementor-widget elementor-widget-html\" data-id=\"1fd15d20\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<script data-jetpack-boost=\"ignore\">\r\nif (!window._espPubScriptLoaded) {\r\nwindow._espPubScriptLoaded = true;\r\n\/**\r\n * Configuration centralis\u00e9e\r\n *\/\r\nconst CONFIG = {\r\n    iframeId: 'yearbook-iframe',\r\n    ajaxUrl: 'https:\/\/via-agency.media\/wp-admin\/admin-ajax.php',\r\n    apercuUrl: 'https:\/\/rdc.yearbook-media.com\/apercu',\r\n    \r\n    allowedExtensions: {\r\n        video: ['mp4', 'mov', 'wmv', 'avi', 'flv', 'f4v', 'swf', 'mkv', 'webm', 'mpeg'],\r\n        image: ['jpg', 'jpeg', 'png', 'gif', 'tif', 'svg', 'webp'],\r\n        document: ['doc', 'docx', 'ppt', 'pptx', 'pdf']\r\n    },\r\n    \r\n    mimeTypes: {\r\n        docx: 'application\/vnd.openxmlformats-officedocument.wordprocessingml.document',\r\n        pdf: 'application\/pdf'\r\n    },\r\n    \r\n    dragScroll: {\r\n        threshold: 150,\r\n        maxSpeed: 65,\r\n        throttleDelay: 50\r\n    },\r\n    \r\n    breakpoints: {\r\n        mobile: 1000\r\n    },\r\n    \r\n    keywords: [\r\n        { normal: \"parrainage\", display: \"Parrainage\" },\r\n        { normal: \"communique\", display: \"Communiqu\u00e9\" },\r\n        { normal: \"interview\", display: \"Interview\" }\r\n    ]\r\n};\r\n\r\n\/**\r\n * \u2705 v1.19.1 : Module de positionnement dans l'iframe\r\n * \r\n * PROBL\u00c8ME : L'iframe ne scrolle pas en desktop \u2014 c'est le parent (#PageWebTitrePage) qui scrolle.\r\n * L'iframe est scal\u00e9e \u00e0 0.85 \u2192 les coordonn\u00e9es iframe \u2260 coordonn\u00e9es parent.\r\n * position:fixed dans l'iframe = relatif au CONTENU TOTAL, pas au viewport visible.\r\n * \r\n * SOLUTION : Le parent calcule visibleTopIframe (la position iframe du haut du viewport)\r\n * et l'envoie dans le message 'PageWebTitrePage-scroll'. L'iframe n'a qu'\u00e0 l'utiliser.\r\n * \r\n * Pour scroller, l'iframe envoie 'scrollToIframeY' au parent qui fait la conversion.\r\n *\/\r\nconst ScrollHelper = {\r\n    _visibleTopIframe: 0,\r\n    _iframeScale: 0.85,\r\n\r\n    init() {\r\n        \/\/ \u00c9couter les donn\u00e9es de scroll envoy\u00e9es par le parent\r\n        window.addEventListener('message', (event) => {\r\n            var msg = event.data;\r\n            if (msg && msg.action === 'PageWebTitrePage-scroll') {\r\n                if (typeof msg.visibleTopIframe === 'number') {\r\n                    this._visibleTopIframe = msg.visibleTopIframe;\r\n                }\r\n                if (typeof msg.iframeScale === 'number') {\r\n                    this._iframeScale = msg.iframeScale;\r\n                }\r\n            }\r\n        });\r\n        console.log('\u2705 ScrollHelper initialis\u00e9');\r\n    },\r\n\r\n    \/**\r\n     * Position Y dans le document iframe correspondant au haut du viewport visible\r\n     *\/\r\n    getVisibleTop() {\r\n        if (window === window.top) {\r\n            return window.scrollY || 0;\r\n        }\r\n        return this._visibleTopIframe;\r\n    },\r\n\r\n    \/**\r\n     * Demande au parent de scroller pour positionner `element` \u00e0 `offsetFromTop` px du viewport\r\n     *\/\r\n    scrollElementTo(element, offsetFromTop) {\r\n        if (!element) return;\r\n\r\n        \/\/ getBoundingClientRect().top dans une iframe sans scroll = position absolue Y\r\n        var elementAbsY = element.getBoundingClientRect().top;\r\n\r\n        if (window === window.top) {\r\n            window.scrollTo({ top: elementAbsY - offsetFromTop + (window.scrollY || 0), behavior: 'smooth' });\r\n            return;\r\n        }\r\n\r\n        \/\/ Envoyer au parent \u2014 le parent fait la conversion scale\r\n        window.parent.postMessage({\r\n            type: 'scrollToIframeY',\r\n            iframeId: CONFIG.iframeId,\r\n            iframeY: elementAbsY,\r\n            offsetFromTop: offsetFromTop\r\n        }, '*');\r\n        console.log('\ud83d\udcdc scrollToIframeY:', { iframeY: Math.round(elementAbsY), offsetFromTop });\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'\u00e9tat (SessionStorage)\r\n *\/\r\nconst StateManager = {\r\n    init() {\r\n        if (sessionStorage.getItem(\"AchatEspaceCall\") === 'No') {\r\n            sessionStorage.clear();\r\n        }\r\n        \r\n        this.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        this.set('dragstart_Rank_Emplacement_Page_Web', 'No');\r\n        this.set('dragstart_Commande_Emplacement_Page_Web', 'No');\r\n        \r\n        \/\/ \u2705 v2.1.1 : Popup \u2192 ne jamais pr\u00e9remplir le format\r\n        if (this.get('PopUpChoice') === 'Yes') {\r\n            this.set('Formatchoisi', 'No');\r\n            this.set('FormatSelect', '');\r\n            this.set('Commande_Format_Transmis', '');\r\n        }\r\n    },\r\n    \r\n    get(key) {\r\n        return sessionStorage.getItem(key);\r\n    },\r\n    \r\n    set(key, value) {\r\n        sessionStorage.setItem(key, value);\r\n    },\r\n    \r\n    getMultiple(keys) {\r\n        return keys.reduce((acc, key) => {\r\n            acc[key] = this.get(key);\r\n            return acc;\r\n        }, {});\r\n    },\r\n    \r\n    setMultiple(obj) {\r\n        Object.entries(obj).forEach(([key, value]) => {\r\n            this.set(key, value);\r\n        });\r\n    },\r\n    \r\n    buildEmplacementReference(rank) {\r\n        const codeSite = this.get('codeSite');\r\n        const codePage = this.get('codePage');\r\n        return `${codeSite}${codePage}L${rank.substring(3)}`;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion des fichiers\r\n *\/\r\nconst FileManager = {\r\n    getExtension(filename) {\r\n        console.log('filename:', filename);\r\n        const parts = filename.split('.');\r\n        return parts.length > 1 ? parts.pop().toLowerCase() : '';\r\n    },\r\n    \r\n    isAllowedExtension(extension) {\r\n        return Object.values(CONFIG.allowedExtensions)\r\n            .flat()\r\n            .includes(extension);\r\n    },\r\n    \r\n    getFileType(extension) {\r\n        for (const [type, extensions] of Object.entries(CONFIG.allowedExtensions)) {\r\n            if (extensions.includes(extension)) {\r\n                return type;\r\n            }\r\n        }\r\n        return null;\r\n    },\r\n    \r\n    async urlToFile(url, filename) {\r\n        console.log(\"Fetching from URL:\", url);\r\n        \r\n        const mimeType = filename.includes('.docx') \r\n            ? CONFIG.mimeTypes.docx \r\n            : filename.includes('.pdf') \r\n            ? CONFIG.mimeTypes.pdf \r\n            : null;\r\n        \r\n        try {\r\n            const response = await fetch(url);\r\n            \r\n            if (!response.ok) {\r\n                throw new Error(`Network response was not ok: ${response.status} ${response.statusText}`);\r\n            }\r\n            \r\n            const blob = await response.blob();\r\n            return new File([blob], filename, { type: mimeType });\r\n        } catch (error) {\r\n            console.error(\"Error in urlToFile:\", error);\r\n            alert(\"Erreur lors du chargement du fichier. Veuillez r\u00e9essayer.\");\r\n            throw error;\r\n        }\r\n    },\r\n    \r\n    createObjectUrl(file) {\r\n        \/\/ R\u00e9voquer l'ancien URL si existant\r\n        const oldUrl = StateManager.get('objectUrl');\r\n        if (oldUrl && oldUrl.startsWith('blob:')) {\r\n            URL.revokeObjectURL(oldUrl);\r\n            console.log('\ud83d\uddd1\ufe0f Old Object URL revoked');\r\n        }\r\n        \r\n        const url = URL.createObjectURL(file);\r\n        StateManager.set('objectUrl', url);\r\n        return url;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion du Drag & Drop\r\n *\/\r\nconst DragDropManager = {\r\n    state: {\r\n        isFileBeingDragged: false,\r\n        draggedFile: null,\r\n        dragInProgress: false,\r\n        throttleTimeout: null\r\n    },\r\n    \r\n    init() {\r\n        this.attachEventListeners();\r\n    },\r\n    \r\n    attachEventListeners() {\r\n        window.addEventListener('dragstart', (e) => this.handleDragStart(e), true);\r\n        jQuery(document).on('dragover', (e) => this.handleDragOver(e));\r\n        jQuery(document).on('dragleave drop', (e) => this.handleDragEnd(e));\r\n        jQuery(\"#drop_file_zone_achat\").on(\"dragover\", (e) => this.handleDropZoneDragOver(e));\r\n        jQuery(\".draggable\").on(\"dragend\", (e) => this.handleDraggableEnd(e));\r\n    },\r\n    \r\n    handleDragStart(e) {\r\n        console.log('Window-level dragstart', e);\r\n        this.state.dragInProgress = true;\r\n    \r\n        const $target = $(e.target);\r\n        const droppableParent = $target.closest('.droppable');\r\n        const parentId = droppableParent.length ? droppableParent.attr('id') : null;\r\n        \r\n        StateManager.set('dragstart_Rank_Emplacement_Page_Web', parentId);\r\n        console.log('dragstart_Rank_Emplacement_Page_Web', parentId);\r\n        \r\n        \/\/ \u2705 CALCULER IMM\u00c9DIATEMENT dragstart_Commande_Emplacement_Page_Web\r\n        if (parentId) {\r\n            const dragstartRef = StateManager.buildEmplacementReference(parentId);\r\n            StateManager.set('dragstart_Commande_Emplacement_Page_Web', dragstartRef);\r\n            console.log('dragstart_Commande_Emplacement_Page_Web', dragstartRef);\r\n            \/\/ \u2705 v2.4.5 : Capturer l'\u00e9tat checkbox R\u00e9server au moment du dragstart\r\n            \/\/ Si l'utilisateur a explicitement d\u00e9coch\u00e9, forcer \u00e0 No m\u00eame si DOM est coch\u00e9\r\n            var $_dragCb = $('#' + parentId).find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]');\r\n            var _dragCbChecked = $_dragCb.prop('checked') === true;\r\n            var _expliciteDecocheDrag = StateManager.get('_reserverDecoche_' + parentId) === 'Yes';\r\n            var _reserverDrag = _dragCbChecked && !_expliciteDecocheDrag;\r\n            StateManager.set('dragstart_ReserverChecked', _reserverDrag ? 'Yes' : 'No');\r\n            \/\/ R\u00e9initialiser le flag apr\u00e8s lecture\r\n            StateManager.set('_reserverDecoche_' + parentId, 'No');\r\n            console.log('[dragstart] ReserverChecked dom:', _dragCbChecked, '| d\u00e9coch\u00e9 explicitement:', _expliciteDecocheDrag, '| final:', _reserverDrag);\r\n        }\r\n    \r\n        const dataTransfer = e.dataTransfer || e.originalEvent?.dataTransfer;\r\n        const files = dataTransfer?.files || null;\r\n        \r\n        const imgSrc = $target.closest('.draggable').find('img').attr('src');\r\n        const videoSrc = $target.closest('.draggable').find('video').attr('src') || \r\n                        $target.closest('.draggable').find('video source').attr('src');\r\n        const mediaSrc = imgSrc || videoSrc;\r\n    \r\n        console.log('dragstart target:', e.target);\r\n        console.log('files:', files);\r\n        console.log('mediaSrc:', mediaSrc);\r\n    \r\n        if (!mediaSrc && (!files || files.length === 0)) {\r\n            console.log('No media source or files found, preventing drag');\r\n            e.preventDefault();\r\n            this.state.dragInProgress = false;\r\n            return false;\r\n        }\r\n    \r\n        if (mediaSrc) {\r\n            StateManager.set('objectUrl', mediaSrc);\r\n        }\r\n    \r\n        StateManager.set('Commande_Format_Transmis', '');\r\n        \r\n        if ($target.closest('.droppable').find('.doc-preview-container:visible').length > 0) {\r\n            StateManager.set('Commande_Format_Transmis', 'R\u00e9dactionnel');\r\n            StateManager.set('FullPathAdFile', \r\n                $target.closest('.droppable').find('.doc-preview-FullPathAdFile').text());\r\n        }\r\n    \r\n        if (files && files.length > 0) {\r\n            this.state.isFileBeingDragged = true;\r\n            this.state.draggedFile = files[0];\r\n        }\r\n        \r\n        \/\/ \u2705 TOUJOURS marquer comme \"Moved\" quand on drag depuis un espace existant\r\n        if (parentId && mediaSrc) {\r\n            StateManager.set('FirstUploadFileorMoved', 'Moved');\r\n            console.log('\u2705 Drag depuis espace existant - Moved');\r\n        }\r\n    \r\n        console.log('Drag Started', {\r\n            file: this.state.draggedFile,\r\n            mediaSrc: mediaSrc,\r\n            dragstartRef: StateManager.get('dragstart_Commande_Emplacement_Page_Web')\r\n        });\r\n    },\r\n    \r\n    handleDragOver(e) {\r\n        e.preventDefault();\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            this.handleIframeDragScroll(e);\r\n        } else {\r\n            this.handleDirectPageScroll(e);\r\n        }\r\n    },\r\n    \r\n    handleIframeDragScroll(e) {\r\n        if (!this.state.throttleTimeout) {\r\n            this.state.throttleTimeout = setTimeout(() => {\r\n                MessageManager.sendToParent('dragScroll', { clientY: e.clientY });\r\n                this.state.throttleTimeout = null;\r\n            }, CONFIG.dragScroll.throttleDelay);\r\n        }\r\n    },\r\n    \r\n    handleDirectPageScroll(e) {\r\n        const { threshold, maxSpeed } = CONFIG.dragScroll;\r\n        const windowHeight = window.innerHeight;\r\n        \r\n        if (e.clientY < threshold) {\r\n            const speed = Math.max(1, maxSpeed * (1 - e.clientY \/ threshold));\r\n            window.scrollBy(0, -speed);\r\n        } else if (e.clientY > windowHeight - threshold) {\r\n            const speed = Math.max(1, maxSpeed * (1 - (windowHeight - e.clientY) \/ threshold));\r\n            window.scrollBy(0, speed);\r\n        }\r\n    },\r\n    \r\n    handleDragEnd(e) {\r\n        e.preventDefault();\r\n        MessageManager.sendToParent('dragEnd', {});\r\n        console.log('dragleave drop');\r\n    },\r\n    \r\n    handleDropZoneDragOver(e) {\r\n        e.preventDefault();\r\n        console.log(\"FirstUploadFileorMoved:\", StateManager.get('FirstUploadFileorMoved'));\r\n    },\r\n    \r\n    handleDraggableEnd(e) {\r\n        e.preventDefault();\r\n        this.resetState();\r\n        console.log('dragend');\r\n    },\r\n    \r\n    resetState() {\r\n        this.state.isFileBeingDragged = false;\r\n        this.state.draggedFile = null;\r\n        this.state.dragInProgress = false;\r\n    },\r\n    \r\n    clearDataTransferFiles(e) {\r\n        e.dataTransfer = new DataTransfer();\r\n        console.log('DataTransfer files cleared');\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'interface utilisateur\r\n *\/\r\nconst UIManager = {\r\n    isMobile() {\r\n        return window.outerWidth < CONFIG.breakpoints.mobile;\r\n    },\r\n    \r\n    isDesktop() {\r\n        const userAgent = navigator.userAgent;\r\n        const isWindows = userAgent.indexOf('Windows') > -1;\r\n        const isMac = userAgent.indexOf('Macintosh') > -1;\r\n        const isLinux = userAgent.indexOf('Linux') > -1 && userAgent.indexOf('Android') === -1;\r\n        return isWindows || isMac || isLinux;\r\n    },\r\n    \r\n    initMobileUI() {\r\n        $(document).ready(() => {\r\n            $('label[for=\"form-field-LienAnnonce\"]').each(function() {\r\n                $(this).text('Renseigner le lien hypertexte de l\\'annonce');\r\n            });\r\n            \r\n            $('input[name=\"form_fields[LienAnnonce]\"]').each(function() {\r\n                $(this).attr('placeholder', 'Renseigner le lien hypertexte de l\\'annonce');\r\n            });\r\n        });\r\n        \r\n        jQuery('.MsgDatesText').hide();\r\n        this.attachMobileEventListeners();\r\n    },\r\n    \r\n    attachMobileEventListeners() {\r\n        jQuery('.TransmettreFichierAnnonceContainer').on('click', (e) => {\r\n            this.handleMobileSpaceSelection(e);\r\n        });\r\n        \r\n        jQuery('[id=\"form-field-selected_currency_Mobile\"]').off('change').on('change', (e) => {\r\n            this.handleMobileCurrencyChange(e);\r\n        });\r\n    },\r\n    \r\n    handleMobileSpaceSelection(e) {\r\n        e.preventDefault();\r\n        jQuery('#IndisponibilitesMsg').hide();\r\n        \r\n        jQuery('input[name=\"form_fields[SelectEspacePublicitaireMobile]\"]').prop('checked', false);\r\n        jQuery(e.currentTarget).find('input[name=\"form_fields[SelectEspacePublicitaireMobile]\"]').prop('checked', true);\r\n        \r\n        StateManager.set(\"PageWebDisplayed\", 'Yes');\r\n        \r\n        jQuery('.FormSelectDevisesMobile').hide();\r\n        jQuery(e.target).closest('.EspacePublicitaireMobile').find('.FormSelectDevisesMobile').show();\r\n        \r\n        const $droppable = jQuery(e.currentTarget).closest('.droppable');\r\n        const rankId = $droppable.attr('id');\r\n        \r\n        StateManager.set('Rank_Emplacement_Page_Web', rankId);\r\n        StateManager.set('Commande_Emplacement_Page_Web', \r\n            StateManager.buildEmplacementReference(rankId));\r\n        \r\n        this.updateEmplacementDisplay();\r\n        this.handleAvailabilityDisplay(e);\r\n        this.displayUploadedAdIfExists(e);\r\n        this.updateTariffDisplay(e);\r\n    },\r\n    \r\n    updateEmplacementDisplay() {\r\n        const emplacement = StateManager.get('Commande_Emplacement_Page_Web');\r\n        jQuery('#EmplacementAnnonceDataStep3').html(emplacement).css({'color': '#56BE50'});\r\n        console.log(\"Emplacement:\", emplacement);\r\n    },\r\n    \r\n    handleAvailabilityDisplay(e) {\r\n        const $espace = jQuery(e.target).closest('.EspacePublicitaireMobile');\r\n        const dispoText = $espace.find('.ChoisirEspacePublicitaireDisponibilite').text();\r\n        \r\n        if (dispoText.length > 46) {\r\n            const espacePublicitaireDispoFrom = dispoText.slice(-10);\r\n            console.log(\"espacePublicitaireDispoFrom:\", espacePublicitaireDispoFrom);\r\n            console.log(\"Date de debut:\", StateManager.get(\"Debut_de_campagne\"));\r\n        } else {\r\n            jQuery('#form-field-DebutCampagne').val(StateManager.get(\"Debut_de_campagne\"));\r\n        }\r\n    },\r\n    \r\n    displayUploadedAdIfExists(e) {\r\n        if (StateManager.get(\"FileReceived\") === 'Yes') {\r\n            jQuery('.VisualisationAnnonceMobile').hide();\r\n            \r\n            const espaceId = StateManager.get('espaceChoisi');\r\n            const $espace = document.querySelector(`[id=\"${espaceId}\"]`);\r\n            \r\n            jQuery($espace).find('.MessageAnnonceMobileTexte')\r\n                .html('Merci de choisir des dates de campagne<br>afin d\\'obtenir le tarif de cet espace publicitaire');\r\n            jQuery($espace).find('.VisualisationAnnonceMobile').show();\r\n        \r\n            const img = document.createElement('img');\r\n            img.src = StateManager.get('objectUrl');\r\n            img.style.width = 'auto';\r\n            img.style.height = 'auto';\r\n            img.style.maxWidth = '100%';\r\n            img.style.maxHeight = '200px';\r\n            \r\n            jQuery('.VisualisationAnnonceMobile').empty();\r\n            jQuery($espace).find('.VisualisationAnnonceMobile').append(img);\r\n        }\r\n    },\r\n    \r\n    updateTariffDisplay(e) {\r\n        jQuery('.TariftobedisplayedMobile').html('-');\r\n        const newTarif = StateManager.get('NewTarifformatted');\r\n        \r\n        if (newTarif && newTarif !== '-') {\r\n            jQuery(e.target).closest('.EspacePublicitaireMobile')\r\n                .find('.TariftobedisplayedMobile')\r\n                .html(newTarif);\r\n        }\r\n    },\r\n    \r\n    handleMobileCurrencyChange(e) {\r\n        event.preventDefault();\r\n        StateManager.setMultiple({\r\n            \"SelectionCatalogueOuAchat\": 'Catalogue',\r\n            \"selected_currency\": jQuery(e.currentTarget).val()\r\n        });\r\n        \r\n        jQuery('#form-field-selected_currency_2').val(StateManager.get(\"selected_currency\"));\r\n        console.log(\"selected currency:\", StateManager.get(\"selected_currency\"));\r\n        \r\n        setTimeout(() => {\r\n            jQuery(e.target).closest('.EspacePublicitaireMobile')\r\n                .find('.TariftobedisplayedMobile')\r\n                .html(StateManager.get(\"NewTarifformatted\"));\r\n        }, 500);\r\n    },\r\n    \r\n    initDesktopUI() {\r\n        StateManager.setMultiple({\r\n            \"FileReceived\": \"No\",\r\n            \"AdDisplayed\": \"No\"\r\n        });\r\n        jQuery('.MsgAdNotDisplayed').hide();\r\n    },\r\n    \r\n    showUploadProgress($dropZone) {\r\n        \/\/ Cacher les \u00e9l\u00e9ments\r\n        $dropZone.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed, span.ClassHdpCdp, .ClassRefEsp, .HideFormButton, .EspPubFormatMainContainer, .TexteMobileAnnonce')\r\n            .hide();\r\n        \r\n        \/\/ Afficher et styler le message de progression\r\n        var _uplMsg = 'Loading in progress <span class=\"dot-container\"><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><\/span>';\r\n        $dropZone.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed')\r\n            .show()\r\n            .html(_uplMsg)\r\n            .css({\r\n                'color': '#00ff19',\r\n                'background-color': 'white',\r\n                'padding': '12px 20px',\r\n                'border-radius': '6px',\r\n                'font-weight': '700',\r\n                'font-size': '18px',\r\n                'line-height': '1.4',\r\n                'display': 'inline-block',\r\n                'margin': '10px auto',\r\n                'text-align': 'center'\r\n            });\r\n        \r\n        \/\/ Cacher les autres \u00e9l\u00e9ments\r\n        $dropZone.closest('.droppable')\r\n            .find('.UploadIci, .EnvoiUlterieurTexte, .EnvoiUlterieurContainer')\r\n            .hide();\r\n            \r\n        $dropZone.closest('.droppable')\r\n            .find('.UploadFileConteneur')\r\n            .css({\r\n                'background-color': 'transparent'\r\n            });\r\n    },\r\n    \r\n    showFormatError($dropZone, message = 'Format de fichier incompatible') {\r\n        \/\/ \u2705 v2.4.6 : M\u00eame rendu overlay que le bloc jpeg \u2014 position absolute sur $dropZone\r\n        var _errId = 'fmt-error-msg-' + Date.now();\r\n        $dropZone.css('position', 'relative');\r\n        var _errHtml = '<div id=\"' + _errId + '\" style=\"'\r\n            + 'position:absolute;top:50px;left:50%;transform:translateX(-50%);width:auto;white-space:nowrap;'\r\n            + 'background:#fff;color:#FB5E2A;font-weight:700;font-size:13px;'\r\n            + 'text-align:center;padding:8px 10px;border-radius:6px;'\r\n            + 'border:2px solid #FB5E2A;box-sizing:border-box;'\r\n            + 'z-index:99999;line-height:1.4;'\r\n            + '\">' + message + '<\/div>';\r\n        $dropZone.append(_errHtml);\r\n        setTimeout(function() { jQuery('#' + _errId).remove(); }, 4000);\r\n    },\r\n    \r\n    updateAfterSuccessfulUpload($dropZone) {\r\n        jQuery('#errorMessageMobileText').hide();\r\n        \r\n        $dropZone.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed, span.ClassHdpCdp, .ClassRefEsp, .HideFormButton, .EspPubFormatMainContainer, .EnvoiUlterieurContainer')\r\n            .hide();\r\n        \r\n        \/\/ \u2705 Pas de margin-top:150px si d\u00e9p\u00f4t depuis miniature kit (d\u00e9j\u00e0 positionn\u00e9)\r\n        if (!window._dropFromMiniature) {\r\n            $dropZone.closest('.OrdiMobileConteneurClass')\r\n                .css({'margin-top': '150px', 'margin-bottom': '0px'});\r\n        }\r\n    },\r\n    \r\n    finalizeAdDisplay($dropZone) {\r\n        StateManager.setMultiple({\r\n            \"FileReceived\": \"Yes\",\r\n            \"PageWebDisplayed\": \"Yes\"\r\n        });\r\n        \r\n        jQuery('#MsgChoixPageWeb, #MsgInsererAnnonceConteneur').hide();\r\n        jQuery('#ChoixEspacePublicitaire')\r\n            .html('L\\'annonce est plac\u00e9e dans un espace publicitaire')\r\n            .show()\r\n            .css({'color': '#56BE50'});\r\n        \r\n        jQuery('#MsgPlacerAnnoncePosition').hide();\r\n        jQuery('#FonctionMenu4').show();\r\n        jQuery('.AnnonceData').html(\"Transmis\").css({'color': '#56BE50'});\r\n        \r\n        jQuery('#ProcederPaiementConteneur').hide();\r\n        jQuery('#ProcederPaiementTitreIconeUp').hide();\r\n        jQuery('#ProcederPaiementTitreIconeDown').show();\r\n        \r\n        jQuery('#message').remove();\r\n        \r\n        this.styleUploadedAd($dropZone);\r\n        this.adjustLayoutAfterUpload($dropZone);\r\n        \r\n        \/\/ \u2705 Mettre \u00e0 jour l'\u00e9tat de la checkbox \"R\u00e9server\" apr\u00e8s upload\r\n        FormatUIManager.updateReserverCheckboxState($dropZone.closest('.droppable'));\r\n    },\r\n    \r\n    styleUploadedAd($dropZone) {\r\n        const $container = $dropZone.closest('.OrdiMobileConteneurClass');\r\n        const $droppable = $dropZone.closest('.droppable');\r\n        \r\n        \/\/ \u2705 v1.19.5 : V\u00e9rifier si c'est une restauration via flag d\u00e9di\u00e9\r\n        const isRestoration = StateManager.get('_isAdRestoration') === 'Yes';\r\n        \r\n        $container\r\n            .find('.PositionReference, .TexteMobile, .EnvoiUlterieurContainer')\r\n            .hide();\r\n        \r\n        $container\r\n            .find('.AdUploadedTitle, .DimensionsMaximales')\r\n            .show();\r\n        \r\n        \/\/ \u2705 Bug 2 fix : montrer le conteneur parent + la croix (CroixResetAnnonceContainer cach\u00e9 par reset)\r\n        $droppable.find('.CroixResetAnnonceContainer').show();\r\n        $droppable.find('#CroixResetAnnonce').show();\r\n        \r\n        \/\/ \u2705 v2.2 : Marquer le droppable comme occup\u00e9 pour qu'Entete le skip\r\n        $droppable.attr('data-via-ad-loaded', 'true');\r\n        \r\n        \/\/ \u2705 v2.0.11 : AdUploadedTitle ne doit pas bloquer le touch sur doc-preview-readmore (mobile)\r\n        $container.find('.AdUploadedTitle').css('pointer-events', 'none');\r\n        \r\n        \/\/ \u2705 #CroixResetAnnonce au-dessus de tous les conteneurs superpos\u00e9s\r\n        $container.find('#CroixResetAnnonce').css({\r\n            'position': 'relative',\r\n            'z-index': '9999'\r\n        });\r\n        \r\n        \/\/ \u2705 Desktop : les conteneurs superpos\u00e9s bloquent la croix \u2014 les rendre transparents aux clics\r\n        if (!UIManager.isMobile()) {\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css('pointer-events', 'none');\r\n            \/\/ R\u00e9activer les \u00e9l\u00e9ments interactifs\r\n            $container.find('#CroixResetAnnonce').css('pointer-events', 'auto');\r\n            $dropZone.closest('#PopUpMessageAchattest').css('pointer-events', 'auto'); \/\/ drag annonce\r\n        }\r\n        \r\n        \/\/ \u2705 v2.4.3 : Sur mobile, masquer titre et logo drag quand annonce d\u00e9pos\u00e9e dans Ele0A\r\n        if (UIManager.isMobile()) {\r\n            if ($droppable.attr('id') === 'Ele0A') {\r\n                $droppable.find('#ChoixEspacePublicitaireTexte').hide();\r\n                $droppable.find('#Ele0ADragHandle').hide();\r\n                \/\/ \u2705 v2.4.12 : UploadFileConteneur a pointer-events:none \u2192 forcer auto sur la croix\r\n                $droppable.find('.CroixResetAnnonceContainer')[0] && $droppable.find('.CroixResetAnnonceContainer')[0].style.setProperty('pointer-events', 'auto', 'important');\r\n                $droppable.find('#CroixResetAnnonce')[0] && $droppable.find('#CroixResetAnnonce')[0].style.setProperty('pointer-events', 'auto', 'important');\r\n            }\r\n        }\r\n        \r\n        jQuery(\".HTMLUploadfileConteneur\").css({\r\n            'border': 'none',\r\n            'background-color': 'transparent'\r\n        });\r\n        \r\n        \/\/ \u2705 v2.4.12 : Retirer le liser\u00e9 envoi diff\u00e9r\u00e9 (#UploadFileConteneur) si pr\u00e9sent\r\n        \/\/ (le d\u00e9p\u00f4t d'une annonce cr\u00e9e son propre liser\u00e9 sur .HTMLUploadfileConteneur)\r\n        var $_ufcEd = $dropZone.closest('.droppable').find('#UploadFileConteneur');\r\n        if ($_ufcEd[0]) {\r\n            $_ufcEd[0].style.removeProperty('box-shadow');\r\n            $_ufcEd[0].style.removeProperty('box-sizing');\r\n            if (UIManager.isMobile()) {\r\n                $_ufcEd[0].style.removeProperty('transform');\r\n                $_ufcEd[0].style.removeProperty('transform-origin');\r\n            }\r\n        }\r\n        \r\n        $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n            'box-shadow': 'inset 0 0 0 2px #00FF19',  \/\/ \u2705 v2.4.5 : inset \u2192 jamais clipp\u00e9 par overflow:hidden\r\n            'background-color': 'white',\r\n            'box-sizing': 'border-box',\r\n            'overflow': 'hidden'\r\n        });\r\n        \r\n        \/\/ \u2705 v2.0.9 : Fix mobile \u2014 r\u00e9duire le scale pour que le liser\u00e9 vert soit visible\r\n        \/\/ \u2705 Pas de scale si annonce d\u00e9pos\u00e9e depuis la miniature kit (d\u00e9j\u00e0 aux bonnes dimensions)\r\n        \/\/ \u2705 v2.4.9 : Pas de scale si AchatEspaceCall=Yes (drop depuis miniature dans iframe)\r\n        \/\/ \u2705 data-kit-drop : marqueur DOM pos\u00e9 par kitAdCreated, r\u00e9siste \u00e0 l'async\r\n        var _fromKitDrop = $droppable[0] ? $droppable[0].getAttribute('data-kit-drop') === 'true' : false;\r\n        if (_fromKitDrop) { window._dropFromMiniature = true; } \/\/ sync le flag window\r\n        var _fromMiniature = window._dropFromMiniature || _fromKitDrop;\r\n        var _fromAchat = StateManager.get('AchatEspaceCall') === 'Yes';\r\n        if (UIManager.isMobile() && !_fromMiniature && !_fromAchat) {\r\n            $dropZone.closest('.UploadFileConteneur').css({\r\n                'transform': 'scale(1.35)',\r\n                'transform-origin': 'top center'\r\n            });\r\n            \/\/ \u2705 v2.4.11 : Corps de page mobile \u2014 le .ToBeHidden clippe le scale(1.35) c\u00f4t\u00e9 droit\r\n            \/\/ \u2192 overflow:visible pour que le liser\u00e9 vert soit visible sur les 4 c\u00f4t\u00e9s\r\n            $dropZone.closest('.ToBeHidden').css('overflow', 'visible');\r\n        }\r\n        \r\n        \/\/ \u2705 v2.2 : Sur restauration, Entete a d\u00e9j\u00e0 positionn\u00e9 le droppable correctement\r\n        \/\/ et est emp\u00each\u00e9 de le retoucher (data-via-ad-loaded). On ne touche pas aux marges.\r\n        \/\/ Sur premier upload, on applique les marges normalement.\r\n        \/\/ \u2705 Pas de marges si d\u00e9p\u00f4t depuis miniature kit (dimensions naturelles conserv\u00e9es)\r\n        if (!isRestoration && !_fromMiniature) {\r\n            if ($container.data('orig-mb') === undefined) {\r\n                $container.data('orig-mb', parseInt($container.css('margin-bottom')) || 0);\r\n            }\r\n            if ($droppable.data('orig-mt') === undefined) {\r\n                $droppable.data('orig-mt', parseInt($droppable.css('margin-top')) || 0);\r\n            }\r\n            var _isDocPreview = $dropZone.find('.doc-preview-container').length > 0;\r\n            var _marginAdd = _isDocPreview ? 60 : 130;\r\n            var _marginReduce = _isDocPreview ? 60 : 130;\r\n            $container.css({\r\n                'margin-bottom': ($container.data('orig-mb') + _marginAdd) + 'px'\r\n            });\r\n            $droppable.css({\r\n                'margin-top': ($droppable.data('orig-mt') - _marginReduce + 75) + 'px'\r\n            });\r\n        } else {\r\n            \/\/ \u2705 Sur restauration, ajouter 50px en dessous pour \u00e9viter que le contenu soit trop coll\u00e9\r\n            var _curMb = parseInt($container.css('margin-bottom')) || 0;\r\n            $container.css('margin-bottom', (_curMb + 50) + 'px');\r\n        }\r\n        \r\n        \/\/ \u2705 Masquer .PositionEspacePublicitaireContainer et l'ancien .ReserverContainer\r\n        $droppable.find('.PositionEspacePublicitaireContainer').hide();\r\n        $droppable.find('.ReserverContainer').hide();\r\n        \r\n        \/\/ \u2705 Supprimer tout ancien bouton dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ \u2705 v2.1.2 : Cr\u00e9er le bouton R\u00e9server m\u00eame lors d'une restauration\r\n        if (isRestoration) {\r\n            console.log('\ud83d\udd04 Restauration d\u00e9tect\u00e9e - affichage bouton R\u00e9server + DeplaceAnnonce');\r\n            $droppable.find('.DeplaceAnnonce').show();\r\n            \/\/ S'assurer que FileReceived est d\u00e9fini pour la validation\r\n            StateManager.set('FileReceived', 'Yes');\r\n            \/\/ Cocher automatiquement SEULEMENT si c'est une restauration de commande r\u00e9serv\u00e9e (pas pendingAd)\r\n            var _isPendingAdRestore = sessionStorage.getItem('_pendingAdRestoration') === 'Yes';\r\n            if (!_isPendingAdRestore) {\r\n                var _isReservedRestore = sessionStorage.getItem('_isReservedRestoration') === 'Yes';\r\n                setTimeout(function() {\r\n                    var $checkbox = $droppable.find('.reserver-dynamic-checkbox');\r\n                    if ($checkbox.length && _isReservedRestore) {\r\n                        $checkbox.prop('checked', true);\r\n                        $droppable.find('.reserver-dynamic-label').text('Espace publicitaire r\u00e9serv\u00e9').css('color', 'rgb(62, 170, 19)');\r\n                        console.log('\u2705 R\u00e9server coch\u00e9 automatiquement (restauration commande r\u00e9serv\u00e9e)');\r\n                    }\r\n                    sessionStorage.removeItem('_isReservedRestoration');\r\n                    StateManager.set('_isAdRestoration', 'No');\r\n                    \/\/ \u2705 v2.4.7 : updateReserverCheckboxState APR\u00c8S avoir coch\u00e9 la checkbox\r\n                    \/\/ (l'appel synchrone ligne 614 intervient avant le cocher \u2192 label incorrect)\r\n                    if (typeof FormatUIManager !== 'undefined') {\r\n                        FormatUIManager.updateReserverCheckboxState($droppable);\r\n                    }\r\n                }, 150);\r\n            } else {\r\n                \/\/ pendingAd : ne pas cocher, ne pas envoyer au parent\r\n                console.log('\u2705 pendingAd restaur\u00e9 \u2014 R\u00e9server NON coch\u00e9');\r\n                sessionStorage.removeItem('_pendingAdRestoration');\r\n                StateManager.set('_isAdRestoration', 'No');\r\n            }\r\n        }\r\n        \r\n        \/\/ \u2705 Supprimer tout bouton R\u00e9server existant avant insertion (\u00e9vite doublons sur restauration)\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ \u2705 Cr\u00e9er le bouton \"R\u00e9server\" dynamique avec id unique pour \u00e9viter conflit label\/for Elementor\r\n        const _rankId = $droppable.attr('id') || ('drop_' + Date.now());\r\n        const _cbId = 'reserver-cb-' + _rankId;\r\n        const reserverHTML = `\r\n            <div class=\"reserver-dynamic-container\">\r\n                <span class=\"reserver-dynamic-option\">\r\n                    <input type=\"checkbox\" id=\"${_cbId}\" value=\"R\u00e9server cet espace publicitaire\" \r\n                           class=\"reserver-dynamic-checkbox\"\r\n                           name=\"form_fields[ReserverEspacePublicitaire]\">\r\n                    <span class=\"reserver-dynamic-label\">R\u00e9server cet espace publicitaire<\/span>\r\n                <\/span>\r\n            <\/div>\r\n        `;\r\n        \r\n        \/\/ \u2705 Ins\u00e9rer juste avant .DeplaceAnnonceText (position stable)\r\n        const $anchor = $droppable.find('.DeplaceAnnonceText');\r\n        if ($anchor.length) {\r\n            $anchor.before(reserverHTML);\r\n            $anchor.prev('.reserver-dynamic-container').css('margin-bottom', '-40px');\r\n            if (!UIManager.isMobile()) {\r\n                $anchor.prev('.reserver-dynamic-container').find('.reserver-dynamic-label').css({'font-size': '20px', 'font-weight': '700'});\r\n            }\r\n        } else {\r\n            $droppable.after(reserverHTML);\r\n            const $btn = $droppable.next('.reserver-dynamic-container');\r\n            $btn.css('margin-top', UIManager.isMobile() ? '-10px' : '-140px');\r\n        }\r\n        \r\n        console.log('\u2705 Bouton \"R\u00e9server\" dynamique cr\u00e9\u00e9');\r\n    },\r\n    \r\n    adjustLayoutAfterUpload($dropZone) {\r\n        console.log('\ud83d\udcf1 adjustLayoutAfterUpload \u2014 isMobile():', this.isMobile(), 'outerWidth:', window.outerWidth);\r\n        if (this.isMobile()) {\r\n            this.adjustMobileLayout($dropZone);\r\n            \r\n            \/\/ Repositionner le bouton R\u00e9server APR\u00c8S les ajustements de layout\r\n            setTimeout(() => {\r\n                const $droppable = $dropZone.closest('.droppable');\r\n                const $btn = $droppable.find('.reserver-dynamic-container').add($droppable.next('.reserver-dynamic-container')).first();\r\n                const $lisere = $droppable.find('.HTMLUploadfileConteneur');\r\n                if ($btn.length && $lisere.length) {\r\n                    const lisereBottom = $lisere[0].getBoundingClientRect().bottom;\r\n                    const btnTop = $btn[0].getBoundingClientRect().top;\r\n                    const offset = lisereBottom - btnTop - 48;\r\n                    \r\n                    \/\/ 15px suppl\u00e9mentaires pour homepage et articles\r\n                    let extraOffset = 0;\r\n                    const isHomepage = window.location.pathname === \"\/\" || window.location.pathname === \"\/en\/\";\r\n                    const isSectorPage = $('body').hasClass('page');\r\n                    if (isHomepage) {\r\n                        extraOffset = 13;\r\n                    }\r\n                    if (!isSectorPage) {\r\n                        extraOffset = 15;\r\n                    }\r\n                    \r\n                    \/\/ \u2705 v2.0.9 : +4px pour documents (communiqu\u00e9\/interview\/PDF) avec pr\u00e9sentation HTML\r\n                    if ($droppable.find('.doc-preview-container:visible').length > 0) {\r\n                        extraOffset += 4;\r\n                    }\r\n                    \r\n                    $btn.css({\r\n                        'margin-top': (offset + extraOffset + 20) + 'px',\r\n                        'margin-bottom': (-(offset + extraOffset) - 100) + 'px'\r\n                    });\r\n                    console.log('\ud83d\udcd0 Repositionnement mobile R\u00e9server:', { lisereBottom, btnTop, offset });\r\n                }\r\n            }, 50);\r\n        } else {\r\n            this.adjustDesktopLayout($dropZone);\r\n        }\r\n    },\r\n    \r\n    adjustMobileLayout($dropZone) {\r\n        console.log('\ud83d\udcf1 adjustMobileLayout START');\r\n        console.log('\ud83d\udcf1 AchatEspaceCall:', StateManager.get(\"AchatEspaceCall\"));\r\n        console.log('\ud83d\udcf1 PageAjoutModifAnnonce:', StateManager.get(\"PageAjoutModifAnnonce\"));\r\n        console.log('\ud83d\udcf1 window===window.top:', window === window.top);\r\n        console.log('\ud83d\udcf1 pathname:', location.pathname);\r\n        \r\n        const $droppable = $dropZone.closest('.droppable');\r\n        \r\n        \/\/ \u2705 v2.4.3 : Masquer les textes position\/label\/r\u00e9f\u00e9rence (comme sur desktop)\r\n        $droppable\r\n            .find('.PositionEspacePublicitaire, .ReferenceEspacePublicitaire, .ChoisirEspacePublicitaireDisponibiliteConteneur')\r\n            .hide();\r\n        \r\n        \/\/ \u2705 v2.6 : Renseigner .PositionEspacePublicitaire sur mobile (manquait vs desktop)\r\n        (function() {\r\n            var _rankPosMob = StateManager.get('Rank_Emplacement_Page_Web') || $droppable.attr('id') || '';\r\n            var _posLibMob = PreviewRenderer._getPositionLibelle(_rankPosMob);\r\n            if (_posLibMob) {\r\n                $droppable\r\n                    .find('.PositionEspacePublicitaire')\r\n                    .text(_posLibMob)\r\n                    .each(function() {\r\n                        this.style.setProperty('display', 'block', 'important');\r\n                    });\r\n            }\r\n        })();\r\n        \r\n        \/\/ \u2705 Scop\u00e9 au $dropZone courant (\u00e9vite d'affecter les autres espaces pub)\r\n        $dropZone.closest('.droppable').find('#CroixResetAnnonce').css({'zoom': '75%'});\r\n\r\n        \/\/ \u2705 v2.4.3 : Remonter la croix reset sur mobile (override margin-top Elementor)\r\n        \/\/ \u2705 v2.4.5 : Poser aussi margin-right ici (Entete.txt ne l'atteint pas pour Ele0A)\r\n        var _croixContainer = $dropZone.closest('.OrdiMobileConteneurClass').find('.CroixResetAnnonceContainer')[0];\r\n        if (_croixContainer) {\r\n            var _isEle0ACroix = ($dropZone.closest('.droppable').attr('id') === 'Ele0A');\r\n            var _mtCroix = StateManager.get(\"PageAjoutModifAnnonce\") === 'Yes' ? '-88px' : '24px';\r\n            \/\/ Ele0A : +40px vers le bas, +15px vers la gauche (margin-right) par rapport \u00e0 Ele1A\r\n            \/\/ Ele0A : margin-top identique aux autres espaces (pas de d\u00e9calage suppl\u00e9mentaire)\r\n            _croixContainer.style.setProperty('margin-top', _mtCroix, 'important');\r\n            _croixContainer.style.setProperty('margin-right', _isEle0ACroix ? '17px' : '12px', 'important');\r\n        }\r\n        \r\n        var _isMiniatureAdj = window._dropFromMiniature;\r\n        window._dropFromMiniature = false;\r\n\r\n        if (_isMiniatureAdj && window.outerWidth <= 1000) {\r\n            \/\/ \u2705 Miniature doc-preview MOBILE : ajuster HTMLUploadfileConteneur \u00e0 la hauteur du contenu\r\n            \/\/ et neutraliser tous les margins Elementor qui d\u00e9calent le $dropZone hors du parent\r\n            var _isDocPreviewMob = $dropZone.find('.doc-preview-container').length > 0;\r\n            var _docH = _isDocPreviewMob ? 144 : 115;\r\n            $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n                'height':     _docH + 'px',\r\n                'min-height': _docH + 'px',\r\n                'max-height': _docH + 'px',\r\n                'margin-top': '-55px',\r\n                'margin-bottom': '0px',\r\n                'overflow': 'hidden'\r\n            });\r\n            $dropZone.css({'margin-top': '0px', 'margin-bottom': '0px', 'top': '0px', 'height': (_docH - 6) + 'px'});\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css({'margin-top': '65px', 'margin-bottom': '-10px'});\r\n            \/\/ \u2705 v2.4.9 : Doc-preview \u2014 overflow:visible pour que le liser\u00e9 du haut ne soit pas clipp\u00e9\r\n            if (_isDocPreviewMob) {\r\n                $dropZone.closest('.OrdiMobileConteneurClass').css('overflow', 'visible');\r\n                $dropZone.closest('.OrdiMobileConteneurClass').parent().css('overflow', 'visible');\r\n            }\r\n            \/\/ \u2705 v2.4.9 : Ele0A popup mobile \u2014 neutraliser translateY(-32px) pos\u00e9 par Entete sur EnvoiUlterieurTexte\r\n            var _isEle0AMob = ($dropZone.closest('.droppable').attr('id') === 'Ele0A');\r\n            if (_isEle0AMob) {\r\n                var $_euTxt = $dropZone.closest('.droppable').find('.EnvoiUlterieurTexte');\r\n                if ($_euTxt[0]) {\r\n                    $_euTxt[0].style.setProperty('transform', 'translateY(0px)', 'important');\r\n                    $_euTxt[0].style.setProperty('margin-top', '0px', 'important');\r\n                }\r\n            }\r\n            \/\/ \u2705 v2.4.12 : AchatEspaceCall=Yes \u2192 override margins (m\u00eame correction que pour upload direct)\r\n            if (StateManager.get('AchatEspaceCall') === 'Yes') {\r\n                $dropZone.css({'margin-top': '0px', 'margin-bottom': '0px', 'top': '0px'});\r\n                var _docHAchatMini = _isDocPreviewMob ? 150 : 112;\r\n                $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n                    'margin-top': '70px',\r\n                    'margin-bottom': '35px',\r\n                    'min-height': _docHAchatMini + 'px',\r\n                    'height': _isDocPreviewMob ? _docHAchatMini + 'px' : '',\r\n                    'max-height': _isDocPreviewMob ? _docHAchatMini + 'px' : ''\r\n                });\r\n                console.log('\ud83d\udcf1 [miniature] AchatEspaceCall=Yes OVERRIDE: mt=70px | docPreview:', _isDocPreviewMob);\r\n            }\r\n            return;\r\n        }\r\n        \/\/ \u2705 v2.4.10 : Miniature DESKTOP \u2192 layout normal appliqu\u00e9 ci-dessous\r\n        if (_isMiniatureAdj) {\r\n            \/\/ Pas de overflow:hidden \u2014 le liser\u00e9 box-shadow inset doit rester visible\r\n        }\r\n\r\n        $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n            'min-height': '112px',\r\n            'margin-top': '-85px',\r\n            \/\/ \u2705 v2.4.10 : Miniature desktop \u2014 pas de margin-bottom excessif qui fait grandir le droppable\r\n            'margin-bottom': _isMiniatureAdj ? '0px' : '20px' \/\/ \u2705 v2.6 : 195px \u2192 59px \u2192 20px (\u00f73) espace sous checkbox R\u00e9server\r\n        });\r\n        console.log('\ud83d\udcf1 HTMLUploadfileConteneur margins set: mt=-85px mb=20px, el found:', $dropZone.closest('.HTMLUploadfileConteneur').length);\r\n        \r\n        $dropZone.css({\r\n            'margin-top': '-50px',\r\n            'margin-bottom': '-140px'\r\n        });\r\n        \r\n        $dropZone.closest('.OrdiMobileConteneurClass').css({\r\n            'margin-top': '65px',\r\n            'margin-bottom': '-10px'\r\n        });\r\n        console.log('\ud83d\udcf1 OrdiMobile margins set: mt=65px mb=-10px');\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            \/\/ \u2705 v2.4.12 : Reset $dropZone margins (les -50px\/-140px tirent le contenu vers le haut dans l'iframe)\r\n            \/\/ Pour doc-preview (Communiqu\u00e9\/Interview), la hauteur est plus grande \u2192 ajuster min-height\r\n            var _isDocPreviewAchat = $dropZone.find('.doc-preview-container').length > 0;\r\n            var _docHAchat = _isDocPreviewAchat ? 150 : 112;\r\n            $dropZone.css({'margin-top': '0px', 'margin-bottom': '0px', 'top': '0px'});\r\n            $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n                \/\/ \u2705 v2.4.13 : Miniature desktop \u2192 +40px suppl\u00e9mentaires pour compenser le d\u00e9calage\r\n                'margin-top': _isMiniatureAdj ? '110px' : '70px',\r\n                'margin-bottom': '35px',\r\n                'min-height': _docHAchat + 'px',\r\n                'height': _isDocPreviewAchat ? _docHAchat + 'px' : '',\r\n                'max-height': _isDocPreviewAchat ? _docHAchat + 'px' : ''\r\n            });\r\n            console.log('\ud83d\udcf1 AchatEspaceCall=Yes OVERRIDE: mt=' + (_isMiniatureAdj ? '110px' : '70px') + ' | docPreview:', _isDocPreviewAchat, '| h:', _docHAchat);\r\n        }\r\n        \r\n        if (location.pathname === '\/annonce' || location.pathname === '\/annonce\/') {\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css({'margin-top': '70px'});\r\n        }\r\n        \r\n        if (window === window.top) {\r\n            console.log('\ud83d\udcf1 window===window.top OVERRIDE droppable margins');\r\n            $dropZone.closest('.droppable').css({\r\n                'margin-top': '-100px',\r\n                'margin-bottom': '-100px'\r\n            });\r\n            $dropZone.closest('#UploadFileConteneur').css({'width': '80%'});\r\n        }        \r\n    },\r\n    \r\n    adjustDesktopLayout($dropZone) {\r\n        const emplacement = StateManager.get('Commande_Emplacement_Page_Web');\r\n        const $droppable = $dropZone.closest('.droppable');\r\n        \/\/ \u2705 v2.4.13 : Lire et resetter _dropFromMiniature ici aussi (desktop)\r\n        var _fromMiniatureDesktop = window._dropFromMiniature || ($droppable[0] ? $droppable[0].getAttribute('data-kit-drop') === 'true' : false);\r\n        window._dropFromMiniature = false;\r\n        \/\/ \u2705 Nettoyer data-kit-drop apr\u00e8s lecture\r\n        if ($droppable[0]) { $droppable[0].removeAttribute('data-kit-drop'); }\r\n        \r\n        \/\/ \u2705 Masquer les textes enfants (position, label, r\u00e9f\u00e9rence) sans toucher au conteneur\r\n        $droppable\r\n            .find('.PositionEspacePublicitaire, .ReferenceEspacePublicitaire, .ChoisirEspacePublicitaireDisponibiliteConteneur > div > .elementor-widget-text-editor')\r\n            .hide();\r\n        \r\n        \/\/ \u2705 +15px sur .droppable \u2014 sauf si drop depuis miniature (dimensions naturelles)\r\n        if (!_fromMiniatureDesktop) {\r\n            const currentMt = parseInt($droppable.css('margin-top')) || 0;\r\n            $droppable.css('margin-top', (currentMt + 15) + 'px');\r\n        } else {\r\n            \/\/ \u2705 v2.4.13 : Drop depuis miniature Kit \u2014 d\u00e9caler de 30px vers le bas\r\n            const currentMt = parseInt($droppable.css('margin-top')) || 0;\r\n            \/\/ \u2705 Homepage : -20px (annonce trop basse sur r\u00e9gie) \u2014 autres pages : +70px\r\n            var _mtOffsetMini = (window.location.pathname === '\/' || window.location.pathname === '\/en\/' || window.location.pathname === '\/fr\/') ? -20 : 70;\r\n            $droppable.css('margin-top', (currentMt + _mtOffsetMini) + 'px');\r\n        }\r\n        \r\n        $dropZone.closest('.OrdiMobileConteneurClass')\r\n            .find('.RefEspacePublicitaire')\r\n            .html(emplacement)\r\n            .attr('id', 'RefEspacePublicitaire')\r\n            .each(function() {\r\n                \/\/ \u2705 Forcer aussi le parent .DeplaceAnnonce visible (display:none !important inline)\r\n                var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                this.style.setProperty('display', 'block', 'important');\r\n            });\r\n        \/\/ \u2705 v2.4.5 : Renseigner et afficher .PositionEspacePublicitaire\r\n        (function() {\r\n            var _rankPos = StateManager.get('Rank_Emplacement_Page_Web') || $droppable.attr('id') || '';\r\n            var _posLib = PreviewRenderer._getPositionLibelle(_rankPos);\r\n            if (_posLib) {\r\n                $dropZone.closest('.OrdiMobileConteneurClass')\r\n                    .find('.PositionEspacePublicitaireDeplacer')\r\n                    .text(_posLib)\r\n                    .each(function() {\r\n                        var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                        if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                        this.style.setProperty('display', 'block', 'important');\r\n                    });\r\n            }\r\n        })();\r\n        \r\n        if (window.location.pathname === \"\/\" || window.location.pathname === \"\/en\/\") {\r\n            \/\/ \u2705 v2.4.10 : top selon contexte \u2014 espaces hors .remainingContent d\u00e9calent de 60px, ceux dedans de 20px\r\n            var _inRemainingContent = $dropZone.closest('.remainingContent').length > 0;\r\n            var _topOffsetHP = _inRemainingContent ? '20px' : '100px';\r\n            $dropZone.closest('.ToBeHidden')\r\n                .css('top', _topOffsetHP)\r\n                .css('min-height', '300px');\r\n            \/\/ NB : pas de overflow:hidden ici \u2014 le liser\u00e9 vert (box-shadow inset sur HTMLUploadfileConteneur)\r\n            \/\/ doit rester visible sur les 4 c\u00f4t\u00e9s\r\n        }\r\n        \r\n        \/\/ \u2705 Toutes pages desktop : rendre le parent du droppable non-clippant\r\n        \/\/ Le bouton R\u00e9server est ins\u00e9r\u00e9 apr\u00e8s .droppable avec margin-top n\u00e9gatif \u2014\r\n        \/\/ overflow:hidden sur le parent Elementor le masque sinon.\r\n        $droppable.parent().css('overflow', 'visible');\r\n        \r\n        if (location.pathname === '\/annonce' || location.pathname === '\/annonce\/') {\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css({'margin-top': '0px'});\r\n        }\r\n    }\r\n};\r\n\r\n\/**\r\n * \u2705 Module de gestion des formats et du titre .SelectionFormatTitre\r\n *\/\r\nconst FormatUIManager = {\r\n    \r\n    \/**\r\n     * V\u00e9rifie si un format est s\u00e9lectionn\u00e9 dans un espace publicitaire\r\n     * V\u00e9rifie le background-color OU le sessionStorage (format venant de l'accord\u00e9on)\r\n     *\/\r\n    hasSelectedFormat($element) {\r\n        const $droppable = $element.closest('.droppable');\r\n        const isEle0A = $droppable.attr('id') === 'Ele0A';\r\n        if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n            if (isEle0A) {\r\n                \/\/ \u2705 v2.3.4 : Ele0A popup \u2014 vrai seulement si un format sous-jacent (hors FormatIdPopUp) est s\u00e9lectionn\u00e9\r\n                var _hasDomFmt = $droppable.find('.EspPubFormatContainer').not('.FormatIdPopUp').toArray().some(el => {\r\n                    return $(el).css('background-color') === 'rgb(255, 255, 255)';\r\n                });\r\n                if (_hasDomFmt) return true;\r\n                \/\/ \u2705 v2.4.5 : Fallback sessionStorage \u2014 DOM pas encore mis \u00e0 jour (timing MutationObserver)\r\n                return !!sessionStorage.getItem('FormatSelect');\r\n            }\r\n            \/\/ Autres espaces en mode popup \u2192 toujours vrai\r\n            return true;\r\n        }\r\n        const hasWhiteBg = $droppable.find('.EspPubFormatContainer').toArray().some(el => {\r\n            return $(el).css('background-color') === 'rgb(255, 255, 255)';\r\n        });\r\n        if (hasWhiteBg) return true;\r\n        \/\/ \u2705 v1.16.0 : Fallback sessionStorage Formatchoisi\r\n        if (sessionStorage.getItem('Formatchoisi') === 'Yes') return true;\r\n        \/\/ \u2705 v2.4.5 : Fallback FormatSelect \u2014 cas du chargement initial avec format d\u00e9j\u00e0 s\u00e9lectionn\u00e9\r\n        \/\/ (Formatchoisi peut \u00eatre remis \u00e0 No au chargement, mais FormatSelect persiste)\r\n        if (sessionStorage.getItem('FormatSelect')) return true;\r\n        \/\/ \u2705 v2.4.9 : Fallback _FormatSelectApplied \u2014 survit au clear de yearbook-media.js init\r\n        return !!sessionStorage.getItem('_FormatSelectApplied');\r\n    },\r\n    \r\n    \/**\r\n     * Met \u00e0 jour la couleur du titre .SelectionFormatTitre\r\n     * Blanc si un format est s\u00e9lectionn\u00e9, rouge #FB5E2A sinon\r\n     *\/\r\n    updateTitleColor($droppable) {\r\n        \/\/ \u2705 v2.4.5 : Ele0A \u2014 ne jamais afficher SelectionFormatTitre\r\n        if (sessionStorage.getItem('PopUpChoice') === 'Yes' && $droppable.attr('id') === 'Ele0A') {\r\n            $droppable.find('.SelectionFormatTitre').hide();\r\n            $droppable.find('.SelectionFormatTitreBlanc').show();\r\n            return;\r\n        }\r\n\r\n        if (this.hasSelectedFormat($droppable)) {\r\n            $droppable.find('.SelectionFormatTitre').hide();\r\n            $droppable.find('.SelectionFormatTitreBlanc').show();\r\n            console.log('\u2705 SelectionFormatTitreBlanc affich\u00e9 (format s\u00e9lectionn\u00e9)');\r\n        } else {\r\n            $droppable.find('.SelectionFormatTitre').show();\r\n            $droppable.find('.SelectionFormatTitreBlanc').hide();\r\n            console.log('\u26a0\ufe0f SelectionFormatTitre affich\u00e9 (aucun format s\u00e9lectionn\u00e9)');\r\n        }\r\n    },\r\n    \r\n    \/**\r\n     * Flash visuel sur le titre pour indiquer qu'un format est requis\r\n     *\/\r\n    flashTitle($element) {\r\n        const $droppable = $element.closest('.droppable');\r\n        const $titre = $droppable.find('.SelectionFormatTitre');\r\n        if (!$titre.length) return;\r\n        \r\n        \/\/ Flash rouge rapide 3 fois\r\n        let count = 0;\r\n        const originalColor = $titre.css('color');\r\n        \r\n        const flash = setInterval(() => {\r\n            $titre.css('color', count % 2 === 0 ? '#FF0000' : '#FB5E2A');\r\n            count++;\r\n            if (count >= 6) {\r\n                clearInterval(flash);\r\n                $titre.css('color', '#FB5E2A');\r\n            }\r\n        }, 250);\r\n        \r\n        console.log('\u26a0\ufe0f Flash titre format - action bloqu\u00e9e (aucun format s\u00e9lectionn\u00e9)');\r\n    },\r\n    \r\n    \/**\r\n     * Met \u00e0 jour l'\u00e9tat de la checkbox \"R\u00e9server cet espace publicitaire\"\r\n     * La checkbox est activable si : format s\u00e9lectionn\u00e9 ET (fichier d\u00e9pos\u00e9 OU envoi diff\u00e9r\u00e9)\r\n     *\/\r\n    updateReserverCheckboxState($droppable) {\r\n        \/\/ \u2705 Chercher le label : dynamique ou Elementor statique\r\n        let $label = null;\r\n        let $container = null;\r\n        \r\n        \/\/ 1. Bouton dynamique dans le droppable\r\n        $container = $droppable.find('.reserver-dynamic-container');\r\n        if (!$container.length) {\r\n            $container = $droppable.next('.reserver-dynamic-container');\r\n        }\r\n        if (!$container.length) {\r\n            \/\/ Mobile : checkbox attach\u00e9e au body avec data-droppable-id\r\n            $container = $('body > .reserver-dynamic-container[data-droppable-id=\"' + $droppable.attr('id') + '\"]');\r\n        }\r\n        if (!$container.length) {\r\n            $container = $('body > .reserver-dynamic-container');\r\n        }\r\n        \r\n        if ($container.length) {\r\n            $label = $container.find('.reserver-dynamic-label');\r\n            $container.find('.reserver-dynamic-option, .elementor-field-option').css('opacity', '1');\r\n        }\r\n        \r\n        \/\/ 2. Bouton Elementor statique - chercher dans le droppable puis globalement\r\n        let $reserverStatique = $droppable.find('.elementor-field-group-ReserverEspacePublicitaire label');\r\n        if (!$reserverStatique.length) {\r\n            $reserverStatique = $droppable.find('label[for^=\"form-field-ReserverEspacePublicitaire\"]');\r\n        }\r\n        if (!$reserverStatique.length) {\r\n            \/\/ Fallback global : le formulaire peut \u00eatre en dehors du droppable\r\n            $reserverStatique = $('.elementor-field-group-ReserverEspacePublicitaire .elementor-field-option label');\r\n        }\r\n        \r\n        const hasFormat = this.hasSelectedFormat($droppable);\r\n        const hasFile = StateManager.get('FileReceived') === 'Yes';\r\n        const hasEnvoiDiffere = $droppable.find('input[name*=\"EnvoiUlterieur\"]:checked').length > 0;\r\n        \r\n        const canReserve = hasFormat && (hasFile || hasEnvoiDiffere);\r\n        \r\n        \/\/ \u2705 Si la checkbox R\u00e9server est coch\u00e9e \u2192 label vert \"Espace publicitaire r\u00e9serv\u00e9\"\r\n        const isChecked = $droppable.find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').prop('checked') ||\r\n                          ($container.length && $container.find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').prop('checked'));\r\n        \/\/ \u2705 v2.4.7 : Signal de restauration r\u00e9serv\u00e9e \u2014 checkbox pas encore coch\u00e9e (setTimeout 150ms)\r\n        \/\/             mais on sait d\u00e9j\u00e0 que l'espace est r\u00e9serv\u00e9 \u2192 traiter comme coch\u00e9\r\n        const _isReservedRestoration = sessionStorage.getItem('_isReservedRestoration') === 'Yes';\r\n        const isCheckedOrReservedRestore = isChecked || _isReservedRestoration;\r\n        \r\n        if ($label && $label.length) {\r\n            if (isCheckedOrReservedRestore) {\r\n                $label.text('Espace publicitaire r\u00e9serv\u00e9').css('color', 'rgb(62, 170, 19)');\r\n            } else {\r\n                $label.text('R\u00e9server cet espace publicitaire').css('color', canReserve ? '#FB5E2A' : '');\r\n            }\r\n        }\r\n        if ($reserverStatique.length) {\r\n            if (isCheckedOrReservedRestore) {\r\n                $reserverStatique.attr('style', 'color: rgb(62, 170, 19) !important;');\r\n            } else if (canReserve) {\r\n                $reserverStatique.attr('style', 'color: #FB5E2A !important;');\r\n            } else {\r\n                $reserverStatique.removeAttr('style');\r\n            }\r\n        }\r\n        \r\n        console.log('\ud83d\udd04 updateReserverCheckboxState:', { hasFormat, hasFile, hasEnvoiDiffere, canReserve, dynamicLabel: !!($label && $label.length), staticLabel: $reserverStatique.length });\r\n    },\r\n    \r\n    \/**\r\n     * Initialise les listeners pour le changement de format et la checkbox R\u00e9server\r\n     *\/\r\n    init() {\r\n        \/\/ \u2705 \u00c9couter les clics sur les conteneurs de format et leurs parents\r\n        jQuery(document).on('click', '.EspPubFormatContainer, .EspPubFormatListe, .EspPubFormatMainContainer', (e) => {\r\n            const $droppable = jQuery(e.target).closest('.droppable');\r\n            if (!$droppable.length) return;\r\n            \r\n            \/\/ Multiples d\u00e9lais pour couvrir les traitements asynchrones\r\n            [50, 200, 500].forEach(delay => {\r\n                setTimeout(() => {\r\n                    this.updateTitleColor($droppable);\r\n                    this.updateReserverCheckboxState($droppable);\r\n                }, delay);\r\n            });\r\n\r\n            \/\/ \u2705 v2.2.0 : Si un format (non Cr\u00e9ation) est cliqu\u00e9, notifier le parent pour mettre \u00e0 jour le Kit\r\n            const $btn = jQuery(e.target).closest('.EspPubFormatContainer');\r\n            if ($btn.length && !$btn.hasClass('FormatIdCreation') && !$btn.hasClass('FormatIdPopUp')) {\r\n                \/\/ \u2705 v2.3.4 : FormatIdPopUp g\u00e9r\u00e9 par clickFormatFromIframe (Entete.txt) \u2014 ne pas doubler\r\n                var classes = $btn.attr('class') || '';\r\n                var match = classes.match(\/FormatId(\\w+)\/);\r\n                if (match && match[1]) {\r\n                    var _rankEP = $droppable.attr('id') || '';\r\n                    setTimeout(function() {\r\n                        MessageManager.sendToParent('formatChangedInIframe', { formatSelect: match[1], rank: _rankEP });\r\n                        console.log('\ud83d\udd04 formatChangedInIframe envoy\u00e9:', match[1], '| rank:', _rankEP);\r\n                    }, 100);\r\n                }\r\n            }\r\n        });\r\n        \r\n        \/\/ \u2705 MutationObserver sur les conteneurs de format pour d\u00e9tecter les changements de style\r\n        setTimeout(() => {\r\n            this.observeFormatChanges();\r\n            \r\n            \/\/ Initialiser les couleurs des titres au chargement\r\n            jQuery('.droppable').each((i, el) => {\r\n                this.updateTitleColor(jQuery(el));\r\n            });\r\n            \r\n            \/\/ \u2705 v2.3.4 : Popup \u2192 restaurer FormatIdPopUp + format sous-jacent (sans \u00e9craser applyFormatState)\r\n            if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n                jQuery('.FormatIdPopUp').css({'background-color': '#ffffff'});\r\n                jQuery('.FormatIdPopUp').find('.EspPubFormat').css({'color': '#37D900'});\r\n                \/\/ Restaurer aussi le format sous-jacent dans Ele0A\r\n                var _fmtSS = sessionStorage.getItem('FormatSelect') || '';\r\n                if (_fmtSS) {\r\n                    var _fmtSSNorm = _fmtSS.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                    jQuery('#Ele0A').find('.EspPubFormatContainer').not('.FormatIdCreation').each(function() {\r\n                        var _cls = this.className.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                        if (_cls.includes(_fmtSSNorm)) {\r\n                            jQuery(this).css({'background-color': '#ffffff'});\r\n                            jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                        }\r\n                    });\r\n                }\r\n                jQuery('.droppable').each((i, el) => {\r\n                    this.updateTitleColor(jQuery(el));\r\n                });\r\n            }\r\n        }, 500);\r\n        \r\n        \/\/ \u2705 v1.16.0 : Re-v\u00e9rifier apr\u00e8s un d\u00e9lai plus long (format venant de l'accord\u00e9on via postMessage)\r\n        [1500, 3000].forEach(delay => {\r\n            setTimeout(() => {\r\n                \/\/ \u2705 v2.3.4 : Popup \u2192 restaurer FormatIdPopUp + format sous-jacent\r\n                if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n                    jQuery('.FormatIdPopUp').css({'background-color': '#ffffff'});\r\n                    jQuery('.FormatIdPopUp').find('.EspPubFormat').css({'color': '#37D900'});\r\n                    var _fmtSSR = sessionStorage.getItem('FormatSelect') || '';\r\n                    if (_fmtSSR) {\r\n                        var _fmtSSRNorm = _fmtSSR.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                        jQuery('#Ele0A').find('.EspPubFormatContainer').not('.FormatIdCreation').each(function() {\r\n                            var _cls = this.className.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                            if (_cls.includes(_fmtSSRNorm)) {\r\n                                jQuery(this).css({'background-color': '#ffffff'});\r\n                                jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                            }\r\n                        });\r\n                    }\r\n                    jQuery('.droppable').each((i, el) => {\r\n                        this.updateTitleColor(jQuery(el));\r\n                    });\r\n                    return;\r\n                }\r\n                if (sessionStorage.getItem('Formatchoisi') === 'Yes') {\r\n                    jQuery('.droppable').each((i, el) => {\r\n                        this.updateTitleColor(jQuery(el));\r\n                    });\r\n                }\r\n            }, delay);\r\n        });\r\n    },\r\n    \r\n    \/**\r\n     * Attache un MutationObserver sur chaque .EspPubFormatContainer\r\n     * pour d\u00e9tecter tout changement de style (background-color) \r\n     * quel que soit le script qui le d\u00e9clenche\r\n     *\/\r\n    observeFormatChanges() {\r\n        \/\/ \u2705 Guard global anti-boucle \u2014 un seul verrou pour tous les observers\r\n        window._formatObserverLocked = false;\r\n        \r\n        jQuery('.EspPubFormatContainer').each((i, el) => {\r\n            const observer = new MutationObserver(() => {\r\n                if (window._formatObserverLocked) return;\r\n                window._formatObserverLocked = true;\r\n                \/\/ \u2705 v2.4.12 : Debounce 150ms \u2014 applyFormatState manipule plusieurs containers\r\n                \/\/ en s\u00e9quence rapide, le MutationObserver peut firer sur un \u00e9tat interm\u00e9diaire\r\n                clearTimeout(window._formatObserverTimer);\r\n                window._formatObserverTimer = setTimeout(() => {\r\n                    const $droppable = jQuery(el).closest('.droppable');\r\n                    this.updateTitleColor($droppable);\r\n                    this.updateReserverCheckboxState($droppable);\r\n                    window._formatObserverLocked = false;\r\n                }, 150);\r\n            });\r\n            observer.observe(el, { \r\n                attributes: true, \r\n                attributeFilter: ['style', 'class'] \r\n            });\r\n        });\r\n        console.log('\u2705 MutationObserver attach\u00e9 aux conteneurs de format');\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de communication avec la page parente\r\n *\/\r\nconst MessageManager = {\r\n    sendToParent(type, data = {}) {\r\n        try {\r\n            window.parent.postMessage({\r\n                type: type,\r\n                iframeId: CONFIG.iframeId,\r\n                data: data\r\n            }, '*');\r\n        } catch (error) {\r\n            console.error('Error sending message to parent:', error);\r\n            window.parent.postMessage({\r\n                type: 'error',\r\n                error: error.message,\r\n                iframeId: CONFIG.iframeId\r\n            }, '*');\r\n        }\r\n    },\r\n    \r\n    sendDataToParent(data) {\r\n        this.sendToParent('dataFromIframeEspacePub', data);\r\n    },\r\n    \r\n    sendDelAdToParent(data) {\r\n        this.sendToParent('dataDelAd', data);\r\n    },\r\n    \r\n    prepareUploadData() {\r\n        const keys = [\r\n            'AddNewRefInVosCampagnes',\r\n            'FirstUploadFileorMoved',\r\n            'LoadedPageUrl',\r\n            'codePage',\r\n            'Rank_Emplacement_Page_Web',\r\n            'Commande_Emplacement_Page_Web',\r\n            'dragstart_Commande_Emplacement_Page_Web',\r\n            'dragstart_Rank_Emplacement_Page_Web',  \r\n            'FullPathAdFile',\r\n            'Upload_File_Name',\r\n            'FileReceived',\r\n            'PageWebDisplayed',\r\n            'Commande_Format_Transmis',\r\n            'EspPubLienAnnonce',\r\n            'EnvoiUlterieur',\r\n            'Formatchoisi'\r\n        ];\r\n        \r\n        const data = StateManager.getMultiple(keys);\r\n        \r\n        \/\/ \u2705 v2.3.4 : Popup (Ele0A) \u2014 lire le format sous-jacent depuis le DOM\r\n        \/\/ StateManager contient 'PopUp' (virtuel), mais le vrai format est visuellement s\u00e9lectionn\u00e9 dans #Ele0A\r\n        if (data.Rank_Emplacement_Page_Web === 'Ele0A' || sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n            var _ele0AFormatDOM = '';\r\n            jQuery('#Ele0A').find('.EspPubFormatContainer').not('.FormatIdPopUp').each(function() {\r\n                if (jQuery(this).css('background-color') === 'rgb(255, 255, 255)') {\r\n                    var _cls = this.className || '';\r\n                    var _match = _cls.match(\/FormatId(\\S+)\/);\r\n                    if (_match) { _ele0AFormatDOM = _match[1]; return false; }\r\n                }\r\n            });\r\n            if (_ele0AFormatDOM) {\r\n                data.Commande_Format_Transmis = _ele0AFormatDOM;\r\n            }\r\n        }\r\n        \r\n        console.log('\ud83d\udce4 prepareUploadData:', {\r\n            FirstUploadFileorMoved: data.FirstUploadFileorMoved,\r\n            dragstart_Commande_Emplacement_Page_Web: data.dragstart_Commande_Emplacement_Page_Web,\r\n            Commande_Emplacement_Page_Web: data.Commande_Emplacement_Page_Web\r\n        });\r\n    \r\n        return data;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de rendu des aper\u00e7us de fichiers\r\n *\/\r\nconst PreviewRenderer = {\r\n    _getPositionLibelle(rankId) {\r\n        if (!rankId) return '';\r\n        var match = rankId.match(\/Ele(\\d+)[A-Z]\/);\r\n        if (!match) return '';\r\n        var rang = parseInt(match[1]);\r\n        if (rang === 0) return 'Pop-up';\r\n        if (rang === 1 || rang === 2) return 'Haut de page';\r\n        return 'Corps de page';\r\n    },\r\n    renderVideo(objectUrl, fileName, $dropZone) {\r\n        const videoElement = jQuery('<video controls autoplay muted>').attr({\r\n            'src': objectUrl,\r\n            'width': 'auto',\r\n            'height': 'auto',\r\n            'id': fileName\r\n        }).css({\r\n            'max-width': '100%',\r\n            'max-height': '100%'\r\n        });\r\n        \r\n        if (UIManager.isDesktop()) {\r\n            $dropZone.empty().append(videoElement.clone());\r\n            jQuery('#ApercuMobile').css({\r\n                'display': 'flex',\r\n                'justify-content': 'center',\r\n                'align-items': 'center'\r\n            }).append(videoElement);\r\n        } else {\r\n            const img = document.createElement('img');\r\n            img.src = objectUrl;\r\n            img.style.width = 'auto';\r\n            img.style.height = 'auto';\r\n            img.style.maxWidth = 'calc(100% - 4px)';  \/\/ \u2705 v2.4.5 : 2px retrait inset box-shadow\r\n            img.style.maxHeight = '115px';\r\n            \r\n            const container = $dropZone[0];\r\n            while (container.firstChild) {\r\n                container.removeChild(container.firstChild);\r\n            }\r\n            container.appendChild(img);\r\n        }\r\n        \r\n        StateManager.setMultiple({\r\n            'Commande_Format': 'Vid\u00e9o',\r\n            'Commande_Format_Transmis': 'Vid\u00e9o',\r\n            'videoSrc': objectUrl,\r\n            'FormatAnnonceSelection': 'Yes',\r\n            'PositionAnnonceSelection': 'Yes'\r\n        });\r\n        \r\n        jQuery('#FormatDataStep3').html('Vid\u00e9o').css({'color': '#56BE50'});\r\n        jQuery('#TarifDataStep3').css({'color': '#96894D'});\r\n    },\r\n    \r\n    renderImage(objectUrl, $dropZone) {\r\n        const maxHeight = UIManager.isMobile() ? 105 : $dropZone.closest('.HTMLUploadfileConteneur').height();\r\n    \r\n        $dropZone.css({\r\n            'display': 'flex',\r\n            'justify-content': 'center',\r\n            'align-items': 'center',\r\n            'width': '100%',\r\n            'height': maxHeight + 'px',\r\n            'overflow': 'hidden',\r\n            'position': UIManager.isMobile() ? 'relative' : '',\r\n            'top': UIManager.isMobile() ? '45px' : '',\r\n            'padding': UIManager.isMobile() ? '0 2px' : ''  \/\/ \u2705 v2.4.5 : 2px retrait inset box-shadow mobile\r\n        });\r\n    \r\n        \/\/ \u2705 v1.19.2 : Image charg\u00e9e en arri\u00e8re-plan, remplace le message d'attente au onload\r\n        \/\/ \u2705 v2.4.5 : max-width calc(100%-4px) sur mobile pour ne pas recouvrir le box-shadow inset 2px\r\n        var _mxw = UIManager.isMobile() ? 'calc(100% - 4px)' : '100%';\r\n        var img = new Image();\r\n        img.style.cssText = 'max-width:' + _mxw + '; max-height:' + maxHeight + 'px; width:auto; height:auto; object-fit:contain;';\r\n        img.onload = function() {\r\n            $dropZone.empty().append(img);\r\n        };\r\n        img.onerror = function() {\r\n            $dropZone.html('<img decoding=\"async\" src=\"' + objectUrl + '\" style=\"max-width:' + _mxw + '; max-height:' + maxHeight + 'px; width:auto; height:auto; object-fit:contain;\">');\r\n        };\r\n        img.src = objectUrl;\r\n    \r\n        StateManager.setMultiple({\r\n            'Commande_Format_Transmis': 'Image',\r\n            'FormatAnnonceSelection': 'Yes',\r\n            'PositionAnnonceSelection': 'Yes'\r\n        });\r\n    \r\n        console.log('Image ajout\u00e9e avec succ\u00e8s');\r\n    },\r\n    \r\n    async renderWord(fileObj, $dropZone) {\r\n        return new Promise((resolve, reject) => {\r\n            const reader = new FileReader();\r\n            \r\n            reader.onload = async (e) => {\r\n                try {\r\n                    const arrayBuffer = e.target.result;\r\n                    const result = await mammoth.convertToHtml({arrayBuffer: arrayBuffer});\r\n                    \r\n                    const htmlContent = result.value;\r\n                    const tempContainer = document.createElement('div');\r\n                    tempContainer.innerHTML = htmlContent;\r\n                    \r\n                    const textContent = tempContainer.textContent || \"\";\r\n                    const normalizedText = this.normalizeText(textContent);\r\n                    const firstImage = tempContainer.querySelector('img');\r\n                    \r\n                    const titleText = this.findDocumentTitle(normalizedText);\r\n                    \r\n                    if (firstImage) {\r\n                        this.renderDocumentPreview(\r\n                            $dropZone,\r\n                            firstImage.src,\r\n                            titleText,\r\n                            textContent,\r\n                            htmlContent\r\n                        );\r\n                    } else {\r\n                        \/\/ \u2705 v1.19.0 : Accepter les documents sans image\r\n                        this.renderDocumentPreview(\r\n                            $dropZone,\r\n                            null,\r\n                            titleText,\r\n                            textContent,\r\n                            htmlContent\r\n                        );\r\n                        console.log('\u2139\ufe0f Document Word sans image \u2014 aper\u00e7u texte seul');\r\n                    }\r\n                    resolve();\r\n                } catch (error) {\r\n                    $dropZone.html(`<p style=\"color: #FB5E2A; font-weight: 600; font-family: Roboto, Arial, sans-serif; font-size: 12px; text-align: center; padding: 15px;\">Erreur lors de la lecture du document<\/p>`);\r\n                    reject(error);\r\n                }\r\n            };\r\n            \r\n            reader.readAsArrayBuffer(fileObj);\r\n        });\r\n        \r\n        this.finalizeRedactionnelUpload();\r\n    },\r\n    \r\n    renderDocumentPreview($dropZone, imageSrc, title, text, htmlContent = null) {\r\n        \/\/ \u2705 v1.19.0 : Deux layouts \u2014 avec image ou texte seul\r\n        let previewHtml;\r\n\r\n        if (imageSrc) {\r\n            \/\/ Layout avec miniature image\r\n            previewHtml = `\r\n                <div class=\"doc-preview-container\">\r\n                    <div class=\"doc-preview-thumbnail\">\r\n                        <img decoding=\"async\" src=\"${imageSrc}\" alt=\"Document image\">\r\n                    <\/div>\r\n                    <div class=\"doc-preview-info\">\r\n                        <div class=\"doc-preview-title\" id=\"AdTitle\">${title}<\/div>\r\n                        <div class=\"doc-preview-description\" id=\"AdText\">${this.getTextPreview(text, 13)}<\/div>\r\n                        <div class=\"doc-preview-readmore\" id=\"AdLirelasuite\">Ouvrir et visualiser<\/div>\r\n                        <div class=\"doc-preview-FullPathAdFile\" id=\"AdFullPathAdFile\">${StateManager.get(\"FullPathAdFile\")}<\/div>\r\n                    <\/div>\r\n                <\/div>\r\n            `;\r\n        } else {\r\n            \/\/ Layout texte seul (sans image)\r\n            previewHtml = `\r\n                <div class=\"doc-preview-container doc-preview-noimage\">\r\n                    <div class=\"doc-preview-icon\">\r\n                        <svg width=\"36\" height=\"36\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#213864\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n                            <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"\/><polyline points=\"14 2 14 8 20 8\"\/><line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"\/><line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"\/><polyline points=\"10 9 9 9 8 9\"\/>\r\n                        <\/svg>\r\n                    <\/div>\r\n                    <div class=\"doc-preview-info doc-preview-info-full\">\r\n                        <div class=\"doc-preview-title\" id=\"AdTitle\">${title}<\/div>\r\n                        <div class=\"doc-preview-description\" id=\"AdText\">${this.getTextPreview(text, 25)}<\/div>\r\n                        <div class=\"doc-preview-readmore\" id=\"AdLirelasuite\">Ouvrir et visualiser<\/div>\r\n                        <div class=\"doc-preview-FullPathAdFile\" id=\"AdFullPathAdFile\">${StateManager.get(\"FullPathAdFile\")}<\/div>\r\n                    <\/div>\r\n                <\/div>\r\n            `;\r\n        }\r\n        \r\n        $dropZone.html(previewHtml + this.getPreviewStyles());\r\n        \r\n        if (htmlContent) {\r\n            this.attachWordPreviewHandler($dropZone, title, htmlContent);\r\n        }\r\n    },\r\n    \r\n    attachWordPreviewHandler($dropZone, titleText, htmlContent) {\r\n        var $droppable = $dropZone.closest('.droppable');\r\n\r\n        \/\/ \u2705 Adapter le libell\u00e9 selon le type de document\r\n        var isInterview = (titleText || '').toLowerCase().indexOf('interview') !== -1;\r\n        var formatLabel = isInterview ? 'l\\'interview' : 'le communiqu\u00e9';\r\n        $droppable.find('.doc-preview-readmore').text('Ouvrir et visualiser ' + formatLabel);\r\n\r\n        \/\/ \u2705 v2.0.11 : D\u00e9l\u00e9gation d'\u00e9v\u00e9nement \u2014 plus robuste sur mobile (survit aux manipulations DOM)\r\n        $droppable.off('click.docpreview').on('click.docpreview', '.doc-preview-readmore', (event) => {\r\n            event.preventDefault();\r\n            event.stopPropagation();\r\n            \r\n            if (htmlContent) {\r\n                var popupTitle = isInterview ? 'Interview' : 'Communiqu\u00e9';\r\n                PDFHandler.showInlineDocPopup($dropZone, {\r\n                    formatTitle: popupTitle,\r\n                    htmlContent: htmlContent\r\n                });\r\n            } else {\r\n                console.warn('Le document est encore en cours de traitement.');\r\n            }\r\n        });\r\n    },\r\n    \r\n    normalizeText(text) {\r\n        return text\r\n            .toLowerCase()\r\n            .normalize(\"NFD\")\r\n            .replace(\/[\\u0300-\\u036f]\/g, \"\");\r\n    },\r\n    \r\n    findDocumentTitle(normalizedText) {\r\n        const foundKeyword = CONFIG.keywords.find(keyword => \r\n            normalizedText.includes(keyword.normal)\r\n        );\r\n        if (foundKeyword) return foundKeyword.display;\r\n        \r\n        \/\/ \u2705 v1.19.1 : Fallback \u2014 utiliser le format s\u00e9lectionn\u00e9 (FormatSelect)\r\n        var formatSelect = (sessionStorage.getItem('FormatSelect') || '').toLowerCase();\r\n        if (formatSelect.indexOf('interview') !== -1) return 'Interview';\r\n        if (formatSelect.indexOf('communiq') !== -1) return 'Communiqu\u00e9';\r\n        \r\n        return \"Document\";\r\n    },\r\n    \r\n    getTextPreview(text, maxWords) {\r\n        const words = text.split(' ');\r\n        if (words.length > maxWords) {\r\n            return words.slice(0, maxWords).join(' ') + ' ...';\r\n        }\r\n        return text;\r\n    },\r\n    \r\n    getPreviewStyles() {\r\n        return `\r\n            <style>\r\n                @import url('https:\/\/fonts.googleapis.com\/css2?family=Roboto:wght@400;600&display=swap');\r\n                \r\n                .doc-preview-container {\r\n                    margin: 0px 0;\r\n                    display: flex;\r\n                    width: 100%;\r\n                    max-height: 140px;\r\n                    overflow: hidden;\r\n                    box-sizing: border-box;  \/* \u2705 v2.4.5 *\/\r\n                    background: white;\r\n                    background-color: #f8f8f8;\r\n                }\r\n                .doc-preview-thumbnail {\r\n                    width: 50%; \r\n                    height: 130px;\r\n                    overflow: hidden;\r\n                    display: flex;\r\n                    align-items: center;\r\n                    justify-content: center;\r\n                    margin-top: 0px;\r\n                }\r\n                .doc-preview-thumbnail img {\r\n                    max-width: 75%;\r\n                    max-height: 75%;\r\n                    object-position: center;\r\n                    object-fit: fill;\r\n                }\r\n                .doc-preview-info {\r\n                    width: 50%;\r\n                    height: 130px; \r\n                    flex: 1;\r\n                    padding: 10px;\r\n                    display: flex;\r\n                    flex-direction: column; \r\n                }\r\n                .doc-preview-title {\r\n                    font-family: 'Roboto', sans-serif;\r\n                    color: #213864;\r\n                    font-size: 14px;\r\n                    font-weight: 600;\r\n                    text-align: left;\r\n                    margin-bottom: 5px;\r\n                }\r\n                .doc-preview-description {\r\n                    font-family: 'Roboto', sans-serif;\r\n                    color: #213864;\r\n                    font-size: 11px;\r\n                    font-weight: 400;\r\n                    text-align: left;\r\n                    overflow: hidden;\r\n                    margin-bottom: 5px;\r\n                    flex: 1;\r\n                }\r\n                .doc-preview-readmore {\r\n                    font-family: 'Roboto', sans-serif;\r\n                    color: #958848;\r\n                    font-size: 13px;\r\n                    font-weight: 600;\r\n                    text-align: left;\r\n                    cursor: pointer;\r\n                    padding: 4px 0;\r\n                    -webkit-tap-highlight-color: rgba(149,136,72,0.2);\r\n                }\r\n                @media (max-width: 999px) {\r\n                    .doc-preview-readmore { font-size: 12px; }\r\n                    \/* \u2705 Laisser 3px tout autour pour que le liser\u00e9 vert (box-shadow\/outline sur parent) soit visible *\/\r\n                    .doc-preview-container {\r\n                        width: calc(100% - 16px) !important;\r\n                        max-height: 109px !important;\r\n                        margin: 3px !important;\r\n                        margin-top: 23px !important;\r\n                        box-sizing: border-box !important;\r\n                    }\r\n                }\r\n                .doc-preview-FullPathAdFile {\r\n                    display: none;\r\n                }\r\n                \/* \u2705 v1.19.0 : Layout sans image *\/\r\n                .doc-preview-noimage {\r\n                    flex-direction: row;\r\n                    align-items: flex-start;\r\n                    gap: 10px;\r\n                    padding: 8px 10px;\r\n                }\r\n                .doc-preview-icon {\r\n                    flex-shrink: 0;\r\n                    display: flex;\r\n                    align-items: center;\r\n                    justify-content: center;\r\n                    width: 44px;\r\n                    height: 44px;\r\n                    background: #eef2f7;\r\n                    border-radius: 6px;\r\n                    margin-top: 4px;\r\n                }\r\n                .doc-preview-info-full {\r\n                    width: 100%;\r\n                    height: auto;\r\n                    max-height: 130px;\r\n                }\r\n                .doc-preview-noimage .doc-preview-description {\r\n                    font-size: 11px;\r\n                    line-height: 1.35;\r\n                    max-height: 60px;\r\n                    overflow: hidden;\r\n                }\r\n            <\/style>\r\n        `;\r\n    },\r\n    \r\n    finalizeRedactionnelUpload() {\r\n        \/\/ \u2705 v1.19.5 : D\u00e9terminer le format r\u00e9dactionnel correct\r\n        \/\/ Si le format s\u00e9lectionn\u00e9 est \"Interview\", on garde \"Interview\"\r\n        \/\/ Sinon on met \"Communiqu\u00e9\" par d\u00e9faut (au lieu de \"R\u00e9dactionnel\" qui n'est pas un format tarifaire valide)\r\n        var formatSelect = sessionStorage.getItem('FormatSelect') || '';\r\n        var formatTransmis = 'Communiqu\u00e9'; \/\/ Par d\u00e9faut\r\n        \r\n        if (formatSelect.toLowerCase().indexOf('interview') !== -1) {\r\n            formatTransmis = 'Interview';\r\n        } else if (formatSelect.toLowerCase().indexOf('communiq') !== -1) {\r\n            formatTransmis = 'Communiqu\u00e9';\r\n        }\r\n        \r\n        StateManager.set('Commande_Format_Transmis', formatTransmis);\r\n        console.log('\u2705 Format r\u00e9dactionnel d\u00e9termin\u00e9:', formatTransmis, '(FormatSelect:', formatSelect, ')');\r\n        \r\n        if (StateManager.get(\"TarifDirectSelectionne\") === 'Yes') {\r\n            const formatText = jQuery('#FormatDataStep3').text();\r\n            if (formatText !== 'Vid\u00e9o' && formatText !== 'Banni\u00e8re') {\r\n                jQuery('#form-field-RedactionnelSelection')\r\n                    .val(formatText)\r\n                    .css({'color': '#56BE50'});\r\n            }\r\n        }\r\n        \r\n        RedactionnelDepose();\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'upload\r\n *\/\r\nconst UploadManager = {\r\n    isRunning: false,\r\n    \r\n    \/\/ \u2705 Reset manuel espace publicitaire\r\n    resetEspaceManuel: function($droppable) {\r\n        console.log('\ud83d\udd27 Reset manuel espace publicitaire');\r\n        \r\n        var $dropZone = $droppable.find('#drop_file_zone_achat');\r\n        var $uploadContainer = $droppable.find('.HTMLUploadfileConteneur');\r\n        var $container = $droppable.find('.OrdiMobileConteneurClass');\r\n        \r\n        \/\/ 1. Vider la zone de drop et restaurer le HTML par d\u00e9faut\r\n        $dropZone.empty().html(\r\n            '<div id=\"drag_upload_file_achat\">' +\r\n                '<p class=\"UploadIci\" style=\"color: #FB5E2A; font-weight: 600;\">Ici glisser \u2013 d\u00e9poser ou<br>t\u00e9l\u00e9charger une annonce<\/p>' +\r\n            '<\/div>'\r\n        );\r\n        \r\n        \/\/ 2. Afficher les \u00e9l\u00e9ments cach\u00e9s lors de l'upload\r\n        $droppable.find('.UploadIci').show();\r\n        $droppable.find('.EnvoiUlterieurTexte').show();\r\n        $droppable.find('.EnvoiUlterieurContainer').show();\r\n        $droppable.find('.EspPubFormatMainContainer').show();\r\n        $droppable.find('.EspPubFormatListe').show();\r\n        $droppable.find('.ChoisirEspacePublicitaireClass').show();\r\n        $droppable.find('.GlisserDeposerConteneur').show();\r\n        $droppable.find('.OUClass').show();\r\n        $droppable.find('.TexteMobileAnnonce').show();\r\n        $droppable.find('.PositionReference').show();\r\n        $droppable.find('.ClassHdpCdp').show();\r\n        $droppable.find('.ClassRefEsp').show();\r\n        \r\n        \/\/ 3. Cacher les \u00e9l\u00e9ments d'annonce upload\u00e9e\r\n        $droppable.find('.AdUploadedTitle').hide();\r\n        $droppable.find('#CroixResetAnnonce').hide();\r\n        $droppable.find('.CroixResetAnnonceContainer').hide();\r\n        $droppable.find('.DeplaceAnnonce').hide();\r\n        $droppable.find('.RefEspacePublicitaire').hide();\r\n        $droppable.find('.AdDroppedTextNotDisplayed').hide();\r\n        \r\n        \/\/ 4. Reset des styles\r\n        $uploadContainer.css({\r\n            'border': 'none',\r\n            'background-color': '',\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'min-height': ''\r\n        });\r\n        \r\n        $container.css({\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'top': '',\r\n            'height': ''\r\n        });\r\n        \r\n        \/\/ \u2705 Reset des positionnements desktop appliqu\u00e9s par adjustDesktopLayout\r\n        $droppable.closest('.ToBeHidden').css({'top': '', 'min-height': ''});\r\n        $droppable.parent().css('overflow', '');\r\n        \/\/ \u2705 v2.0.11 : Cleanup event namespace docpreview\r\n        $droppable.off('click.docpreview');\r\n        \r\n        \/\/ 5. Reset des formats s\u00e9lectionn\u00e9s\r\n        $droppable.find('.EspPubFormatContainer').css({\r\n            'background-color': '',\r\n            'border': ''\r\n        });\r\n        \r\n        \/\/ 6. Supprimer le bouton \"R\u00e9server\" dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ 7. Restaurer .PositionEspacePublicitaireContainer et .ReserverContainer\r\n        $droppable.find('.PositionEspacePublicitaireContainer').show();\r\n        $droppable.find('.ReserverContainer').hide();\r\n        \r\n        console.log('\u2705 Reset manuel termin\u00e9');\r\n    },\r\n    \r\n    async handleFileUpload(fileObj, $dropZone) {\r\n        console.log('fileObj:', fileObj);\r\n        \r\n        \/\/ \u2705 v2.4.6 : Contr\u00f4les d'extension EN PREMIER \u2014 avant tout affichage\r\n        const extension = FileManager.getExtension(fileObj.name);\r\n        StateManager.set('FileExtension', extension);\r\n        console.log('FileExtension:', extension);\r\n        \r\n        \/\/ \u2705 v2.6 : jpg\/jpeg accept\u00e9s sur desktop et mobile\r\n        \r\n        if (!FileManager.isAllowedExtension(extension)) {\r\n            UIManager.showFormatError($dropZone);\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 v1.19.5 : Afficher le message d'attente seulement si le format est valide\r\n        var _waitMsg = 'Loading in progress <span class=\"dot-container\"><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><\/span>';\r\n        $dropZone.html('<div class=\"ad-loading-msg\" style=\"color:#00ff19; background:white; padding:12px 20px; border-radius:6px; font-weight:700; text-align:center; font-size:18px; line-height:1.4;\">' + _waitMsg + '<\/div>');\r\n        \r\n        this.prepareUIForUpload($dropZone);\r\n        \r\n        const formData = new FormData();\r\n        formData.append('file', fileObj);\r\n        formData.append('action', 'upload_annonce_file_v3');\r\n        \r\n        UIManager.showUploadProgress($dropZone);\r\n        \r\n        try {\r\n            const response = await this.sendUploadRequest(formData);\r\n            await this.handleUploadResponse(response, fileObj, $dropZone, extension);\r\n        } catch (error) {\r\n            console.error('Upload error:', error);\r\n        }\r\n    },\r\n    \r\n    prepareUIForUpload($dropZone) {\r\n        if (!UIManager.isMobile()) {\r\n            jQuery('.ChoisirEspacePublicitaireClass').show();\r\n            jQuery('.ChoisirEspacePublicitaire2ndLigne').show();\r\n            jQuery('.GlisserDeposerConteneur').show();\r\n            jQuery('.OUClass').show();\r\n            \/\/ \u2705 Cibler uniquement le droppable courant \u2014 ne pas r\u00e9afficher sur les espaces d\u00e9j\u00e0 upload\u00e9s\r\n            $dropZone.closest('.droppable').find('.UploadIci').show();\r\n        }\r\n        \r\n        if (StateManager.get(\"PopUpChoice\") === 'Yes') {\r\n            \/\/ \u2705 Ne masquer DeplaceAnnonce QUE sur Ele0A \u2014 pas sur Ele1A qui a deja une annonce chargee\r\n            $dropZone.closest('.OrdiMobileConteneurClass').find('.DeplaceAnnonce').each(function() {\r\n                var _d = jQuery(this).closest('.droppable')[0];\r\n                if (_d && _d.getAttribute('data-via-ad-loaded') === 'true') { return; }\r\n                jQuery(this).hide();\r\n            });\r\n            $('.AnnonceDragIcone').show().find('img').attr('alt', '');\r\n        } else {\r\n            $('.AnnonceDragIcone').hide();\r\n        }\r\n        \r\n        if (StateManager.get(\"Commande_Page\") === 'Home Page') {\r\n            jQuery('#HPTarifConteneur').css({'background-color': '#B5FFB1'});\r\n        }\r\n        \r\n        jQuery('.ChoisirEspacePublicitaireClass').css({'color': '#ffffff'});\r\n        jQuery('.InterfaceTitreDore').not('#PageWebTitreDore')\r\n            .html(\"Merci de choisir les \u00e9l\u00e9ments de votre campagne publicitaire\");\r\n        jQuery('#ProcessCommande').show();\r\n    },\r\n    \r\n    sendUploadRequest(formData) {\r\n        \/\/ \u2705 v2.6 : dataType 'text' pour eviter parsererror si texte parasite apres le JSON\r\n        return jQuery.ajax({\r\n            url: CONFIG.ajaxUrl,\r\n            type: 'POST',\r\n            data: formData,\r\n            cache: false,\r\n            contentType: false,\r\n            processData: false,\r\n            dataType: 'text'\r\n        }).then(function(text) {\r\n            \/\/ Extraire le JSON meme si du texte parasite suit\r\n            var _json = null;\r\n            try {\r\n                var _match = text.match(\/(\\{[\\s\\S]*?\\})(?:[^{]|$)\/);\r\n                _json = JSON.parse(_match ? _match[1] : text);\r\n            } catch(_e) {\r\n                return jQuery.Deferred().reject({ responseText: text }).promise();\r\n            }\r\n            \/\/ Normaliser le format vers {success, data} attendu par handleUploadResponse\r\n            if (_json.status === 'success') {\r\n                var _fp = _json.file_path || '';\r\n                var _baseUrl = CONFIG.ajaxUrl.replace('\/wp-admin\/admin-ajax.php', '\/wp-content\/');\r\n                return {\r\n                    success: true,\r\n                    data: {\r\n                        file_url:  _baseUrl + _fp,\r\n                        file_name: _fp.replace(\/^.*\\\/\/, ''),\r\n                        file_path: _fp\r\n                    }\r\n                };\r\n            }\r\n            \/\/ Format WordPress standard {success, data} - retourner tel quel\r\n            return _json;\r\n        });\r\n    },\r\n    \r\n    async handleUploadResponse(response, fileObj, $dropZone, extension) {\r\n        console.log('\u2705 R\u00e9ponse re\u00e7ue');\r\n        \r\n        if (response.responseJSON) {\r\n            response = response.responseJSON;\r\n        }\r\n        \r\n        console.log('\u2705 Response pars\u00e9e:', response);\r\n        \r\n        if (!response.success || !response.data) {\r\n            \/\/ \u2705 v2.1.2 : Si c'est une restauration (_isAdRestoration = 'Yes'),\r\n            \/\/ le fichier existe d\u00e9j\u00e0 sur le serveur \u2192 afficher l'image depuis le fileObj local\r\n            if (StateManager.get('_isAdRestoration') === 'Yes' && fileObj) {\r\n                console.log('\ud83d\udd04 Restauration: upload \u00e9chou\u00e9 (fichier existant) \u2192 rendu local');\r\n                \r\n                FileManager.createObjectUrl(fileObj);\r\n                StateManager.set('FileReceived', 'Yes');\r\n                \r\n                \/\/ \u2705 v2.1.2 : Restaurer l'\u00e9tat EnvoiUlterieur depuis le sessionStorage parent\r\n                var _restoredEnvoi = sessionStorage.getItem('_restoredEnvoiUlterieur');\r\n                if (_restoredEnvoi === 'true') {\r\n                    StateManager.set('EnvoiUlterieur', 'true');\r\n                    StateManager.set('FileReceived', 'No');\r\n                    StateManager.set('FullPathAdFile', '');\r\n                    console.log('\ud83d\udce4 Restauration EnvoiUlterieur = true');\r\n                }\r\n                \r\n                var _objUrl = StateManager.get('objectUrl');\r\n                var _fileType = FileManager.getFileType(extension);\r\n                \r\n                StateManager.set('FormatReconnu', 'No');\r\n                \r\n                switch (_fileType) {\r\n                    case 'video':\r\n                        PreviewRenderer.renderVideo(_objUrl, fileObj.name, $dropZone);\r\n                        StateManager.set('FormatReconnu', 'Yes');\r\n                        break;\r\n                    case 'image':\r\n                        PreviewRenderer.renderImage(_objUrl, $dropZone);\r\n                        StateManager.set('FormatReconnu', 'Yes');\r\n                        break;\r\n                    case 'document':\r\n                        \/\/ \u2705 v2.1.2 : Documents Word\/PDF aussi en restauration\r\n                        await this.handleDocumentUpload(extension, fileObj, $dropZone);\r\n                        break;\r\n                }\r\n                \r\n                UIManager.updateAfterSuccessfulUpload($dropZone);\r\n                \r\n                if (StateManager.get('FormatReconnu') === 'Yes') {\r\n                    this.finalizeUpload($dropZone);\r\n                    $('#MsgSelectEspace').hide();\r\n                }\r\n                \r\n                FormatUIManager.updateReserverCheckboxState($dropZone.closest('.droppable'));\r\n                console.log('\u2705 Restauration visuelle termin\u00e9e (upload bypass)');\r\n                StateManager.set('_isAdRestoration', 'No');\r\n            }\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 SAUVEGARDER les infos de d\u00e9placement AVANT updateStateAfterUpload\r\n        const isMoved = StateManager.get('FirstUploadFileorMoved') === 'Moved';\r\n        const dragstartRankId = StateManager.get('dragstart_Rank_Emplacement_Page_Web');\r\n        const currentRankId = StateManager.get('Rank_Emplacement_Page_Web');\r\n        const shouldResetOldSpace = isMoved && dragstartRankId && dragstartRankId !== currentRankId;\r\n        \r\n        console.log('\ud83d\udd0d D\u00e9placement?', { isMoved, dragstartRankId, currentRankId, shouldResetOldSpace });\r\n        \r\n        this.updateStateAfterUploadWithoutReset(response, fileObj);\r\n        \r\n        const fileType = FileManager.getFileType(extension);\r\n        \r\n        StateManager.set('FormatReconnu', 'No');\r\n        \r\n        \/\/ \u2705 v1.19.2 : Message d'attente IMM\u00c9DIAT avant le rendu de l'annonce\r\n        var _waitMsg = 'Loading in progress <span class=\"dot-container\"><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><\/span>';\r\n        $dropZone.html('<div class=\"ad-loading-msg\" style=\"color:#00ff19; background:white; padding:12px 20px; border-radius:6px; font-weight:700; text-align:center; font-size:18px; line-height:1.4;\">' + _waitMsg + '<\/div>');\r\n        \r\n        switch (fileType) {\r\n            case 'video':\r\n                PreviewRenderer.renderVideo(StateManager.get('objectUrl'), fileObj.name, $dropZone);\r\n                StateManager.set('FormatReconnu', 'Yes');\r\n                break;\r\n                \r\n            case 'image':\r\n                PreviewRenderer.renderImage(StateManager.get('objectUrl'), $dropZone);\r\n                StateManager.set('FormatReconnu', 'Yes');\r\n                break;\r\n                \r\n            case 'document':\r\n                await this.handleDocumentUpload(extension, fileObj, $dropZone);\r\n                break;\r\n        }\r\n        \r\n        UIManager.updateAfterSuccessfulUpload($dropZone);\r\n        \r\n        if (StateManager.get('FormatReconnu') === 'Yes') {\r\n            this.finalizeUpload($dropZone);\r\n            $('#MsgSelectEspace').hide();\r\n        }\r\n        \r\n        \/\/ \u2705 RESET L'ANCIEN ESPACE ICI - APR\u00c8S avoir affich\u00e9 la nouvelle image\r\n        \/\/ \u2705 v2.4.5 : Toujours initialiser \u00e0 false avant le bloc (\u00e9vite la valeur r\u00e9siduelle)\r\n        var _sourceWasReserved = false;\r\n        StateManager.set('_sourceWasReserved', 'No');\r\n        \r\n        if (shouldResetOldSpace) {\r\n            console.log('\ud83d\udd04 Reset ancien espace:', dragstartRankId);\r\n            \r\n            var $oldDroppable = $('#' + dragstartRankId);\r\n            \r\n            if ($oldDroppable.length) {\r\n                var $container = $oldDroppable.find('.OrdiMobileConteneurClass').first();\r\n                \r\n                \/\/ \u2705 v2.4.5 : Utiliser l'\u00e9tat captur\u00e9 au dragstart (fiable vs re-check async)\r\n                if ($container.length) {\r\n                    _sourceWasReserved = StateManager.get('dragstart_ReserverChecked') === 'Yes';\r\n                    console.log('[d\u00e9placement] ReserverChecked au dragstart:', _sourceWasReserved, '| rank:', dragstartRankId);\r\n                    StateManager.set('_sourceWasReserved', _sourceWasReserved ? 'Yes' : 'No');\r\n                    RestoreadSpaceTemplateLocal($container[0]);\r\n                }\r\n            }\r\n        }\r\n        StateManager.set(\"EnvoiUlterieur\", 'false');\r\n        \r\n        \/\/ \u2705 v1.19.1 : Positionner l'espace \u00e0 10px du haut du viewport apr\u00e8s upload\r\n        setTimeout(function() {\r\n            var el = $dropZone.closest('.droppable').find('.HTMLUploadfileConteneur')[0]\r\n                     || $dropZone.closest('.droppable')[0];\r\n            if (el) {\r\n                ScrollHelper.scrollElementTo(el, 10);\r\n            }\r\n        }, 400);\r\n        \r\n        \/\/ \u2705 NE PLUS envoyer automatiquement - c'est la checkbox \"R\u00e9server\" qui d\u00e9clenche\r\n        \/\/ On met \u00e0 jour l'\u00e9tat de la checkbox pour qu'elle devienne activable\r\n        FormatUIManager.updateReserverCheckboxState($dropZone.closest('.droppable'));\r\n        \r\n        \/\/ \u2705 v2.4.5 : Si l'espace source \u00e9tait r\u00e9serv\u00e9, cocher la checkbox de l'espace cible\r\n        if (StateManager.get('_sourceWasReserved') === 'Yes') {\r\n            var $targetCb = $dropZone.closest('.droppable').find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]');\r\n            if ($targetCb.length && !$targetCb.prop('checked')) {\r\n                $targetCb.prop('checked', true).trigger('change');\r\n                console.log('\u2705 [d\u00e9placement] Checkbox R\u00e9server coch\u00e9e sur espace cible');\r\n            }\r\n            StateManager.set('_sourceWasReserved', 'No');\r\n        }\r\n        \r\n        console.log('\ud83d\udccb Upload termin\u00e9 - en attente de validation via checkbox \"R\u00e9server\"');\r\n    },\r\n    \r\n    updateStateAfterUploadWithoutReset(response, fileObj) {\r\n        StateManager.setMultiple({\r\n            \"PageWhithADType\": StateManager.get('SelectedPageType'),\r\n            \"PageWhithADSecteur\": StateManager.get('SelectedPageSecteur')\r\n        });\r\n        \r\n        $('#BackPageWebWithADCroix').hide();\r\n        jQuery('#ApercuMobile').empty().css({\r\n            'display': 'flex',\r\n            'justify-content': 'center',\r\n            'align-items': 'center'\r\n        });\r\n        \r\n        const firstUploadOrMoved = StateManager.get('FirstUploadFileorMoved');\r\n        \r\n        if (firstUploadOrMoved === 'FirstUpload') {\r\n            StateManager.setMultiple({\r\n                \"FullPathAdFile\": response.data.file_url,\r\n                \"fileObj\": fileObj,\r\n                \"Upload_File_Name\": fileObj.name\r\n            });\r\n            \r\n            FileManager.createObjectUrl(fileObj);\r\n            \r\n            console.log('\ud83d\udcc1 Fichier upload\u00e9:', {\r\n                fullUrl: response.data.file_url,\r\n                fileName: response.data.file_name,\r\n                filePath: response.data.file_path\r\n            });\r\n        }\r\n    },\r\n    \r\n    updateStateAfterUpload(response, fileObj) {\r\n        StateManager.setMultiple({\r\n            \"PageWhithADType\": StateManager.get('SelectedPageType'),\r\n            \"PageWhithADSecteur\": StateManager.get('SelectedPageSecteur')\r\n        });\r\n        \r\n        $('#BackPageWebWithADCroix').hide();\r\n        jQuery('#ApercuMobile').empty().css({\r\n            'display': 'flex',\r\n            'justify-content': 'center',\r\n            'align-items': 'center'\r\n        });\r\n        \r\n        const firstUploadOrMoved = StateManager.get('FirstUploadFileorMoved');\r\n        console.log('\ud83d\udd0d FirstUploadFileorMoved:', firstUploadOrMoved);\r\n        \r\n        if (firstUploadOrMoved === 'FirstUpload') {\r\n            StateManager.setMultiple({\r\n                \"FullPathAdFile\": response.data.file_url,\r\n                \"fileObj\": fileObj,\r\n                \"Upload_File_Name\": fileObj.name\r\n            });\r\n            \r\n            FileManager.createObjectUrl(fileObj);\r\n            \r\n            console.log('\ud83d\udcc1 Fichier upload\u00e9:', {\r\n                fullUrl: response.data.file_url,\r\n                fileName: response.data.file_name,\r\n                filePath: response.data.file_path\r\n            });\r\n        } else if (firstUploadOrMoved === 'Moved') {\r\n            const dragstartRankId = StateManager.get('dragstart_Rank_Emplacement_Page_Web');\r\n            const currentRankId = StateManager.get('Rank_Emplacement_Page_Web');\r\n            \r\n            console.log('\ud83d\udd04 D\u00c9PLACEMENT D\u00c9TECT\u00c9');\r\n            console.log('   Ancien espace (dragstart):', dragstartRankId);\r\n            console.log('   Nouvel espace (current):', currentRankId);\r\n            \r\n            if (dragstartRankId && dragstartRankId !== currentRankId) {\r\n                const $oldDroppable = $('#' + dragstartRankId);\r\n                \r\n                console.log('   $oldDroppable trouv\u00e9:', $oldDroppable.length > 0);\r\n                \r\n                if ($oldDroppable.length) {\r\n                    const $container = $oldDroppable.find('.OrdiMobileConteneurClass');\r\n                    \r\n                    console.log('   $container trouv\u00e9:', $container.length > 0);\r\n                    \r\n                    if ($container.length) {\r\n                        console.log('\ud83d\udd27 Appel RestoreadSpaceTemplate sur:', $container[0]);\r\n                        \r\n                        if (typeof window.RestoreadSpaceTemplate === 'function') {\r\n                            window.RestoreadSpaceTemplate($container[0]);\r\n                            console.log('\u2705 RestoreadSpaceTemplate ex\u00e9cut\u00e9');\r\n                        }\r\n                    } else {\r\n                        console.warn('\u26a0\ufe0f .OrdiMobileConteneurClass non trouv\u00e9 dans', dragstartRankId);\r\n                    }\r\n                }\r\n            } else {\r\n                console.log('\u23ed\ufe0f M\u00eame espace ou dragstartRankId invalide, pas de reset');\r\n            }\r\n        }\r\n    },\r\n        \r\n    async handleDocumentUpload(extension, fileObj, $dropZone) {\r\n        StateManager.set('FormatReconnu', 'Yes');\r\n        \r\n        \/\/ \u2705 Cacher le File r\u00e9dactionnel pour r\u00e9utilisation lors des d\u00e9placements (\u00e9vite CORS)\r\n        window._lastRedactionnelFile = fileObj;\r\n        \r\n        if (extension === 'doc' || extension === 'docx') {\r\n            await new Promise(resolve => window.VIALibraries.loadMammoth(resolve));\r\n            await PreviewRenderer.renderWord(fileObj, $dropZone);\r\n        } else if (extension === 'ppt' || extension === 'pptx') {\r\n            this.renderPowerPoint($dropZone);\r\n            PreviewRenderer.finalizeRedactionnelUpload();\r\n        } else if (extension === 'pdf') {\r\n            await new Promise(resolve => window.VIALibraries.loadPdfJs(resolve));\r\n            await PDFHandler.renderPDF(fileObj, $dropZone);\r\n            PreviewRenderer.finalizeRedactionnelUpload();\r\n        }\r\n    },\r\n    \r\n    renderPowerPoint($dropZone) {\r\n        const img = jQuery('<img \/>', {\r\n            src: '\/wp-content\/uploads\/2024\/06\/microsoft-powerpoint.png',\r\n            css: {\r\n                'width': 'auto',\r\n                'height': 'auto',\r\n                'margin-bottom': '20px',\r\n                'max-width': '150px',\r\n                'max-height': '160px'\r\n            }\r\n        });\r\n        $dropZone.empty().append(img.clone());\r\n        jQuery('#ApercuMobile').append(img);\r\n    },\r\n    \r\n    finalizeUpload($dropZone) {\r\n        \/\/ \u2705 Reset sendDataToParentFlag : nouvel upload = pas encore r\u00e9serv\u00e9\r\n        StateManager.set('sendDataToParentFlag', 'No');\r\n        \r\n        StateManager.setMultiple({\r\n            \"PageAnnonceSelection\": 'Yes',\r\n            \"FormatReconnu\": 'Yes'\r\n        });\r\n        \r\n        jQuery('#MsgChoixPageWeb, #MsgInsererAnnonceConteneur').hide();\r\n        \r\n        if (StateManager.get(\"Commande_Format\") === 'R\u00e9dactionnel') {\r\n            StateManager.set('Commande_Format', '\u00e0 choisir');\r\n            RedactionnelDepose();\r\n        }\r\n        \r\n        if (StateManager.get(\"Commande_Page\") === ' ') {\r\n            jQuery('#HPTarifConteneur').css({'background-color': '#BCFFAD'});\r\n            jQuery('#EmplacementDataStep3').html(\"Home Page\");\r\n            StateManager.setMultiple({\r\n                \"Commande_Page\": 'Home Page',\r\n                \"PageAnnonceSelection\": 'Yes'\r\n            });\r\n        }\r\n        \r\n        $('#PageWeb').css('zoom', '70%');\r\n        $('#PageWebTitreDore').css({'font-size': '14px'});\r\n        \r\n        if (!UIManager.isMobile()) {\r\n            $('#PageWebTitreDore').css({'color': '#213864'});\r\n        }\r\n        \r\n        StateManager.set(\"Page_Web_with_AD_URL\", StateManager.get(\"Page_Web_URL\"));\r\n        \r\n        UIManager.finalizeAdDisplay($dropZone);\r\n        \r\n        \/\/ \u2705 Notifier le parent de l'annonce d\u00e9pos\u00e9e non r\u00e9serv\u00e9e \u2014 pour restauration au retour sur la page\r\n        var _fileRcv = StateManager.get('FileReceived');\r\n        var _isRestoring = StateManager.get('_isAdRestoration') === 'Yes';\r\n        console.log('\ud83d\udfe1 [finalizeUpload] FileReceived:', _fileRcv, '| _isAdRestoration:', _isRestoring);\r\n        if (_fileRcv === 'Yes' && !_isRestoring) {\r\n            var _pendingRank = StateManager.get('Rank_Emplacement_Page_Web') || $dropZone.closest('.droppable').attr('id') || '';\r\n            console.log('\ud83d\udfe1 [finalizeUpload] pendingRank:', _pendingRank, '| FullPathAdFile:', StateManager.get('FullPathAdFile'));\r\n            if (_pendingRank) {\r\n                console.log('\ud83d\udce4 [finalizeUpload] annonceDeposeeSansReservation \u2192 parent rank:', _pendingRank);\r\n                \/\/ \u2705 D\u00e9terminer le vrai format commercial selon le type de fichier d\u00e9pos\u00e9 + format s\u00e9lectionn\u00e9\r\n                var _formatSelect = sessionStorage.getItem('FormatSelect') || StateManager.get('Commande_Format_Transmis') || '';\r\n                var _uploadedExt = (StateManager.get('Upload_File_Name') || '').split('.').pop().toLowerCase();\r\n                var _fileKind = CONFIG.allowedExtensions.video.indexOf(_uploadedExt) !== -1 ? 'video'\r\n                              : CONFIG.allowedExtensions.image.indexOf(_uploadedExt) !== -1 ? 'image'\r\n                              : CONFIG.allowedExtensions.document.indexOf(_uploadedExt) !== -1 ? 'document'\r\n                              : '';\r\n                var _formatPending;\r\n                if (_fileKind === 'video') {\r\n                    \/\/ Vid\u00e9o \u2192 toujours Vid\u00e9o\r\n                    _formatPending = 'Vid\u00e9o';\r\n                } else if (_fileKind === 'image') {\r\n                    \/\/ Image \u2192 Banni\u00e8re ou Parrainage si s\u00e9lectionn\u00e9, sinon Banni\u00e8re par d\u00e9faut\r\n                    var _imgFormats = ['Banni\u00e8re', 'Banniere', 'Parrainage'];\r\n                    _formatPending = (_imgFormats.indexOf(_formatSelect) !== -1) ? _formatSelect : 'Banni\u00e8re';\r\n                } else if (_fileKind === 'document') {\r\n                    \/\/ Document \u2192 Communiqu\u00e9 ou Interview si s\u00e9lectionn\u00e9, sinon Communiqu\u00e9 par d\u00e9faut\r\n                    var _docFormats = ['Communiqu\u00e9', 'Communique', 'Interview'];\r\n                    _formatPending = (_docFormats.indexOf(_formatSelect) !== -1) ? _formatSelect : 'Communiqu\u00e9';\r\n                } else {\r\n                    \/\/ Fallback\r\n                    _formatPending = _formatSelect || StateManager.get('Commande_Format_Transmis') || '';\r\n                }\r\n                \/\/ \u2705 v2.4.9 : Si le format d\u00e9duit diff\u00e8re du format s\u00e9lectionn\u00e9 \u2192 mettre \u00e0 jour vignette + sessionStorage\r\n                if (_formatPending && _formatPending !== _formatSelect) {\r\n                    StateManager.set('FormatSelect', _formatPending);\r\n                    StateManager.set('Commande_Format_Transmis', _formatPending);\r\n                    StateManager.set('Formatchoisi', 'Yes');\r\n                    \/\/ Mettre \u00e0 jour visuellement la vignette dans le droppable courant\r\n                    var _fmtNorm = _formatPending.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    var $_drp = $dropZone.closest('.droppable');\r\n                    $_drp.find('.EspPubFormatContainer').each(function() {\r\n                        var _cls = this.className.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                        if (_cls.includes(_fmtNorm)) {\r\n                            jQuery(this).css({'background-color': '#ffffff'});\r\n                            jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                        } else if (!jQuery(this).hasClass('FormatIdPopUp')) {\r\n                            jQuery(this).css({'background-color': ''});\r\n                            jQuery(this).find('.EspPubFormat').css({'color': ''});\r\n                        }\r\n                    });\r\n                    \/\/ Mettre \u00e0 jour aussi le bandeau parent via postMessage\r\n                    MessageManager.sendToParent('formatChangedInIframe', { formatSelect: _formatPending, rank: _pendingRank });\r\n                    console.log('\ud83d\udd04 [finalizeUpload] Format corrig\u00e9:', _formatSelect, '\u2192', _formatPending);\r\n                }\r\n                var _firstUploadOrMoved = StateManager.get('FirstUploadFileorMoved');\r\n                var _isMoved = _firstUploadOrMoved === 'Moved';\r\n                var _oldRankMoved = _isMoved ? (StateManager.get('dragstart_Rank_Emplacement_Page_Web') || '') : '';\r\n                MessageManager.sendToParent('annonceDeposeeSansReservation', {\r\n                    Rank_Emplacement_Page_Web: _pendingRank,\r\n                    FullPathAdFile: StateManager.get('FullPathAdFile') || '',\r\n                    Upload_File_Name: StateManager.get('Upload_File_Name') || '',\r\n                    LoadedPageUrl: window.location.href,\r\n                    FileReceived: 'Yes',\r\n                    \/\/ \u2705 Lire EnvoiUlterieur depuis la checkbox du droppable courant (pas le StateManager global)\r\n                    \/\/ StateManager.get('EnvoiUlterieur') est global \u2192 peut valoir 'true' si un autre espace a sa checkbox coch\u00e9e\r\n                    EnvoiUlterieur: ($dropZone.closest('.droppable').find('input[name*=\"EnvoiUlterieur\"]').prop('checked') ? 'true' : 'false'),\r\n                    Commande_Format_Transmis: _formatPending,\r\n                    codeSite: StateManager.get('codeSite') || '',\r\n                    codePage: StateManager.get('codePage') || '',\r\n                    Commande_Emplacement_Page_Web: StateManager.buildEmplacementReference(_pendingRank),\r\n                    isMoved: _isMoved,\r\n                    oldRank: _oldRankMoved\r\n                });\r\n            }\r\n        }\r\n    },\r\n    \r\n    activateSendDataToParent($dropZone) {\r\n        if (StateManager.get(\"sendDataToParentFlag\") !== 'Yes') {\r\n            return;\r\n        }\r\n        \r\n        if (StateManager.get(\"FirstUploadFileorMoved\") === 'Moved') {\r\n            const dragstartRef = StateManager.buildEmplacementReference(\r\n                StateManager.get(\"dragstart_Rank_Emplacement_Page_Web\")\r\n            );\r\n            StateManager.set('dragstart_Commande_Emplacement_Page_Web', dragstartRef);\r\n        }\r\n        \r\n        console.log('Esp Pub Ref FirstUploadFileorMoved:', StateManager.get(\"FirstUploadFileorMoved\"));\r\n        console.log('Esp Pub dragstart_Commande:', StateManager.get(\"dragstart_Commande_Emplacement_Page_Web\"));\r\n        \r\n        if (StateManager.get(\"PageAjoutModifAnnonce\") === 'Yes') {\r\n            this.handlePageModification($dropZone);\r\n        } else {\r\n            this.handleNormalUpload();\r\n        }\r\n        \r\n        StateManager.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        setTimeout(() => {\r\n            StateManager.set(\"AddNewRefInVosCampagnes\", 'Yes');\r\n        }, 4000);\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            StateManager.set('Commande_Format_Transmis', '');\r\n        }\r\n    },\r\n    \r\n    handlePageModification($dropZone) {\r\n        $('#CroixResetAnnonce, .DeplaceAnnonce').hide();\r\n        $('.PageAjoutModifAnnonceCroixResetAnnonce').show();\r\n        \r\n        const emplacementRef = $dropZone.closest('.CampagnesTemplateClass')\r\n            .find('.ReferenceEspace').text();\r\n        \r\n        console.log('Commande_Emplacement_Page_Web:', emplacementRef);\r\n        \r\n        jQuery.ajax({\r\n            type: \"POST\",\r\n            url: CONFIG.ajaxUrl,\r\n            data: {\r\n                action: 'via_update_fichier_annonce',\r\n                commande_ref_url: StateManager.get(\"commande_ref_url\"),\r\n                emplacement_page_web: emplacementRef,\r\n                chemin_fichier: StateManager.get(\"FullPathAdFile\")\r\n            },\r\n            xhrFields: { withCredentials: true },\r\n            success: (response) => {\r\n                if (response.success) {\r\n                    console.log('\u2705 Fichier annonce mis \u00e0 jour:', response.data.message);\r\n                    location.reload();\r\n                } else {\r\n                    console.error('\u274c Erreur:', response.data.message);\r\n                }\r\n            },\r\n            error: (xhr, status, error) => {\r\n                console.error('\u274c Erreur AJAX:', error);\r\n            }\r\n        });\r\n    },\r\n    \r\n    handleNormalUpload() {\r\n        if (StateManager.get(\"EnvoiUlterieur\") === 'true') {\r\n            StateManager.setMultiple({\r\n                \"FullPathAdFile\": '',\r\n                \"Upload_File_Name\": ''\r\n            });\r\n        }\r\n        \r\n        StateManager.set(\"LoadedPageUrl\", window.location.href);\r\n        \r\n        console.log('EnvoiUlterieur:', StateManager.get(\"EnvoiUlterieur\"));\r\n        console.log('LoadedPageUrl:', StateManager.get(\"LoadedPageUrl\"));\r\n        console.log('FileReceived:', StateManager.get(\"FileReceived\"));\r\n        \r\n        const data = MessageManager.prepareUploadData();\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            MessageManager.sendDataToParent(data);\r\n        } else {\r\n            const formatChoisi = StateManager.get(\"Formatchoisi\") === 'Yes';\r\n            const fichierDepose = StateManager.get(\"FileReceived\") === 'Yes';\r\n            const envoiDiffere = StateManager.get(\"EnvoiUlterieur\") === 'true';\r\n            \r\n            console.log('\ud83d\udd0d handleNormalUpload - Conditions:', { formatChoisi, fichierDepose, envoiDiffere });\r\n            \r\n            if (formatChoisi && (fichierDepose || envoiDiffere)) {\r\n                if (typeof window.handleEspacePubData === 'function') {\r\n                    window.handleEspacePubData(data);\r\n                } else {\r\n                    console.warn('\u26a0\ufe0f handleEspacePubData non disponible, fallback direct');\r\n                    if (typeof window.executeWithProcessLoaded === 'function') {\r\n                        window.executeWithProcessLoaded(function() {\r\n                            jQuery('#PopupProcessCommandeContainer').show();\r\n                        });\r\n                    } else {\r\n                        jQuery('#PopupProcessCommandeContainer').show();\r\n                    }\r\n                }\r\n            } else if (formatChoisi) {\r\n                console.log('\ud83d\udcdd Mise \u00e0 jour format uniquement');\r\n                \r\n                const borderStyle = {'box-shadow': 'inset 0 0 0 2px #00FF19', 'box-sizing': 'border-box'};  \/\/ \u2705 v2.4.5\r\n                \r\n                jQuery(\".FormatClassique, .FormatPopup\").css({'border': 'none'});\r\n                \r\n                jQuery('.FormatClassique, .FormatPopup').each(function() {\r\n                    \/\/ \u2705 v2.1.1 : NFD normalize both sides\r\n                    var _cn = this.className.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    var _cf = (data.Commande_Format_Transmis || '').normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    if (_cn.includes(_cf) && _cf) {\r\n                        jQuery(this).css(borderStyle);\r\n                    }\r\n                });\r\n            }\r\n        }\r\n        \r\n        StateManager.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        setTimeout(() => {\r\n            StateManager.set(\"AddNewRefInVosCampagnes\", 'Yes');\r\n        }, 4000);\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            StateManager.set('Commande_Format_Transmis', '');\r\n        }\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion des fichiers PDF (s\u00e9par\u00e9 pour \u00e9viter la complexit\u00e9)\r\n *\/\r\nconst PDFHandler = {\r\n    pdfData: null,\r\n    pdfDataForViewer: null,\r\n    \r\n    async renderPDF(fileObj, $dropZone) {\r\n        return new Promise((resolve, reject) => {\r\n            const reader = new FileReader();\r\n            \r\n            reader.onload = async (e) => {\r\n                try {\r\n                    const arrayBuffer = e.target.result;\r\n                    this.pdfData = new Uint8Array(arrayBuffer);\r\n                    this.pdfDataForViewer = arrayBuffer;\r\n                    \r\n                    console.log(\"Initial PDF load, size:\", this.pdfData.byteLength);\r\n                    \r\n                    const pdfjsLib = window['pdfjs-dist\/build\/pdf'];\r\n                    pdfjsLib.GlobalWorkerOptions.workerSrc = \r\n                        '\/\/cdn.jsdelivr.net\/npm\/pdfjs-dist@latest\/build\/pdf.worker.min.js';\r\n                    \r\n                    const pdf = await pdfjsLib.getDocument({ data: new Uint8Array(this.pdfData) }).promise;\r\n                    const page = await pdf.getPage(1);\r\n                    \r\n                    const { titleText, pageText } = await this.extractTextFromPage(page);\r\n                    const imageData = await this.extractImageFromPage(page, pdfjsLib);\r\n                    \r\n                    if (imageData) {\r\n                        PreviewRenderer.renderDocumentPreview(\r\n                            $dropZone,\r\n                            imageData.dataUrl,\r\n                            titleText,\r\n                            pageText\r\n                        );\r\n                    } else {\r\n                        \/\/ \u2705 v1.19.0 : Accepter les PDF sans image\r\n                        PreviewRenderer.renderDocumentPreview(\r\n                            $dropZone,\r\n                            null,\r\n                            titleText,\r\n                            pageText\r\n                        );\r\n                        console.log('\u2139\ufe0f PDF sans image \u2014 aper\u00e7u texte seul');\r\n                    }\r\n                    \r\n                    this.attachPDFPreviewHandler($dropZone, titleText);\r\n                    resolve();\r\n                } catch (error) {\r\n                    console.error('Error extracting from PDF:', error);\r\n                    \/\/ \u2705 v1.19.0 : Message d'erreur en fran\u00e7ais\r\n                    $dropZone.html(`\r\n                        <div style=\"padding: 15px; background-color: #f8f8f8; border-radius: 4px; text-align: center;\">\r\n                            <p style=\"color: #FB5E2A; font-weight: 600; font-family: Roboto, Arial, sans-serif; font-size: 12px;\">\r\n                                Erreur lors de la lecture du document\r\n                            <\/p>\r\n                        <\/div>\r\n                    `);\r\n                    reject(error);\r\n                }\r\n            };\r\n            \r\n            reader.readAsArrayBuffer(fileObj);\r\n        });\r\n    },\r\n    \r\n    async extractTextFromPage(page) {\r\n        const textContent = await page.getTextContent();\r\n        \r\n        let text = '';\r\n        let lastX = -1;\r\n        let lastY = -1;\r\n        \r\n        for (const item of textContent.items) {\r\n            if (lastY !== -1 && (Math.abs(lastY - item.transform[5]) > 5)) {\r\n                text += '\\n';\r\n            } else if (lastX !== -1 && (item.transform[4] - lastX > 10)) {\r\n                text += ' ';\r\n            }\r\n            \r\n            text += item.str;\r\n            \r\n            lastX = item.transform[4] + (item.width || 0);\r\n            lastY = item.transform[5];\r\n        }\r\n        \r\n        text = text\r\n            .replace(\/(\\w) (\\w)\/g, (match, p1, p2) => {\r\n                if (\/[\u00e9\u00e8\u00ea\u00eb\u00e0\u00e2\u00e4\u00f4\u00f6\u00fb\u00fc\u00ef\u00ee\u00e7]\/i.test(p2)) {\r\n                    return p1 + p2;\r\n                }\r\n                return match;\r\n            })\r\n            .replace(\/ ([.,;:!?])\/g, '$1');\r\n        \r\n        const normalizedText = PreviewRenderer.normalizeText(text);\r\n        const titleText = PreviewRenderer.findDocumentTitle(normalizedText);\r\n        \r\n        return { titleText, pageText: text };\r\n    },\r\n    \r\n    async extractImageFromPage(page, pdfjsLib) {\r\n        const opList = await page.getOperatorList();\r\n        const imageInfo = [];\r\n        let currentTransform = null;\r\n        \r\n        for (let i = 0; i < opList.fnArray.length; i++) {\r\n            const operator = opList.fnArray[i];\r\n            const args = opList.argsArray[i];\r\n            \r\n            if (operator === pdfjsLib.OPS.transform) {\r\n                currentTransform = args;\r\n            } else if (operator === pdfjsLib.OPS.paintImageXObject) {\r\n                const imageName = args[0];\r\n                \r\n                if (!imageInfo.some(info => info.name === imageName)) {\r\n                    const position = currentTransform ? {\r\n                        x: currentTransform[4] || 0,\r\n                        y: currentTransform[5] || 0\r\n                    } : { x: 0, y: 0 };\r\n                    \r\n                    imageInfo.push({ name: imageName, position: position });\r\n                }\r\n            }\r\n        }\r\n        \r\n        if (imageInfo.length === 0) {\r\n            return null;\r\n        }\r\n        \r\n        imageInfo.sort((a, b) => b.position.y - a.position.y);\r\n        \r\n        const targetImageName = imageInfo[0].name;\r\n        const imageObj = page.objs.get(targetImageName);\r\n        \r\n        if (!imageObj) {\r\n            const img = await page.objs.get(targetImageName, true);\r\n            return this.processImageObject(img);\r\n        }\r\n        \r\n        return this.processImageObject(imageObj);\r\n    },\r\n    \r\n    processImageObject(imageObj) {\r\n        if (!imageObj) {\r\n            throw new Error('Image object is null');\r\n        }\r\n        \r\n        if (imageObj.bitmap instanceof ImageBitmap) {\r\n            const width = imageObj.bitmap.width || imageObj.width || imageObj.w;\r\n            const height = imageObj.bitmap.height || imageObj.height || imageObj.h;\r\n            \r\n            const canvas = document.createElement('canvas');\r\n            canvas.width = width;\r\n            canvas.height = height;\r\n            const ctx = canvas.getContext('2d');\r\n            \r\n            ctx.drawImage(imageObj.bitmap, 0, 0);\r\n            \r\n            return {\r\n                canvas: canvas,\r\n                width: width,\r\n                height: height,\r\n                dataUrl: canvas.toDataURL('image\/jpeg', 0.92)\r\n            };\r\n        }\r\n        \r\n        const width = imageObj.width || imageObj.w;\r\n        const height = imageObj.height || imageObj.h;\r\n        \r\n        if (!width || !height) {\r\n            throw new Error('Could not determine image dimensions');\r\n        }\r\n        \r\n        let imgData = imageObj.data || imageObj.bitmap;\r\n        \r\n        if (!imgData) {\r\n            throw new Error('No valid image data found');\r\n        }\r\n        \r\n        const canvas = document.createElement('canvas');\r\n        canvas.width = width;\r\n        canvas.height = height;\r\n        const ctx = canvas.getContext('2d');\r\n        \r\n        ctx.fillStyle = 'white';\r\n        ctx.fillRect(0, 0, width, height);\r\n        \r\n        const imageData = ctx.createImageData(width, height);\r\n        \r\n        this.fillImageData(imageData, imgData, imageObj.kind, width, height);\r\n        \r\n        ctx.putImageData(imageData, 0, 0);\r\n        \r\n        return {\r\n            canvas: canvas,\r\n            width: width,\r\n            height: height,\r\n            dataUrl: canvas.toDataURL('image\/jpeg', 0.92)\r\n        };\r\n    },\r\n    \r\n    fillImageData(imageData, imgData, kind, width, height) {\r\n        if (kind === 'GRAY') {\r\n            for (let i = 0, j = 0; i < imgData.length; i++, j += 4) {\r\n                const value = imgData[i];\r\n                imageData.data[j] = value;\r\n                imageData.data[j + 1] = value;\r\n                imageData.data[j + 2] = value;\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else if (kind === 'CMYK') {\r\n            for (let i = 0, j = 0; i < imgData.length; i += 4, j += 4) {\r\n                const c = imgData[i] \/ 255;\r\n                const m = imgData[i + 1] \/ 255;\r\n                const y = imgData[i + 2] \/ 255;\r\n                const k = imgData[i + 3] \/ 255;\r\n                \r\n                imageData.data[j] = 255 * (1 - c) * (1 - k);\r\n                imageData.data[j + 1] = 255 * (1 - m) * (1 - k);\r\n                imageData.data[j + 2] = 255 * (1 - y) * (1 - k);\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else if (kind === 'RGB24') {\r\n            for (let i = 0, j = 0; i < imgData.length; i += 3, j += 4) {\r\n                imageData.data[j] = imgData[i];\r\n                imageData.data[j + 1] = imgData[i + 1];\r\n                imageData.data[j + 2] = imgData[i + 2];\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else if (imgData.length === width * height * 3) {\r\n            for (let i = 0, j = 0; i < imgData.length; i += 3, j += 4) {\r\n                imageData.data[j] = imgData[i];\r\n                imageData.data[j + 1] = imgData[i + 1];\r\n                imageData.data[j + 2] = imgData[i + 2];\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else {\r\n            const tempArray = new Uint8ClampedArray(imgData.length);\r\n            for (let i = 0; i < imgData.length; i++) {\r\n                tempArray[i] = imgData[i];\r\n            }\r\n            \r\n            if (tempArray.length === imageData.data.length \/ 4 * 3) {\r\n                for (let i = 0, j = 0; i < tempArray.length; i += 3, j += 4) {\r\n                    imageData.data[j] = tempArray[i];\r\n                    imageData.data[j + 1] = tempArray[i + 1];\r\n                    imageData.data[j + 2] = tempArray[i + 2];\r\n                    imageData.data[j + 3] = 255;\r\n                }\r\n            } else if (tempArray.length === imageData.data.length) {\r\n                imageData.data.set(tempArray);\r\n            } else {\r\n                console.warn('Unknown image format - creating placeholder');\r\n                for (let i = 0; i < imageData.data.length; i += 4) {\r\n                    const x = (i\/4) % width;\r\n                    const y = Math.floor((i\/4) \/ width);\r\n                    imageData.data[i] = x % 256;\r\n                    imageData.data[i + 1] = y % 256;\r\n                    imageData.data[i + 2] = 100;\r\n                    imageData.data[i + 3] = 255;\r\n                }\r\n            }\r\n        }\r\n    },\r\n    \r\n    attachPDFPreviewHandler($dropZone, titleText) {\r\n        var $droppable = $dropZone.closest('.droppable');\r\n        var self = this;\r\n\r\n        \/\/ \u2705 Adapter le libell\u00e9 selon le format (communiqu\u00e9 \/ interview)\r\n        var kitFormat = $droppable.data('kitFormatSelect') || '';\r\n        var isInterview = (kitFormat || titleText || '').toLowerCase().indexOf('interview') !== -1;\r\n        var formatLabel = isInterview ? 'l\\'interview' : 'le communiqu\u00e9';\r\n        $droppable.find('.doc-preview-readmore').text('Ouvrir et visualiser ' + formatLabel);\r\n\r\n        \/\/ \u2705 v2.0.11 : D\u00e9l\u00e9gation d'\u00e9v\u00e9nement \u2014 plus robuste sur mobile\r\n        $droppable.off('click.docpreview').on('click.docpreview', '.doc-preview-readmore', (event) => {\r\n            event.preventDefault();\r\n            event.stopPropagation();\r\n            var popupTitle = isInterview ? 'Interview' : 'Communiqu\u00e9';\r\n\r\n            \/\/ \u2705 Priorit\u00e9 1 : pdfImageDataURL dispo (Kit)\r\n            var kitPdfImage = $droppable.data('kitPdfImageDataURL');\r\n            if (kitPdfImage) {\r\n                PDFHandler.showInlineDocPopup($dropZone, {\r\n                    formatTitle: popupTitle,\r\n                    pdfDataURL: kitPdfImage\r\n                });\r\n                return;\r\n            }\r\n\r\n            \/\/ \u2705 Priorit\u00e9 2 : PDF upload\u00e9 manuellement \u2192 popup inline aussi\r\n            if (self.pdfDataForViewer && self.pdfDataForViewer.byteLength > 0) {\r\n                PDFHandler.showInlineDocPopup($dropZone, {\r\n                    formatTitle: popupTitle,\r\n                    pdfArrayBuffer: self.pdfDataForViewer\r\n                });\r\n                return;\r\n            }\r\n\r\n            console.error('PDF data is not available');\r\n        });\r\n    },\r\n\r\n    \/\/ \u2705 v1.19.1 : Popup inline document \u2014 position:absolute + ScrollHelper.getVisibleTop()\r\n    \/\/ Le parent envoie visibleTopIframe dans le message scroll \u2192 positionnement fiable.\r\n    showInlineDocPopup($dropZone, options) {\r\n        var existing = document.getElementById('via-pdf-inline-popup');\r\n        if (existing) existing.remove();\r\n\r\n        var $droppable = $dropZone.closest('.droppable');\r\n        var droppableW = $droppable.outerWidth() || 300;\r\n        var popupW = Math.round(droppableW * 1.15);\r\n        \/\/ \u2705 v2.0.11 : Contraindre la largeur au viewport sur mobile (\u00e9vite troncature gauche\/droite)\r\n        var viewportW = document.documentElement.clientWidth || window.innerWidth;\r\n        if (UIManager.isMobile()) {\r\n            popupW = Math.min(popupW, viewportW - 8);\r\n        }\r\n        var popupH = Math.round(popupW * 2.5 * 0.51);\r\n\r\n        \/\/ \u2500\u2500 Position visible r\u00e9elle \u2500\u2500\r\n        var visibleTop = ScrollHelper.getVisibleTop();\r\n        var popupTop = Math.round(visibleTop + 284);\r\n\r\n        \/\/ \u2500\u2500 Popup position:absolute (positionn\u00e9 dans le document iframe) \u2500\u2500\r\n        var popup = document.createElement('div');\r\n        popup.id = 'via-pdf-inline-popup';\r\n        popup.style.cssText =\r\n            'position:absolute;z-index:99999;top:' + popupTop + 'px;' +\r\n            'width:' + popupW + 'px;height:' + popupH + 'px;' +\r\n            'background:#fff;border-radius:8px 8px 0 0;padding:0;' +\r\n            'box-shadow:0 8px 32px rgba(0,0,0,0.35);display:flex;flex-direction:column;' +\r\n            'min-width:200px;min-height:150px;touch-action:none;';\r\n\r\n        \/\/ Centrer horizontalement sur le droppable (coordonn\u00e9es absolues)\r\n        var droppableRect = $droppable[0].getBoundingClientRect();\r\n        var scrollX = window.scrollX || 0;\r\n        var initLeft = Math.round(droppableRect.left + scrollX + (droppableRect.width - popupW) \/ 2);\r\n        initLeft = Math.max(4, initLeft);\r\n        \/\/ \u2705 v2.0.11 : Contraindre \u00e0 droite aussi sur mobile\r\n        if (UIManager.isMobile()) {\r\n            initLeft = Math.min(initLeft, viewportW - popupW - 4);\r\n            initLeft = Math.max(4, initLeft);\r\n        }\r\n        popup.style.left = initLeft + 'px';\r\n\r\n        \/\/ \u2500\u2500 Header \u2500\u2500\r\n        var header = document.createElement('div');\r\n        header.style.cssText =\r\n            'display:flex;align-items:center;justify-content:center;position:relative;' +\r\n            'padding:10px 14px;background:#f0f0f0;color:#494949;flex-shrink:0;' +\r\n            'cursor:grab;user-select:none;border-radius:8px 8px 0 0;';\r\n        var titleEl = document.createElement('span');\r\n        titleEl.style.cssText = 'font-family:Roboto,Arial,sans-serif;font-size:15px;font-weight:600;';\r\n        titleEl.textContent = options.formatTitle || 'Document';\r\n        header.appendChild(titleEl);\r\n\r\n        var closeBtn = document.createElement('button');\r\n        closeBtn.textContent = '\u00d7';\r\n        closeBtn.style.cssText =\r\n            'position:absolute;right:10px;top:50%;transform:translateY(-50%);' +\r\n            'background:transparent;border:none;color:#494949;font-size:20px;' +\r\n            'cursor:pointer;line-height:1;padding:0 4px;';\r\n        closeBtn.addEventListener('click', cleanup);\r\n        header.appendChild(closeBtn);\r\n        popup.appendChild(header);\r\n\r\n        \/\/ \u2500\u2500 Zone scrollable \u2014 pleine largeur \u2500\u2500\r\n        var scrollZone = document.createElement('div');\r\n        scrollZone.style.cssText =\r\n            'flex:1;overflow-y:auto;overflow-x:hidden;padding:0;margin:0;touch-action:pan-y;';\r\n        popup.appendChild(scrollZone);\r\n\r\n        var loader = document.createElement('div');\r\n        loader.style.cssText =\r\n            'text-align:center;padding:30px;font-family:Roboto,Arial,sans-serif;font-size:12px;color:#666;';\r\n        loader.textContent = 'Chargement du document\u2026';\r\n        scrollZone.appendChild(loader);\r\n\r\n        \/\/ \u2500\u2500 8 poign\u00e9es de redimensionnement \u2500\u2500\r\n        var handles = [\r\n            { cursor:'nw-resize', pos:'top:-4px;left:-4px;',       dx:-1, dy:-1 },\r\n            { cursor:'n-resize',  pos:'top:-4px;left:50%;',        dx:0,  dy:-1 },\r\n            { cursor:'ne-resize', pos:'top:-4px;right:-4px;',      dx:1,  dy:-1 },\r\n            { cursor:'w-resize',  pos:'top:50%;left:-4px;',        dx:-1, dy:0  },\r\n            { cursor:'e-resize',  pos:'top:50%;right:-4px;',       dx:1,  dy:0  },\r\n            { cursor:'sw-resize', pos:'bottom:-4px;left:-4px;',    dx:-1, dy:1  },\r\n            { cursor:'s-resize',  pos:'bottom:-4px;left:50%;',     dx:0,  dy:1  },\r\n            { cursor:'se-resize', pos:'bottom:-4px;right:-4px;',   dx:1,  dy:1  }\r\n        ];\r\n        handles.forEach(function(h) {\r\n            var handle = document.createElement('div');\r\n            var isCorner = (h.dx !== 0 && h.dy !== 0);\r\n            handle.style.cssText =\r\n                'position:absolute;touch-action:none;' + h.pos +\r\n                'width:' + (isCorner ? '12px' : (h.dy === 0 ? '8px' : '30px')) + ';' +\r\n                'height:' + (isCorner ? '12px' : (h.dy === 0 ? '30px' : '8px')) + ';' +\r\n                'cursor:' + h.cursor + ';z-index:10;';\r\n            (function(hInfo) {\r\n                handle.addEventListener('pointerdown', function(e) {\r\n                    e.preventDefault(); e.stopPropagation();\r\n                    handle.setPointerCapture(e.pointerId);\r\n                    var startX = e.clientX, startY = e.clientY;\r\n                    var rect0 = popup.getBoundingClientRect();\r\n                    var sY = window.scrollY || 0, sX = window.scrollX || 0;\r\n                    var startW = rect0.width, startH = rect0.height;\r\n                    var startL = rect0.left + sX, startT = rect0.top + sY;\r\n                    function onResize(ev) {\r\n                        ev.preventDefault();\r\n                        var ddx = ev.clientX - startX, ddy = ev.clientY - startY;\r\n                        var newW = startW, newH = startH, newL = startL, newT = startT;\r\n                        if (hInfo.dx === 1)  newW = Math.max(200, startW + ddx);\r\n                        if (hInfo.dx === -1) { newW = Math.max(200, startW - ddx); newL = startL + ddx; }\r\n                        if (hInfo.dy === 1)  newH = Math.max(150, startH + ddy);\r\n                        if (hInfo.dy === -1) { newH = Math.max(150, startH - ddy); newT = startT + ddy; }\r\n                        popup.style.width  = newW + 'px';\r\n                        popup.style.height = newH + 'px';\r\n                        popup.style.left   = newL + 'px';\r\n                        popup.style.top    = newT + 'px';\r\n                    }\r\n                    function onResizeEnd(ev) {\r\n                        handle.releasePointerCapture(ev.pointerId);\r\n                        handle.removeEventListener('pointermove', onResize);\r\n                        handle.removeEventListener('pointerup', onResizeEnd);\r\n                    }\r\n                    handle.addEventListener('pointermove', onResize);\r\n                    handle.addEventListener('pointerup', onResizeEnd);\r\n                });\r\n            })(h);\r\n            popup.appendChild(handle);\r\n        });\r\n\r\n        \/\/ \u2500\u2500 Drag via header \u2500\u2500\r\n        header.style.touchAction = 'none';\r\n        header.addEventListener('pointerdown', function(e) {\r\n            if (e.target === closeBtn) return;\r\n            e.preventDefault();\r\n            header.setPointerCapture(e.pointerId);\r\n            var mx = e.clientX, my = e.clientY;\r\n            var popupRect = popup.getBoundingClientRect();\r\n            var scrollY = window.scrollY || 0;\r\n            var scrollX = window.scrollX || 0;\r\n            var curLeft = popupRect.left + scrollX;\r\n            var curTop  = popupRect.top  + scrollY;\r\n            header.style.cursor = 'grabbing';\r\n            function onMove(ev) {\r\n                ev.preventDefault();\r\n                var dx = ev.clientX - mx;\r\n                var dy = ev.clientY - my;\r\n                curLeft += dx;\r\n                curTop  += dy;\r\n                popup.style.left = curLeft + 'px';\r\n                popup.style.top  = curTop  + 'px';\r\n                mx = ev.clientX;\r\n                my = ev.clientY;\r\n            }\r\n            function onUp(ev) {\r\n                header.releasePointerCapture(ev.pointerId);\r\n                header.style.cursor = 'grab';\r\n                header.removeEventListener('pointermove', onMove);\r\n                header.removeEventListener('pointerup', onUp);\r\n            }\r\n            header.addEventListener('pointermove', onMove);\r\n            header.addEventListener('pointerup', onUp);\r\n        });\r\n\r\n        \/\/ \u2500\u2500 Cleanup \u2500\u2500\r\n        function cleanup() {\r\n            popup.remove();\r\n            document.removeEventListener('keydown', escHandler);\r\n        }\r\n        var escHandler = function(e) { if (e.key === 'Escape') cleanup(); };\r\n        document.addEventListener('keydown', escHandler);\r\n\r\n        document.body.appendChild(popup);\r\n\r\n        \/\/ \u2500\u2500 Rendre le contenu \u2500\u2500\r\n        if (options.pdfDataURL)          this.renderPdfInPopup(scrollZone, options.pdfDataURL, popupW, 'dataurl');\r\n        else if (options.pdfArrayBuffer) this.renderPdfInPopup(scrollZone, options.pdfArrayBuffer, popupW, 'arraybuffer');\r\n        else if (options.htmlContent)    this.renderHtmlInPopup(scrollZone, options.htmlContent);\r\n    },\r\n\r\n    \/\/ Alias pour compatibilit\u00e9\r\n    showInlinePdfPopup($dropZone, pdfImageDataURL, formatTitle) {\r\n        this.showInlineDocPopup($dropZone, { formatTitle: formatTitle, pdfDataURL: pdfImageDataURL });\r\n    },\r\n\r\n    \/\/ \u2705 Rendu PDF dans popup (dataurl ou arraybuffer) \u2014 avec crop des marges blanches\r\n    async renderPdfInPopup(container, pdfData, popupWidth, mode) {\r\n        try {\r\n            var u8;\r\n            if (mode === 'dataurl') {\r\n                var b64 = pdfData.split(',')[1];\r\n                var bstr = atob(b64);\r\n                u8 = new Uint8Array(bstr.length);\r\n                for (var i = 0; i < bstr.length; i++) { u8[i] = bstr.charCodeAt(i); }\r\n            } else {\r\n                u8 = new Uint8Array(pdfData);\r\n            }\r\n\r\n            var pdfjsLib = window['pdfjs-dist\/build\/pdf'];\r\n            if (!pdfjsLib) {\r\n                container.innerHTML = '<div style=\"padding:20px;text-align:center;color:#c00;\">pdf.js non charg\u00e9<\/div>';\r\n                return;\r\n            }\r\n            pdfjsLib.GlobalWorkerOptions.workerSrc =\r\n                '\/\/cdn.jsdelivr.net\/npm\/pdfjs-dist@latest\/build\/pdf.worker.min.js';\r\n\r\n            var pdf = await pdfjsLib.getDocument({ data: u8 }).promise;\r\n            console.log('\ud83d\udcc4 PDF popup :', pdf.numPages, 'pages');\r\n            container.innerHTML = '';\r\n\r\n            var firstPage = await pdf.getPage(1);\r\n            var vpNative = firstPage.getViewport({ scale: 1 });\r\n            var scale = popupWidth \/ vpNative.width;\r\n\r\n            \/\/ \u2705 R\u00e9f\u00e9rence au popup pour ajuster sa hauteur apr\u00e8s rendu\r\n            var _popup = container.closest('#via-pdf-inline-popup');\r\n            var _headerH = _popup ? (_popup.querySelector('div[style*=\"grab\"]') || {offsetHeight: 44}).offsetHeight : 44;\r\n\r\n            \/\/ \u2705 D\u00e9tecte les marges blanches haut\/bas d'un canvas rendu et retourne {top, bottom}\r\n            function detectWhiteMargins(canvas) {\r\n                var ctx = canvas.getContext('2d');\r\n                var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;\r\n                var W = canvas.width, H = canvas.height;\r\n                var topRow = 0, bottomRow = H - 1;\r\n                \/\/ Chercher la premi\u00e8re ligne non-blanche (tol\u00e9rance 252 pour les artefacts anti-aliasing)\r\n                outer: for (var y = 0; y < H; y++) {\r\n                    for (var x = 0; x < W; x++) {\r\n                        var i = (y * W + x) * 4;\r\n                        if (data[i] < 252 || data[i+1] < 252 || data[i+2] < 252) { topRow = y; break outer; }\r\n                    }\r\n                }\r\n                outer2: for (var y2 = H - 1; y2 >= topRow; y2--) {\r\n                    for (var x2 = 0; x2 < W; x2++) {\r\n                        var i2 = (y2 * W + x2) * 4;\r\n                        if (data[i2] < 252 || data[i2+1] < 252 || data[i2+2] < 252) { bottomRow = y2; break outer2; }\r\n                    }\r\n                }\r\n                return { top: topRow, bottom: bottomRow };\r\n            }\r\n\r\n            for (var pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\r\n                var page = await pdf.getPage(pageNum);\r\n                var vp = page.getViewport({ scale: scale });\r\n                \/\/ Rendre dans un canvas temporaire\r\n                var tmpCanvas = document.createElement('canvas');\r\n                tmpCanvas.width = vp.width;\r\n                tmpCanvas.height = vp.height;\r\n                await page.render({ canvasContext: tmpCanvas.getContext('2d'), viewport: vp }).promise;\r\n\r\n                \/\/ \u2705 Crop marges blanches\r\n                var margins = detectWhiteMargins(tmpCanvas);\r\n                var cropTop = Math.max(0, margins.top - 4);\r\n                var cropBottom = Math.min(tmpCanvas.height - 1, margins.bottom + 4);\r\n                var croppedH = cropBottom - cropTop + 1;\r\n\r\n                \/\/ Canvas final crop\u00e9\r\n                var canvas = document.createElement('canvas');\r\n                canvas.width = tmpCanvas.width;\r\n                canvas.height = croppedH;\r\n                canvas.getContext('2d').drawImage(tmpCanvas, 0, cropTop, tmpCanvas.width, croppedH, 0, 0, tmpCanvas.width, croppedH);\r\n                canvas.style.cssText = 'display:block;width:100%;height:auto;margin:0;padding:0;';\r\n                container.appendChild(canvas);\r\n                console.log('\ud83d\udcc4 Page', pageNum, '- crop:', cropTop, '\u2192', cropBottom, '(', Math.round(cropTop\/vp.height*100), '% top trimmed)');\r\n            }\r\n\r\n            \/\/ \u2705 Ajuster la hauteur du popup \u00e0 la hauteur r\u00e9elle du contenu rendu\r\n            \/\/ (popup \u00e9tait calcul\u00e9 sur popupW*2.5*0.51 qui peut \u00eatre trop grand ou trop petit)\r\n            if (_popup) {\r\n                var _totalH = 0;\r\n                container.querySelectorAll('canvas').forEach(function(c) { _totalH += c.height * (popupWidth \/ c.width); });\r\n                var _viewportH = window.innerHeight || document.documentElement.clientHeight || 600;\r\n                var _maxPopupH = Math.round(_viewportH * 0.88);\r\n                var _idealH = Math.min(_totalH + _headerH + 8, _maxPopupH);\r\n                _popup.style.height = _idealH + 'px';\r\n                console.log('\ud83d\udcd0 Popup redimensionn\u00e9:', Math.round(_idealH), 'px (contenu:', Math.round(_totalH), ')');\r\n            }\r\n        } catch (err) {\r\n            console.error('\u274c Erreur rendu PDF popup:', err);\r\n            container.innerHTML =\r\n                '<div style=\"padding:20px;text-align:center;color:#c00;font-size:12px;\">Erreur lors du chargement du document<\/div>';\r\n        }\r\n    },\r\n\r\n    \/\/ \u2705 Rendu HTML (Word) dans popup \u2014 avec CSS complet pour mammoth\r\n    renderHtmlInPopup(container, htmlContent) {\r\n        container.innerHTML = '';\r\n        \/\/ \u2705 Nettoyer les <p> vides en d\u00e9but\/fin produits par mammoth (marges parasites)\r\n        htmlContent = htmlContent\r\n            .replace(\/^(\\s*<p[^>]*>\\s*(<br\\s*\\\/?>\\s*)*<\\\/p>\\s*)+\/i, '')\r\n            .replace(\/(\\s*<p[^>]*>\\s*(<br\\s*\\\/?>\\s*)*<\\\/p>\\s*)+$\/i, '');\r\n        \/\/ \u2500\u2500 Styles pour le HTML g\u00e9n\u00e9r\u00e9 par mammoth (titres, paragraphes, listes, images) \u2500\u2500\r\n        var style = document.createElement('style');\r\n        style.textContent = [\r\n            '.via-html-popup-body { padding:20px 24px; background:#fff; color:#222; font-family:Georgia,\"Times New Roman\",serif; font-size:15px; line-height:1.7; }',\r\n            '.via-html-popup-body h1 { font-size:22px; font-weight:700; margin:0 0 12px; line-height:1.3; }',\r\n            '.via-html-popup-body h2 { font-size:18px; font-weight:700; margin:18px 0 8px; line-height:1.3; }',\r\n            '.via-html-popup-body h3 { font-size:15px; font-weight:700; margin:14px 0 6px; }',\r\n            '.via-html-popup-body p  { margin:0 0 10px; }',\r\n            '.via-html-popup-body p:first-child { margin-top:0; }',\r\n            '.via-html-popup-body strong, .via-html-popup-body b { font-weight:700; }',\r\n            '.via-html-popup-body em, .via-html-popup-body i { font-style:italic; }',\r\n            '.via-html-popup-body ul, .via-html-popup-body ol { margin:6px 0 10px 22px; padding:0; }',\r\n            '.via-html-popup-body li { margin-bottom:4px; }',\r\n            '.via-html-popup-body img { max-width:100%; height:auto; display:block; margin:10px auto; border-radius:4px; }',\r\n            '.via-html-popup-body table { width:100%; border-collapse:collapse; margin:10px 0; font-size:13px; }',\r\n            '.via-html-popup-body td, .via-html-popup-body th { border:1px solid #ddd; padding:6px 8px; vertical-align:top; }',\r\n            '.via-html-popup-body th { background:#f0f4f8; font-weight:700; }',\r\n            '.via-html-popup-body a { color:#225da9; text-decoration:underline; }'\r\n        ].join('');\r\n        container.appendChild(style);\r\n        var wrapper = document.createElement('div');\r\n        wrapper.className = 'via-html-popup-body';\r\n        wrapper.innerHTML = htmlContent;\r\n        container.appendChild(wrapper);\r\n    },\r\n    \r\n    async renderPDFInWindow(childWindow, container) {\r\n        container.innerHTML = '';\r\n        \r\n        const script = childWindow.document.createElement('script');\r\n        script.src = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.4.120\/pdf.min.js';\r\n        childWindow.document.head.appendChild(script);\r\n        \r\n        script.onload = async () => {\r\n            const pdfjsLib = childWindow.pdfjsLib;\r\n            const viewerContainer = childWindow.document.createElement('div');\r\n            viewerContainer.style.width = '100%';\r\n            viewerContainer.style.backgroundColor = 'white';\r\n            viewerContainer.style.position = 'relative';\r\n            container.appendChild(viewerContainer);\r\n            \r\n            const loadingTask = pdfjsLib.getDocument({data: window.pdfDataToTransfer});\r\n            const pdf = await loadingTask.promise;\r\n            \r\n            const firstPage = await pdf.getPage(1);\r\n            const viewport = firstPage.getViewport({scale: 1.5});\r\n            const pageHeight = viewport.height;\r\n            \r\n            const spacing = -15;\r\n            const totalHeight = (pageHeight * pdf.numPages) + (spacing * (pdf.numPages - 1));\r\n            viewerContainer.style.height = `${totalHeight}px`;\r\n            \r\n            for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\r\n                const page = await pdf.getPage(pageNum);\r\n                const canvas = childWindow.document.createElement('canvas');\r\n                const context = canvas.getContext('2d');\r\n                \r\n                canvas.width = viewport.width;\r\n                canvas.height = viewport.height;\r\n                \r\n                canvas.style.position = 'absolute';\r\n                canvas.style.left = '50%';\r\n                canvas.style.transform = 'translateX(-50%)';\r\n                canvas.style.top = `${(pageNum - 1) * (pageHeight + spacing)}px`;\r\n                \r\n                await page.render({\r\n                    canvasContext: context,\r\n                    viewport: viewport\r\n                }).promise;\r\n                \r\n                viewerContainer.appendChild(canvas);\r\n            }\r\n        };\r\n    },\r\n    \r\n    arrayBufferToBase64(buffer) {\r\n        let binary = '';\r\n        const bytes = new Uint8Array(buffer);\r\n        const len = bytes.byteLength;\r\n        for (let i = 0; i < len; i++) {\r\n            binary += String.fromCharCode(bytes[i]);\r\n        }\r\n        return window.btoa(binary);\r\n    },\r\n    \r\n    base64ToArrayBuffer(base64) {\r\n        const binaryString = window.atob(base64);\r\n        const len = binaryString.length;\r\n        const bytes = new Uint8Array(len);\r\n        for (let i = 0; i < len; i++) {\r\n            bytes[i] = binaryString.charCodeAt(i);\r\n        }\r\n        return bytes.buffer;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion des \u00e9v\u00e9nements de drop et d'upload\r\n *\/\r\nconst DropHandler = {\r\n    async handleDrop(e) {\r\n        e.preventDefault();\r\n        \r\n        const $currentTarget = this.findDropTarget(e);\r\n        \r\n        if (!$currentTarget) {\r\n            console.log('No valid drop target found');\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 V\u00c9RIFIER SI C'EST UN D\u00c9PLACEMENT (pas besoin de v\u00e9rifier le format)\r\n        const isMoved = StateManager.get('FirstUploadFileorMoved') === 'Moved';\r\n        const dragstartRef = StateManager.get('dragstart_Commande_Emplacement_Page_Web');\r\n        let hasDragstartRef = false;\r\n        \r\n        if (dragstartRef) {\r\n            if (dragstartRef !== 'No') {\r\n                hasDragstartRef = true;\r\n            }\r\n        }\r\n        \r\n        let isDeplacementAnnonce = false;\r\n        if (isMoved) {\r\n            if (hasDragstartRef) {\r\n                isDeplacementAnnonce = true;\r\n            }\r\n        }\r\n        \r\n        if (isDeplacementAnnonce) {\r\n            console.log('\ud83d\udd04 D\u00e9placement d\u00e9tect\u00e9 - contr\u00f4le format ignor\u00e9');\r\n        } else {\r\n            \/\/ \u2705 CONTR\u00d4LE FORMAT SEULEMENT POUR NOUVEAU D\u00c9P\u00d4T\r\n            \/\/ Utilise FormatUIManager au lieu de showFormatWarning\r\n            if (StateManager.get('Formatchoisi') === 'No') {\r\n                FormatUIManager.flashTitle($currentTarget);\r\n                return;\r\n            }\r\n            \r\n            if (!FormatUIManager.hasSelectedFormat($currentTarget)) {\r\n                FormatUIManager.flashTitle($currentTarget);\r\n                return;\r\n            }\r\n        }\r\n    \r\n        console.log(\"Drop at:\", $currentTarget);\r\n        \r\n        this.updateEmplacementState($currentTarget);\r\n        \r\n        const shouldProcess = this.shouldProcessDrop(e, $currentTarget);\r\n        \r\n        if (shouldProcess) {\r\n            await this.processFileDrop(e, $currentTarget);\r\n        } else {\r\n            this.processVideoDrop($currentTarget);\r\n        }\r\n        \r\n        DragDropManager.clearDataTransferFiles(e);\r\n    },\r\n    \r\n    findDropTarget(e) {\r\n        \/\/ \u2705 v2.4.3 : Si Ele0A est actif et le drop arrive sur Ele1A \u2192 rediriger vers Ele0A\r\n        if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n            var _ele0ADrop = document.querySelector('#Ele0A #drop_file_zone_achat');\r\n            if (_ele0ADrop) {\r\n                console.log('\ud83c\udfaf findDropTarget \u2014 PopUpChoice=Yes \u2192 cible forc\u00e9e: Ele0A');\r\n                return jQuery(_ele0ADrop);\r\n            }\r\n        }\r\n\r\n        let target = e.target.closest('#drop_file_zone_achat');\r\n        \r\n        if (!target) {\r\n            target = e.currentTarget.closest('#drop_file_zone_achat');\r\n            console.log('Drop target found 1');\r\n        }\r\n        \r\n        if (!target) {\r\n            target = jQuery(e.target).closest('#drop_file_zone_achat')[0];\r\n            console.log('Drop target found 2');\r\n        }\r\n        \r\n        return target ? jQuery(target) : null;\r\n    },\r\n    \r\n    updateEmplacementState($target) {\r\n        const espaceId = $target.closest('.droppable').attr('id');\r\n        \r\n        StateManager.set('Rank_Emplacement_Page_Web', espaceId);\r\n        StateManager.set('Commande_Emplacement_Page_Web',\r\n            StateManager.buildEmplacementReference(espaceId));\r\n        \r\n        UIManager.updateEmplacementDisplay();\r\n        \r\n        console.log(\"Rank_Emplacement_Page_Web:\", StateManager.get('Rank_Emplacement_Page_Web'));\r\n        console.log(\"Droppable at:\", StateManager.get('Commande_Emplacement_Page_Web'));\r\n    },\r\n    \r\n    shouldProcessDrop(e, $target) {\r\n        const hasFiles = e.dataTransfer.files.length > 0;\r\n        const isRedactionnel = StateManager.get('Commande_Format_Transmis') === 'R\u00e9dactionnel';\r\n        const isValidBackground = window.getComputedStyle(\r\n            $target.closest('#UploadFileConteneur')[0]\r\n        ).backgroundColor !== 'rgba(0, 0, 0, 0)';\r\n        \r\n        return (hasFiles || isRedactionnel) && isValidBackground;\r\n    },\r\n    \r\n    async processFileDrop(e, $target) {\r\n        jQuery('.MsgAdNotDisplayed').hide();\r\n        StateManager.setMultiple({\r\n            \"AdDisplayed\": 'Yes',\r\n            \/\/ \u2705 NE PLUS mettre sendDataToParentFlag ici - c'est la checkbox \"R\u00e9server\" qui le fera\r\n            \/\/ \"sendDataToParentFlag\": 'Yes'\r\n        });\r\n        \r\n        console.log('ajaxFileUpload_achat launched');\r\n        console.log(\"FirstUploadFileorMoved:\", StateManager.get('FirstUploadFileorMoved'));\r\n        \r\n        if (UIManager.isMobile()) {\r\n            $target = jQuery('#Ele1A').find('#drop_file_zone_achat');\r\n        }\r\n        \r\n        if (StateManager.get('Commande_Format_Transmis') === 'R\u00e9dactionnel') {\r\n            const fileURL = StateManager.get('FullPathAdFile');\r\n            const filename = fileURL.substring(fileURL.indexOf('_') + 1);\r\n            \r\n            try {\r\n                \/\/ \u2705 R\u00e9utiliser le File cach\u00e9 (\u00e9vite CORS cross-domain)\r\n                let file;\r\n                if (window._lastRedactionnelFile) {\r\n                    file = window._lastRedactionnelFile;\r\n                    console.log('\u267b\ufe0f R\u00e9utilisation du File cach\u00e9:', file.name, Math.round(file.size \/ 1024) + 'KB');\r\n                } else {\r\n                    file = await FileManager.urlToFile(fileURL, filename);\r\n                }\r\n                await UploadManager.handleFileUpload(file, $target);\r\n            } catch (error) {\r\n                console.error('Error:', error);\r\n            }\r\n        } else {\r\n            await UploadManager.handleFileUpload(e.dataTransfer.files[0], $target);\r\n        }\r\n    },\r\n    \r\n    processVideoDrop($target) {\r\n        const isValidBackground = window.getComputedStyle(\r\n            $target.closest('#UploadFileConteneur')[0]\r\n        ).backgroundColor !== 'rgba(0, 0, 0, 0)';\r\n        \r\n        if (!isValidBackground) {\r\n            jQuery('.MsgAdNotDisplayed').show();\r\n            StateManager.set(\"AdDisplayed\", 'No');\r\n            return;\r\n        }\r\n        \r\n        StateManager.set(\"AdDisplayed\", 'Yes');\r\n        \r\n        const objectUrl = StateManager.get('videoSrc');\r\n        const $previousDropZone = $('.drop_file_zone_achat_class').has(`video[src=\"${objectUrl}\"]`);\r\n        window.RestoreadSpaceTemplate($previousDropZone);\r\n        \r\n        const videoElement = jQuery('<video controls autoplay muted>').attr({\r\n            'src': objectUrl,\r\n            'max-width': '100%',\r\n            'max-height': '100%',\r\n            'draggable': 'true'\r\n        }).css({\r\n            'max-width': '100%',\r\n            'max-height': '100%'\r\n        });\r\n        \r\n        $target.empty().append(videoElement);\r\n        \r\n        $target.closest('#UploadFileConteneur').css({'background-color': '#FFFFFF00'});\r\n        \r\n        $target.closest('.OrdiMobileConteneurClass')\r\n            .find('.RefEspacePublicitaire')\r\n            .html('R\u00e9f\u00e9rence de l\\'espace : ' + StateManager.get('Commande_Emplacement_Page_Web'))\r\n            .attr('id', 'RefEspacePublicitaire')\r\n            .each(function() {\r\n                var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                this.style.setProperty('display', 'block', 'important');\r\n            });\r\n        \/\/ \u2705 v2.4.5 : Renseigner et afficher .PositionEspacePublicitaire\r\n        (function() {\r\n            var _rankPosV = StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            var _posLibV = PreviewRenderer._getPositionLibelle(_rankPosV);\r\n            if (_posLibV) {\r\n                $target.closest('.OrdiMobileConteneurClass')\r\n                    .find('.PositionEspacePublicitaireDeplacer')\r\n                    .text(_posLibV)\r\n                    .each(function() {\r\n                        var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                        if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                        this.style.setProperty('display', 'block', 'important');\r\n                    });\r\n            }\r\n        })();\r\n        \r\n        $target.closest('.OrdiMobileConteneurClass').find('.AdUploadedTitle').show();\r\n        \r\n        $target.closest('.OrdiMobileConteneurClass')\r\n            .css({'top': '60px', 'margin-bottom': '80px'});\r\n        \r\n        $target.closest('.HTMLUploadfileConteneur')\r\n            .not('.AdUploadedTitle')\r\n            .css({\r\n                'top': '0px',\r\n                'margin-bottom': '0px',\r\n                'box-shadow': 'inset 0 0 0 2px #00FF19',  \/\/ \u2705 v2.4.5\r\n                'background-color': 'white'\r\n            });\r\n        \r\n        $target.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed, .ChoisirEspacePublicitaire2ndLigne, span.ClassHdpCdp, .ClassRefEsp, .HideFormButton, .EspPubFormatMainContainer, .EnvoiUlterieurContainer')\r\n            .hide();\r\n        \r\n        jQuery('#MsgElementsCommandeValides, #MessageOptionsacompleterConteneur').hide();\r\n        \r\n        StateManager.set(\"FirstUploadFileorMoved\", 'Moved');\r\n        \r\n        \/\/ \u2705 Mettre \u00e0 jour l'\u00e9tat de la checkbox R\u00e9server (au lieu d'envoyer automatiquement)\r\n        FormatUIManager.updateReserverCheckboxState($target.closest('.droppable'));\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'explorateur de fichiers\r\n *\/\r\nconst FileExplorer = {\r\n    isRunning: false,\r\n\r\n    open(e) {\r\n        if (this.isRunning) {\r\n            return;\r\n        }\r\n        \r\n        const $element = jQuery(e.target).closest('.droppable');\r\n        \r\n        \/\/ \u2705 V\u00e9rifier si un format est s\u00e9lectionn\u00e9 (utilise FormatUIManager)\r\n        if (!FormatUIManager.hasSelectedFormat($element)) {\r\n            FormatUIManager.flashTitle($element);\r\n            return;\r\n        }\r\n        \r\n        this.isRunning = true;\r\n        \r\n        const rankId = $element.attr('id');\r\n        \r\n        StateManager.set('Rank_Emplacement_Page_Web', rankId);\r\n        StateManager.set('Commande_Emplacement_Page_Web',\r\n            StateManager.buildEmplacementReference(rankId));\r\n        \r\n        UIManager.updateEmplacementDisplay();\r\n        \r\n        console.log(\"Drop at:\", StateManager.get('Commande_Emplacement_Page_Web'));\r\n        \r\n        StateManager.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        \r\n        const $currentTarget = jQuery(e.target).closest('#drop_file_zone_achat');\r\n        const $fileInput = jQuery('#selectfile_achat');\r\n        \r\n        console.log(\"currentTarget\", $currentTarget);\r\n        \r\n        $fileInput.off('change');\r\n        $fileInput.off('click');\r\n        \r\n        const onChange = (event) => {\r\n            this.isRunning = false;\r\n            $fileInput.off('change', onChange);\r\n            \r\n            \/\/ \u2705 NE PLUS mettre sendDataToParentFlag ici\r\n            \/\/ StateManager.set(\"sendDataToParentFlag\", 'Yes');\r\n            \r\n            if ($fileInput[0].files.length > 0) {\r\n                UploadManager.handleFileUpload($fileInput[0].files[0], $currentTarget);\r\n            }\r\n        };\r\n        \r\n        const onClick = () => {\r\n            $fileInput.off('click', onClick);\r\n            $fileInput.on('focus', function onFocus() {\r\n                setTimeout(() => {\r\n                    if (!$fileInput.val()) {\r\n                        FileExplorer.isRunning = false;\r\n                    }\r\n                }, 200);\r\n                $fileInput.off('focus', onFocus);\r\n            });\r\n        };\r\n        \r\n        $fileInput.on('change', onChange);\r\n        $fileInput.on('click', onClick);\r\n        \r\n        $fileInput.click();\r\n        \r\n        setTimeout(() => {\r\n            this.isRunning = false;\r\n        }, 300);\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion du reset d'annonce\r\n *\/\r\nconst AdResetHandler = {\r\n    handle(e) {\r\n        e.preventDefault();\r\n        console.log(\"CroixResetAnnonce click\");\r\n        \r\n        \/\/ Reset l'\u00e9tat EnvoiUlterieur\r\n        StateManager.set('EnvoiUlterieur', 'false');\r\n        \r\n        \/\/ \u2705 v1.19.6 : Reset FileReceived mais garder le format s\u00e9lectionn\u00e9\r\n        StateManager.set('FileReceived', 'No');\r\n        \r\n        const $element = jQuery(e.currentTarget);\r\n        const $droppable = $element.closest('.droppable');\r\n        const resetRef = StateManager.buildEmplacementReference($droppable.attr('id'));\r\n        \r\n        console.log(\"Reset_Commande_Emplacement_Page_Web:\", resetRef);\r\n        \r\n        \/\/ \u2705 Supprimer le bouton \"R\u00e9server\" dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        $droppable.find('.ReserverContainer').hide();\r\n        \r\n        var _rankForDel = $droppable.attr('id') || StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            MessageManager.sendDelAdToParent({\r\n                Commande_Emplacement_Page_Web: resetRef,\r\n                Rank_Emplacement_Page_Web: _rankForDel,\r\n                LoadedPageUrl: window.location.href\r\n            });\r\n        } else {\r\n            window.processdataDelAd({\r\n                Commande_Emplacement_Page_Web: resetRef,\r\n                Rank_Emplacement_Page_Web: _rankForDel,\r\n                LoadedPageUrl: window.location.href\r\n            });\r\n        }\r\n        \r\n        \/\/ \u2705 v1.16.0 : Appeler RestoreadSpaceTemplateLocal directement (accessible dans ce scope)\r\n        RestoreadSpaceTemplateLocal(e.currentTarget);\r\n        \r\n        window.FonctionCroixResetAnnonce(e.currentTarget);\r\n        \r\n        \/\/ \u2705 v2.1.1 : Sauf popup\r\n        var formatWasSelected = sessionStorage.getItem('FormatSelect') \r\n            || sessionStorage.getItem('Commande_Format_Transmis')\r\n            || $droppable.data('kitFormatSelect');\r\n        \r\n        if (sessionStorage.getItem('PopUpChoice') !== 'Yes' && (formatWasSelected || sessionStorage.getItem('Formatchoisi') === 'Yes')) {\r\n            sessionStorage.setItem('Formatchoisi', 'Yes');\r\n            console.log('\u2705 Formatchoisi forc\u00e9 \u00e0 Yes apr\u00e8s reset');\r\n        }\r\n        \r\n        \/\/ \u2705 v1.19.6 : Remettre \u00e0 jour le titre format et r\u00e9afficher la checkbox R\u00e9server\r\n        setTimeout(() => {\r\n            FormatUIManager.updateTitleColor($droppable);\r\n            FormatUIManager.updateReserverCheckboxState($droppable);\r\n            \r\n            \/\/ \u2705 R\u00e9afficher le .ReserverContainer statique\r\n            $droppable.find('.ReserverContainer').show();\r\n        }, 150);\r\n    }\r\n};\r\n\r\n\/**\r\n * \u2705 Template pour r\u00e9initialisation des espaces publicitaires (IFRAME)\r\n *\/\r\nvar adSpaceTemplatesLocal = {};\r\n\r\nfunction saveAdSpaceTemplateLocal() {\r\n    var saved = 0;\r\n    jQuery('.droppable').each(function() {\r\n        var droppableId = jQuery(this).attr('id');\r\n        if (!droppableId) return;\r\n        \r\n        \/\/ \u2705 Ne jamais sauvegarder Ele0A (clone temporaire popup, pas un template d'origine)\r\n        if (droppableId === 'Ele0A') return;\r\n        \r\n        \/\/ \u2705 Ne pas r\u00e9-\u00e9craser un template d\u00e9j\u00e0 sauvegard\u00e9\r\n        if (adSpaceTemplatesLocal[droppableId]) return;\r\n        \r\n        \/\/ \u2705 v2.3.4 : Ne pas sauvegarder si template d\u00e9j\u00e0 connu (\u00e9tat propre sauvegard\u00e9)\r\n        \/\/ Le guard hasAd est supprim\u00e9 \u2014 on veut capturer le template le plus t\u00f4t possible\r\n        \/\/ Si le template existe d\u00e9j\u00e0, on ne le r\u00e9\u00e9crase pas\r\n        \/\/ (le guard anti-\u00e9crasement if (adSpaceTemplatesLocal[droppableId]) return; suffit)\r\n        \r\n        var $content = jQuery(this).find('.OrdiMobileConteneurClass').first();\r\n        if ($content.length > 0) {\r\n            adSpaceTemplatesLocal[droppableId] = $content.clone(true, true);\r\n            saved++;\r\n        }\r\n    });\r\n    if (saved > 0) {\r\n        console.log('\u2705 Templates espaces pub sauvegard\u00e9s:', saved, 'espaces -', Object.keys(adSpaceTemplatesLocal));\r\n        return true;\r\n    }\r\n    return false;\r\n}\r\n\r\nfunction RestoreadSpaceTemplateLocal(element) {\r\n    console.log('\ud83d\udd04 RestoreadSpaceTemplateLocal', element);\r\n    \r\n    var $element = jQuery(element);\r\n    var $droppable = $element.closest('.droppable');\r\n    var droppableId = $droppable.attr('id');\r\n    \r\n    \/\/ \u2705 FIX Ele0A : pas de template sauvegard\u00e9 (clone temporaire popup)\r\n    \/\/ \u2192 pas de remplacement DOM, reset visuel direct sur le contenu existant\r\n    var _isEle0A = (droppableId === 'Ele0A');\r\n\r\n    \/\/ \u2705 v1.19.3 : Chercher le template sp\u00e9cifique \u00e0 CET espace (sauf Ele0A)\r\n    if (!_isEle0A) {\r\n        if (!droppableId || !adSpaceTemplatesLocal[droppableId]) {\r\n            if (!saveAdSpaceTemplateLocal()) {\r\n                console.error('\u274c Template non disponible');\r\n                return false;\r\n            }\r\n            if (!adSpaceTemplatesLocal[droppableId]) {\r\n                console.error('\u274c Template non trouv\u00e9 pour', droppableId);\r\n                return false;\r\n            }\r\n        }\r\n    }\r\n    \r\n    var adSpaceElement = $droppable.find('.OrdiMobileConteneurClass').first();\r\n    \r\n    if (!adSpaceElement || !adSpaceElement.length) {\r\n        console.error('\u274c OrdiMobileConteneurClass non trouv\u00e9');\r\n        return false;\r\n    }\r\n    \r\n    var newElement;\r\n    if (_isEle0A) {\r\n        \/\/ Ele0A : pas de clone \u2014 on remet en \u00e9tat le contenu existant directement\r\n        newElement = adSpaceElement;\r\n        console.log('\u2705 [Ele0A] reset visuel direct (pas de template clone)');\r\n        \/\/ \u2705 Vider le contenu du dropzone et restaurer le HTML par d\u00e9faut\r\n        \/\/ (le replaceWith n'ayant pas lieu, l'image d\u00e9pos\u00e9e et le fond blanc restent sinon)\r\n        var $dz0A = $droppable.find('#drop_file_zone_achat');\r\n        $dz0A.empty().html(\r\n            '<div id=\"drag_upload_file_achat\">' +\r\n                '<p class=\"UploadIci\" style=\"color:#FB5E2A;font-weight:600;\">Ici glisser \u2013 d\u00e9poser ou<br>t\u00e9l\u00e9charger une annonce<\/p>' +\r\n            '<\/div>'\r\n        );\r\n        \/\/ Restaurer le fond bleu #9FC5F3 et retirer les styles d'annonce upload\u00e9e\r\n        $droppable.find('#UploadFileConteneur').css({\r\n            'background-color': '#9FC5F3',\r\n            'border': '',\r\n            'box-sizing': ''\r\n        });\r\n        $droppable.find('.HTMLUploadfileConteneur').css({\r\n            'box-shadow': '',\r\n            'background-color': '',\r\n            'border': '',\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'min-height': '',\r\n            'overflow': '',\r\n            'height': '',\r\n            'max-height': ''\r\n        });\r\n        \/\/ Masquer la croix et le titre d'annonce upload\u00e9e\r\n        $droppable.find('.AdUploadedTitle, #CroixResetAnnonce, .CroixResetAnnonceContainer, .DeplaceAnnonce').hide();\r\n        $droppable.removeAttr('data-via-ad-loaded').removeAttr('data-from-miniature');\r\n        console.log('\u2705 [Ele0A] dropzone vid\u00e9 + fond restaur\u00e9');\r\n    } else {\r\n        \/\/ \u2705 v1.19.3 : Cloner le template SP\u00c9CIFIQUE \u00e0 cet espace (pas le premier)\r\n        newElement = adSpaceTemplatesLocal[droppableId].clone(true, true);\r\n        console.log('\u2705 Template utilis\u00e9 pour', droppableId);\r\n        adSpaceElement.replaceWith(newElement);\r\n        \/\/ \u2705 v2.4.12 : Effacer data-via-ad-loaded (sinon selectEspaceActif masque .ReserverContainer)\r\n        $droppable.removeAttr('data-via-ad-loaded').removeAttr('data-from-miniature');\r\n        if (window.outerWidth < 1000) {\r\n            newElement.css({'margin-top': '-25px', 'bottom': '0px'});\r\n        }\r\n    }\r\n    \r\n    \/\/ D\u00e9cocher la case Envoi diff\u00e9r\u00e9 si elle existe\r\n    newElement.find('input[name*=\"EnvoiUlterieur\"]').prop('checked', false);\r\n    \r\n    \/\/ \u2705 D\u00e9cocher la checkbox \"R\u00e9server\"\r\n    newElement.find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').prop('checked', false);\r\n    \r\n    \/\/ Reset l'\u00e9tat EnvoiUlterieur\r\n    StateManager.set('EnvoiUlterieur', 'false');\r\n    \r\n    \/\/ \u2705 v1.19.3 : R\u00e9initialiser TOUS les styles inline des conteneurs parents modifi\u00e9s pendant le d\u00e9p\u00f4t\r\n    if ($droppable.length) {\r\n        \/\/ \u2705 v2.0.9 : Restaurer les marges de l'algorithme de positionnement (sauvegard\u00e9es par styleUploadedAd)\r\n        var origMt = $droppable.data('orig-mt');\r\n        $droppable.css({\r\n            'margin-top': (origMt !== undefined) ? origMt + 'px' : '',\r\n            'margin-bottom': '',\r\n            'margin-left': '',\r\n            'margin-right': ''\r\n        });\r\n        \/\/ \u2705 v2.0.11 : Cleanup event namespace docpreview\r\n        $droppable.off('click.docpreview');\r\n        \r\n        \/\/ Reset .OrdiMobileConteneurClass margins\r\n        var $container = $droppable.find('.OrdiMobileConteneurClass');\r\n        var origMb = $container.data('orig-mb');\r\n        $container.css({\r\n            'margin-top': '',\r\n            'margin-bottom': (origMb !== undefined) ? origMb + 'px' : ''\r\n        });\r\n        \r\n        \/\/ Reset .HTMLUploadfileConteneur (set by styleUploadedAd: box-shadow inset, background-color:white)\r\n        $droppable.find('.HTMLUploadfileConteneur').css({\r\n            'border': '',\r\n            'box-shadow': '',\r\n            'outline': '',\r\n            'outline-offset': '',\r\n            'background-color': '',\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'min-height': '',\r\n            'overflow': '',\r\n            'padding': '',\r\n            'position': ''\r\n        });\r\n        $droppable.find('.via-green-border-overlay').remove();\r\n        \r\n        \/\/ \u2705 Restaurer pointer-events sur OrdiMobileConteneurClass et ses enfants\r\n        $droppable.find('.OrdiMobileConteneurClass').css('pointer-events', '');\r\n        $droppable.find('#CroixResetAnnonce').css({'pointer-events': '', 'position': '', 'z-index': ''});\r\n        \/\/ \u2705 v2.4.5 : Reset margin-right Ele0A (pos\u00e9 par adjustMobileLayout)\r\n        var _croixContReset = $droppable.find('.CroixResetAnnonceContainer')[0];\r\n        if (_croixContReset) { _croixContReset.style.removeProperty('margin-right'); _croixContReset.style.removeProperty('margin-top'); }\r\n        $droppable.find('#PopUpMessageAchattest').css('pointer-events', '');\r\n        \r\n        \/\/ \u2705 v2.0.9 : Restaurer le scale(1.4) sur .UploadFileConteneur (r\u00e9duit \u00e0 scale(1) par styleUploadedAd sur mobile)\r\n        $droppable.find('.UploadFileConteneur').css({\r\n            'transform': '',\r\n            'transform-origin': ''\r\n        });\r\n        \r\n        \/\/ Reset #UploadFileConteneur - Restaurer le fond bleu #9FC5F3 + retirer liser\u00e9 envoi diff\u00e9r\u00e9\r\n        $droppable.find('#UploadFileConteneur').css({\r\n            'width': '',\r\n            'background-color': '#9FC5F3',\r\n            'border': '',\r\n            'box-sizing': ''\r\n        });\r\n        \r\n        \/\/ Reset .ToBeHidden (set by adjustDesktopLayout: top:105px, min-height:300px + overflow mobile)\r\n        $droppable.closest('.ToBeHidden').css({\r\n            'top': '',\r\n            'min-height': '',\r\n            'overflow': ''\r\n        });\r\n        \r\n        \/\/ Reset overflow sur le parent du droppable (set by adjustDesktopLayout)\r\n        $droppable.parent().css('overflow', '');\r\n        \r\n        \/\/ \u2705 v1.19.5 : Gestion device-specific pour les textes\r\n        var isDesktop = window.outerWidth >= 1000;\r\n        \r\n        if (isDesktop) {\r\n            \/\/ Desktop : cacher les textes mobiles, afficher UploadIci\r\n            $droppable.find('.TexteMobile').hide();\r\n            $droppable.find('.TexteMobileAnnonce').hide();\r\n            $droppable.find('.TexteMobileAjoutAnnonce').hide();\r\n            $droppable.find('.UploadIci').show();\r\n        } else {\r\n            \/\/ Mobile : afficher TexteMobileAnnonce\r\n            $droppable.find('.TexteMobileAnnonce').show();\r\n        }\r\n        \r\n        \/\/ R\u00e9-afficher les \u00e9l\u00e9ments masqu\u00e9s pendant l'upload\r\n        $droppable.find('.PositionEspacePublicitaireContainer').show();\r\n        $droppable.find('.ChoisirEspacePublicitaireDisponibiliteConteneur').show();\r\n        $droppable.find('.PositionEspacePublicitaire, .ReferenceEspacePublicitaire, .ChoisirEspacePublicitaireDisponibiliteConteneur > div > .elementor-widget-text-editor').show();\r\n        $droppable.find('.AdDroppedTextNotDisplayed').hide();\r\n        \/\/ \u2705 v2.4.5 : Ele0A + PopUpChoice=Yes \u2192 ne pas r\u00e9-afficher le titre si format d\u00e9j\u00e0 s\u00e9lectionn\u00e9\r\n        var _skipTitre = (sessionStorage.getItem('PopUpChoice') === 'Yes' && $droppable.attr('id') === 'Ele0A');\r\n        $droppable.find('.SelectionFormatTitreBlanc').hide();\r\n        if (!_skipTitre) {\r\n            $droppable.find('.SelectionFormatTitre').show();\r\n        }\r\n        $droppable.find('span.ClassHdpCdp, .ClassRefEsp').show();\r\n        $droppable.find('.EspPubFormatMainContainer').show();\r\n        $droppable.find('.EspPubFormatListe').show();\r\n        $droppable.find('.ChoisirEspacePublicitaireClass').show();\r\n        $droppable.find('.GlisserDeposerConteneur').show();\r\n        $droppable.find('.OUClass').show();\r\n        $droppable.find('.PositionReference').show();\r\n        $droppable.find('.ClassHdpCdp').show();\r\n        $droppable.find('.ClassRefEsp').show();\r\n        $droppable.find('.EnvoiUlterieurTexte').show();\r\n        $droppable.find('.EnvoiUlterieurContainer').show();\r\n        \r\n        \/\/ \u2705 v1.19.5 : R\u00e9afficher le .ReserverContainer (bouton Elementor statique)\r\n        $droppable.find('.ReserverContainer').show();\r\n        newElement.find('.ReserverContainer').show();\r\n        \r\n        \/\/ Masquer les \u00e9l\u00e9ments sp\u00e9cifiques \u00e0 l'annonce upload\u00e9e\r\n        $droppable.find('.AdUploadedTitle, #CroixResetAnnonce, .CroixResetAnnonceContainer, .DeplaceAnnonce').hide();\r\n        $droppable.find('#CroixResetAnnonce').css({'position': '', 'z-index': ''});\r\n        $droppable.find('.RefEspacePublicitaire').hide();\r\n        \r\n        \/\/ Supprimer le bouton \"R\u00e9server\" dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ \u2705 v1.19.6 : Restaurer le format s\u00e9lectionn\u00e9 visuellement\r\n        \/\/ Chercher le format dans plusieurs sources possibles\r\n        var formatSelect = sessionStorage.getItem('FormatSelect') \r\n            || sessionStorage.getItem('Commande_Format_Transmis')\r\n            || $droppable.data('kitFormatSelect')\r\n            || '';\r\n        \r\n        var formatchoisi = sessionStorage.getItem('Formatchoisi');\r\n        console.log('\ud83d\udcd0 Format \u00e0 restaurer:', formatSelect, '| Formatchoisi:', formatchoisi);\r\n        \r\n        \/\/ D'abord reset tous les formats visuellement (sur newElement ET $droppable)\r\n        var $allFormats = newElement.find('.EspPubFormatContainer').add($droppable.find('.EspPubFormatContainer'));\r\n        $allFormats.css({\r\n            'background-color': '',\r\n            'border': ''\r\n        });\r\n        newElement.find('.EspPubFormat').add($droppable.find('.EspPubFormat')).css({\r\n            'color': ''\r\n        });\r\n        \r\n        \/\/ Si un format \u00e9tait s\u00e9lectionn\u00e9 (via sessionStorage OU visuellement avant)\r\n        \/\/ \u2705 v2.1.1 : Sauf popup\r\n        if ((formatSelect || formatchoisi === 'Yes') && sessionStorage.getItem('PopUpChoice') !== 'Yes') {\r\n            var formatFound = false;\r\n            \r\n            if (formatSelect) {\r\n                \/\/ \u2705 v2.1.1 : Normaliser via NFD (plus fiable que les replace manuels)\r\n                var formatLower = formatSelect.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase().replace(\/ \/g, '');\r\n                \r\n                \/\/ Appliquer sur newElement ET $droppable pour \u00eatre s\u00fbr\r\n                var $allContainers = newElement.find('.EspPubFormatContainer').add($droppable.find('.EspPubFormatContainer'));\r\n                \r\n                $allContainers.each(function() {\r\n                    var className = this.className.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    \r\n                    if (className.includes(formatLower)) {\r\n                        jQuery(this).css({'background-color': '#ffffff'});\r\n                        jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                        formatFound = true;\r\n                        \/\/ \u2705 v2.4.12 : M\u00e9moriser le format restaur\u00e9 (lu par selectEspaceActif pour re-surligner apr\u00e8s reset global)\r\n                        $droppable.attr('data-restored-format', formatSelect);\r\n                        console.log('\u2705 Format restaur\u00e9 visuellement:', formatSelect, '- classe:', this.className);\r\n                    }\r\n                });\r\n            }\r\n            \r\n            \/\/ \u2705 IMPORTANT : Pr\u00e9server Formatchoisi = Yes pour permettre l'upload\r\n            sessionStorage.setItem('Formatchoisi', 'Yes');\r\n            console.log('\u2705 Formatchoisi maintenu \u00e0 Yes');\r\n            \r\n            \/\/ Basculer les titres format (sur newElement ET $droppable)\r\n            newElement.find('.SelectionFormatTitre').hide();\r\n            newElement.find('.SelectionFormatTitreBlanc').show();\r\n            $droppable.find('.SelectionFormatTitre').hide();\r\n            $droppable.find('.SelectionFormatTitreBlanc').show();\r\n        }\r\n    }\r\n    \r\n    \/\/ \u2705 v1.19.2 : Relancer InitLoadedPage pour recalculer positions et tailles\r\n    setTimeout(function() {\r\n        if (typeof window.InitLoadedPage === 'function') {\r\n            window.InitLoadedPage();\r\n        }\r\n        \r\n        \/\/ \u2705 v1.19.6 : R\u00e9attacher les MutationObservers sur les formats\r\n        if (typeof FormatUIManager !== 'undefined' && FormatUIManager.observeFormatChanges) {\r\n            FormatUIManager.observeFormatChanges();\r\n        }\r\n    }, 100);\r\n    \r\n    console.log('\u2705 Espace publicitaire r\u00e9initialis\u00e9');\r\n    return true;\r\n}\r\n\r\n\/\/ \u2705 Exposer pour appel depuis yearbook-media.js (suppression popup mode=popup)\r\nwindow.RestoreadSpaceTemplateLocal = RestoreadSpaceTemplateLocal;\r\n\r\nwindow.verifierAffichageMsgSelectEspaceLocal = function() {\r\n    const formatChoisi = StateManager.get('Formatchoisi') === 'Yes';\r\n    const fileReceived = StateManager.get('FileReceived');\r\n    const envoiUlterieur = StateManager.get('EnvoiUlterieur');\r\n    \r\n    var dateDebut, dateFin, pays;\r\n    try {\r\n        dateDebut = window.parent.$('#form-field-DebutCampagne').val();\r\n        dateFin = window.parent.$('#form-field-FinCampagne').val();\r\n        pays = window.parent.$('#form-field-Nationalite_Societe').val();\r\n    } catch(e) {\r\n        jQuery('#MsgSelectEspace').hide();\r\n        return;\r\n    }\r\n    \r\n    if (!dateDebut || !dateFin || !pays || !formatChoisi) {\r\n        jQuery('#MsgSelectEspace').hide();\r\n        return;\r\n    }\r\n    \r\n    if (fileReceived !== 'Yes') {\r\n        if (envoiUlterieur !== 'true') {\r\n            jQuery('#MsgSelectEspace').show();\r\n        } else {\r\n            jQuery('#MsgSelectEspace').hide();\r\n        }\r\n    } else {\r\n        jQuery('#MsgSelectEspace').hide();\r\n    }\r\n};\r\n\r\n\/\/ Sauvegarder les templates au chargement (apr\u00e8s rendu complet Elementor)\r\njQuery(document).ready(function() {\r\n    \/\/ \u2705 v1.19.3 : D\u00e9lai augment\u00e9 + double sauvegarde pour garantir les bonnes dimensions\r\n    setTimeout(saveAdSpaceTemplateLocal, 3000);\r\n    setTimeout(saveAdSpaceTemplateLocal, 6000);\r\n    \/\/ \u2705 v2.3.4 : Sauvegarde imm\u00e9diate d\u00e8s que la page est pr\u00eate dans l'iframe\r\n    \/\/ (avant toute interaction utilisateur)\r\n    setTimeout(saveAdSpaceTemplateLocal, 100);\r\n    setTimeout(saveAdSpaceTemplateLocal, 500);\r\n});\r\n\r\n\/\/ \u2705 v2.3.4 : Forcer sauvegarde \u00e0 la r\u00e9ception de elementsRemoved (espaces visibles + vierges)\r\nwindow.addEventListener('message', function(e) {\r\n    if (e.data && e.data.type === 'elementsRemoved') {\r\n        \/\/ Les espaces sont vierges \u00e0 ce stade \u2192 sauvegarder imm\u00e9diatement\r\n        setTimeout(saveAdSpaceTemplateLocal, 50);\r\n        setTimeout(saveAdSpaceTemplateLocal, 300);\r\n    }\r\n});\r\n\r\n\/**\r\n * Fonction helper pour le d\u00e9p\u00f4t r\u00e9dactionnel\r\n *\/\r\nfunction RedactionnelDepose() {\r\n    jQuery('#Tariftobedisplayed').html('-');\r\n    jQuery('#TarifDataStep3').html('\u00e0 choisir').css({'color': '#FB5E2A'});\r\n    jQuery('#FormatDataStep3').html('\u00e0 choisir').css({'color': '#FB5E2A'});\r\n    jQuery('#ListePaysDirect, #ListeThemeDirect, .ListeArticles, #PageAfficheeMessage').hide();\r\n    StateManager.set(\"PositionAnnonceSelection\", 'Yes');\r\n}\r\n\r\n\/**\r\n * Exposition des fonctions globales n\u00e9cessaires\r\n *\/\r\nwindow.uploadFile_achat = (e) => DropHandler.handleDrop(e);\r\nwindow.fileExplorer_achat = (e) => FileExplorer.open(e);\r\nwindow.ajaxFileUpload_achat = (fileObj, dropZone) => UploadManager.handleFileUpload(fileObj, dropZone);\r\nwindow.ActivatesendDataToParent = (dropZone) => UploadManager.activateSendDataToParent(dropZone);\r\n\/\/ \u2705 v2.3.4 : Exposer FormatUIManager pour appel depuis Entete.txt (selectEspaceActif)\r\nwindow.FormatUIManagerRef = FormatUIManager;\r\n\r\n\/**\r\n * Initialisation de l'application\r\n *\/\r\njQuery(document).ready(() => {\r\n    StateManager.init();\r\n    ScrollHelper.init();\r\n    DragDropManager.init();\r\n    FormatUIManager.init();\r\n    \r\n    if (UIManager.isMobile()) {\r\n        UIManager.initMobileUI();\r\n    } else {\r\n        UIManager.initDesktopUI();\r\n    }\r\n    \r\n    jQuery(document).on('click', '#CroixResetAnnonce', (e) => AdResetHandler.handle(e));\r\n    \r\n    \/\/ \u2705 Clic sur le texte du label \u2192 toggle manuel de la checkbox du m\u00eame conteneur\r\n    jQuery(document).on('click', '.reserver-dynamic-label', function(e) {\r\n        e.preventDefault();\r\n        e.stopPropagation();\r\n        const $cb = $(this).closest('.reserver-dynamic-option, .reserver-dynamic-container').find('.reserver-dynamic-checkbox');\r\n        if ($cb.length) {\r\n            $cb.prop('checked', !$cb.prop('checked')).trigger('change');\r\n        }\r\n    });\r\n\r\n    \/\/ \u2705 CHECKBOX \"R\u00e9server cet espace publicitaire\" \u2014 VALIDATION ET ENVOI DES DONN\u00c9ES\r\n    \/\/ \u2705 v2.4.13 : iOS touchend\r\n    \/\/ \u2705 v2.4.13 : Mobile \u2014 \u00e9couter touchend sur input ET click\/touchend sur label\r\n    jQuery(document).on('touchend', 'input[name=\"form_fields[ReserverEspacePublicitaire]\"]', function() {\r\n        if (this._viaResTouch) { return; }\r\n        this._viaResTouch = true;\r\n        var _self = this;\r\n        setTimeout(function() { _self._viaResTouch = false; }, 500);\r\n        setTimeout(function() { jQuery(_self).trigger('change'); }, 100);\r\n    });\r\n    jQuery(document).on('touchend click', '.elementor-field-group-ReserverEspacePublicitaire label, .reserver-dynamic-label, .reserver-dynamic-option label', function(e) {\r\n        \/\/ Trouver l'input associ\u00e9\r\n        var $input = jQuery(this).closest('.elementor-field-option, .reserver-dynamic-option').find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]');\r\n        if (!$input.length) { $input = jQuery(this).siblings('input[name=\"form_fields[ReserverEspacePublicitaire]\"]'); }\r\n        if (!$input.length) { $input = jQuery('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').first(); }\r\n        if ($input.length) {\r\n            if (e.type === 'touchend') { e.preventDefault(); }\r\n            var _wasChecked = $input.prop('checked');\r\n            $input.prop('checked', !_wasChecked);\r\n            setTimeout(function() {\r\n                $input.trigger('change');\r\n            }, 50);\r\n        }\r\n    });\r\n    jQuery(document).on('change', 'input[name=\"form_fields[ReserverEspacePublicitaire]\"]', function(e) {\r\n        const $checkbox = $(this);\r\n        let $droppable = $checkbox.closest('.droppable');\r\n        if (!$droppable.length) {\r\n            $droppable = $checkbox.closest('.reserver-dynamic-container').prev('.droppable');\r\n        }\r\n        \/\/ \u2705 v2.4.13 : Fallback mobile \u2014 checkbox dans body > .reserver-dynamic-container[data-droppable-id]\r\n        if (!$droppable.length) {\r\n            const $dynContainer = $checkbox.closest('.reserver-dynamic-container');\r\n            const _droppableId = $dynContainer.attr('data-droppable-id') || '';\r\n            if (_droppableId) {\r\n                $droppable = $('#' + _droppableId);\r\n            }\r\n        }\r\n        \/\/ Dernier recours : utiliser le rank en sessionStorage\r\n        if (!$droppable.length) {\r\n            const _rankFallback = StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            if (_rankFallback) { $droppable = $('#' + _rankFallback); }\r\n        }\r\n        \r\n        \/\/ Si on d\u00e9coche\r\n        if (!$checkbox.is(':checked')) {\r\n            console.log('\u2610 Checkbox \"R\u00e9server\" d\u00e9coch\u00e9e');\r\n            \/\/ \u2705 Mettre \u00e0 jour le label\r\n            const $lbl = $checkbox.closest('.reserver-dynamic-option, .elementor-field-option').find('.reserver-dynamic-label, label').not('input');\r\n            $lbl.text('R\u00e9server cet espace publicitaire').css('color', '');\r\n            \/\/ \u2705 Notifier le parent pour d\u00e9-r\u00e9server l'item dans le r\u00e9cap\r\n            const _rankDecoche = $droppable.attr('id') || StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            const _emplacementDecoche = StateManager.buildEmplacementReference(_rankDecoche);\r\n            MessageManager.sendToParent('annulationReservation', {\r\n                Rank_Emplacement_Page_Web: _rankDecoche,\r\n                Commande_Emplacement_Page_Web: _emplacementDecoche,\r\n                LoadedPageUrl: window.location.href\r\n            });\r\n            \/\/ \u2705 v2.4.5 : M\u00e9moriser que ce rank a \u00e9t\u00e9 explicitement d\u00e9coch\u00e9\r\n            StateManager.set('_reserverDecoche_' + _rankDecoche, 'Yes');\r\n            console.log('\ud83d\udce4 annulationReservation envoy\u00e9 \u2192 parent | rank:', _rankDecoche, '| emplacement:', _emplacementDecoche);\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 V\u00e9rifier les conditions : format s\u00e9lectionn\u00e9 ET (fichier d\u00e9pos\u00e9 OU envoi diff\u00e9r\u00e9)\r\n        const hasFormat = FormatUIManager.hasSelectedFormat($droppable);\r\n        const hasFile = StateManager.get('FileReceived') === 'Yes';\r\n        const hasEnvoiDiffere = $droppable.find('input[name*=\"EnvoiUlterieur\"]:checked').length > 0;\r\n        \r\n        console.log('\ud83d\udd0d Checkbox \"R\u00e9server\" - Validation:', { hasFormat, hasFile, hasEnvoiDiffere });\r\n        \r\n        if (!hasFormat) {\r\n            \/\/ \u2705 Si un fichier est d\u00e9j\u00e0 d\u00e9pos\u00e9 \u2192 d\u00e9duire le format depuis l'extension (ne pas bloquer)\r\n            if (hasFile) {\r\n                const _uploadedName = StateManager.get('Upload_File_Name') || '';\r\n                const _ext = _uploadedName.split('.').pop().toLowerCase();\r\n                const _fileType = FileManager.getFileType(_ext);\r\n                let _deducedFormat = '';\r\n                if (_fileType === 'video') {\r\n                    _deducedFormat = sessionStorage.getItem('SiteLangue') === 'EN' ? 'Video' : 'Vid\u00e9o';\r\n                } else if (_fileType === 'image') {\r\n                    _deducedFormat = sessionStorage.getItem('SiteLangue') === 'EN' ? 'Banner' : 'Banni\u00e8re';\r\n                } else if (_fileType === 'document') {\r\n                    _deducedFormat = sessionStorage.getItem('SiteLangue') === 'EN' ? 'Press release' : 'Communiqu\u00e9';\r\n                }\r\n                if (_deducedFormat) {\r\n                    StateManager.set('Commande_Format_Transmis', _deducedFormat);\r\n                    StateManager.set('FormatSelect', _deducedFormat);\r\n                    StateManager.set('Formatchoisi', 'Yes');\r\n                    console.log('\u2705 Format d\u00e9duit depuis extension (' + _ext + '):', _deducedFormat);\r\n                    \/\/ Continuer vers l'envoi (pas de return false)\r\n                } else {\r\n                    e.preventDefault();\r\n                    $checkbox.prop('checked', false);\r\n                    FormatUIManager.flashTitle($droppable);\r\n                    console.log('\u274c R\u00e9servation bloqu\u00e9e : format non d\u00e9ductible depuis extension:', _ext);\r\n                    return false;\r\n                }\r\n            } else {\r\n                e.preventDefault();\r\n                $checkbox.prop('checked', false);\r\n                FormatUIManager.flashTitle($droppable);\r\n                console.log('\u274c R\u00e9servation bloqu\u00e9e : aucun format s\u00e9lectionn\u00e9');\r\n                return false;\r\n            }\r\n        }\r\n        \r\n        if (!hasFile && !hasEnvoiDiffere) {\r\n            e.preventDefault();\r\n            $checkbox.prop('checked', false);\r\n            console.log('\u274c R\u00e9servation bloqu\u00e9e : ni annonce d\u00e9pos\u00e9e ni envoi diff\u00e9r\u00e9');\r\n            return false;\r\n        }\r\n        \r\n        \/\/ \u2705 Conditions remplies \u2014 Pr\u00e9parer et envoyer les donn\u00e9es\r\n        console.log('\u2705 Checkbox \"R\u00e9server\" valid\u00e9e \u2014 envoi des donn\u00e9es');\r\n        \r\n        const rankId = $droppable.attr('id');\r\n        \r\n        StateManager.setMultiple({\r\n            \"sendDataToParentFlag\": \"Yes\",\r\n            \"Formatchoisi\": \"Yes\",\r\n            \"Rank_Emplacement_Page_Web\": rankId,\r\n            \"Commande_Emplacement_Page_Web\": StateManager.buildEmplacementReference(rankId),\r\n            \"LoadedPageUrl\": window.location.href,\r\n            \/\/ \u2705 v2.3.0 : Forcer avant l'envoi \u2014 le setTimeout(4000) dans activateSendDataToParent\r\n            \/\/ arrive trop tard sur le 1er clic \u2192 AddNewRefInVosCampagnes restait null\r\n            \"AddNewRefInVosCampagnes\": \"Yes\"\r\n        });\r\n        \r\n        \/\/ \u2705 D\u00e9clencher l'envoi des donn\u00e9es via activateSendDataToParent\r\n        const $dropZone = $droppable.find('#drop_file_zone_achat');\r\n        UploadManager.activateSendDataToParent($dropZone);\r\n    });\r\n    \r\n    \/\/ G\u00c9RER \"Envoi diff\u00e9r\u00e9\" \u2014 marquer l'\u00e9tat sans envoyer (c'est \"R\u00e9server\" qui envoie)\r\n    \/\/ \u2705 v2.4.13 : iOS touchend\r\n    jQuery(document).on('touchend', 'input[name*=\"EnvoiUlterieur\"]', function() {\r\n        if (this._viaTouch) { return; }\r\n        this._viaTouch = true;\r\n        var _self = this;\r\n        setTimeout(function() { _self._viaTouch = false; }, 500);\r\n        setTimeout(function() { jQuery(_self).trigger('change'); }, 100);\r\n    });\r\n    jQuery(document).on('change', 'input[name*=\"EnvoiUlterieur\"]', function(e) {\r\n        const $checkbox = $(this);\r\n        let $droppable = $checkbox.closest('.droppable');\r\n        \/\/ \u2705 v2.4.13 : Fallback mobile\r\n        if (!$droppable.length) {\r\n            const $dynContainer = $checkbox.closest('.reserver-dynamic-container');\r\n            const _droppableId = $dynContainer.attr('data-droppable-id') || '';\r\n            if (_droppableId) { $droppable = $('#' + _droppableId); }\r\n        }\r\n        if (!$droppable.length) {\r\n            const _rankFallback = StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            if (_rankFallback) { $droppable = $('#' + _rankFallback); }\r\n        }\r\n  \r\n        \/\/ Si on d\u00e9coche\r\n        if (!$checkbox.is(':checked')) {\r\n            StateManager.set('EnvoiUlterieur', 'false');\r\n            \r\n            if (typeof window.verifierAffichageMsgSelectEspaceLocal === 'function') {\r\n                window.verifierAffichageMsgSelectEspaceLocal();\r\n            }\r\n            \r\n            \/\/ Mettre \u00e0 jour l'\u00e9tat de la checkbox R\u00e9server\r\n            FormatUIManager.updateReserverCheckboxState($droppable);\r\n            return;\r\n        }\r\n        \r\n        \/\/ Si on coche, masquer le message\r\n        jQuery('#MsgSelectEspace').hide();\r\n    \r\n        \/\/ V\u00e9rifier si un format est s\u00e9lectionn\u00e9\r\n        const hasSelectedFormat = FormatUIManager.hasSelectedFormat($droppable);\r\n        \r\n        if (!hasSelectedFormat) {\r\n            e.preventDefault();\r\n            $checkbox.prop('checked', false);\r\n            FormatUIManager.flashTitle($droppable);\r\n            return false;\r\n        }\r\n        \r\n        \/\/ \u2705 FORMAT OK \u2014 Marquer l'\u00e9tat envoi diff\u00e9r\u00e9 (sans envoyer les donn\u00e9es)\r\n        const rankId = $droppable.attr('id');\r\n        \r\n        StateManager.setMultiple({\r\n            \"EnvoiUlterieur\": 'true',\r\n            \"Rank_Emplacement_Page_Web\": rankId,\r\n            \"Commande_Emplacement_Page_Web\": StateManager.buildEmplacementReference(rankId),\r\n            \"LoadedPageUrl\": window.location.href,\r\n            \"FileReceived\": \"No\",\r\n            \"FullPathAdFile\": '',\r\n            \"Upload_File_Name\": '',\r\n            \"Formatchoisi\": 'Yes'\r\n        });\r\n        \r\n        console.log('\ud83d\udcdd Envoi diff\u00e9r\u00e9 coch\u00e9 \u2014 en attente de validation via checkbox \"R\u00e9server\"');\r\n        \r\n        \/\/ \u2705 Mettre \u00e0 jour l'\u00e9tat de la checkbox R\u00e9server (maintenant activable)\r\n        FormatUIManager.updateReserverCheckboxState($droppable);\r\n    });\r\n\r\n    \/\/ \u2705 v2.2.0 : Bouton \"Cr\u00e9ation\" dans espace publicitaire \u2192 Kit Ad Creator dans le parent\r\n    jQuery(document).on('click', '.FormatIdCreation', function(e) {\r\n        e.preventDefault();\r\n        var $btn = jQuery(this);\r\n        var isActive = $btn.data('creationActive') === true;\r\n\r\n        if (isActive) {\r\n            \/\/ D\u00e9sactiver\r\n            $btn.data('creationActive', false);\r\n            $btn.find('.EspPubFormat').css({'color': '#ffffff'});\r\n            $btn.css({'background-color': 'transparent'});\r\n            MessageManager.sendToParent('closeAdCreatorFromIframe', {});\r\n            console.log('\ud83c\udfa8 Cr\u00e9ation iframe \u2192 toggle OFF, fermeture popup parent');\r\n        } else {\r\n            \/\/ Activer : texte vert sur fond blanc\r\n            $btn.data('creationActive', true);\r\n            $btn.find('.EspPubFormat').css({'color': '#37D900'});\r\n            $btn.css({'background-color': '#ffffff'});\r\n            var formatSelect = sessionStorage.getItem('FormatSelect') || '';\r\n            var formatTransmis = sessionStorage.getItem('Commande_Format_Transmis') || '';\r\n            \/\/ \u2705 v2.2.1 : Envoyer aussi Commande_Format_Transmis (format cliqu\u00e9 dans l'iframe, sans accent)\r\n            var _rankKit = $btn.closest('.droppable').attr('id') || sessionStorage.getItem('Rank_Emplacement_Page_Web') || '';\r\n            var _cSite = sessionStorage.getItem('codeSite') || '';\r\n            var _cPage = sessionStorage.getItem('codePage') || '';\r\n            var _sfxKit = _rankKit.replace('Ele', '');\r\n            var _emplKit = (_cSite && _cPage && _sfxKit) ? (_cSite + _cPage + 'L' + _sfxKit) : (sessionStorage.getItem('Commande_Emplacement_Page_Web') || '');\r\n            MessageManager.sendToParent('openAdCreatorFromIframe', { formatSelect: formatSelect, formatTransmis: formatTransmis, rankId: _rankKit, emplacement: _emplKit });\r\n            console.log('\ud83c\udfa8 Cr\u00e9ation iframe \u2192 toggle ON (FormatSelect:', formatSelect, '| Commande_Format_Transmis:', formatTransmis, ')');\r\n        }\r\n    });\r\n\r\n    \/\/ \u2705 v2.2.0 : Messages depuis le parent concernant le bouton Cr\u00e9ation\r\n    window.addEventListener('message', function(event) {\r\n        var msg = event.data;\r\n        if (!msg) return;\r\n\r\n        \/\/ \u2705 v2.2.1 : Fournir la position du titre R\u00e9server pour positionner la miniature\r\n        if (msg.type === 'getReserverLabelRect') {\r\n            var $label = jQuery('.reserver-dynamic-label').first();\r\n            if ($label.length) {\r\n                var r = $label[0].getBoundingClientRect();\r\n                var iframeScale = (window.outerWidth > 1000) ? 0.75 : 0.80; \/\/ \u2705 v2.4.12 : 0.85 \u2192 0.75 (scale r\u00e9el du parent)\r\n                event.source.postMessage({\r\n                    type: 'reserVeurLabelRectResult',\r\n                    \/\/ Retourner bottom en coordonn\u00e9es iframe internes (non scal\u00e9es)\r\n                    bottom: r.bottom,\r\n                    left: r.left,\r\n                    right: r.right,\r\n                    iframeScale: iframeScale\r\n                }, '*');\r\n            } else {\r\n                event.source.postMessage({ type: 'reserVeurLabelRectResult', bottom: null }, '*');\r\n            }\r\n        }\r\n\r\n        \/\/ Fermeture du popup \u2192 d\u00e9s\u00e9lectionner le bouton Cr\u00e9ation\r\n        if (msg.type === 'adCreatorClosedFromParent') {\r\n            jQuery('.FormatIdCreation').each(function() {\r\n                jQuery(this).data('creationActive', false);\r\n                jQuery(this).find('.EspPubFormat').css({'color': '#ffffff'});\r\n                jQuery(this).css({'background-color': 'transparent'});\r\n            });\r\n            console.log('\ud83c\udfa8 adCreatorClosedFromParent re\u00e7u \u2192 bouton Cr\u00e9ation d\u00e9s\u00e9lectionn\u00e9');\r\n        }\r\n\r\n        \/\/ Restaurer le style du bouton Cr\u00e9ation apr\u00e8s un reset de removeElements\r\n        if (msg.type === 'restoreCreationButton') {\r\n            jQuery('.FormatIdCreation').each(function() {\r\n                if (jQuery(this).data('creationActive') === true) {\r\n                    jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                    jQuery(this).css({'background-color': '#ffffff'});\r\n                }\r\n            });\r\n            console.log('\ud83c\udfa8 restoreCreationButton re\u00e7u \u2192 style Cr\u00e9ation restaur\u00e9');\r\n        }\r\n    });\r\n\r\n});\r\n\r\n\/\/ =========================================================================\r\n\/\/ \u2705 Listener kitAdCreated \u2014 annonce cr\u00e9\u00e9e par le Kit overlay (mode=kit)\r\n\/\/ Injecte directement dans l'espace pub identifi\u00e9 par rankId\r\nwindow.addEventListener('message', function(event) {\r\n    var msg = event.data;\r\n    if (!msg || msg.action !== 'kitAdCreated') return;\r\n\r\n    var _rankId = msg.rankId || '';\r\n    var _emplacement = msg.emplacement || '';\r\n    console.log('\ud83c\udfa8 [espace_pub] kitAdCreated re\u00e7u | rankId:', _rankId, '| emplacement:', _emplacement);\r\n\r\n    if (!_rankId) { console.warn('\u26a0\ufe0f [kitAdCreated] rankId manquant'); return; }\r\n\r\n    var $droppable = jQuery('#' + _rankId);\r\n    if (!$droppable.length) { console.warn('\u26a0\ufe0f [kitAdCreated] droppable non trouv\u00e9:', _rankId); return; }\r\n    var $dropZone = $droppable.find('.drop_file_zone_achat_class').first();\r\n    if (!$dropZone.length) { $dropZone = $droppable.find('#drop_file_zone_achat').first(); }\r\n    if (!$dropZone.length) { console.warn('\u26a0\ufe0f [kitAdCreated] dropZone non trouv\u00e9e dans', _rankId); return; }\r\n\r\n    var _dataURL = msg.fullResDataURL || msg.pdfDataURL || null;\r\n    var _filename = msg.filename || 'annonce.png';\r\n    var _isPDF = msg.isPDF || false;\r\n    if (!_dataURL) { console.warn('\u26a0\ufe0f [kitAdCreated] aucune donn\u00e9e image'); return; }\r\n\r\n    var _parts = _dataURL.split(',');\r\n    var _mime = (_parts[0].match(\/:(.*?);\/) || [])[1] || (_isPDF ? 'application\/pdf' : 'image\/png');\r\n    var _bStr = atob(_parts[1]);\r\n    var _bytes = new Uint8Array(_bStr.length);\r\n    for (var _i = 0; _i < _bStr.length; _i++) { _bytes[_i] = _bStr.charCodeAt(_i); }\r\n    var _blob = new Blob([_bytes], { type: _mime });\r\n    \/\/ \u2705 Ajouter extension si absente\r\n    var _MIME_EXT = {'image\/png':'.png','image\/jpeg':'.jpg','image\/jpg':'.jpg','image\/webp':'.webp','application\/pdf':'.pdf'};\r\n    if (_filename.indexOf('.') === -1) { _filename = _filename + (_MIME_EXT[_mime] || (_isPDF ? '.pdf' : '.png')); }\r\n    var _file = new File([_blob], _filename, { type: _mime });\r\n\r\n    \/\/ \u2705 Pr\u00e9parer StateManager\r\n    StateManager.set('Rank_Emplacement_Page_Web', _rankId);\r\n    StateManager.set('Commande_Emplacement_Page_Web', _emplacement);\r\n    StateManager.set('Formatchoisi', 'Yes');\r\n    \/\/ \u2705 Marquer le droppable directement en DOM \u2014 r\u00e9siste \u00e0 l'async, lu par styleUploadedAd\r\n    $droppable[0].setAttribute('data-kit-drop', 'true');\r\n    window._dropFromMiniature = true;\r\n\r\n    console.log('\u2705 [kitAdCreated] \u2192 UploadManager.handleFileUpload | rankId:', _rankId);\r\n    UploadManager.handleFileUpload(_file, $dropZone).then(function() {\r\n        console.log('\u2705 [kitAdCreated] handleFileUpload termin\u00e9');\r\n    }).catch(function(err) {\r\n        window._dropFromMiniature = false;\r\n        $droppable[0].removeAttribute('data-kit-drop');\r\n        console.error('\u274c [kitAdCreated] handleFileUpload erreur:', err);\r\n    });\r\n});\r\n\r\n\/\/ \u2705 v1.17.0 : Listener \"thumbnailDropped\" \u2014 d\u00e9p\u00f4t de l'annonce depuis la miniature\r\n\/\/ =========================================================================\r\n\/**\r\n * Re\u00e7oit le drop de l'image-annonce depuis la miniature dans la page parente.\r\n * Identifie l'espace publicitaire sous le curseur, s\u00e9lectionne cet espace,\r\n * et d\u00e9clenche le flux dataFromIframeEspacePub en mode \"envoi diff\u00e9r\u00e9\"\r\n * (l'utilisateur uploadera le vrai fichier depuis le formulaire de commande).\r\n *\r\n * Coordonn\u00e9es re\u00e7ues : viewport de l'iframe (clientX\/clientY relatifs \u00e0 l'iframe)\r\n *\/\r\nwindow.addEventListener('message', function(event) {\r\n    var msg = event.data;\r\n    if (!msg || msg.action !== 'thumbnailDropped') return;\r\n\r\n    console.log('\ud83d\udce8 thumbnailDropped re\u00e7u \u2014 coords iframe:', msg.xRel, msg.yRel);\r\n\r\n    \/\/ \u2705 v1.19.3 : Corriger les coordonn\u00e9es pour le facteur de scale de l'iframe\r\n    \/\/ \u2705 v2.4.10 : 0.75 = scale appliqu\u00e9 par le PARENT sur l'\u00e9l\u00e9ment iframe (et non 0.85 qui est le scale interne OrdiMobileConteneurClass)\r\n    \/\/ Les coords xRel\/yRel viennent de getBoundingClientRect() sur l'iframe scal\u00e9 \u00e0 0.75 dans le parent \u2192 diviser par 0.75\r\n    var iframeScale = (window.outerWidth > 1000) ? 0.75 : 0.80;\r\n    \/\/ \u2705 v2.4.3 : Si Entete a intercept\u00e9 et pos\u00e9 un redirect vers Ele0A, utiliser ces coords\r\n    var _redirect = window._thumbnailDropRedirect || null;\r\n    window._thumbnailDropRedirect = null;\r\n    \/\/ \u2705 v2.4.4 : Les coords de redirect viennent de getBoundingClientRect() dans l'iframe (espace logique)\r\n    \/\/            \u2192 ne pas re-diviser par iframeScale (d\u00e9j\u00e0 en coords iframe-logiques)\r\n    var xAdjusted = _redirect ? _redirect.xRel : (msg.xRel \/ iframeScale);\r\n    var yAdjusted = _redirect ? _redirect.yRel : (msg.yRel \/ iframeScale);\r\n    if (_redirect) { console.log('\ud83d\udd00 [thumbnailDropped] coords redirig\u00e9es vers Ele0A:', Math.round(xAdjusted), Math.round(yAdjusted)); }\r\n    else { console.log('\ud83d\udcd0 Coords ajust\u00e9es (scale', iframeScale, '):', Math.round(xAdjusted), Math.round(yAdjusted)); }\r\n\r\n    \/\/ 1. Identifier l'espace publicitaire le plus proche du point de drop\r\n    \/\/    \u2705 v1.18.1 : Recherche par distance \u2014 coords \u00e9ventuellement redirig\u00e9es par Entete.txt\r\n    var allDroppables = document.querySelectorAll('.droppable');\r\n    var droppableEl = null;\r\n    var closestDist = Infinity;\r\n\r\n    \/\/ \u2705 v2.4.4 : Guard rect Ele0A \u2014 si PopUpChoice=Yes ET curseur dans le rect d'Ele0A \u2192 forcer\r\n    \/\/            (Ele0A est un popup flottant : son centre peut \u00eatre loin du curseur \u2192 algo distance l'ignore)\r\n    \/\/            Ne force PAS si le drop est hors d'Ele0A \u2192 les autres espaces restent accessibles\r\n    if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n        var _ele0ACheck = document.getElementById('Ele0A');\r\n        if (_ele0ACheck) {\r\n            var _r0A = _ele0ACheck.getBoundingClientRect();\r\n            var _margin = 30;\r\n            var _inR0A = (xAdjusted >= _r0A.left - _margin);\r\n            if (_inR0A) { _inR0A = (xAdjusted <= _r0A.right + _margin); }\r\n            if (_inR0A) { _inR0A = (yAdjusted >= _r0A.top - _margin); }\r\n            if (_inR0A) { _inR0A = (yAdjusted <= _r0A.bottom + _margin); }\r\n            if (_inR0A) {\r\n                droppableEl = _ele0ACheck;\r\n                closestDist = 0;\r\n                console.log('\ud83c\udfaf [thumbnailDropped] Ele0A forc\u00e9 (curseur dans rect Ele0A +30px)');\r\n            }\r\n        }\r\n    }\r\n\r\n    if (!droppableEl) {\r\n        allDroppables.forEach(function(d) {\r\n            var r = d.getBoundingClientRect();\r\n            var dCenterX = r.left + r.width  \/ 2;\r\n            var dCenterY = r.top  + r.height \/ 2;\r\n            var dist = Math.abs(dCenterX - xAdjusted) + Math.abs(dCenterY - yAdjusted);\r\n            if (dist < closestDist) { closestDist = dist; droppableEl = d; }\r\n        });\r\n        \/\/ \u2705 v2.4.3 : Si Entete a d\u00e9tect\u00e9 un drop sur Ele0A \u2192 forcer directement\r\n        if (_redirect) { if (_redirect.forceEle0A) {\r\n            var _ele0AForced = document.getElementById('Ele0A');\r\n            if (_ele0AForced) { droppableEl = _ele0AForced; console.log('\ud83c\udfaf [thumbnailDropped] Ele0A forc\u00e9 (redirect Entete)'); }\r\n        } }\r\n    }\r\n\r\n    if (!droppableEl || closestDist > 800) {\r\n        console.warn('thumbnailDropped \u2014 aucun droppable proche (dist min:', closestDist, ')');\r\n        return;\r\n    }\r\n    console.log('\ud83d\udccd Droppable trouv\u00e9:', droppableEl.id, '(dist:', Math.round(closestDist), ')');\r\n\r\n    var $droppable = jQuery(droppableEl);\r\n    var rankId = $droppable.attr('id');\r\n    if (!rankId) { console.warn('thumbnailDropped \u2014 .droppable sans id'); return; }\r\n\r\n    var $dropZone = $droppable.find('#drop_file_zone_achat').first();\r\n    if (!$dropZone.length) { console.warn('thumbnailDropped \u2014 #drop_file_zone_achat introuvable dans', rankId); return; }\r\n\r\n    var emplacementRef = StateManager.buildEmplacementReference(rankId);\r\n    console.log('\u2705 thumbnailDropped \u2014 espace pub:', rankId, '\u2192', emplacementRef);\r\n\r\n    \/\/ 2. Pr\u00e9parer l'\u00e9tat SessionStorage (comme un vrai drop de fichier)\r\n    StateManager.setMultiple({\r\n        'Rank_Emplacement_Page_Web':     rankId,\r\n        'Commande_Emplacement_Page_Web': emplacementRef,\r\n        'FirstUploadFileorMoved':        'FirstUpload',\r\n        'Formatchoisi':                  'Yes',\r\n        'Commande_Format_Transmis':      'Image',\r\n        'EnvoiUlterieur':                'false',\r\n        'FileReceived':                  'No',\r\n        'AdDisplayed':                   'Yes'\r\n    });\r\n\r\n    UIManager.updateEmplacementDisplay();\r\n\r\n    \/\/ 3. Construire le File \u00e0 partir du PDF (communiqu\u00e9\/interview) ou de l'image PNG (autres formats)\r\n    \/\/    puis appeler handleFileUpload \u2192 m\u00eame flux qu'un vrai drag&drop : liser\u00e9 vert, aper\u00e7u, R\u00e9server\r\n    var dataURL, mime, ext;\r\n\r\n    \/\/ \u2705 Stocker le PDF image et le format sur le droppable pour le popup de visualisation inline\r\n    if (msg.pdfImageDataURL) {\r\n        $droppable.data('kitPdfImageDataURL', msg.pdfImageDataURL);\r\n        $droppable.data('kitFormatSelect', msg.FormatSelect || '');\r\n        console.log('\ud83d\udcce pdfImageDataURL stock\u00e9 sur', rankId, '| format:', msg.FormatSelect);\r\n    } else {\r\n        $droppable.removeData('kitPdfImageDataURL');\r\n        $droppable.removeData('kitFormatSelect');\r\n    }\r\n\r\n    if (msg.isPDF && msg.pdfDataURL) {\r\n        \/\/ \u2500\u2500 Format PDF (communiqu\u00e9 \/ interview) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        dataURL = msg.pdfDataURL;                         \/\/ \"data:application\/pdf;base64,\u2026\"\r\n        mime    = 'application\/pdf';\r\n        ext     = '.pdf';\r\n    } else if (msg.imageDataURL) {\r\n        \/\/ \u2500\u2500 Format image (banni\u00e8re \/ parrainage) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        dataURL = msg.imageDataURL;\r\n        var mimeMatch = dataURL.match(\/^data:([^;]+);base64,\/);\r\n        mime    = mimeMatch ? mimeMatch[1] : 'image\/png';\r\n        ext     = mime === 'image\/jpeg' ? '.jpg' : '.png';\r\n    } else {\r\n        console.warn('thumbnailDropped \u2014 aucune donn\u00e9e image\/pdf disponible');\r\n        return;\r\n    }\r\n\r\n    var baseName = msg.filename ? msg.filename.replace(\/\\.[^.]+$\/, '') : 'annonce-kit';\r\n    var fileName = baseName + ext;\r\n\r\n    \/\/ dataURL \u2192 Uint8Array \u2192 Blob \u2192 File\r\n    var b64  = dataURL.split(',')[1];\r\n    var bstr = atob(b64);\r\n    var u8   = new Uint8Array(bstr.length);\r\n    for (var i = 0; i < bstr.length; i++) { u8[i] = bstr.charCodeAt(i); }\r\n    var blob    = new Blob([u8], { type: mime });\r\n    var fileObj = new File([blob], fileName, { type: mime });\r\n\r\n    console.log('thumbnailDropped \u2192 handleFileUpload:', fileName, Math.round(fileObj.size \/ 1024) + 'KB');\r\n\r\n    \/\/ \u2705 Cacher le File pour r\u00e9utilisation lors des d\u00e9placements (\u00e9vite CORS)\r\n    window._lastRedactionnelFile = fileObj;\r\n\r\n    \/\/ \u2705 v2.4.10 : Signaler \u00e0 adjustDesktopLayout que c'est un drop depuis la miniature\r\n    \/\/ \u2192 applique max-height sur HTMLUploadfileConteneur pour \u00e9viter le d\u00e9bordement vertical (homepage corps de page)\r\n    window._dropFromMiniature = true;\r\n    UploadManager.handleFileUpload(fileObj, $dropZone);\r\n\r\n    \/\/ \u2705 v1.19.1 : Positionner l'espace \u00e0 10px du haut du viewport (tous formats)\r\n    \/\/ \u2705 v2.4.13 : Skip si drop depuis miniature \u2014 selectEspaceActif g\u00e8re d\u00e9j\u00e0 le scroll\r\n    if (!window._dropFromMiniature) {\r\n        setTimeout(function() {\r\n            var el = $droppable.find('.HTMLUploadfileConteneur')[0] || $droppable[0];\r\n            if (el) {\r\n                ScrollHelper.scrollElementTo(el, 10);\r\n            }\r\n        }, 400);\r\n    }\r\n});\r\n\r\nconsole.log('This is a ' + (UIManager.isDesktop() ? 'desktop' : 'non-desktop') + ' device.');\r\n\r\n} \/\/ end _espPubScriptLoaded guard\r\n<\/script>\r\n\r\n<style>\r\n\/* Les styles CSS restent inchang\u00e9s *\/\r\n#drop_file_zone_achat {\r\n    background-color: #FFFFFF00;\r\n    color: #225DA9;\r\n    font-weight: 500;\r\n    text-align: center;\r\n    border: #999 0px dashed;\r\n    width: 100%;\r\n    height: 180px;\r\n    font-size: 11.5px;\r\n    display: flex;\r\n    justify-content: center; \r\n    align-items: center; \r\n    flex-wrap: wrap;\r\n}\r\n\r\n#drag_upload_file_achat {\r\n    margin: 0 auto;\r\n    width: 90%;\r\n    height: 60px;\r\n}\r\n\r\n#drag_upload_file_achat p {\r\n    text-align: center;\r\n}\r\n\r\n\/* \u2705 v1.16.0 : Liser\u00e9 noir fin autour du texte \"Ici glisser \u2013 d\u00e9poser\" *\/\r\n.GlisserDeposerConteneur .elementor-widget-container p {\r\n    border: 1px solid #000000;\r\n    border-radius: 4px;\r\n    padding: 4px 10px;\r\n    display: inline-block;\r\n}\r\n\r\n#selectfile_achat {\r\n    display: none;\r\n}\r\n\r\n.button-2_achat, .button-2_achat-after-reset {\r\n    background-color: #ffffff00!important;\r\n    border: 1px solid white!important;\r\n    border-radius: 8px;\r\n    color: #225DA9!important;\r\n    cursor: pointer;\r\n    display: inline-block;\r\n    font-size: 11px;\r\n    font-weight: 500;\r\n    list-style: none;\r\n    width: 390px;\r\n    height: 62px;\r\n    top: 0px!important; \r\n    margin-top: 0px!important; \r\n    padding-left: 5px!important;\r\n    padding-right: 5px!important;\r\n    margin-bottom: 70px!important;\r\n    margin: 0;\r\n    text-align: center;\r\n    transition: all 200ms;\r\n    vertical-align: baseline;\r\n    white-space: wrap!important;\r\n}\r\n\r\n@media only screen and (max-width: 1000px) {\r\n    .button-2_achat, .button-2_achat-after-reset {\r\n        width: 95%;\r\n        height: 50px;\r\n    }\r\n}\r\n\r\n.newMessageClass {\r\n    background-color: #FFFFFF00!important;\r\n    font-size: 13px; \r\n    font-weight: 600;\r\n    color: #56BE50;\r\n    height: 35px;\r\n    width: 550px; \r\n    position: relative;\r\n    z-index: 99;\r\n    top: 45px;\r\n    bottom: 0px;\r\n    right: 0px;\r\n    left: 0px;\r\n    display: flex;\r\n    justify-content: center;\r\n    align-items: center;\r\n    text-align: center;\r\n}\r\n\r\n.MessageClassFormatnonReconnuTitre {\r\n    background-color: #FFFFFF00!important;\r\n    font-size: 13px; \r\n    font-weight: 600;\r\n    color: #FB5E2A;\r\n    height: 35px;\r\n    width: 550px; \r\n    position: relative;\r\n    z-index: 99;\r\n    margin-top: -300px;\r\n    right: 0px;\r\n    text-align: center;\r\n    line-height: 15px;\r\n}\r\n\r\n.MessageClassFormatnonReconnu {\r\n    background-color: #FFFFFF00!important;\r\n    font-size: 13px; \r\n    font-weight: 600;\r\n    color: #ffffff;\r\n    height: 35px;\r\n    width: 550px; \r\n    position: relative;\r\n    z-index: 99;\r\n    margin-top: -280px;\r\n    right: 0px;\r\n    text-align: center;\r\n    line-height: 15px;\r\n}\r\n\r\n.newButtonClass {\r\n    font-size: 12px; \r\n    font-weight: 500;\r\n    background-color: #ffffff00;\r\n    color: #717171;\r\n    height: 10px;\r\n    width: 100%; \r\n    position: relative;\r\n    z-index: 99;\r\n    top: 45px;\r\n    bottom: 0px;\r\n    text-align: center;\r\n    right:  50px;\r\n    line-height: 10px;\r\n    border-radius: 3px;\r\n    border: 0px solid #E8ECF1;\r\n}\r\n\r\n.linkClass {\r\n    width: 15px; \r\n    height: 15px;\r\n    margin-top: -310px;\r\n    margin-bottom: -25px;\r\n    margin-right: -50px;\r\n    position: relative;\r\n    top: 0; \r\n    z-index: 99;\r\n    display: block;\r\n    background-image: url('https:\/\/rdc.via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-blanc.jpg');\r\n    background-size: cover;\r\n}\r\n\r\n.newButtonClassVideo {\r\n    font-size: 12px; \r\n    font-weight: 500;\r\n    background-color: #ffffff00;\r\n    color: #717171;\r\n    height: 10px;\r\n    width: 100%; \r\n    position: relative;\r\n    z-index: 99;\r\n    top: 0px;\r\n    bottom: 0px;\r\n    right: 10px;\r\n    text-align: center;\r\n    line-height: 10px;\r\n    border-radius: 3px;\r\n    border: 0px solid #E8ECF1;\r\n}\r\n\r\n.linkClassVideo {\r\n    width: 15px; \r\n    height: 15px;\r\n    margin-top: -438px;\r\n    margin-bottom: -25px;\r\n    margin-right: -15px;\r\n    position: relative;\r\n    top: 0; \r\n    z-index: 99;\r\n    display: block;\r\n    background-image: url('https:\/\/rdc.via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-blanc.jpg');\r\n    background-size: cover;\r\n}\r\n\r\n.FinCampagneMobileClass .elementor-button,\r\n.DebutCampagneMobileClass .elementor-button,\r\n.FormSelectDevisesMobile .elementor-button,\r\n.HideFormButton .elementor-button {\r\n    display: none !important;\r\n}\r\n\r\n#drag_upload_file_achat {\r\n    margin: 0;\r\n    padding: 0;\r\n    position: relative;\r\n}\r\n\r\n.dot-container {\r\n    display: inline-block;\r\n}\r\n\r\n.dot {\r\n    opacity: 0;\r\n    transition: opacity 0.3s ease;\r\n}\r\n\r\n@keyframes firstDot {\r\n    0%, 100% { opacity: 0; }\r\n    10%, 70% { opacity: 1; }\r\n    90% { opacity: 0; }\r\n}\r\n\r\n@keyframes secondDot {\r\n    0%, 20%, 100% { opacity: 0; }\r\n    30%, 70% { opacity: 1; }\r\n    90% { opacity: 0; }\r\n}\r\n\r\n@keyframes thirdDot {\r\n    0%, 40%, 100% { opacity: 0; }\r\n    50%, 70% { opacity: 1; }\r\n    90% { opacity: 0; }\r\n}\r\n\r\n.dot:nth-child(1) {\r\n    animation: firstDot 3s infinite;\r\n}\r\n\r\n.dot:nth-child(2) {\r\n    animation: secondDot 3s infinite;\r\n}\r\n\r\n.dot:nth-child(3) {\r\n    animation: thirdDot 3s infinite;\r\n}\r\n\r\n.droppable .elementor-field-type-checkbox .elementor-field-option {\r\n    display: flex;\r\n    flex-direction: row-reverse;\r\n    align-items: center;\r\n    gap: 8px;\r\n}\r\n\r\n.droppable .elementor-field-type-checkbox .elementor-field-option input[type=\"checkbox\"] {\r\n    width: 12px;\r\n    height: 12px;\r\n    min-width: 12px;\r\n    min-height: 12px;\r\n}\r\n\r\n\/* \u2705 Bouton \"R\u00e9server\" dynamique *\/\r\n.reserver-dynamic-container {\r\n    text-align: center;\r\n    margin-top: -7px;\r\n    margin-bottom: 15px;\r\n    padding: 5px 0;\r\n    transform: scale(1.4);\r\n    transform-origin: center top;\r\n    position: relative;\r\n    z-index: 200;\r\n}\r\n\r\n@media only screen and (min-width: 1001px) {\r\n    .reserver-dynamic-container {\r\n        transform: scale(1);\r\n        margin-top: -200px;\r\n        margin-bottom: 0;\r\n    }\r\n}\r\n\r\n.reserver-dynamic-option {\r\n    display: inline-flex;\r\n    flex-direction: row-reverse;\r\n    align-items: center;\r\n    gap: 8px;\r\n    cursor: pointer;\r\n    color: #213864;\r\n    background-color: #ffffff;\r\n    padding: 2px 4px;\r\n    border-radius: 6px;\r\n}\r\n\r\n.reserver-dynamic-checkbox {\r\n    width: 16px;\r\n    height: 16px;\r\n    min-width: 16px;\r\n    min-height: 16px;\r\n    cursor: pointer;\r\n    pointer-events: auto;\r\n}\r\n\r\n.reserver-dynamic-label {\r\n    cursor: pointer;\r\n    color: #213864;\r\n    font-size: 16px;\r\n    font-weight: 600;\r\n    user-select: none;\r\n}\r\n\r\n@media only screen and (max-width: 1000px) {\r\n    .reserver-dynamic-container {\r\n        transform: scale(0.98);\r\n        margin-bottom: 20px;\r\n        white-space: nowrap;\r\n        z-index: 300;\r\n        pointer-events: auto;\r\n    }\r\n    .reserver-dynamic-option {\r\n        padding-top: 0px;\r\n        padding-bottom: 0px;\r\n    }\r\n}\r\n\r\n\/* \u2705 v2.1.3 : DeplaceAnnonceText \/ DeplaceAnnonce \u2014 desktop uniquement *\/\r\n@media only screen and (min-width: 1001px) {\r\n    .DeplaceAnnonceText {\r\n        margin-top: -5px;\r\n        position: relative;\r\n        z-index: 201;\r\n    }\r\n    .DeplaceAnnonce {\r\n        margin-bottom: -150px;\r\n    }\r\n}\r\n<\/style>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-54e4e530 e-con-full MsgFormatIncorrectConteneur elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile e-flex e-con e-child\" data-id=\"54e4e530\" data-element_type=\"container\" id=\"NotusedAnymore\">\n\t\t\t\t<div class=\"elementor-element elementor-element-531f3cb1 MsgFormatIncorrect elementor-widget__width-inherit elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"531f3cb1\" data-element_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 style=\"text-align: center;\">Le format du fichier n&rsquo;est pas reconnu<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3a352c3f elementor-hidden-desktop TexteMobile TexteMobileAnnonce elementor-widget elementor-widget-text-editor\" data-id=\"3a352c3f\" data-element_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\tGlisser-d\u00e9poser ou cliquer ici<br>pour t\u00e9l\u00e9charger une annonce\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7abb0aba elementor-hidden-desktop TexteMobileAjoutAnnonce elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"7abb0aba\" data-element_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 style=\"text-align: center;\">Cliquer ici pour t\u00e9l\u00e9charger une annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-68e2b2ca UploadIci elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"68e2b2ca\" data-element_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>Ici glisser-d\u00e9poser ou t\u00e9l\u00e9charger une annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-8d50d33 e-con-full e-flex e-con e-child\" data-id=\"8d50d33\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6ae6ef83 elementor-button-align-center elementor-widget__width-initial HideFormButton EspPubLienAnnonce elementor-widget-mobile__width-initial elementor-widget elementor-widget-form\" data-id=\"6ae6ef83\" data-element_type=\"widget\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_URL_annonce\" aria-label=\"Formulaire_URL_annonce\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249678\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"6ae6ef83\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-text elementor-field-group elementor-column elementor-field-group-LienAnnonce elementor-col-100 elementor-sm-100 elementor-field-required\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-LienAnnonce\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tIci renseigner si n\u00e9cessaire le lien hypertexte de l\u2019annonce\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<input size=\"1\" type=\"text\" name=\"form_fields[LienAnnonce]\" id=\"form-field-LienAnnonce\" class=\"elementor-field elementor-size-xs  elementor-field-textual\" placeholder=\"Ici renseigner si n\u00e9cessaire le lien hypertexte de l\u2019annonce\" required=\"required\">\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidURLAnnonce\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-66fd4d36 e-con-full EnvoiUlterieurContainer e-flex e-con e-child\" data-id=\"66fd4d36\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4ea8e2b4 elementor-button-align-center elementor-widget__width-auto HideFormButton EnvoiUlterieur elementor-widget elementor-widget-form\" data-id=\"4ea8e2b4\" data-element_type=\"widget\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_Envoi_Ulterieur\" aria-label=\"Formulaire_Envoi_Ulterieur\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249678\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"4ea8e2b4\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-checkbox elementor-field-group elementor-column elementor-field-group-EnvoiUlterieur elementor-col-100 elementor-sm-100\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-EnvoiUlterieur\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tEnvoi diff\u00e9r\u00e9 de l'annonce\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t<div class=\"elementor-field-subgroup\"><span class=\"elementor-field-option\"><input type=\"checkbox\" value=\"Envoi diff\u00e9r\u00e9 de l&#039;annonce\" id=\"form-field-EnvoiUlterieur-0\" name=\"form_fields[EnvoiUlterieur]\"> <label for=\"form-field-EnvoiUlterieur-0\">Envoi diff\u00e9r\u00e9 de l'annonce<\/label><\/span><\/div>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidEnvoiUlterieur\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\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-4a59cf88 EnvoiUlterieurTexte elementor-widget elementor-widget-text-editor\" data-id=\"4a59cf88\" data-element_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 style=\"text-align: center;\">Envoyer l\u2019annonce jusqu\u2019\u00e0 8 jours apr\u00e8s paiement<br>\nUn lien vous sera adress\u00e9 par <span style=\"color: #ffffff;\"><a style=\"color: #ffffff;\" href=\"mailto:contact@via-agency.media\">contact@via-agency.media<\/a><\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-17d3ad0c e-con-full ReserverContainer e-flex e-con e-child\" data-id=\"17d3ad0c\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-177c9b71 elementor-button-align-center elementor-widget__width-auto HideFormButton ReserverBouton elementor-widget elementor-widget-form\" data-id=\"177c9b71\" data-element_type=\"widget\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_Envoi_Ulterieur\" aria-label=\"Formulaire_Envoi_Ulterieur\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249678\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"177c9b71\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-checkbox elementor-field-group elementor-column elementor-field-group-ReserverEspacePublicitaire elementor-col-100 elementor-sm-100\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-ReserverEspacePublicitaire\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tR\u00e9server cet espace publicitaire\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t<div class=\"elementor-field-subgroup\"><span class=\"elementor-field-option\"><input type=\"checkbox\" value=\"R\u00e9server cet espace publicitaire\" id=\"form-field-ReserverEspacePublicitaire-0\" name=\"form_fields[ReserverEspacePublicitaire]\"> <label for=\"form-field-ReserverEspacePublicitaire-0\">R\u00e9server cet espace publicitaire<\/label><\/span><\/div>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidEnvoiUlterieur\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-5bafe1f3 e-con-full AdUploadedTitle DeplaceAnnonce elementor-hidden-tablet elementor-hidden-mobile elementor-hidden-desktop e-flex e-con e-child\" data-id=\"5bafe1f3\" data-element_type=\"container\" id=\"DeplaceAnnonceId\">\n\t\t<div class=\"elementor-element elementor-element-432cc2a1 e-con-full DeplaceAnnonceSubContainer e-flex e-con e-child\" data-id=\"432cc2a1\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-446e8565 elementor-hidden-tablet elementor-hidden-mobile EspaceReserve elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"446e8565\" data-element_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>Espace r\u00e9serv\u00e9<br \/>Annonce transmise<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-60df49d0 elementor-hidden-tablet elementor-hidden-mobile DeplaceAnnonceText elementor-widget elementor-widget-text-editor\" data-id=\"60df49d0\" data-element_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\tSi vous souhaitez un autre emplacement, vous pouvez d\u00e9placer cette annonce\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-62ef38f0 e-con-full e-flex e-con e-child\" data-id=\"62ef38f0\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f4f51cb elementor-hidden-tablet elementor-hidden-mobile PositionEspacePublicitaireDeplacer elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"f4f51cb\" data-element_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>Position<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f214306 elementor-hidden-tablet elementor-hidden-mobile RefEspacePublicitaire elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"f214306\" data-element_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>R\u00e9f\u00e9rence<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1c5a5ed5 e-con-full AdUploadedOverlay elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile e-flex e-con e-child\" data-id=\"1c5a5ed5\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-4740d3e8 e-con-full OverlayHeader e-flex e-con e-child\" data-id=\"4740d3e8\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e964c6b elementor-hidden-tablet elementor-hidden-mobile OverlayRefEspace elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"e964c6b\" data-element_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>R\u00e9f\u00e9rence<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-30eb836c OverlayCroixReset elementor-widget elementor-widget-image\" data-id=\"30eb836c\" data-element_type=\"widget\" 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\t<a href=\"#\">\n\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-transparent.png\" title=\"\" alt=\"\" loading=\"lazy\" \/>\t\t\t\t\t\t\t\t<\/a>\n\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<\/div>\n\t\t<div class=\"elementor-element elementor-element-342c88b1 e-con-full OverlayPreviewZone e-flex e-con e-child\" data-id=\"342c88b1\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3c7e790f OverlayDeplaceTexte elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"3c7e790f\" data-element_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>Si vous souhaitez un autre emplacement, vous pouvez d\u00e9placer cette annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-51f00578 elementor-button-align-center elementor-widget__width-auto HideFormButton OverlayReserverForm elementor-widget elementor-widget-form\" data-id=\"51f00578\" data-element_type=\"widget\" id=\"Formulaire_Reserver_Overlay\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_Envoi_Ulterieur\" aria-label=\"Formulaire_Envoi_Ulterieur\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249678\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"51f00578\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-checkbox elementor-field-group elementor-column elementor-field-group-ReserverEspacePublicitaire elementor-col-100 elementor-sm-100\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-ReserverEspacePublicitaire\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tR\u00e9server cet espace publicitaire\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t<div class=\"elementor-field-subgroup\"><span class=\"elementor-field-option\"><input type=\"checkbox\" value=\"R\u00e9server cet espace publicitaire\" id=\"form-field-ReserverEspacePublicitaire-0\" name=\"form_fields[ReserverEspacePublicitaire]\"> <label for=\"form-field-ReserverEspacePublicitaire-0\">R\u00e9server cet espace publicitaire<\/label><\/span><\/div>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidEnvoiUlterieur\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<\/p>\t\t\t\t\t\t\t\t<\/div>\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-60c1ade1 e-flex e-con-boxed e-con e-parent\" data-id=\"60c1ade1\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-141f3f53 e-con-full e-flex e-con e-child\" data-id=\"141f3f53\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5c548923 elementor-widget__width-initial elementor-pagination-position-inside elementor-pagination-type-bullets elementor-widget elementor-widget-loop-carousel\" data-id=\"5c548923\" data-element_type=\"widget\" data-settings=\"{&quot;template_id&quot;:114717,&quot;speed&quot;:0,&quot;image_spacing_custom&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:0,&quot;sizes&quot;:[]},&quot;offset_sides&quot;:&quot;both&quot;,&quot;offset_width&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;slides_to_show&quot;:&quot;1&quot;,&quot;slides_to_show_tablet&quot;:&quot;1&quot;,&quot;_skin&quot;:&quot;post&quot;,&quot;slides_to_show_mobile&quot;:&quot;1&quot;,&quot;slides_to_scroll&quot;:&quot;1&quot;,&quot;edit_handle_selector&quot;:&quot;.elementor-loop-container&quot;,&quot;infinite&quot;:&quot;yes&quot;,&quot;offset_width_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;offset_width_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;pagination&quot;:&quot;bullets&quot;,&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;:[]}}\" data-widget_type=\"loop-carousel.post\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"swiper elementor-loop-container elementor-grid\" role=\"list\" dir=\"ltr\">\n\t\t\t\t<div class=\"swiper-wrapper\" aria-live=\"polite\">\n\t\t<style id=\"loop-dynamic-114717\">.e-loop-item-32630 .elementor-element.elementor-element-c37dff8::before, .e-loop-item-32630 .elementor-element.elementor-element-c37dff8 > .elementor-background-video-container::before, .e-loop-item-32630 .elementor-element.elementor-element-c37dff8 > .e-con-inner > .elementor-background-video-container::before, .e-loop-item-32630 .elementor-element.elementor-element-c37dff8 > .elementor-background-slideshow::before, .e-loop-item-32630 .elementor-element.elementor-element-c37dff8 > .e-con-inner > .elementor-background-slideshow::before, .e-loop-item-32630 .elementor-element.elementor-element-c37dff8 > .elementor-motion-effects-container > .elementor-motion-effects-layer::before{background-image:url(\"https:\/\/togo-en.yearbook-media.com\/wp-content\/uploads\/2024\/02\/beautiful-alternative-energy-plant-with-solar-panels-e1719511128506.jpg\");}@media(max-width:1000px){.e-loop-item-32630 .elementor-element.elementor-element-c37dff8::before, .e-loop-item-32630 .elementor-element.elementor-element-c37dff8 > .elementor-background-video-container::before, .e-loop-item-32630 .elementor-element.elementor-element-c37dff8 > .e-con-inner > .elementor-background-video-container::before, .e-loop-item-32630 .elementor-element.elementor-element-c37dff8 > .elementor-background-slideshow::before, .e-loop-item-32630 .elementor-element.elementor-element-c37dff8 > .e-con-inner > .elementor-background-slideshow::before, .e-loop-item-32630 .elementor-element.elementor-element-c37dff8 > .elementor-motion-effects-container > .elementor-motion-effects-layer::before{background-image:url(\"https:\/\/togo-en.yearbook-media.com\/wp-content\/uploads\/2024\/02\/beautiful-alternative-energy-plant-with-solar-panels-e1719511128506.jpg\");}}<\/style><style id=\"loop-114717\">.elementor-114717 .elementor-element.elementor-element-ffeb86e{--display:flex;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114717 .elementor-element.elementor-element-c37dff8{--display:flex;--min-height:300px;--flex-direction:row;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:flex-start;--align-items:flex-start;--gap:40px 40px;--row-gap:40px;--column-gap:40px;--overlay-opacity:1;--overlay-mix-blend-mode:darken;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114717 .elementor-element.elementor-element-c37dff8::before, .elementor-114717 .elementor-element.elementor-element-c37dff8 > .elementor-background-video-container::before, .elementor-114717 .elementor-element.elementor-element-c37dff8 > .e-con-inner > .elementor-background-video-container::before, .elementor-114717 .elementor-element.elementor-element-c37dff8 > .elementor-background-slideshow::before, .elementor-114717 .elementor-element.elementor-element-c37dff8 > .e-con-inner > .elementor-background-slideshow::before, .elementor-114717 .elementor-element.elementor-element-c37dff8 > .elementor-motion-effects-container > .elementor-motion-effects-layer::before{background-color:#FFFFFF;--background-overlay:'';background-position:center center;background-repeat:no-repeat;background-size:cover;}.elementor-114717 .elementor-element.elementor-element-c37dff8::before{filter:brightness( 73% ) contrast( 100% ) saturate( 100% ) blur( 0px ) hue-rotate( 0deg );}.elementor-114717 .elementor-element.elementor-element-c37dff8.e-con{--align-self:flex-start;}.elementor-114717 .elementor-element.elementor-element-12ca4f0{--display:flex;--margin-top:75px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-widget-text-editor{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );color:var( --e-global-color-text );}.elementor-widget-text-editor.elementor-drop-cap-view-stacked .elementor-drop-cap{background-color:var( --e-global-color-primary );}.elementor-widget-text-editor.elementor-drop-cap-view-framed .elementor-drop-cap, .elementor-widget-text-editor.elementor-drop-cap-view-default .elementor-drop-cap{color:var( --e-global-color-primary );border-color:var( --e-global-color-primary );}.elementor-114717 .elementor-element.elementor-element-b4d164c{width:var( --container-widget-width, 300px );max-width:300px;--container-widget-width:300px;--container-widget-flex-grow:0;columns:1;text-align:justify;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;color:#FFFFFF;}.elementor-114717 .elementor-element.elementor-element-b4d164c > .elementor-widget-container{margin:0px 0px 0px 0px;}.elementor-114717 .elementor-element.elementor-element-b4d164c.elementor-element{--align-self:flex-end;}.elementor-114717 .elementor-element.elementor-element-ddeb0ef{--display:flex;--justify-content:flex-start;--margin-top:75px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114717 .elementor-element.elementor-element-65c0501{--display:flex;--justify-content:flex-start;--gap:15px 15px;--row-gap:15px;--column-gap:15px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-widget-theme-post-title .elementor-heading-title{font-family:var( --e-global-typography-primary-font-family ), Sans-serif;font-weight:var( --e-global-typography-primary-font-weight );color:var( --e-global-color-primary );}.elementor-114717 .elementor-element.elementor-element-de0c48c > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-114717 .elementor-element.elementor-element-de0c48c .elementor-heading-title{font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:600;line-height:1.3em;color:#FFFFFF;}.elementor-widget-theme-post-excerpt .elementor-widget-container{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );color:var( --e-global-color-text );}.elementor-114717 .elementor-element.elementor-element-667589b > .elementor-widget-container{margin:0px 0px -20px 0px;padding:0px 0px 0px 0px;}.elementor-114717 .elementor-element.elementor-element-667589b .elementor-widget-container{font-family:\"Roboto\", Sans-serif;font-size:13.5px;font-weight:600;line-height:1.3em;color:#FFFFFF;}.elementor-114717 .elementor-element.elementor-element-8fc0fe6{--display:flex;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114717 .elementor-element.elementor-element-f6def83 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-114717 .elementor-element.elementor-element-f6def83{font-family:\"Roboto\", Sans-serif;font-size:13.5px;font-weight:600;color:#FFFFFF;}@media(max-width:1001px){.elementor-114717 .elementor-element.elementor-element-c37dff8{--min-height:230px;--align-items:flex-start;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--border-radius:0px 0px 0px 0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114717 .elementor-element.elementor-element-667589b > .elementor-widget-container{margin:0px 0px 0px 20px;}.elementor-114717 .elementor-element.elementor-element-667589b .elementor-widget-container{font-size:11.5px;}.elementor-114717 .elementor-element.elementor-element-8fc0fe6{--margin-top:-20px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114717 .elementor-element.elementor-element-f6def83 > .elementor-widget-container{margin:0px 0px 0px 20px;padding:0px 0px 0px 0px;}.elementor-114717 .elementor-element.elementor-element-f6def83{font-size:11.5px;}}@media(min-width:1001px){.elementor-114717 .elementor-element.elementor-element-ffeb86e{--content-width:1250px;}.elementor-114717 .elementor-element.elementor-element-65c0501{--width:300px;}}@media(max-width:1001px) and (min-width:1001px){.elementor-114717 .elementor-element.elementor-element-c37dff8{--width:100%;}}@media(max-width:1000px){.elementor-114717 .elementor-element.elementor-element-c37dff8{--width:100%;--min-height:260px;--gap:20px 20px;--row-gap:20px;--column-gap:20px;--flex-wrap:nowrap;--border-radius:0px 0px 0px 0px;--margin-top:20px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114717 .elementor-element.elementor-element-12ca4f0{--margin-top:50px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114717 .elementor-element.elementor-element-b4d164c > .elementor-widget-container{margin:0px 0px 0px 10px;padding:0px 0px 0px 0px;}.elementor-114717 .elementor-element.elementor-element-b4d164c{--container-widget-width:100%;--container-widget-flex-grow:0;width:var( --container-widget-width, 100% );max-width:100%;font-size:12px;line-height:1.3em;}.elementor-114717 .elementor-element.elementor-element-ddeb0ef{--margin-top:50px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114717 .elementor-element.elementor-element-65c0501{--width:100%;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114717 .elementor-element.elementor-element-de0c48c{width:100%;max-width:100%;}.elementor-114717 .elementor-element.elementor-element-de0c48c > .elementor-widget-container{margin:0px 10px 0px 0px;padding:0px 0px 0px 0px;}.elementor-114717 .elementor-element.elementor-element-de0c48c .elementor-heading-title{font-size:13px;}.elementor-114717 .elementor-element.elementor-element-667589b > .elementor-widget-container{margin:0px 10px 0px 0px;padding:0% 0% 0% 0%;}.elementor-114717 .elementor-element.elementor-element-667589b .elementor-widget-container{font-size:12px;}.elementor-114717 .elementor-element.elementor-element-8fc0fe6{--margin-top:-10px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-114717 .elementor-element.elementor-element-f6def83 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-114717 .elementor-element.elementor-element-f6def83{font-size:12px;}}<\/style>\t\t<div data-elementor-type=\"loop-item\" data-elementor-id=\"114717\" class=\"elementor elementor-114717 swiper-slide e-loop-item e-loop-item-32630 post-32630 post type-post status-publish format-standard has-post-thumbnail hentry category-electricite category-togo category-togo-energie generate-columns tablet-grid-50 mobile-grid-100 grid-parent grid-20\" data-elementor-post-type=\"elementor_library\" role=\"group\" aria-roledescription=\"slide\" data-custom-edit-handle=\"1\">\n\t\t\t<div class=\"elementor-element elementor-element-ffeb86e e-flex e-con-boxed e-con e-parent\" data-id=\"ffeb86e\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-c37dff8 e-con-full e-flex e-con e-child\" data-id=\"c37dff8\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t<div class=\"elementor-element elementor-element-12ca4f0 e-con-full e-flex e-con e-child\" data-id=\"12ca4f0\" data-element_type=\"container\">\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-ddeb0ef e-con-full e-flex e-con e-child\" data-id=\"ddeb0ef\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-65c0501 e-con-full e-flex e-con e-child\" data-id=\"65c0501\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-de0c48c elementor-widget-mobile__width-inherit elementor-widget elementor-widget-theme-post-title elementor-page-title elementor-widget-heading\" data-id=\"de0c48c\" data-element_type=\"widget\" data-widget_type=\"theme-post-title.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\">Togo &#8211; Electricit\u00e9 <br>&#8211; L\u2019\u00e9lectricit\u00e9, une activit\u00e9 strat\u00e9gique<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-667589b elementor-widget elementor-widget-theme-post-excerpt\" data-id=\"667589b\" data-element_type=\"widget\" data-widget_type=\"theme-post-excerpt.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<p>Pour passer d\u2019un taux d\u2019\u00e9lectrification de 58% \u00e0 un acc\u00e8s universel \u00e0 une \u00e9nergie propre et fiable \u00e0 l\u2019horizon 2030, ...\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<a class=\"elementor-element elementor-element-8fc0fe6 e-con-full e-flex e-con e-child\" data-id=\"8fc0fe6\" data-element_type=\"container\" href=\"https:\/\/togo-en.yearbook-media.com\/fr\/togo-electricite-lelectricite-une-activite-strategique\/\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f6def83 elementor-widget elementor-widget-text-editor\" data-id=\"f6def83\" data-element_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>Lire la suite \u00bb<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t\t\t<\/div>\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\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<div class=\"swiper-pagination\"><\/div>\n\t\t\t\t\t\t<\/div>\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-b08fc3 ToBeHidden elementor-hidden-tablet elementor-hidden-mobile e-flex e-con-boxed e-con e-child\" data-id=\"b08fc3\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-bc1cad8 e-con-full droppable e-flex e-con e-child\" data-id=\"bc1cad8\" data-element_type=\"container\" id=\"Ele2A\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5b7f1b0d elementor-widget__width-inherit elementor-widget elementor-widget-text-editor\" data-id=\"5b7f1b0d\" data-element_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>\t\t<div data-elementor-type=\"page\" data-elementor-id=\"83347\" class=\"elementor elementor-83347\" data-elementor-post-type=\"elementor_library\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6442de91 e-con-full OrdiMobileConteneurClass e-flex e-con e-child\" data-id=\"6442de91\" data-element_type=\"container\" id=\"testIdTest\">\n\t\t\t\t<div class=\"elementor-element elementor-element-57de103 elementor-widget elementor-widget-text-editor\" data-id=\"57de103\" data-element_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><style>.elementor-249679 .elementor-element.elementor-element-6da64a60{--display:flex;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--justify-content:space-around;--align-items:center;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:50px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-6da64a60.e-con{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-45f807e0{--display:flex;--min-height:0px;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:-100px;--margin-bottom:62px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:3;}.elementor-249679 .elementor-element.elementor-element-45f807e0.e-con{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-61dcced4{--display:flex;--margin-top:0px;--margin-bottom:-11px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-6c65b106{--display:flex;--margin-top:0px;--margin-bottom:-30px;--margin-left:-25px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-eb74aa8{--display:flex;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-eb74aa8:not(.elementor-motion-effects-element-type-background), .elementor-249679 .elementor-element.elementor-element-eb74aa8 > .elementor-motion-effects-container > .elementor-motion-effects-layer{background-color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-1c762c45{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--flex-wrap:nowrap;--margin-top:-3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-5be6a53a{--display:flex;--align-items:flex-start;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-5be6a53a.e-con{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-75917e71{--display:flex;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-widget-image .widget-image-caption{color:var( --e-global-color-text );font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-249679 .elementor-element.elementor-element-6be76773 > .elementor-widget-container{margin:38px 5px -38px -40px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-6be76773.elementor-element{--align-self:flex-start;}.elementor-249679 .elementor-element.elementor-element-6be76773{text-align:right;}.elementor-249679 .elementor-element.elementor-element-6be76773 img{width:17px;}.elementor-249679 .elementor-element.elementor-element-5ad25a69{--display:flex;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-5ad25a69.e-con{--align-self:flex-end;}.elementor-249679 .elementor-element.elementor-element-52dec736 > .elementor-widget-container{margin:45px -18px -55px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-52dec736{z-index:101;text-align:right;}.elementor-249679 .elementor-element.elementor-element-469b1a7c{--display:flex;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:-25px;--margin-bottom:90px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-469b1a7c:not(.elementor-motion-effects-element-type-background), .elementor-249679 .elementor-element.elementor-element-469b1a7c > .elementor-motion-effects-container > .elementor-motion-effects-layer{background-color:#9FC5F3;}.elementor-249679 .elementor-element.elementor-element-3f5f9124{--display:flex;--min-height:30px;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:center;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:1px;--margin-bottom:-6px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:99;}.elementor-249679 .elementor-element.elementor-element-3f5f9124.e-con{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-48a37689{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:flex-start;--margin-top:3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-widget-text-editor{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );color:var( --e-global-color-text );}.elementor-widget-text-editor.elementor-drop-cap-view-stacked .elementor-drop-cap{background-color:var( --e-global-color-primary );}.elementor-widget-text-editor.elementor-drop-cap-view-framed .elementor-drop-cap, .elementor-widget-text-editor.elementor-drop-cap-view-default .elementor-drop-cap{color:var( --e-global-color-primary );border-color:var( --e-global-color-primary );}.elementor-249679 .elementor-element.elementor-element-4b68287 > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249679 .elementor-element.elementor-element-4b68287.elementor-element{--align-self:flex-start;}.elementor-249679 .elementor-element.elementor-element-4b68287{text-align:start;font-family:\"Roboto\", Sans-serif;font-size:12px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-79a46db6{--display:flex;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-47d25f98 > .elementor-widget-container{margin:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-47d25f98{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:18px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-3aa42503{--display:flex;--flex-direction:row;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:flex-end;--align-items:flex-end;--margin-top:4px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-12d5dc39 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-12d5dc39.elementor-element{--align-self:flex-start;}.elementor-249679 .elementor-element.elementor-element-12d5dc39{text-align:end;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-21535e15{--display:flex;--justify-content:flex-start;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--flex-wrap:wrap;--margin-top:-2px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-21535e15.e-con{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-de420c1{--display:flex;--min-height:30px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-2f60f3f > .elementor-widget-container{margin:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-2f60f3f.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-2f60f3f{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:500;line-height:1.1em;color:#FB5E2A;}.elementor-249679 .elementor-element.elementor-element-6b485447 > .elementor-widget-container{margin:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-6b485447.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-6b485447{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-78e1d9f5{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:center;--gap:010px 9px;--row-gap:010px;--column-gap:9px;--flex-wrap:wrap;--margin-top:-14px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:100;}.elementor-249679 .elementor-element.elementor-element-78e1d9f5.e-con{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-cf3602e{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-7a1bb33 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-7a1bb33.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-7a1bb33{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-6bf72a5{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-1a57dd9 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-1a57dd9.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-1a57dd9{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-34d8bbba{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-32bd35c6 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-32bd35c6.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-32bd35c6{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-5a9252c3{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-8722042 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-8722042.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-8722042{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-19ecc2b3{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-6071d405 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-6071d405.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-6071d405{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-3617569c{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-4b013e71 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-4b013e71.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-4b013e71{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-7450a6f8{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-30970f89 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-30970f89.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-30970f89{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-6aac67a6{--display:flex;--margin-top:-46px;--margin-bottom:-20px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:2;}.elementor-249679 .elementor-element.elementor-element-40d299c{width:100%;max-width:100%;}.elementor-249679 .elementor-element.elementor-element-40d299c.elementor-element{--align-self:flex-end;}.elementor-249679 .elementor-element.elementor-element-1fd15d20{width:100%;max-width:100%;}.elementor-249679 .elementor-element.elementor-element-1fd15d20.elementor-element{--align-self:flex-end;}.elementor-249679 .elementor-element.elementor-element-54e4e530{--display:flex;--justify-content:center;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-531f3cb1{width:100%;max-width:100%;font-family:\"Roboto\", Sans-serif;font-size:10px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249679 .elementor-element.elementor-element-531f3cb1 > .elementor-widget-container{margin:-37px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-531f3cb1.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-3a352c3f > .elementor-widget-container{margin:7px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-3a352c3f.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-3a352c3f{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:15px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249679 .elementor-element.elementor-element-7abb0aba > .elementor-widget-container{margin:7px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-7abb0aba.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-7abb0aba{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:15px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249679 .elementor-element.elementor-element-68e2b2ca > .elementor-widget-container{margin:-110px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-68e2b2ca.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-68e2b2ca{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:18px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249679 .elementor-element.elementor-element-8d50d33{--display:flex;--margin-top:-85px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-8d50d33.e-con{--align-self:center;}.elementor-widget-form .elementor-field-group > label, .elementor-widget-form .elementor-field-subgroup label{color:var( --e-global-color-text );}.elementor-widget-form .elementor-field-group > label{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .elementor-field-type-html{color:var( --e-global-color-text );font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .elementor-field-group .elementor-field{color:var( --e-global-color-text );}.elementor-widget-form .elementor-field-group .elementor-field, .elementor-widget-form .elementor-field-subgroup label{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .elementor-button{font-family:var( --e-global-typography-accent-font-family ), Sans-serif;font-weight:var( --e-global-typography-accent-font-weight );}.elementor-widget-form .e-form__buttons__wrapper__button-next{background-color:var( --e-global-color-accent );}.elementor-widget-form .elementor-button[type=\"submit\"]{background-color:var( --e-global-color-accent );}.elementor-widget-form .e-form__buttons__wrapper__button-previous{background-color:var( --e-global-color-accent );}.elementor-widget-form .elementor-message{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .e-form__indicators__indicator, .elementor-widget-form .e-form__indicators__indicator__label{font-family:var( --e-global-typography-accent-font-family ), Sans-serif;font-weight:var( --e-global-typography-accent-font-weight );}.elementor-widget-form{--e-form-steps-indicator-inactive-primary-color:var( --e-global-color-text );--e-form-steps-indicator-active-primary-color:var( --e-global-color-accent );--e-form-steps-indicator-completed-primary-color:var( --e-global-color-accent );--e-form-steps-indicator-progress-color:var( --e-global-color-accent );--e-form-steps-indicator-progress-background-color:var( --e-global-color-text );--e-form-steps-indicator-progress-meter-color:var( --e-global-color-text );}.elementor-widget-form .e-form__indicators__indicator__progress__meter{font-family:var( --e-global-typography-accent-font-family ), Sans-serif;font-weight:var( --e-global-typography-accent-font-weight );}.elementor-249679 .elementor-element.elementor-element-6ae6ef83{width:var( --container-widget-width, 75% );max-width:75%;--container-widget-width:75%;--container-widget-flex-grow:0;z-index:120;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group{padding-right:calc( 10px\/2 );padding-left:calc( 10px\/2 );margin-bottom:6px;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-form-fields-wrapper{margin-left:calc( -10px\/2 );margin-right:calc( -10px\/2 );margin-bottom:-6px;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group > label, .elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{color:#7B88A3;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-type-html{padding-bottom:0px;color:#7A7A7A;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field{color:#484848;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field, .elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:01px 01px 01px 01px;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:01px 01px 01px 01px;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-message.elementor-message-success{color:#00FF2700;}.elementor-249679 .elementor-element.elementor-element-66fd4d36{--display:flex;--min-height:58px;--gap:0px 0px;--row-gap:0px;--column-gap:0px;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:8px 8px 8px 8px;--margin-top:12px;--margin-bottom:10px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:151;}.elementor-249679 .elementor-element.elementor-element-66fd4d36.e-con{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4{width:auto;max-width:auto;z-index:120;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 > .elementor-widget-container{margin:2px 0px 2px 1px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group{padding-right:calc( 0px\/2 );padding-left:calc( 0px\/2 );margin-bottom:0px;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-form-fields-wrapper{margin-left:calc( -0px\/2 );margin-right:calc( -0px\/2 );margin-bottom:-0px;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group > label, .elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-type-html{padding-bottom:0px;color:#FFFFFF;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field{color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field, .elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:600;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-message.elementor-message-success{color:#00FF2700;}.elementor-249679 .elementor-element.elementor-element-4a59cf88 > .elementor-widget-container{margin:-3px 0px -24px 0px;}.elementor-249679 .elementor-element.elementor-element-4a59cf88.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-4a59cf88{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-17d3ad0c{--display:flex;--gap:0px 0px;--row-gap:0px;--column-gap:0px;border-style:none;--border-style:none;--border-radius:8px 8px 8px 8px;--margin-top:-4px;--margin-bottom:05px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:151;}.elementor-249679 .elementor-element.elementor-element-17d3ad0c.e-con{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-177c9b71{width:auto;max-width:auto;z-index:5;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249679 .elementor-element.elementor-element-177c9b71 > .elementor-widget-container{margin:2px 0px 2px 1px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-177c9b71.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-group{padding-right:calc( 0px\/2 );padding-left:calc( 0px\/2 );margin-bottom:0px;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-form-fields-wrapper{margin-left:calc( -0px\/2 );margin-right:calc( -0px\/2 );margin-bottom:-0px;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-group > label, .elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{color:#000000;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:400;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-type-html{padding-bottom:0px;color:#FFFFFF;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field{color:#000000;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field, .elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:16px;font-weight:600;line-height:1.1em;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-message.elementor-message-success{color:#00FF2700;}.elementor-249679 .elementor-element.elementor-element-5bafe1f3{--display:flex;--min-height:0px;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--gap:0px 0px;--row-gap:0px;--column-gap:0px;--overlay-opacity:1;--margin-top:230px;--margin-bottom:-220px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:10;}.elementor-249679 .elementor-element.elementor-element-5bafe1f3::before, .elementor-249679 .elementor-element.elementor-element-5bafe1f3 > .elementor-background-video-container::before, .elementor-249679 .elementor-element.elementor-element-5bafe1f3 > .e-con-inner > .elementor-background-video-container::before, .elementor-249679 .elementor-element.elementor-element-5bafe1f3 > .elementor-background-slideshow::before, .elementor-249679 .elementor-element.elementor-element-5bafe1f3 > .e-con-inner > .elementor-background-slideshow::before, .elementor-249679 .elementor-element.elementor-element-5bafe1f3 > .elementor-motion-effects-container > .elementor-motion-effects-layer::before{--background-overlay:'';background-size:cover;}.elementor-249679 .elementor-element.elementor-element-5bafe1f3.e-con{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-432cc2a1{--display:flex;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-446e8565 > .elementor-widget-container{margin:0px 3px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-446e8565.elementor-element{--align-self:flex-end;}.elementor-249679 .elementor-element.elementor-element-446e8565{z-index:5;text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249679 .elementor-element.elementor-element-60df49d0 > .elementor-widget-container{margin:35px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-60df49d0.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-60df49d0{z-index:5;text-align:center;font-family:\"Roboto\", Sans-serif;font-size:15px;font-weight:500;line-height:1.1em;color:#6185C0;}.elementor-249679 .elementor-element.elementor-element-62ef38f0{--display:flex;--flex-direction:row;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:space-between;--align-items:flex-start;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:-287px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-f4f51cb > .elementor-widget-container{margin:0px 3px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-f4f51cb.elementor-element{--align-self:flex-end;}.elementor-249679 .elementor-element.elementor-element-f4f51cb{z-index:5;text-align:left;font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249679 .elementor-element.elementor-element-f214306 > .elementor-widget-container{margin:0px 0px 0px 3px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-f214306.elementor-element{--align-self:flex-end;}.elementor-249679 .elementor-element.elementor-element-f214306{z-index:5;text-align:start;font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249679 .elementor-element.elementor-element-1c5a5ed5{--display:flex;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--justify-content:flex-start;--align-items:center;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-1c5a5ed5.e-con{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-4740d3e8{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:space-between;--margin-top:5px;--margin-bottom:5px;--margin-left:010px;--margin-right:10px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-e964c6b > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-e964c6b.elementor-element{--align-self:flex-end;}.elementor-249679 .elementor-element.elementor-element-e964c6b{z-index:5;text-align:left;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249679 .elementor-element.elementor-element-30eb836c > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-30eb836c{z-index:101;text-align:right;}.elementor-249679 .elementor-element.elementor-element-342c88b1{--display:flex;--min-height:180px;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--justify-content:center;--align-items:center;--overflow:hidden;border-style:solid;--border-style:solid;border-width:4px 4px 4px 4px;--border-top-width:4px;--border-right-width:4px;--border-bottom-width:4px;--border-left-width:4px;border-color:#00FF19;--border-color:#00FF19;--border-radius:0px 0px 0px 0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-342c88b1:not(.elementor-motion-effects-element-type-background), .elementor-249679 .elementor-element.elementor-element-342c88b1 > .elementor-motion-effects-container > .elementor-motion-effects-layer{background-color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-3c7e790f > .elementor-widget-container{padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-3c7e790f{font-family:\"Roboto\", Sans-serif;font-weight:500;color:#6185C0;}.elementor-249679 .elementor-element.elementor-element-51f00578{width:auto;max-width:auto;z-index:5;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249679 .elementor-element.elementor-element-51f00578 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-51f00578.elementor-element{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-group{padding-right:calc( 0px\/2 );padding-left:calc( 0px\/2 );margin-bottom:0px;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-form-fields-wrapper{margin-left:calc( -0px\/2 );margin-right:calc( -0px\/2 );margin-bottom:-0px;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-group > label, .elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{color:#000000;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:400;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-type-html{padding-bottom:0px;color:#FFFFFF;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field{color:#213864;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field, .elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:15.5px;font-weight:600;line-height:1.1em;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249679 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249679 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249679 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249679 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-message.elementor-message-success{color:#00FF2700;}@media(max-width:1001px){.elementor-249679 .elementor-element.elementor-element-6ae6ef83{z-index:11;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field, .elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{font-size:10px;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-button{font-size:12px;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4{z-index:11;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field, .elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{font-size:10px;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-button{font-size:12px;}.elementor-249679 .elementor-element.elementor-element-177c9b71{z-index:11;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field, .elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{font-size:10px;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-button{font-size:12px;}.elementor-249679 .elementor-element.elementor-element-51f00578{z-index:11;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field, .elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{font-size:10px;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-button{font-size:12px;}}@media(min-width:1001px){.elementor-249679 .elementor-element.elementor-element-6da64a60{--width:500px;}.elementor-249679 .elementor-element.elementor-element-45f807e0{--width:100%;}.elementor-249679 .elementor-element.elementor-element-6c65b106{--width:500px;}.elementor-249679 .elementor-element.elementor-element-75917e71{--width:10px;}.elementor-249679 .elementor-element.elementor-element-5ad25a69{--width:100%;}.elementor-249679 .elementor-element.elementor-element-469b1a7c{--width:500px;}.elementor-249679 .elementor-element.elementor-element-48a37689{--width:22%;}.elementor-249679 .elementor-element.elementor-element-79a46db6{--width:50%;}.elementor-249679 .elementor-element.elementor-element-3aa42503{--width:22%;}.elementor-249679 .elementor-element.elementor-element-78e1d9f5{--width:100%;}.elementor-249679 .elementor-element.elementor-element-cf3602e{--width:103px;}.elementor-249679 .elementor-element.elementor-element-6bf72a5{--width:103px;}.elementor-249679 .elementor-element.elementor-element-34d8bbba{--width:103px;}.elementor-249679 .elementor-element.elementor-element-5a9252c3{--width:103px;}.elementor-249679 .elementor-element.elementor-element-19ecc2b3{--width:103px;}.elementor-249679 .elementor-element.elementor-element-3617569c{--width:103px;}.elementor-249679 .elementor-element.elementor-element-7450a6f8{--width:103px;}.elementor-249679 .elementor-element.elementor-element-8d50d33{--width:100%;}.elementor-249679 .elementor-element.elementor-element-66fd4d36{--width:390px;}.elementor-249679 .elementor-element.elementor-element-17d3ad0c{--width:100%;}.elementor-249679 .elementor-element.elementor-element-5bafe1f3{--width:150%;}.elementor-249679 .elementor-element.elementor-element-62ef38f0{--width:95%;}.elementor-249679 .elementor-element.elementor-element-1c5a5ed5{--width:100%;}.elementor-249679 .elementor-element.elementor-element-4740d3e8{--width:100%;}}@media(max-width:1000px){.elementor-249679 .elementor-element.elementor-element-6da64a60{--width:390px;--margin-top:105px;--margin-bottom:-75px;--margin-left:0px;--margin-right:0px;}.elementor-249679 .elementor-element.elementor-element-45f807e0{--min-height:150px;--flex-direction:column;--container-widget-width:100%;--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--margin-top:-47px;--margin-bottom:-32px;--margin-left:0px;--margin-right:0px;--z-index:3;}.elementor-249679 .elementor-element.elementor-element-61dcced4{--width:25%;}.elementor-249679 .elementor-element.elementor-element-6c65b106{--width:100%;--flex-direction:row;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:center;--align-items:center;--flex-wrap:nowrap;--margin-top:3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249679 .elementor-element.elementor-element-6c65b106.e-con{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-eb74aa8{--width:75%;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--align-items:center;}.elementor-249679 .elementor-element.elementor-element-eb74aa8.e-con{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-1c762c45{--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249679 .elementor-element.elementor-element-6be76773 > .elementor-widget-container{margin:-3px 40px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-5ad25a69{--width:100%;--justify-content:flex-end;--align-items:flex-end;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-52dec736 > .elementor-widget-container{margin:40px 55px -30px 0px;}.elementor-249679 .elementor-element.elementor-element-52dec736{z-index:100;}.elementor-249679 .elementor-element.elementor-element-469b1a7c{--width:78%;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--flex-wrap:nowrap;--margin-top:-103px;--margin-bottom:-7px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-469b1a7c.e-con{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-3f5f9124{--justify-content:center;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249679 .elementor-element.elementor-element-48a37689{--width:25%;--margin-top:2px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-4b68287 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-4b68287{font-size:8px;}.elementor-249679 .elementor-element.elementor-element-79a46db6{--width:46%;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-47d25f98 > .elementor-widget-container{margin:0px -20px 0px -20px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-47d25f98{font-size:12px;}.elementor-249679 .elementor-element.elementor-element-3aa42503{--width:25%;--margin-top:4px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-12d5dc39 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-12d5dc39{font-size:7px;}.elementor-249679 .elementor-element.elementor-element-21535e15{--margin-top:-15px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249679 .elementor-element.elementor-element-de420c1{--min-height:15px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-2f60f3f{width:100%;max-width:100%;font-size:10px;}.elementor-249679 .elementor-element.elementor-element-2f60f3f > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-6b485447{width:100%;max-width:100%;font-size:10px;}.elementor-249679 .elementor-element.elementor-element-6b485447 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-78e1d9f5{--width:100%;--gap:6px 4px;--row-gap:6px;--column-gap:4px;--flex-wrap:wrap;--margin-top:-12px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249679 .elementor-element.elementor-element-cf3602e{--width:61px;--min-height:15px;}.elementor-249679 .elementor-element.elementor-element-7a1bb33{font-size:9px;}.elementor-249679 .elementor-element.elementor-element-6bf72a5{--width:61px;--min-height:15px;}.elementor-249679 .elementor-element.elementor-element-1a57dd9{font-size:9px;}.elementor-249679 .elementor-element.elementor-element-34d8bbba{--width:61px;--min-height:15px;}.elementor-249679 .elementor-element.elementor-element-32bd35c6{font-size:9px;}.elementor-249679 .elementor-element.elementor-element-5a9252c3{--width:61px;--min-height:15px;}.elementor-249679 .elementor-element.elementor-element-8722042{font-size:9px;}.elementor-249679 .elementor-element.elementor-element-19ecc2b3{--width:61px;--min-height:15px;}.elementor-249679 .elementor-element.elementor-element-6071d405{font-size:9px;}.elementor-249679 .elementor-element.elementor-element-3617569c{--width:61px;--min-height:15px;}.elementor-249679 .elementor-element.elementor-element-4b013e71{font-size:9px;}.elementor-249679 .elementor-element.elementor-element-7450a6f8{--width:61px;--min-height:15px;}.elementor-249679 .elementor-element.elementor-element-30970f89{font-size:9px;}.elementor-249679 .elementor-element.elementor-element-6aac67a6{--width:96%;--min-height:250px;--margin-top:-56px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-40d299c > .elementor-widget-container{margin:5px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-1fd15d20 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-54e4e530{--margin-top:3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249679 .elementor-element.elementor-element-54e4e530.e-con{--order:-99999 \/* order start hack *\/;}.elementor-249679 .elementor-element.elementor-element-531f3cb1 > .elementor-widget-container{margin:-30px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-3a352c3f > .elementor-widget-container{margin:-181px 0px 1px 0px;}.elementor-249679 .elementor-element.elementor-element-3a352c3f{text-align:center;font-size:10px;line-height:1.2em;}.elementor-249679 .elementor-element.elementor-element-7abb0aba > .elementor-widget-container{margin:-180px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-7abb0aba{text-align:center;font-size:14px;line-height:1.2em;}.elementor-249679 .elementor-element.elementor-element-68e2b2ca > .elementor-widget-container{margin:-110px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-68e2b2ca{font-size:10px;}.elementor-249679 .elementor-element.elementor-element-8d50d33{--width:184px;--margin-top:-156px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249679 .elementor-element.elementor-element-8d50d33.e-con{--align-self:center;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83{width:var( --container-widget-width, 100% );max-width:100%;--container-widget-width:100%;--container-widget-flex-grow:0;z-index:120;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group > label{font-size:12px;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field, .elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{font-size:8px;}.elementor-249679 .elementor-element.elementor-element-6ae6ef83 .elementor-button{font-size:10.5px;}.elementor-249679 .elementor-element.elementor-element-66fd4d36{--width:85%;--min-height:42px;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--align-items:center;--margin-top:10px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:151;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 > .elementor-widget-container{margin:2px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4{z-index:120;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group > label{font-size:12px;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-type-html{font-size:12px;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field, .elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{font-size:10px;}.elementor-249679 .elementor-element.elementor-element-4ea8e2b4 .elementor-button{font-size:10.5px;}.elementor-249679 .elementor-element.elementor-element-4a59cf88 > .elementor-widget-container{margin:2px 0px -10px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-4a59cf88{font-size:7.5px;}.elementor-249679 .elementor-element.elementor-element-17d3ad0c{--width:85%;--min-height:42px;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--align-items:center;--margin-top:2px;--margin-bottom:-20px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:251;}.elementor-249679 .elementor-element.elementor-element-177c9b71 > .elementor-widget-container{margin:2px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-177c9b71{z-index:120;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-group > label{font-size:12px;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-type-html{font-size:12px;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field, .elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{font-size:12px;}.elementor-249679 .elementor-element.elementor-element-177c9b71 .elementor-button{font-size:10.5px;}.elementor-249679 .elementor-element.elementor-element-5bafe1f3{--min-height:150px;--margin-top:-149px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249679 .elementor-element.elementor-element-446e8565 > .elementor-widget-container{margin:-133px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-446e8565.elementor-element{--align-self:flex-start;}.elementor-249679 .elementor-element.elementor-element-446e8565{text-align:left;font-size:10px;}.elementor-249679 .elementor-element.elementor-element-f4f51cb > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249679 .elementor-element.elementor-element-f4f51cb.elementor-element{--align-self:flex-start;}.elementor-249679 .elementor-element.elementor-element-f4f51cb{text-align:center;font-size:10px;}.elementor-249679 .elementor-element.elementor-element-f214306 > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249679 .elementor-element.elementor-element-f214306.elementor-element{--align-self:flex-start;}.elementor-249679 .elementor-element.elementor-element-f214306{text-align:center;font-size:10px;}.elementor-249679 .elementor-element.elementor-element-1c5a5ed5{--width:390px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-e964c6b > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249679 .elementor-element.elementor-element-e964c6b.elementor-element{--align-self:flex-start;}.elementor-249679 .elementor-element.elementor-element-e964c6b{text-align:center;font-size:10px;}.elementor-249679 .elementor-element.elementor-element-30eb836c > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-30eb836c{z-index:100;}.elementor-249679 .elementor-element.elementor-element-342c88b1{--min-height:112px;--margin-top:5px;--margin-bottom:5px;--margin-left:5px;--margin-right:5px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249679 .elementor-element.elementor-element-3c7e790f{text-align:center;font-size:15px;}.elementor-249679 .elementor-element.elementor-element-51f00578 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249679 .elementor-element.elementor-element-51f00578{z-index:120;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-group > label{font-size:12px;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-type-html{font-size:12px;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field, .elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{font-size:12px;}.elementor-249679 .elementor-element.elementor-element-51f00578 .elementor-button{font-size:10.5px;}}<\/style>\t\t<div data-elementor-type=\"loop-item\" data-elementor-id=\"249679\" class=\"elementor elementor-249679 elementor-bc-flex-widget e-loop-item e-loop-item-32630 post-32630 post type-post status-publish format-standard has-post-thumbnail hentry category-electricite category-togo category-togo-energie generate-columns tablet-grid-50 mobile-grid-100 grid-parent grid-20\" data-elementor-post-type=\"elementor_library\" data-custom-edit-handle=\"1\">\n\t\t\t<div class=\"elementor-element elementor-element-6da64a60 e-con-full OrdiMobileConteneurClass e-flex e-con e-child\" data-id=\"6da64a60\" data-element_type=\"container\" id=\"testIdTest\">\n\t\t<div class=\"elementor-element elementor-element-45f807e0 e-con-full UploadFileConteneur AdUploadedTitle elementor-hidden-tablet elementor-hidden-mobile elementor-hidden-desktop e-flex e-con e-child\" data-id=\"45f807e0\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-61dcced4 e-con-full e-flex e-con e-child\" data-id=\"61dcced4\" data-element_type=\"container\">\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-6c65b106 e-con-full e-flex e-con e-child\" data-id=\"6c65b106\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-eb74aa8 e-con-full e-flex e-con e-child\" data-id=\"eb74aa8\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1c762c45 e-con-full e-flex e-con e-child\" data-id=\"1c762c45\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-5be6a53a e-con-full e-flex e-con e-child\" data-id=\"5be6a53a\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-75917e71 e-con-full e-flex e-con e-child\" data-id=\"75917e71\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6be76773 AnnonceDragIcone elementor-widget elementor-widget-image\" data-id=\"6be76773\" data-element_type=\"widget\" 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 decoding=\"async\" src=\"https:\/\/via-agency.media\/wp-content\/uploads\/2025\/05\/arrow-drag-64-bleu.png\" title=\"\" alt=\"\" loading=\"lazy\" \/>\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<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-5ad25a69 e-con-full CroixResetAnnonceContainer e-flex e-con e-child\" data-id=\"5ad25a69\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-52dec736 elementor-widget elementor-widget-image\" data-id=\"52dec736\" data-element_type=\"widget\" id=\"CroixResetAnnonce\" 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\t<a href=\"#\">\n\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-transparent.png\" title=\"\" alt=\"\" loading=\"lazy\" \/>\t\t\t\t\t\t\t\t<\/a>\n\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<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-469b1a7c e-con-full UploadFileConteneur e-flex e-con e-child\" data-id=\"469b1a7c\" data-element_type=\"container\" id=\"UploadFileConteneur\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t<div class=\"elementor-element elementor-element-3f5f9124 e-con-full ChoisirEspacePublicitaireDisponibiliteConteneur e-flex e-con e-child\" data-id=\"3f5f9124\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-48a37689 e-con-full e-flex e-con e-child\" data-id=\"48a37689\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4b68287 PositionEspacePublicitaire elementor-widget elementor-widget-text-editor\" data-id=\"4b68287\" data-element_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\tPosition\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-79a46db6 e-con-full e-flex e-con e-child\" data-id=\"79a46db6\" data-element_type=\"container\" id=\"ChoixEspacePublicitaireTitre\">\n\t\t\t\t<div class=\"elementor-element elementor-element-47d25f98 elementor-widget elementor-widget-text-editor\" data-id=\"47d25f98\" data-element_type=\"widget\" id=\"ChoixEspacePublicitaireTexte\" 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\tChoix d&rsquo;espace publicitaire\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-3aa42503 e-con-full e-flex e-con e-child\" data-id=\"3aa42503\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-12d5dc39 ReferenceEspacePublicitaire elementor-widget elementor-widget-text-editor\" data-id=\"12d5dc39\" data-element_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>R\u00e9f\u00e9rence<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-21535e15 e-con-full EspPubFormatMainContainer e-flex e-con e-child\" data-id=\"21535e15\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-de420c1 e-con-full e-flex e-con e-child\" data-id=\"de420c1\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2f60f3f elementor-widget-mobile__width-inherit SelectionFormatTitre elementor-widget elementor-widget-text-editor\" data-id=\"2f60f3f\" data-element_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 style=\"text-align: center;\">Merci de s\u00e9lectionner un format d&rsquo;annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6b485447 elementor-widget-mobile__width-inherit elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile SelectionFormatTitreBlancOLD elementor-widget elementor-widget-text-editor\" data-id=\"6b485447\" data-element_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 style=\"text-align: center;\">Vous pouvez changer de format d&rsquo;annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-78e1d9f5 e-con-full EspPubFormatListe e-flex e-con e-child\" data-id=\"78e1d9f5\" data-element_type=\"container\">\n\t\t<a class=\"elementor-element elementor-element-cf3602e e-con-full EspPubFormatContainer FormatIdCreation e-flex e-con e-child\" data-id=\"cf3602e\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-7a1bb33 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"7a1bb33\" data-element_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\tCr\u00e9ation\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-6bf72a5 e-con-full EspPubFormatContainer FormatIdPopUp e-flex e-con e-child\" data-id=\"6bf72a5\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-1a57dd9 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"1a57dd9\" data-element_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\tPop-up\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-34d8bbba e-con-full EspPubFormatContainer FormatIdBanniere e-flex e-con e-child\" data-id=\"34d8bbba\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-32bd35c6 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"32bd35c6\" data-element_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\tBanni\u00e8re\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-5a9252c3 e-con-full EspPubFormatContainer FormatIdVideo e-flex e-con e-child\" data-id=\"5a9252c3\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8722042 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"8722042\" data-element_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\tVid\u00e9o\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-19ecc2b3 e-con-full EspPubFormatContainer FormatIdCommunique e-flex e-con e-child\" data-id=\"19ecc2b3\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6071d405 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"6071d405\" data-element_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\tCommuniqu\u00e9\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-3617569c e-con-full EspPubFormatContainer FormatIdInterview e-flex e-con e-child\" data-id=\"3617569c\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4b013e71 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"4b013e71\" data-element_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\tInterview\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-7450a6f8 e-con-full EspPubFormatContainer FormatIdParrainage e-flex e-con e-child\" data-id=\"7450a6f8\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-30970f89 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"30970f89\" data-element_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\tParrainage\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-6aac67a6 e-con-full HTMLUploadfileConteneur e-flex e-con e-child\" data-id=\"6aac67a6\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-40d299c elementor-widget__width-inherit HTMLUploadfileClass elementor-widget elementor-widget-html\" data-id=\"40d299c\" data-element_type=\"widget\" id=\"HTMLUploadfile\" 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=\"en\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <meta name=\"google\" content=\"notranslate\">\r\n    \r\n    <script data-jetpack-boost=\"ignore\" src=\"https:\/\/code.jquery.com\/jquery-3.6.0.min.js\"><\/script>\r\n    <script data-jetpack-boost=\"ignore\" src=\"https:\/\/code.jquery.com\/ui\/1.12.1\/jquery-ui.min.js\"><\/script>\r\n\r\n<script data-jetpack-boost=\"ignore\">\r\n\/\/ Lazy loading des biblioth\u00e8ques - charg\u00e9es uniquement au besoin\r\nwindow.VIALibraries = {\r\n    mammothLoaded: false,\r\n    pdfLoaded: false,\r\n    \r\n    loadMammoth: function(callback) {\r\n        if (this.mammothLoaded) { callback(); return; }\r\n        var script = document.createElement('script');\r\n        script.src = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/mammoth\/1.4.0\/mammoth.browser.min.js';\r\n        script.onload = function() { \r\n            window.VIALibraries.mammothLoaded = true; \r\n            callback(); \r\n        };\r\n        document.head.appendChild(script);\r\n    },\r\n    \r\n    loadPdfJs: function(callback) {\r\n        if (this.pdfLoaded) { callback(); return; }\r\n        var script = document.createElement('script');\r\n        script.src = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.11.174\/pdf.min.js';\r\n        script.onload = function() {\r\n            window.VIALibraries.pdfLoaded = true;\r\n            pdfjsLib.GlobalWorkerOptions.workerSrc = '\/\/cdn.jsdelivr.net\/npm\/pdfjs-dist@latest\/build\/pdf.worker.min.js';\r\n            callback();\r\n        };\r\n        document.head.appendChild(script);\r\n    }\r\n};\r\n<\/script>\r\n\r\n<\/head>\r\n<body>\r\n    <div id=\"PopUpMessageAchattest\" class=\"draggable\" draggable=\"true\" style=\"justify-content: center; align-items: flex-start;\">\r\n        <div id=\"drop_file_zone_achat\" class=\"drop_file_zone_achat_class\" ondrop=\"uploadFile_achat(event)\" ondragover=\"return false\">\r\n        <div id=\"drag_upload_file_achat\">\r\n            <p><input class=\"button-2_achat\" type=\"button\" value=\"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\" onclick=\"fileExplorer_achat(event);\" \/><\/p>\r\n                <input type=\"file\" id=\"selectfile_achat\" \/>\r\n        <\/div>\r\n        <\/div>\r\n        <div class=\"img-content\"><\/div>\r\n    <\/div>\r\n<\/body>\r\n<\/html>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1fd15d20 elementor-widget__width-inherit HTMLUploadfileClass elementor-widget elementor-widget-html\" data-id=\"1fd15d20\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<script data-jetpack-boost=\"ignore\">\r\nif (!window._espPubScriptLoaded) {\r\nwindow._espPubScriptLoaded = true;\r\n\/**\r\n * Configuration centralis\u00e9e\r\n *\/\r\nconst CONFIG = {\r\n    iframeId: 'yearbook-iframe',\r\n    ajaxUrl: 'https:\/\/via-agency.media\/wp-admin\/admin-ajax.php',\r\n    apercuUrl: 'https:\/\/rdc.yearbook-media.com\/apercu',\r\n    \r\n    allowedExtensions: {\r\n        video: ['mp4', 'mov', 'wmv', 'avi', 'flv', 'f4v', 'swf', 'mkv', 'webm', 'mpeg'],\r\n        image: ['jpg', 'jpeg', 'png', 'gif', 'tif', 'svg', 'webp'],\r\n        document: ['doc', 'docx', 'ppt', 'pptx', 'pdf']\r\n    },\r\n    \r\n    mimeTypes: {\r\n        docx: 'application\/vnd.openxmlformats-officedocument.wordprocessingml.document',\r\n        pdf: 'application\/pdf'\r\n    },\r\n    \r\n    dragScroll: {\r\n        threshold: 150,\r\n        maxSpeed: 65,\r\n        throttleDelay: 50\r\n    },\r\n    \r\n    breakpoints: {\r\n        mobile: 1000\r\n    },\r\n    \r\n    keywords: [\r\n        { normal: \"parrainage\", display: \"Parrainage\" },\r\n        { normal: \"communique\", display: \"Communiqu\u00e9\" },\r\n        { normal: \"interview\", display: \"Interview\" }\r\n    ]\r\n};\r\n\r\n\/**\r\n * \u2705 v1.19.1 : Module de positionnement dans l'iframe\r\n * \r\n * PROBL\u00c8ME : L'iframe ne scrolle pas en desktop \u2014 c'est le parent (#PageWebTitrePage) qui scrolle.\r\n * L'iframe est scal\u00e9e \u00e0 0.85 \u2192 les coordonn\u00e9es iframe \u2260 coordonn\u00e9es parent.\r\n * position:fixed dans l'iframe = relatif au CONTENU TOTAL, pas au viewport visible.\r\n * \r\n * SOLUTION : Le parent calcule visibleTopIframe (la position iframe du haut du viewport)\r\n * et l'envoie dans le message 'PageWebTitrePage-scroll'. L'iframe n'a qu'\u00e0 l'utiliser.\r\n * \r\n * Pour scroller, l'iframe envoie 'scrollToIframeY' au parent qui fait la conversion.\r\n *\/\r\nconst ScrollHelper = {\r\n    _visibleTopIframe: 0,\r\n    _iframeScale: 0.85,\r\n\r\n    init() {\r\n        \/\/ \u00c9couter les donn\u00e9es de scroll envoy\u00e9es par le parent\r\n        window.addEventListener('message', (event) => {\r\n            var msg = event.data;\r\n            if (msg && msg.action === 'PageWebTitrePage-scroll') {\r\n                if (typeof msg.visibleTopIframe === 'number') {\r\n                    this._visibleTopIframe = msg.visibleTopIframe;\r\n                }\r\n                if (typeof msg.iframeScale === 'number') {\r\n                    this._iframeScale = msg.iframeScale;\r\n                }\r\n            }\r\n        });\r\n        console.log('\u2705 ScrollHelper initialis\u00e9');\r\n    },\r\n\r\n    \/**\r\n     * Position Y dans le document iframe correspondant au haut du viewport visible\r\n     *\/\r\n    getVisibleTop() {\r\n        if (window === window.top) {\r\n            return window.scrollY || 0;\r\n        }\r\n        return this._visibleTopIframe;\r\n    },\r\n\r\n    \/**\r\n     * Demande au parent de scroller pour positionner `element` \u00e0 `offsetFromTop` px du viewport\r\n     *\/\r\n    scrollElementTo(element, offsetFromTop) {\r\n        if (!element) return;\r\n\r\n        \/\/ getBoundingClientRect().top dans une iframe sans scroll = position absolue Y\r\n        var elementAbsY = element.getBoundingClientRect().top;\r\n\r\n        if (window === window.top) {\r\n            window.scrollTo({ top: elementAbsY - offsetFromTop + (window.scrollY || 0), behavior: 'smooth' });\r\n            return;\r\n        }\r\n\r\n        \/\/ Envoyer au parent \u2014 le parent fait la conversion scale\r\n        window.parent.postMessage({\r\n            type: 'scrollToIframeY',\r\n            iframeId: CONFIG.iframeId,\r\n            iframeY: elementAbsY,\r\n            offsetFromTop: offsetFromTop\r\n        }, '*');\r\n        console.log('\ud83d\udcdc scrollToIframeY:', { iframeY: Math.round(elementAbsY), offsetFromTop });\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'\u00e9tat (SessionStorage)\r\n *\/\r\nconst StateManager = {\r\n    init() {\r\n        if (sessionStorage.getItem(\"AchatEspaceCall\") === 'No') {\r\n            sessionStorage.clear();\r\n        }\r\n        \r\n        this.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        this.set('dragstart_Rank_Emplacement_Page_Web', 'No');\r\n        this.set('dragstart_Commande_Emplacement_Page_Web', 'No');\r\n        \r\n        \/\/ \u2705 v2.1.1 : Popup \u2192 ne jamais pr\u00e9remplir le format\r\n        if (this.get('PopUpChoice') === 'Yes') {\r\n            this.set('Formatchoisi', 'No');\r\n            this.set('FormatSelect', '');\r\n            this.set('Commande_Format_Transmis', '');\r\n        }\r\n    },\r\n    \r\n    get(key) {\r\n        return sessionStorage.getItem(key);\r\n    },\r\n    \r\n    set(key, value) {\r\n        sessionStorage.setItem(key, value);\r\n    },\r\n    \r\n    getMultiple(keys) {\r\n        return keys.reduce((acc, key) => {\r\n            acc[key] = this.get(key);\r\n            return acc;\r\n        }, {});\r\n    },\r\n    \r\n    setMultiple(obj) {\r\n        Object.entries(obj).forEach(([key, value]) => {\r\n            this.set(key, value);\r\n        });\r\n    },\r\n    \r\n    buildEmplacementReference(rank) {\r\n        const codeSite = this.get('codeSite');\r\n        const codePage = this.get('codePage');\r\n        return `${codeSite}${codePage}L${rank.substring(3)}`;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion des fichiers\r\n *\/\r\nconst FileManager = {\r\n    getExtension(filename) {\r\n        console.log('filename:', filename);\r\n        const parts = filename.split('.');\r\n        return parts.length > 1 ? parts.pop().toLowerCase() : '';\r\n    },\r\n    \r\n    isAllowedExtension(extension) {\r\n        return Object.values(CONFIG.allowedExtensions)\r\n            .flat()\r\n            .includes(extension);\r\n    },\r\n    \r\n    getFileType(extension) {\r\n        for (const [type, extensions] of Object.entries(CONFIG.allowedExtensions)) {\r\n            if (extensions.includes(extension)) {\r\n                return type;\r\n            }\r\n        }\r\n        return null;\r\n    },\r\n    \r\n    async urlToFile(url, filename) {\r\n        console.log(\"Fetching from URL:\", url);\r\n        \r\n        const mimeType = filename.includes('.docx') \r\n            ? CONFIG.mimeTypes.docx \r\n            : filename.includes('.pdf') \r\n            ? CONFIG.mimeTypes.pdf \r\n            : null;\r\n        \r\n        try {\r\n            const response = await fetch(url);\r\n            \r\n            if (!response.ok) {\r\n                throw new Error(`Network response was not ok: ${response.status} ${response.statusText}`);\r\n            }\r\n            \r\n            const blob = await response.blob();\r\n            return new File([blob], filename, { type: mimeType });\r\n        } catch (error) {\r\n            console.error(\"Error in urlToFile:\", error);\r\n            alert(\"Erreur lors du chargement du fichier. Veuillez r\u00e9essayer.\");\r\n            throw error;\r\n        }\r\n    },\r\n    \r\n    createObjectUrl(file) {\r\n        \/\/ R\u00e9voquer l'ancien URL si existant\r\n        const oldUrl = StateManager.get('objectUrl');\r\n        if (oldUrl && oldUrl.startsWith('blob:')) {\r\n            URL.revokeObjectURL(oldUrl);\r\n            console.log('\ud83d\uddd1\ufe0f Old Object URL revoked');\r\n        }\r\n        \r\n        const url = URL.createObjectURL(file);\r\n        StateManager.set('objectUrl', url);\r\n        return url;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion du Drag & Drop\r\n *\/\r\nconst DragDropManager = {\r\n    state: {\r\n        isFileBeingDragged: false,\r\n        draggedFile: null,\r\n        dragInProgress: false,\r\n        throttleTimeout: null\r\n    },\r\n    \r\n    init() {\r\n        this.attachEventListeners();\r\n    },\r\n    \r\n    attachEventListeners() {\r\n        window.addEventListener('dragstart', (e) => this.handleDragStart(e), true);\r\n        jQuery(document).on('dragover', (e) => this.handleDragOver(e));\r\n        jQuery(document).on('dragleave drop', (e) => this.handleDragEnd(e));\r\n        jQuery(\"#drop_file_zone_achat\").on(\"dragover\", (e) => this.handleDropZoneDragOver(e));\r\n        jQuery(\".draggable\").on(\"dragend\", (e) => this.handleDraggableEnd(e));\r\n    },\r\n    \r\n    handleDragStart(e) {\r\n        console.log('Window-level dragstart', e);\r\n        this.state.dragInProgress = true;\r\n    \r\n        const $target = $(e.target);\r\n        const droppableParent = $target.closest('.droppable');\r\n        const parentId = droppableParent.length ? droppableParent.attr('id') : null;\r\n        \r\n        StateManager.set('dragstart_Rank_Emplacement_Page_Web', parentId);\r\n        console.log('dragstart_Rank_Emplacement_Page_Web', parentId);\r\n        \r\n        \/\/ \u2705 CALCULER IMM\u00c9DIATEMENT dragstart_Commande_Emplacement_Page_Web\r\n        if (parentId) {\r\n            const dragstartRef = StateManager.buildEmplacementReference(parentId);\r\n            StateManager.set('dragstart_Commande_Emplacement_Page_Web', dragstartRef);\r\n            console.log('dragstart_Commande_Emplacement_Page_Web', dragstartRef);\r\n            \/\/ \u2705 v2.4.5 : Capturer l'\u00e9tat checkbox R\u00e9server au moment du dragstart\r\n            \/\/ Si l'utilisateur a explicitement d\u00e9coch\u00e9, forcer \u00e0 No m\u00eame si DOM est coch\u00e9\r\n            var $_dragCb = $('#' + parentId).find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]');\r\n            var _dragCbChecked = $_dragCb.prop('checked') === true;\r\n            var _expliciteDecocheDrag = StateManager.get('_reserverDecoche_' + parentId) === 'Yes';\r\n            var _reserverDrag = _dragCbChecked && !_expliciteDecocheDrag;\r\n            StateManager.set('dragstart_ReserverChecked', _reserverDrag ? 'Yes' : 'No');\r\n            \/\/ R\u00e9initialiser le flag apr\u00e8s lecture\r\n            StateManager.set('_reserverDecoche_' + parentId, 'No');\r\n            console.log('[dragstart] ReserverChecked dom:', _dragCbChecked, '| d\u00e9coch\u00e9 explicitement:', _expliciteDecocheDrag, '| final:', _reserverDrag);\r\n        }\r\n    \r\n        const dataTransfer = e.dataTransfer || e.originalEvent?.dataTransfer;\r\n        const files = dataTransfer?.files || null;\r\n        \r\n        const imgSrc = $target.closest('.draggable').find('img').attr('src');\r\n        const videoSrc = $target.closest('.draggable').find('video').attr('src') || \r\n                        $target.closest('.draggable').find('video source').attr('src');\r\n        const mediaSrc = imgSrc || videoSrc;\r\n    \r\n        console.log('dragstart target:', e.target);\r\n        console.log('files:', files);\r\n        console.log('mediaSrc:', mediaSrc);\r\n    \r\n        if (!mediaSrc && (!files || files.length === 0)) {\r\n            console.log('No media source or files found, preventing drag');\r\n            e.preventDefault();\r\n            this.state.dragInProgress = false;\r\n            return false;\r\n        }\r\n    \r\n        if (mediaSrc) {\r\n            StateManager.set('objectUrl', mediaSrc);\r\n        }\r\n    \r\n        StateManager.set('Commande_Format_Transmis', '');\r\n        \r\n        if ($target.closest('.droppable').find('.doc-preview-container:visible').length > 0) {\r\n            StateManager.set('Commande_Format_Transmis', 'R\u00e9dactionnel');\r\n            StateManager.set('FullPathAdFile', \r\n                $target.closest('.droppable').find('.doc-preview-FullPathAdFile').text());\r\n        }\r\n    \r\n        if (files && files.length > 0) {\r\n            this.state.isFileBeingDragged = true;\r\n            this.state.draggedFile = files[0];\r\n        }\r\n        \r\n        \/\/ \u2705 TOUJOURS marquer comme \"Moved\" quand on drag depuis un espace existant\r\n        if (parentId && mediaSrc) {\r\n            StateManager.set('FirstUploadFileorMoved', 'Moved');\r\n            console.log('\u2705 Drag depuis espace existant - Moved');\r\n        }\r\n    \r\n        console.log('Drag Started', {\r\n            file: this.state.draggedFile,\r\n            mediaSrc: mediaSrc,\r\n            dragstartRef: StateManager.get('dragstart_Commande_Emplacement_Page_Web')\r\n        });\r\n    },\r\n    \r\n    handleDragOver(e) {\r\n        e.preventDefault();\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            this.handleIframeDragScroll(e);\r\n        } else {\r\n            this.handleDirectPageScroll(e);\r\n        }\r\n    },\r\n    \r\n    handleIframeDragScroll(e) {\r\n        if (!this.state.throttleTimeout) {\r\n            this.state.throttleTimeout = setTimeout(() => {\r\n                MessageManager.sendToParent('dragScroll', { clientY: e.clientY });\r\n                this.state.throttleTimeout = null;\r\n            }, CONFIG.dragScroll.throttleDelay);\r\n        }\r\n    },\r\n    \r\n    handleDirectPageScroll(e) {\r\n        const { threshold, maxSpeed } = CONFIG.dragScroll;\r\n        const windowHeight = window.innerHeight;\r\n        \r\n        if (e.clientY < threshold) {\r\n            const speed = Math.max(1, maxSpeed * (1 - e.clientY \/ threshold));\r\n            window.scrollBy(0, -speed);\r\n        } else if (e.clientY > windowHeight - threshold) {\r\n            const speed = Math.max(1, maxSpeed * (1 - (windowHeight - e.clientY) \/ threshold));\r\n            window.scrollBy(0, speed);\r\n        }\r\n    },\r\n    \r\n    handleDragEnd(e) {\r\n        e.preventDefault();\r\n        MessageManager.sendToParent('dragEnd', {});\r\n        console.log('dragleave drop');\r\n    },\r\n    \r\n    handleDropZoneDragOver(e) {\r\n        e.preventDefault();\r\n        console.log(\"FirstUploadFileorMoved:\", StateManager.get('FirstUploadFileorMoved'));\r\n    },\r\n    \r\n    handleDraggableEnd(e) {\r\n        e.preventDefault();\r\n        this.resetState();\r\n        console.log('dragend');\r\n    },\r\n    \r\n    resetState() {\r\n        this.state.isFileBeingDragged = false;\r\n        this.state.draggedFile = null;\r\n        this.state.dragInProgress = false;\r\n    },\r\n    \r\n    clearDataTransferFiles(e) {\r\n        e.dataTransfer = new DataTransfer();\r\n        console.log('DataTransfer files cleared');\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'interface utilisateur\r\n *\/\r\nconst UIManager = {\r\n    isMobile() {\r\n        return window.outerWidth < CONFIG.breakpoints.mobile;\r\n    },\r\n    \r\n    isDesktop() {\r\n        const userAgent = navigator.userAgent;\r\n        const isWindows = userAgent.indexOf('Windows') > -1;\r\n        const isMac = userAgent.indexOf('Macintosh') > -1;\r\n        const isLinux = userAgent.indexOf('Linux') > -1 && userAgent.indexOf('Android') === -1;\r\n        return isWindows || isMac || isLinux;\r\n    },\r\n    \r\n    initMobileUI() {\r\n        $(document).ready(() => {\r\n            $('label[for=\"form-field-LienAnnonce\"]').each(function() {\r\n                $(this).text('Renseigner le lien hypertexte de l\\'annonce');\r\n            });\r\n            \r\n            $('input[name=\"form_fields[LienAnnonce]\"]').each(function() {\r\n                $(this).attr('placeholder', 'Renseigner le lien hypertexte de l\\'annonce');\r\n            });\r\n        });\r\n        \r\n        jQuery('.MsgDatesText').hide();\r\n        this.attachMobileEventListeners();\r\n    },\r\n    \r\n    attachMobileEventListeners() {\r\n        jQuery('.TransmettreFichierAnnonceContainer').on('click', (e) => {\r\n            this.handleMobileSpaceSelection(e);\r\n        });\r\n        \r\n        jQuery('[id=\"form-field-selected_currency_Mobile\"]').off('change').on('change', (e) => {\r\n            this.handleMobileCurrencyChange(e);\r\n        });\r\n    },\r\n    \r\n    handleMobileSpaceSelection(e) {\r\n        e.preventDefault();\r\n        jQuery('#IndisponibilitesMsg').hide();\r\n        \r\n        jQuery('input[name=\"form_fields[SelectEspacePublicitaireMobile]\"]').prop('checked', false);\r\n        jQuery(e.currentTarget).find('input[name=\"form_fields[SelectEspacePublicitaireMobile]\"]').prop('checked', true);\r\n        \r\n        StateManager.set(\"PageWebDisplayed\", 'Yes');\r\n        \r\n        jQuery('.FormSelectDevisesMobile').hide();\r\n        jQuery(e.target).closest('.EspacePublicitaireMobile').find('.FormSelectDevisesMobile').show();\r\n        \r\n        const $droppable = jQuery(e.currentTarget).closest('.droppable');\r\n        const rankId = $droppable.attr('id');\r\n        \r\n        StateManager.set('Rank_Emplacement_Page_Web', rankId);\r\n        StateManager.set('Commande_Emplacement_Page_Web', \r\n            StateManager.buildEmplacementReference(rankId));\r\n        \r\n        this.updateEmplacementDisplay();\r\n        this.handleAvailabilityDisplay(e);\r\n        this.displayUploadedAdIfExists(e);\r\n        this.updateTariffDisplay(e);\r\n    },\r\n    \r\n    updateEmplacementDisplay() {\r\n        const emplacement = StateManager.get('Commande_Emplacement_Page_Web');\r\n        jQuery('#EmplacementAnnonceDataStep3').html(emplacement).css({'color': '#56BE50'});\r\n        console.log(\"Emplacement:\", emplacement);\r\n    },\r\n    \r\n    handleAvailabilityDisplay(e) {\r\n        const $espace = jQuery(e.target).closest('.EspacePublicitaireMobile');\r\n        const dispoText = $espace.find('.ChoisirEspacePublicitaireDisponibilite').text();\r\n        \r\n        if (dispoText.length > 46) {\r\n            const espacePublicitaireDispoFrom = dispoText.slice(-10);\r\n            console.log(\"espacePublicitaireDispoFrom:\", espacePublicitaireDispoFrom);\r\n            console.log(\"Date de debut:\", StateManager.get(\"Debut_de_campagne\"));\r\n        } else {\r\n            jQuery('#form-field-DebutCampagne').val(StateManager.get(\"Debut_de_campagne\"));\r\n        }\r\n    },\r\n    \r\n    displayUploadedAdIfExists(e) {\r\n        if (StateManager.get(\"FileReceived\") === 'Yes') {\r\n            jQuery('.VisualisationAnnonceMobile').hide();\r\n            \r\n            const espaceId = StateManager.get('espaceChoisi');\r\n            const $espace = document.querySelector(`[id=\"${espaceId}\"]`);\r\n            \r\n            jQuery($espace).find('.MessageAnnonceMobileTexte')\r\n                .html('Merci de choisir des dates de campagne<br>afin d\\'obtenir le tarif de cet espace publicitaire');\r\n            jQuery($espace).find('.VisualisationAnnonceMobile').show();\r\n        \r\n            const img = document.createElement('img');\r\n            img.src = StateManager.get('objectUrl');\r\n            img.style.width = 'auto';\r\n            img.style.height = 'auto';\r\n            img.style.maxWidth = '100%';\r\n            img.style.maxHeight = '200px';\r\n            \r\n            jQuery('.VisualisationAnnonceMobile').empty();\r\n            jQuery($espace).find('.VisualisationAnnonceMobile').append(img);\r\n        }\r\n    },\r\n    \r\n    updateTariffDisplay(e) {\r\n        jQuery('.TariftobedisplayedMobile').html('-');\r\n        const newTarif = StateManager.get('NewTarifformatted');\r\n        \r\n        if (newTarif && newTarif !== '-') {\r\n            jQuery(e.target).closest('.EspacePublicitaireMobile')\r\n                .find('.TariftobedisplayedMobile')\r\n                .html(newTarif);\r\n        }\r\n    },\r\n    \r\n    handleMobileCurrencyChange(e) {\r\n        event.preventDefault();\r\n        StateManager.setMultiple({\r\n            \"SelectionCatalogueOuAchat\": 'Catalogue',\r\n            \"selected_currency\": jQuery(e.currentTarget).val()\r\n        });\r\n        \r\n        jQuery('#form-field-selected_currency_2').val(StateManager.get(\"selected_currency\"));\r\n        console.log(\"selected currency:\", StateManager.get(\"selected_currency\"));\r\n        \r\n        setTimeout(() => {\r\n            jQuery(e.target).closest('.EspacePublicitaireMobile')\r\n                .find('.TariftobedisplayedMobile')\r\n                .html(StateManager.get(\"NewTarifformatted\"));\r\n        }, 500);\r\n    },\r\n    \r\n    initDesktopUI() {\r\n        StateManager.setMultiple({\r\n            \"FileReceived\": \"No\",\r\n            \"AdDisplayed\": \"No\"\r\n        });\r\n        jQuery('.MsgAdNotDisplayed').hide();\r\n    },\r\n    \r\n    showUploadProgress($dropZone) {\r\n        \/\/ Cacher les \u00e9l\u00e9ments\r\n        $dropZone.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed, span.ClassHdpCdp, .ClassRefEsp, .HideFormButton, .EspPubFormatMainContainer, .TexteMobileAnnonce')\r\n            .hide();\r\n        \r\n        \/\/ Afficher et styler le message de progression\r\n        var _uplMsg = 'Loading in progress <span class=\"dot-container\"><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><\/span>';\r\n        $dropZone.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed')\r\n            .show()\r\n            .html(_uplMsg)\r\n            .css({\r\n                'color': '#00ff19',\r\n                'background-color': 'white',\r\n                'padding': '12px 20px',\r\n                'border-radius': '6px',\r\n                'font-weight': '700',\r\n                'font-size': '18px',\r\n                'line-height': '1.4',\r\n                'display': 'inline-block',\r\n                'margin': '10px auto',\r\n                'text-align': 'center'\r\n            });\r\n        \r\n        \/\/ Cacher les autres \u00e9l\u00e9ments\r\n        $dropZone.closest('.droppable')\r\n            .find('.UploadIci, .EnvoiUlterieurTexte, .EnvoiUlterieurContainer')\r\n            .hide();\r\n            \r\n        $dropZone.closest('.droppable')\r\n            .find('.UploadFileConteneur')\r\n            .css({\r\n                'background-color': 'transparent'\r\n            });\r\n    },\r\n    \r\n    showFormatError($dropZone, message = 'Format de fichier incompatible') {\r\n        \/\/ \u2705 v2.4.6 : M\u00eame rendu overlay que le bloc jpeg \u2014 position absolute sur $dropZone\r\n        var _errId = 'fmt-error-msg-' + Date.now();\r\n        $dropZone.css('position', 'relative');\r\n        var _errHtml = '<div id=\"' + _errId + '\" style=\"'\r\n            + 'position:absolute;top:50px;left:50%;transform:translateX(-50%);width:auto;white-space:nowrap;'\r\n            + 'background:#fff;color:#FB5E2A;font-weight:700;font-size:13px;'\r\n            + 'text-align:center;padding:8px 10px;border-radius:6px;'\r\n            + 'border:2px solid #FB5E2A;box-sizing:border-box;'\r\n            + 'z-index:99999;line-height:1.4;'\r\n            + '\">' + message + '<\/div>';\r\n        $dropZone.append(_errHtml);\r\n        setTimeout(function() { jQuery('#' + _errId).remove(); }, 4000);\r\n    },\r\n    \r\n    updateAfterSuccessfulUpload($dropZone) {\r\n        jQuery('#errorMessageMobileText').hide();\r\n        \r\n        $dropZone.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed, span.ClassHdpCdp, .ClassRefEsp, .HideFormButton, .EspPubFormatMainContainer, .EnvoiUlterieurContainer')\r\n            .hide();\r\n        \r\n        \/\/ \u2705 Pas de margin-top:150px si d\u00e9p\u00f4t depuis miniature kit (d\u00e9j\u00e0 positionn\u00e9)\r\n        if (!window._dropFromMiniature) {\r\n            $dropZone.closest('.OrdiMobileConteneurClass')\r\n                .css({'margin-top': '150px', 'margin-bottom': '0px'});\r\n        }\r\n    },\r\n    \r\n    finalizeAdDisplay($dropZone) {\r\n        StateManager.setMultiple({\r\n            \"FileReceived\": \"Yes\",\r\n            \"PageWebDisplayed\": \"Yes\"\r\n        });\r\n        \r\n        jQuery('#MsgChoixPageWeb, #MsgInsererAnnonceConteneur').hide();\r\n        jQuery('#ChoixEspacePublicitaire')\r\n            .html('L\\'annonce est plac\u00e9e dans un espace publicitaire')\r\n            .show()\r\n            .css({'color': '#56BE50'});\r\n        \r\n        jQuery('#MsgPlacerAnnoncePosition').hide();\r\n        jQuery('#FonctionMenu4').show();\r\n        jQuery('.AnnonceData').html(\"Transmis\").css({'color': '#56BE50'});\r\n        \r\n        jQuery('#ProcederPaiementConteneur').hide();\r\n        jQuery('#ProcederPaiementTitreIconeUp').hide();\r\n        jQuery('#ProcederPaiementTitreIconeDown').show();\r\n        \r\n        jQuery('#message').remove();\r\n        \r\n        this.styleUploadedAd($dropZone);\r\n        this.adjustLayoutAfterUpload($dropZone);\r\n        \r\n        \/\/ \u2705 Mettre \u00e0 jour l'\u00e9tat de la checkbox \"R\u00e9server\" apr\u00e8s upload\r\n        FormatUIManager.updateReserverCheckboxState($dropZone.closest('.droppable'));\r\n    },\r\n    \r\n    styleUploadedAd($dropZone) {\r\n        const $container = $dropZone.closest('.OrdiMobileConteneurClass');\r\n        const $droppable = $dropZone.closest('.droppable');\r\n        \r\n        \/\/ \u2705 v1.19.5 : V\u00e9rifier si c'est une restauration via flag d\u00e9di\u00e9\r\n        const isRestoration = StateManager.get('_isAdRestoration') === 'Yes';\r\n        \r\n        $container\r\n            .find('.PositionReference, .TexteMobile, .EnvoiUlterieurContainer')\r\n            .hide();\r\n        \r\n        $container\r\n            .find('.AdUploadedTitle, .DimensionsMaximales')\r\n            .show();\r\n        \r\n        \/\/ \u2705 Bug 2 fix : montrer le conteneur parent + la croix (CroixResetAnnonceContainer cach\u00e9 par reset)\r\n        $droppable.find('.CroixResetAnnonceContainer').show();\r\n        $droppable.find('#CroixResetAnnonce').show();\r\n        \r\n        \/\/ \u2705 v2.2 : Marquer le droppable comme occup\u00e9 pour qu'Entete le skip\r\n        $droppable.attr('data-via-ad-loaded', 'true');\r\n        \r\n        \/\/ \u2705 v2.0.11 : AdUploadedTitle ne doit pas bloquer le touch sur doc-preview-readmore (mobile)\r\n        $container.find('.AdUploadedTitle').css('pointer-events', 'none');\r\n        \r\n        \/\/ \u2705 #CroixResetAnnonce au-dessus de tous les conteneurs superpos\u00e9s\r\n        $container.find('#CroixResetAnnonce').css({\r\n            'position': 'relative',\r\n            'z-index': '9999'\r\n        });\r\n        \r\n        \/\/ \u2705 Desktop : les conteneurs superpos\u00e9s bloquent la croix \u2014 les rendre transparents aux clics\r\n        if (!UIManager.isMobile()) {\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css('pointer-events', 'none');\r\n            \/\/ R\u00e9activer les \u00e9l\u00e9ments interactifs\r\n            $container.find('#CroixResetAnnonce').css('pointer-events', 'auto');\r\n            $dropZone.closest('#PopUpMessageAchattest').css('pointer-events', 'auto'); \/\/ drag annonce\r\n        }\r\n        \r\n        \/\/ \u2705 v2.4.3 : Sur mobile, masquer titre et logo drag quand annonce d\u00e9pos\u00e9e dans Ele0A\r\n        if (UIManager.isMobile()) {\r\n            if ($droppable.attr('id') === 'Ele0A') {\r\n                $droppable.find('#ChoixEspacePublicitaireTexte').hide();\r\n                $droppable.find('#Ele0ADragHandle').hide();\r\n                \/\/ \u2705 v2.4.12 : UploadFileConteneur a pointer-events:none \u2192 forcer auto sur la croix\r\n                $droppable.find('.CroixResetAnnonceContainer')[0] && $droppable.find('.CroixResetAnnonceContainer')[0].style.setProperty('pointer-events', 'auto', 'important');\r\n                $droppable.find('#CroixResetAnnonce')[0] && $droppable.find('#CroixResetAnnonce')[0].style.setProperty('pointer-events', 'auto', 'important');\r\n            }\r\n        }\r\n        \r\n        jQuery(\".HTMLUploadfileConteneur\").css({\r\n            'border': 'none',\r\n            'background-color': 'transparent'\r\n        });\r\n        \r\n        \/\/ \u2705 v2.4.12 : Retirer le liser\u00e9 envoi diff\u00e9r\u00e9 (#UploadFileConteneur) si pr\u00e9sent\r\n        \/\/ (le d\u00e9p\u00f4t d'une annonce cr\u00e9e son propre liser\u00e9 sur .HTMLUploadfileConteneur)\r\n        var $_ufcEd = $dropZone.closest('.droppable').find('#UploadFileConteneur');\r\n        if ($_ufcEd[0]) {\r\n            $_ufcEd[0].style.removeProperty('box-shadow');\r\n            $_ufcEd[0].style.removeProperty('box-sizing');\r\n            if (UIManager.isMobile()) {\r\n                $_ufcEd[0].style.removeProperty('transform');\r\n                $_ufcEd[0].style.removeProperty('transform-origin');\r\n            }\r\n        }\r\n        \r\n        $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n            'box-shadow': 'inset 0 0 0 2px #00FF19',  \/\/ \u2705 v2.4.5 : inset \u2192 jamais clipp\u00e9 par overflow:hidden\r\n            'background-color': 'white',\r\n            'box-sizing': 'border-box',\r\n            'overflow': 'hidden'\r\n        });\r\n        \r\n        \/\/ \u2705 v2.0.9 : Fix mobile \u2014 r\u00e9duire le scale pour que le liser\u00e9 vert soit visible\r\n        \/\/ \u2705 Pas de scale si annonce d\u00e9pos\u00e9e depuis la miniature kit (d\u00e9j\u00e0 aux bonnes dimensions)\r\n        \/\/ \u2705 v2.4.9 : Pas de scale si AchatEspaceCall=Yes (drop depuis miniature dans iframe)\r\n        \/\/ \u2705 data-kit-drop : marqueur DOM pos\u00e9 par kitAdCreated, r\u00e9siste \u00e0 l'async\r\n        var _fromKitDrop = $droppable[0] ? $droppable[0].getAttribute('data-kit-drop') === 'true' : false;\r\n        if (_fromKitDrop) { window._dropFromMiniature = true; } \/\/ sync le flag window\r\n        var _fromMiniature = window._dropFromMiniature || _fromKitDrop;\r\n        var _fromAchat = StateManager.get('AchatEspaceCall') === 'Yes';\r\n        if (UIManager.isMobile() && !_fromMiniature && !_fromAchat) {\r\n            $dropZone.closest('.UploadFileConteneur').css({\r\n                'transform': 'scale(1.35)',\r\n                'transform-origin': 'top center'\r\n            });\r\n            \/\/ \u2705 v2.4.11 : Corps de page mobile \u2014 le .ToBeHidden clippe le scale(1.35) c\u00f4t\u00e9 droit\r\n            \/\/ \u2192 overflow:visible pour que le liser\u00e9 vert soit visible sur les 4 c\u00f4t\u00e9s\r\n            $dropZone.closest('.ToBeHidden').css('overflow', 'visible');\r\n        }\r\n        \r\n        \/\/ \u2705 v2.2 : Sur restauration, Entete a d\u00e9j\u00e0 positionn\u00e9 le droppable correctement\r\n        \/\/ et est emp\u00each\u00e9 de le retoucher (data-via-ad-loaded). On ne touche pas aux marges.\r\n        \/\/ Sur premier upload, on applique les marges normalement.\r\n        \/\/ \u2705 Pas de marges si d\u00e9p\u00f4t depuis miniature kit (dimensions naturelles conserv\u00e9es)\r\n        if (!isRestoration && !_fromMiniature) {\r\n            if ($container.data('orig-mb') === undefined) {\r\n                $container.data('orig-mb', parseInt($container.css('margin-bottom')) || 0);\r\n            }\r\n            if ($droppable.data('orig-mt') === undefined) {\r\n                $droppable.data('orig-mt', parseInt($droppable.css('margin-top')) || 0);\r\n            }\r\n            var _isDocPreview = $dropZone.find('.doc-preview-container').length > 0;\r\n            var _marginAdd = _isDocPreview ? 60 : 130;\r\n            var _marginReduce = _isDocPreview ? 60 : 130;\r\n            $container.css({\r\n                'margin-bottom': ($container.data('orig-mb') + _marginAdd) + 'px'\r\n            });\r\n            $droppable.css({\r\n                'margin-top': ($droppable.data('orig-mt') - _marginReduce + 75) + 'px'\r\n            });\r\n        } else {\r\n            \/\/ \u2705 Sur restauration, ajouter 50px en dessous pour \u00e9viter que le contenu soit trop coll\u00e9\r\n            var _curMb = parseInt($container.css('margin-bottom')) || 0;\r\n            $container.css('margin-bottom', (_curMb + 50) + 'px');\r\n        }\r\n        \r\n        \/\/ \u2705 Masquer .PositionEspacePublicitaireContainer et l'ancien .ReserverContainer\r\n        $droppable.find('.PositionEspacePublicitaireContainer').hide();\r\n        $droppable.find('.ReserverContainer').hide();\r\n        \r\n        \/\/ \u2705 Supprimer tout ancien bouton dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ \u2705 v2.1.2 : Cr\u00e9er le bouton R\u00e9server m\u00eame lors d'une restauration\r\n        if (isRestoration) {\r\n            console.log('\ud83d\udd04 Restauration d\u00e9tect\u00e9e - affichage bouton R\u00e9server + DeplaceAnnonce');\r\n            $droppable.find('.DeplaceAnnonce').show();\r\n            \/\/ S'assurer que FileReceived est d\u00e9fini pour la validation\r\n            StateManager.set('FileReceived', 'Yes');\r\n            \/\/ Cocher automatiquement SEULEMENT si c'est une restauration de commande r\u00e9serv\u00e9e (pas pendingAd)\r\n            var _isPendingAdRestore = sessionStorage.getItem('_pendingAdRestoration') === 'Yes';\r\n            if (!_isPendingAdRestore) {\r\n                var _isReservedRestore = sessionStorage.getItem('_isReservedRestoration') === 'Yes';\r\n                setTimeout(function() {\r\n                    var $checkbox = $droppable.find('.reserver-dynamic-checkbox');\r\n                    if ($checkbox.length && _isReservedRestore) {\r\n                        $checkbox.prop('checked', true);\r\n                        $droppable.find('.reserver-dynamic-label').text('Espace publicitaire r\u00e9serv\u00e9').css('color', 'rgb(62, 170, 19)');\r\n                        console.log('\u2705 R\u00e9server coch\u00e9 automatiquement (restauration commande r\u00e9serv\u00e9e)');\r\n                    }\r\n                    sessionStorage.removeItem('_isReservedRestoration');\r\n                    StateManager.set('_isAdRestoration', 'No');\r\n                    \/\/ \u2705 v2.4.7 : updateReserverCheckboxState APR\u00c8S avoir coch\u00e9 la checkbox\r\n                    \/\/ (l'appel synchrone ligne 614 intervient avant le cocher \u2192 label incorrect)\r\n                    if (typeof FormatUIManager !== 'undefined') {\r\n                        FormatUIManager.updateReserverCheckboxState($droppable);\r\n                    }\r\n                }, 150);\r\n            } else {\r\n                \/\/ pendingAd : ne pas cocher, ne pas envoyer au parent\r\n                console.log('\u2705 pendingAd restaur\u00e9 \u2014 R\u00e9server NON coch\u00e9');\r\n                sessionStorage.removeItem('_pendingAdRestoration');\r\n                StateManager.set('_isAdRestoration', 'No');\r\n            }\r\n        }\r\n        \r\n        \/\/ \u2705 Supprimer tout bouton R\u00e9server existant avant insertion (\u00e9vite doublons sur restauration)\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ \u2705 Cr\u00e9er le bouton \"R\u00e9server\" dynamique avec id unique pour \u00e9viter conflit label\/for Elementor\r\n        const _rankId = $droppable.attr('id') || ('drop_' + Date.now());\r\n        const _cbId = 'reserver-cb-' + _rankId;\r\n        const reserverHTML = `\r\n            <div class=\"reserver-dynamic-container\">\r\n                <span class=\"reserver-dynamic-option\">\r\n                    <input type=\"checkbox\" id=\"${_cbId}\" value=\"R\u00e9server cet espace publicitaire\" \r\n                           class=\"reserver-dynamic-checkbox\"\r\n                           name=\"form_fields[ReserverEspacePublicitaire]\">\r\n                    <span class=\"reserver-dynamic-label\">R\u00e9server cet espace publicitaire<\/span>\r\n                <\/span>\r\n            <\/div>\r\n        `;\r\n        \r\n        \/\/ \u2705 Ins\u00e9rer juste avant .DeplaceAnnonceText (position stable)\r\n        const $anchor = $droppable.find('.DeplaceAnnonceText');\r\n        if ($anchor.length) {\r\n            $anchor.before(reserverHTML);\r\n            $anchor.prev('.reserver-dynamic-container').css('margin-bottom', '-40px');\r\n            if (!UIManager.isMobile()) {\r\n                $anchor.prev('.reserver-dynamic-container').find('.reserver-dynamic-label').css({'font-size': '20px', 'font-weight': '700'});\r\n            }\r\n        } else {\r\n            $droppable.after(reserverHTML);\r\n            const $btn = $droppable.next('.reserver-dynamic-container');\r\n            $btn.css('margin-top', UIManager.isMobile() ? '-10px' : '-140px');\r\n        }\r\n        \r\n        console.log('\u2705 Bouton \"R\u00e9server\" dynamique cr\u00e9\u00e9');\r\n    },\r\n    \r\n    adjustLayoutAfterUpload($dropZone) {\r\n        console.log('\ud83d\udcf1 adjustLayoutAfterUpload \u2014 isMobile():', this.isMobile(), 'outerWidth:', window.outerWidth);\r\n        if (this.isMobile()) {\r\n            this.adjustMobileLayout($dropZone);\r\n            \r\n            \/\/ Repositionner le bouton R\u00e9server APR\u00c8S les ajustements de layout\r\n            setTimeout(() => {\r\n                const $droppable = $dropZone.closest('.droppable');\r\n                const $btn = $droppable.find('.reserver-dynamic-container').add($droppable.next('.reserver-dynamic-container')).first();\r\n                const $lisere = $droppable.find('.HTMLUploadfileConteneur');\r\n                if ($btn.length && $lisere.length) {\r\n                    const lisereBottom = $lisere[0].getBoundingClientRect().bottom;\r\n                    const btnTop = $btn[0].getBoundingClientRect().top;\r\n                    const offset = lisereBottom - btnTop - 48;\r\n                    \r\n                    \/\/ 15px suppl\u00e9mentaires pour homepage et articles\r\n                    let extraOffset = 0;\r\n                    const isHomepage = window.location.pathname === \"\/\" || window.location.pathname === \"\/en\/\";\r\n                    const isSectorPage = $('body').hasClass('page');\r\n                    if (isHomepage) {\r\n                        extraOffset = 13;\r\n                    }\r\n                    if (!isSectorPage) {\r\n                        extraOffset = 15;\r\n                    }\r\n                    \r\n                    \/\/ \u2705 v2.0.9 : +4px pour documents (communiqu\u00e9\/interview\/PDF) avec pr\u00e9sentation HTML\r\n                    if ($droppable.find('.doc-preview-container:visible').length > 0) {\r\n                        extraOffset += 4;\r\n                    }\r\n                    \r\n                    $btn.css({\r\n                        'margin-top': (offset + extraOffset + 20) + 'px',\r\n                        'margin-bottom': (-(offset + extraOffset) - 100) + 'px'\r\n                    });\r\n                    console.log('\ud83d\udcd0 Repositionnement mobile R\u00e9server:', { lisereBottom, btnTop, offset });\r\n                }\r\n            }, 50);\r\n        } else {\r\n            this.adjustDesktopLayout($dropZone);\r\n        }\r\n    },\r\n    \r\n    adjustMobileLayout($dropZone) {\r\n        console.log('\ud83d\udcf1 adjustMobileLayout START');\r\n        console.log('\ud83d\udcf1 AchatEspaceCall:', StateManager.get(\"AchatEspaceCall\"));\r\n        console.log('\ud83d\udcf1 PageAjoutModifAnnonce:', StateManager.get(\"PageAjoutModifAnnonce\"));\r\n        console.log('\ud83d\udcf1 window===window.top:', window === window.top);\r\n        console.log('\ud83d\udcf1 pathname:', location.pathname);\r\n        \r\n        const $droppable = $dropZone.closest('.droppable');\r\n        \r\n        \/\/ \u2705 v2.4.3 : Masquer les textes position\/label\/r\u00e9f\u00e9rence (comme sur desktop)\r\n        $droppable\r\n            .find('.PositionEspacePublicitaire, .ReferenceEspacePublicitaire, .ChoisirEspacePublicitaireDisponibiliteConteneur')\r\n            .hide();\r\n        \r\n        \/\/ \u2705 v2.6 : Renseigner .PositionEspacePublicitaire sur mobile (manquait vs desktop)\r\n        (function() {\r\n            var _rankPosMob = StateManager.get('Rank_Emplacement_Page_Web') || $droppable.attr('id') || '';\r\n            var _posLibMob = PreviewRenderer._getPositionLibelle(_rankPosMob);\r\n            if (_posLibMob) {\r\n                $droppable\r\n                    .find('.PositionEspacePublicitaire')\r\n                    .text(_posLibMob)\r\n                    .each(function() {\r\n                        this.style.setProperty('display', 'block', 'important');\r\n                    });\r\n            }\r\n        })();\r\n        \r\n        \/\/ \u2705 Scop\u00e9 au $dropZone courant (\u00e9vite d'affecter les autres espaces pub)\r\n        $dropZone.closest('.droppable').find('#CroixResetAnnonce').css({'zoom': '75%'});\r\n\r\n        \/\/ \u2705 v2.4.3 : Remonter la croix reset sur mobile (override margin-top Elementor)\r\n        \/\/ \u2705 v2.4.5 : Poser aussi margin-right ici (Entete.txt ne l'atteint pas pour Ele0A)\r\n        var _croixContainer = $dropZone.closest('.OrdiMobileConteneurClass').find('.CroixResetAnnonceContainer')[0];\r\n        if (_croixContainer) {\r\n            var _isEle0ACroix = ($dropZone.closest('.droppable').attr('id') === 'Ele0A');\r\n            var _mtCroix = StateManager.get(\"PageAjoutModifAnnonce\") === 'Yes' ? '-88px' : '24px';\r\n            \/\/ Ele0A : +40px vers le bas, +15px vers la gauche (margin-right) par rapport \u00e0 Ele1A\r\n            \/\/ Ele0A : margin-top identique aux autres espaces (pas de d\u00e9calage suppl\u00e9mentaire)\r\n            _croixContainer.style.setProperty('margin-top', _mtCroix, 'important');\r\n            _croixContainer.style.setProperty('margin-right', _isEle0ACroix ? '17px' : '12px', 'important');\r\n        }\r\n        \r\n        var _isMiniatureAdj = window._dropFromMiniature;\r\n        window._dropFromMiniature = false;\r\n\r\n        if (_isMiniatureAdj && window.outerWidth <= 1000) {\r\n            \/\/ \u2705 Miniature doc-preview MOBILE : ajuster HTMLUploadfileConteneur \u00e0 la hauteur du contenu\r\n            \/\/ et neutraliser tous les margins Elementor qui d\u00e9calent le $dropZone hors du parent\r\n            var _isDocPreviewMob = $dropZone.find('.doc-preview-container').length > 0;\r\n            var _docH = _isDocPreviewMob ? 144 : 115;\r\n            $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n                'height':     _docH + 'px',\r\n                'min-height': _docH + 'px',\r\n                'max-height': _docH + 'px',\r\n                'margin-top': '-55px',\r\n                'margin-bottom': '0px',\r\n                'overflow': 'hidden'\r\n            });\r\n            $dropZone.css({'margin-top': '0px', 'margin-bottom': '0px', 'top': '0px', 'height': (_docH - 6) + 'px'});\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css({'margin-top': '65px', 'margin-bottom': '-10px'});\r\n            \/\/ \u2705 v2.4.9 : Doc-preview \u2014 overflow:visible pour que le liser\u00e9 du haut ne soit pas clipp\u00e9\r\n            if (_isDocPreviewMob) {\r\n                $dropZone.closest('.OrdiMobileConteneurClass').css('overflow', 'visible');\r\n                $dropZone.closest('.OrdiMobileConteneurClass').parent().css('overflow', 'visible');\r\n            }\r\n            \/\/ \u2705 v2.4.9 : Ele0A popup mobile \u2014 neutraliser translateY(-32px) pos\u00e9 par Entete sur EnvoiUlterieurTexte\r\n            var _isEle0AMob = ($dropZone.closest('.droppable').attr('id') === 'Ele0A');\r\n            if (_isEle0AMob) {\r\n                var $_euTxt = $dropZone.closest('.droppable').find('.EnvoiUlterieurTexte');\r\n                if ($_euTxt[0]) {\r\n                    $_euTxt[0].style.setProperty('transform', 'translateY(0px)', 'important');\r\n                    $_euTxt[0].style.setProperty('margin-top', '0px', 'important');\r\n                }\r\n            }\r\n            \/\/ \u2705 v2.4.12 : AchatEspaceCall=Yes \u2192 override margins (m\u00eame correction que pour upload direct)\r\n            if (StateManager.get('AchatEspaceCall') === 'Yes') {\r\n                $dropZone.css({'margin-top': '0px', 'margin-bottom': '0px', 'top': '0px'});\r\n                var _docHAchatMini = _isDocPreviewMob ? 150 : 112;\r\n                $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n                    'margin-top': '70px',\r\n                    'margin-bottom': '35px',\r\n                    'min-height': _docHAchatMini + 'px',\r\n                    'height': _isDocPreviewMob ? _docHAchatMini + 'px' : '',\r\n                    'max-height': _isDocPreviewMob ? _docHAchatMini + 'px' : ''\r\n                });\r\n                console.log('\ud83d\udcf1 [miniature] AchatEspaceCall=Yes OVERRIDE: mt=70px | docPreview:', _isDocPreviewMob);\r\n            }\r\n            return;\r\n        }\r\n        \/\/ \u2705 v2.4.10 : Miniature DESKTOP \u2192 layout normal appliqu\u00e9 ci-dessous\r\n        if (_isMiniatureAdj) {\r\n            \/\/ Pas de overflow:hidden \u2014 le liser\u00e9 box-shadow inset doit rester visible\r\n        }\r\n\r\n        $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n            'min-height': '112px',\r\n            'margin-top': '-85px',\r\n            \/\/ \u2705 v2.4.10 : Miniature desktop \u2014 pas de margin-bottom excessif qui fait grandir le droppable\r\n            'margin-bottom': _isMiniatureAdj ? '0px' : '20px' \/\/ \u2705 v2.6 : 195px \u2192 59px \u2192 20px (\u00f73) espace sous checkbox R\u00e9server\r\n        });\r\n        console.log('\ud83d\udcf1 HTMLUploadfileConteneur margins set: mt=-85px mb=20px, el found:', $dropZone.closest('.HTMLUploadfileConteneur').length);\r\n        \r\n        $dropZone.css({\r\n            'margin-top': '-50px',\r\n            'margin-bottom': '-140px'\r\n        });\r\n        \r\n        $dropZone.closest('.OrdiMobileConteneurClass').css({\r\n            'margin-top': '65px',\r\n            'margin-bottom': '-10px'\r\n        });\r\n        console.log('\ud83d\udcf1 OrdiMobile margins set: mt=65px mb=-10px');\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            \/\/ \u2705 v2.4.12 : Reset $dropZone margins (les -50px\/-140px tirent le contenu vers le haut dans l'iframe)\r\n            \/\/ Pour doc-preview (Communiqu\u00e9\/Interview), la hauteur est plus grande \u2192 ajuster min-height\r\n            var _isDocPreviewAchat = $dropZone.find('.doc-preview-container').length > 0;\r\n            var _docHAchat = _isDocPreviewAchat ? 150 : 112;\r\n            $dropZone.css({'margin-top': '0px', 'margin-bottom': '0px', 'top': '0px'});\r\n            $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n                \/\/ \u2705 v2.4.13 : Miniature desktop \u2192 +40px suppl\u00e9mentaires pour compenser le d\u00e9calage\r\n                'margin-top': _isMiniatureAdj ? '110px' : '70px',\r\n                'margin-bottom': '35px',\r\n                'min-height': _docHAchat + 'px',\r\n                'height': _isDocPreviewAchat ? _docHAchat + 'px' : '',\r\n                'max-height': _isDocPreviewAchat ? _docHAchat + 'px' : ''\r\n            });\r\n            console.log('\ud83d\udcf1 AchatEspaceCall=Yes OVERRIDE: mt=' + (_isMiniatureAdj ? '110px' : '70px') + ' | docPreview:', _isDocPreviewAchat, '| h:', _docHAchat);\r\n        }\r\n        \r\n        if (location.pathname === '\/annonce' || location.pathname === '\/annonce\/') {\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css({'margin-top': '70px'});\r\n        }\r\n        \r\n        if (window === window.top) {\r\n            console.log('\ud83d\udcf1 window===window.top OVERRIDE droppable margins');\r\n            $dropZone.closest('.droppable').css({\r\n                'margin-top': '-100px',\r\n                'margin-bottom': '-100px'\r\n            });\r\n            $dropZone.closest('#UploadFileConteneur').css({'width': '80%'});\r\n        }        \r\n    },\r\n    \r\n    adjustDesktopLayout($dropZone) {\r\n        const emplacement = StateManager.get('Commande_Emplacement_Page_Web');\r\n        const $droppable = $dropZone.closest('.droppable');\r\n        \/\/ \u2705 v2.4.13 : Lire et resetter _dropFromMiniature ici aussi (desktop)\r\n        var _fromMiniatureDesktop = window._dropFromMiniature || ($droppable[0] ? $droppable[0].getAttribute('data-kit-drop') === 'true' : false);\r\n        window._dropFromMiniature = false;\r\n        \/\/ \u2705 Nettoyer data-kit-drop apr\u00e8s lecture\r\n        if ($droppable[0]) { $droppable[0].removeAttribute('data-kit-drop'); }\r\n        \r\n        \/\/ \u2705 Masquer les textes enfants (position, label, r\u00e9f\u00e9rence) sans toucher au conteneur\r\n        $droppable\r\n            .find('.PositionEspacePublicitaire, .ReferenceEspacePublicitaire, .ChoisirEspacePublicitaireDisponibiliteConteneur > div > .elementor-widget-text-editor')\r\n            .hide();\r\n        \r\n        \/\/ \u2705 +15px sur .droppable \u2014 sauf si drop depuis miniature (dimensions naturelles)\r\n        if (!_fromMiniatureDesktop) {\r\n            const currentMt = parseInt($droppable.css('margin-top')) || 0;\r\n            $droppable.css('margin-top', (currentMt + 15) + 'px');\r\n        } else {\r\n            \/\/ \u2705 v2.4.13 : Drop depuis miniature Kit \u2014 d\u00e9caler de 30px vers le bas\r\n            const currentMt = parseInt($droppable.css('margin-top')) || 0;\r\n            \/\/ \u2705 Homepage : -20px (annonce trop basse sur r\u00e9gie) \u2014 autres pages : +70px\r\n            var _mtOffsetMini = (window.location.pathname === '\/' || window.location.pathname === '\/en\/' || window.location.pathname === '\/fr\/') ? -20 : 70;\r\n            $droppable.css('margin-top', (currentMt + _mtOffsetMini) + 'px');\r\n        }\r\n        \r\n        $dropZone.closest('.OrdiMobileConteneurClass')\r\n            .find('.RefEspacePublicitaire')\r\n            .html(emplacement)\r\n            .attr('id', 'RefEspacePublicitaire')\r\n            .each(function() {\r\n                \/\/ \u2705 Forcer aussi le parent .DeplaceAnnonce visible (display:none !important inline)\r\n                var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                this.style.setProperty('display', 'block', 'important');\r\n            });\r\n        \/\/ \u2705 v2.4.5 : Renseigner et afficher .PositionEspacePublicitaire\r\n        (function() {\r\n            var _rankPos = StateManager.get('Rank_Emplacement_Page_Web') || $droppable.attr('id') || '';\r\n            var _posLib = PreviewRenderer._getPositionLibelle(_rankPos);\r\n            if (_posLib) {\r\n                $dropZone.closest('.OrdiMobileConteneurClass')\r\n                    .find('.PositionEspacePublicitaireDeplacer')\r\n                    .text(_posLib)\r\n                    .each(function() {\r\n                        var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                        if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                        this.style.setProperty('display', 'block', 'important');\r\n                    });\r\n            }\r\n        })();\r\n        \r\n        if (window.location.pathname === \"\/\" || window.location.pathname === \"\/en\/\") {\r\n            \/\/ \u2705 v2.4.10 : top selon contexte \u2014 espaces hors .remainingContent d\u00e9calent de 60px, ceux dedans de 20px\r\n            var _inRemainingContent = $dropZone.closest('.remainingContent').length > 0;\r\n            var _topOffsetHP = _inRemainingContent ? '20px' : '100px';\r\n            $dropZone.closest('.ToBeHidden')\r\n                .css('top', _topOffsetHP)\r\n                .css('min-height', '300px');\r\n            \/\/ NB : pas de overflow:hidden ici \u2014 le liser\u00e9 vert (box-shadow inset sur HTMLUploadfileConteneur)\r\n            \/\/ doit rester visible sur les 4 c\u00f4t\u00e9s\r\n        }\r\n        \r\n        \/\/ \u2705 Toutes pages desktop : rendre le parent du droppable non-clippant\r\n        \/\/ Le bouton R\u00e9server est ins\u00e9r\u00e9 apr\u00e8s .droppable avec margin-top n\u00e9gatif \u2014\r\n        \/\/ overflow:hidden sur le parent Elementor le masque sinon.\r\n        $droppable.parent().css('overflow', 'visible');\r\n        \r\n        if (location.pathname === '\/annonce' || location.pathname === '\/annonce\/') {\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css({'margin-top': '0px'});\r\n        }\r\n    }\r\n};\r\n\r\n\/**\r\n * \u2705 Module de gestion des formats et du titre .SelectionFormatTitre\r\n *\/\r\nconst FormatUIManager = {\r\n    \r\n    \/**\r\n     * V\u00e9rifie si un format est s\u00e9lectionn\u00e9 dans un espace publicitaire\r\n     * V\u00e9rifie le background-color OU le sessionStorage (format venant de l'accord\u00e9on)\r\n     *\/\r\n    hasSelectedFormat($element) {\r\n        const $droppable = $element.closest('.droppable');\r\n        const isEle0A = $droppable.attr('id') === 'Ele0A';\r\n        if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n            if (isEle0A) {\r\n                \/\/ \u2705 v2.3.4 : Ele0A popup \u2014 vrai seulement si un format sous-jacent (hors FormatIdPopUp) est s\u00e9lectionn\u00e9\r\n                var _hasDomFmt = $droppable.find('.EspPubFormatContainer').not('.FormatIdPopUp').toArray().some(el => {\r\n                    return $(el).css('background-color') === 'rgb(255, 255, 255)';\r\n                });\r\n                if (_hasDomFmt) return true;\r\n                \/\/ \u2705 v2.4.5 : Fallback sessionStorage \u2014 DOM pas encore mis \u00e0 jour (timing MutationObserver)\r\n                return !!sessionStorage.getItem('FormatSelect');\r\n            }\r\n            \/\/ Autres espaces en mode popup \u2192 toujours vrai\r\n            return true;\r\n        }\r\n        const hasWhiteBg = $droppable.find('.EspPubFormatContainer').toArray().some(el => {\r\n            return $(el).css('background-color') === 'rgb(255, 255, 255)';\r\n        });\r\n        if (hasWhiteBg) return true;\r\n        \/\/ \u2705 v1.16.0 : Fallback sessionStorage Formatchoisi\r\n        if (sessionStorage.getItem('Formatchoisi') === 'Yes') return true;\r\n        \/\/ \u2705 v2.4.5 : Fallback FormatSelect \u2014 cas du chargement initial avec format d\u00e9j\u00e0 s\u00e9lectionn\u00e9\r\n        \/\/ (Formatchoisi peut \u00eatre remis \u00e0 No au chargement, mais FormatSelect persiste)\r\n        if (sessionStorage.getItem('FormatSelect')) return true;\r\n        \/\/ \u2705 v2.4.9 : Fallback _FormatSelectApplied \u2014 survit au clear de yearbook-media.js init\r\n        return !!sessionStorage.getItem('_FormatSelectApplied');\r\n    },\r\n    \r\n    \/**\r\n     * Met \u00e0 jour la couleur du titre .SelectionFormatTitre\r\n     * Blanc si un format est s\u00e9lectionn\u00e9, rouge #FB5E2A sinon\r\n     *\/\r\n    updateTitleColor($droppable) {\r\n        \/\/ \u2705 v2.4.5 : Ele0A \u2014 ne jamais afficher SelectionFormatTitre\r\n        if (sessionStorage.getItem('PopUpChoice') === 'Yes' && $droppable.attr('id') === 'Ele0A') {\r\n            $droppable.find('.SelectionFormatTitre').hide();\r\n            $droppable.find('.SelectionFormatTitreBlanc').show();\r\n            return;\r\n        }\r\n\r\n        if (this.hasSelectedFormat($droppable)) {\r\n            $droppable.find('.SelectionFormatTitre').hide();\r\n            $droppable.find('.SelectionFormatTitreBlanc').show();\r\n            console.log('\u2705 SelectionFormatTitreBlanc affich\u00e9 (format s\u00e9lectionn\u00e9)');\r\n        } else {\r\n            $droppable.find('.SelectionFormatTitre').show();\r\n            $droppable.find('.SelectionFormatTitreBlanc').hide();\r\n            console.log('\u26a0\ufe0f SelectionFormatTitre affich\u00e9 (aucun format s\u00e9lectionn\u00e9)');\r\n        }\r\n    },\r\n    \r\n    \/**\r\n     * Flash visuel sur le titre pour indiquer qu'un format est requis\r\n     *\/\r\n    flashTitle($element) {\r\n        const $droppable = $element.closest('.droppable');\r\n        const $titre = $droppable.find('.SelectionFormatTitre');\r\n        if (!$titre.length) return;\r\n        \r\n        \/\/ Flash rouge rapide 3 fois\r\n        let count = 0;\r\n        const originalColor = $titre.css('color');\r\n        \r\n        const flash = setInterval(() => {\r\n            $titre.css('color', count % 2 === 0 ? '#FF0000' : '#FB5E2A');\r\n            count++;\r\n            if (count >= 6) {\r\n                clearInterval(flash);\r\n                $titre.css('color', '#FB5E2A');\r\n            }\r\n        }, 250);\r\n        \r\n        console.log('\u26a0\ufe0f Flash titre format - action bloqu\u00e9e (aucun format s\u00e9lectionn\u00e9)');\r\n    },\r\n    \r\n    \/**\r\n     * Met \u00e0 jour l'\u00e9tat de la checkbox \"R\u00e9server cet espace publicitaire\"\r\n     * La checkbox est activable si : format s\u00e9lectionn\u00e9 ET (fichier d\u00e9pos\u00e9 OU envoi diff\u00e9r\u00e9)\r\n     *\/\r\n    updateReserverCheckboxState($droppable) {\r\n        \/\/ \u2705 Chercher le label : dynamique ou Elementor statique\r\n        let $label = null;\r\n        let $container = null;\r\n        \r\n        \/\/ 1. Bouton dynamique dans le droppable\r\n        $container = $droppable.find('.reserver-dynamic-container');\r\n        if (!$container.length) {\r\n            $container = $droppable.next('.reserver-dynamic-container');\r\n        }\r\n        if (!$container.length) {\r\n            \/\/ Mobile : checkbox attach\u00e9e au body avec data-droppable-id\r\n            $container = $('body > .reserver-dynamic-container[data-droppable-id=\"' + $droppable.attr('id') + '\"]');\r\n        }\r\n        if (!$container.length) {\r\n            $container = $('body > .reserver-dynamic-container');\r\n        }\r\n        \r\n        if ($container.length) {\r\n            $label = $container.find('.reserver-dynamic-label');\r\n            $container.find('.reserver-dynamic-option, .elementor-field-option').css('opacity', '1');\r\n        }\r\n        \r\n        \/\/ 2. Bouton Elementor statique - chercher dans le droppable puis globalement\r\n        let $reserverStatique = $droppable.find('.elementor-field-group-ReserverEspacePublicitaire label');\r\n        if (!$reserverStatique.length) {\r\n            $reserverStatique = $droppable.find('label[for^=\"form-field-ReserverEspacePublicitaire\"]');\r\n        }\r\n        if (!$reserverStatique.length) {\r\n            \/\/ Fallback global : le formulaire peut \u00eatre en dehors du droppable\r\n            $reserverStatique = $('.elementor-field-group-ReserverEspacePublicitaire .elementor-field-option label');\r\n        }\r\n        \r\n        const hasFormat = this.hasSelectedFormat($droppable);\r\n        const hasFile = StateManager.get('FileReceived') === 'Yes';\r\n        const hasEnvoiDiffere = $droppable.find('input[name*=\"EnvoiUlterieur\"]:checked').length > 0;\r\n        \r\n        const canReserve = hasFormat && (hasFile || hasEnvoiDiffere);\r\n        \r\n        \/\/ \u2705 Si la checkbox R\u00e9server est coch\u00e9e \u2192 label vert \"Espace publicitaire r\u00e9serv\u00e9\"\r\n        const isChecked = $droppable.find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').prop('checked') ||\r\n                          ($container.length && $container.find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').prop('checked'));\r\n        \/\/ \u2705 v2.4.7 : Signal de restauration r\u00e9serv\u00e9e \u2014 checkbox pas encore coch\u00e9e (setTimeout 150ms)\r\n        \/\/             mais on sait d\u00e9j\u00e0 que l'espace est r\u00e9serv\u00e9 \u2192 traiter comme coch\u00e9\r\n        const _isReservedRestoration = sessionStorage.getItem('_isReservedRestoration') === 'Yes';\r\n        const isCheckedOrReservedRestore = isChecked || _isReservedRestoration;\r\n        \r\n        if ($label && $label.length) {\r\n            if (isCheckedOrReservedRestore) {\r\n                $label.text('Espace publicitaire r\u00e9serv\u00e9').css('color', 'rgb(62, 170, 19)');\r\n            } else {\r\n                $label.text('R\u00e9server cet espace publicitaire').css('color', canReserve ? '#FB5E2A' : '');\r\n            }\r\n        }\r\n        if ($reserverStatique.length) {\r\n            if (isCheckedOrReservedRestore) {\r\n                $reserverStatique.attr('style', 'color: rgb(62, 170, 19) !important;');\r\n            } else if (canReserve) {\r\n                $reserverStatique.attr('style', 'color: #FB5E2A !important;');\r\n            } else {\r\n                $reserverStatique.removeAttr('style');\r\n            }\r\n        }\r\n        \r\n        console.log('\ud83d\udd04 updateReserverCheckboxState:', { hasFormat, hasFile, hasEnvoiDiffere, canReserve, dynamicLabel: !!($label && $label.length), staticLabel: $reserverStatique.length });\r\n    },\r\n    \r\n    \/**\r\n     * Initialise les listeners pour le changement de format et la checkbox R\u00e9server\r\n     *\/\r\n    init() {\r\n        \/\/ \u2705 \u00c9couter les clics sur les conteneurs de format et leurs parents\r\n        jQuery(document).on('click', '.EspPubFormatContainer, .EspPubFormatListe, .EspPubFormatMainContainer', (e) => {\r\n            const $droppable = jQuery(e.target).closest('.droppable');\r\n            if (!$droppable.length) return;\r\n            \r\n            \/\/ Multiples d\u00e9lais pour couvrir les traitements asynchrones\r\n            [50, 200, 500].forEach(delay => {\r\n                setTimeout(() => {\r\n                    this.updateTitleColor($droppable);\r\n                    this.updateReserverCheckboxState($droppable);\r\n                }, delay);\r\n            });\r\n\r\n            \/\/ \u2705 v2.2.0 : Si un format (non Cr\u00e9ation) est cliqu\u00e9, notifier le parent pour mettre \u00e0 jour le Kit\r\n            const $btn = jQuery(e.target).closest('.EspPubFormatContainer');\r\n            if ($btn.length && !$btn.hasClass('FormatIdCreation') && !$btn.hasClass('FormatIdPopUp')) {\r\n                \/\/ \u2705 v2.3.4 : FormatIdPopUp g\u00e9r\u00e9 par clickFormatFromIframe (Entete.txt) \u2014 ne pas doubler\r\n                var classes = $btn.attr('class') || '';\r\n                var match = classes.match(\/FormatId(\\w+)\/);\r\n                if (match && match[1]) {\r\n                    var _rankEP = $droppable.attr('id') || '';\r\n                    setTimeout(function() {\r\n                        MessageManager.sendToParent('formatChangedInIframe', { formatSelect: match[1], rank: _rankEP });\r\n                        console.log('\ud83d\udd04 formatChangedInIframe envoy\u00e9:', match[1], '| rank:', _rankEP);\r\n                    }, 100);\r\n                }\r\n            }\r\n        });\r\n        \r\n        \/\/ \u2705 MutationObserver sur les conteneurs de format pour d\u00e9tecter les changements de style\r\n        setTimeout(() => {\r\n            this.observeFormatChanges();\r\n            \r\n            \/\/ Initialiser les couleurs des titres au chargement\r\n            jQuery('.droppable').each((i, el) => {\r\n                this.updateTitleColor(jQuery(el));\r\n            });\r\n            \r\n            \/\/ \u2705 v2.3.4 : Popup \u2192 restaurer FormatIdPopUp + format sous-jacent (sans \u00e9craser applyFormatState)\r\n            if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n                jQuery('.FormatIdPopUp').css({'background-color': '#ffffff'});\r\n                jQuery('.FormatIdPopUp').find('.EspPubFormat').css({'color': '#37D900'});\r\n                \/\/ Restaurer aussi le format sous-jacent dans Ele0A\r\n                var _fmtSS = sessionStorage.getItem('FormatSelect') || '';\r\n                if (_fmtSS) {\r\n                    var _fmtSSNorm = _fmtSS.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                    jQuery('#Ele0A').find('.EspPubFormatContainer').not('.FormatIdCreation').each(function() {\r\n                        var _cls = this.className.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                        if (_cls.includes(_fmtSSNorm)) {\r\n                            jQuery(this).css({'background-color': '#ffffff'});\r\n                            jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                        }\r\n                    });\r\n                }\r\n                jQuery('.droppable').each((i, el) => {\r\n                    this.updateTitleColor(jQuery(el));\r\n                });\r\n            }\r\n        }, 500);\r\n        \r\n        \/\/ \u2705 v1.16.0 : Re-v\u00e9rifier apr\u00e8s un d\u00e9lai plus long (format venant de l'accord\u00e9on via postMessage)\r\n        [1500, 3000].forEach(delay => {\r\n            setTimeout(() => {\r\n                \/\/ \u2705 v2.3.4 : Popup \u2192 restaurer FormatIdPopUp + format sous-jacent\r\n                if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n                    jQuery('.FormatIdPopUp').css({'background-color': '#ffffff'});\r\n                    jQuery('.FormatIdPopUp').find('.EspPubFormat').css({'color': '#37D900'});\r\n                    var _fmtSSR = sessionStorage.getItem('FormatSelect') || '';\r\n                    if (_fmtSSR) {\r\n                        var _fmtSSRNorm = _fmtSSR.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                        jQuery('#Ele0A').find('.EspPubFormatContainer').not('.FormatIdCreation').each(function() {\r\n                            var _cls = this.className.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                            if (_cls.includes(_fmtSSRNorm)) {\r\n                                jQuery(this).css({'background-color': '#ffffff'});\r\n                                jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                            }\r\n                        });\r\n                    }\r\n                    jQuery('.droppable').each((i, el) => {\r\n                        this.updateTitleColor(jQuery(el));\r\n                    });\r\n                    return;\r\n                }\r\n                if (sessionStorage.getItem('Formatchoisi') === 'Yes') {\r\n                    jQuery('.droppable').each((i, el) => {\r\n                        this.updateTitleColor(jQuery(el));\r\n                    });\r\n                }\r\n            }, delay);\r\n        });\r\n    },\r\n    \r\n    \/**\r\n     * Attache un MutationObserver sur chaque .EspPubFormatContainer\r\n     * pour d\u00e9tecter tout changement de style (background-color) \r\n     * quel que soit le script qui le d\u00e9clenche\r\n     *\/\r\n    observeFormatChanges() {\r\n        \/\/ \u2705 Guard global anti-boucle \u2014 un seul verrou pour tous les observers\r\n        window._formatObserverLocked = false;\r\n        \r\n        jQuery('.EspPubFormatContainer').each((i, el) => {\r\n            const observer = new MutationObserver(() => {\r\n                if (window._formatObserverLocked) return;\r\n                window._formatObserverLocked = true;\r\n                \/\/ \u2705 v2.4.12 : Debounce 150ms \u2014 applyFormatState manipule plusieurs containers\r\n                \/\/ en s\u00e9quence rapide, le MutationObserver peut firer sur un \u00e9tat interm\u00e9diaire\r\n                clearTimeout(window._formatObserverTimer);\r\n                window._formatObserverTimer = setTimeout(() => {\r\n                    const $droppable = jQuery(el).closest('.droppable');\r\n                    this.updateTitleColor($droppable);\r\n                    this.updateReserverCheckboxState($droppable);\r\n                    window._formatObserverLocked = false;\r\n                }, 150);\r\n            });\r\n            observer.observe(el, { \r\n                attributes: true, \r\n                attributeFilter: ['style', 'class'] \r\n            });\r\n        });\r\n        console.log('\u2705 MutationObserver attach\u00e9 aux conteneurs de format');\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de communication avec la page parente\r\n *\/\r\nconst MessageManager = {\r\n    sendToParent(type, data = {}) {\r\n        try {\r\n            window.parent.postMessage({\r\n                type: type,\r\n                iframeId: CONFIG.iframeId,\r\n                data: data\r\n            }, '*');\r\n        } catch (error) {\r\n            console.error('Error sending message to parent:', error);\r\n            window.parent.postMessage({\r\n                type: 'error',\r\n                error: error.message,\r\n                iframeId: CONFIG.iframeId\r\n            }, '*');\r\n        }\r\n    },\r\n    \r\n    sendDataToParent(data) {\r\n        this.sendToParent('dataFromIframeEspacePub', data);\r\n    },\r\n    \r\n    sendDelAdToParent(data) {\r\n        this.sendToParent('dataDelAd', data);\r\n    },\r\n    \r\n    prepareUploadData() {\r\n        const keys = [\r\n            'AddNewRefInVosCampagnes',\r\n            'FirstUploadFileorMoved',\r\n            'LoadedPageUrl',\r\n            'codePage',\r\n            'Rank_Emplacement_Page_Web',\r\n            'Commande_Emplacement_Page_Web',\r\n            'dragstart_Commande_Emplacement_Page_Web',\r\n            'dragstart_Rank_Emplacement_Page_Web',  \r\n            'FullPathAdFile',\r\n            'Upload_File_Name',\r\n            'FileReceived',\r\n            'PageWebDisplayed',\r\n            'Commande_Format_Transmis',\r\n            'EspPubLienAnnonce',\r\n            'EnvoiUlterieur',\r\n            'Formatchoisi'\r\n        ];\r\n        \r\n        const data = StateManager.getMultiple(keys);\r\n        \r\n        \/\/ \u2705 v2.3.4 : Popup (Ele0A) \u2014 lire le format sous-jacent depuis le DOM\r\n        \/\/ StateManager contient 'PopUp' (virtuel), mais le vrai format est visuellement s\u00e9lectionn\u00e9 dans #Ele0A\r\n        if (data.Rank_Emplacement_Page_Web === 'Ele0A' || sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n            var _ele0AFormatDOM = '';\r\n            jQuery('#Ele0A').find('.EspPubFormatContainer').not('.FormatIdPopUp').each(function() {\r\n                if (jQuery(this).css('background-color') === 'rgb(255, 255, 255)') {\r\n                    var _cls = this.className || '';\r\n                    var _match = _cls.match(\/FormatId(\\S+)\/);\r\n                    if (_match) { _ele0AFormatDOM = _match[1]; return false; }\r\n                }\r\n            });\r\n            if (_ele0AFormatDOM) {\r\n                data.Commande_Format_Transmis = _ele0AFormatDOM;\r\n            }\r\n        }\r\n        \r\n        console.log('\ud83d\udce4 prepareUploadData:', {\r\n            FirstUploadFileorMoved: data.FirstUploadFileorMoved,\r\n            dragstart_Commande_Emplacement_Page_Web: data.dragstart_Commande_Emplacement_Page_Web,\r\n            Commande_Emplacement_Page_Web: data.Commande_Emplacement_Page_Web\r\n        });\r\n    \r\n        return data;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de rendu des aper\u00e7us de fichiers\r\n *\/\r\nconst PreviewRenderer = {\r\n    _getPositionLibelle(rankId) {\r\n        if (!rankId) return '';\r\n        var match = rankId.match(\/Ele(\\d+)[A-Z]\/);\r\n        if (!match) return '';\r\n        var rang = parseInt(match[1]);\r\n        if (rang === 0) return 'Pop-up';\r\n        if (rang === 1 || rang === 2) return 'Haut de page';\r\n        return 'Corps de page';\r\n    },\r\n    renderVideo(objectUrl, fileName, $dropZone) {\r\n        const videoElement = jQuery('<video controls autoplay muted>').attr({\r\n            'src': objectUrl,\r\n            'width': 'auto',\r\n            'height': 'auto',\r\n            'id': fileName\r\n        }).css({\r\n            'max-width': '100%',\r\n            'max-height': '100%'\r\n        });\r\n        \r\n        if (UIManager.isDesktop()) {\r\n            $dropZone.empty().append(videoElement.clone());\r\n            jQuery('#ApercuMobile').css({\r\n                'display': 'flex',\r\n                'justify-content': 'center',\r\n                'align-items': 'center'\r\n            }).append(videoElement);\r\n        } else {\r\n            const img = document.createElement('img');\r\n            img.src = objectUrl;\r\n            img.style.width = 'auto';\r\n            img.style.height = 'auto';\r\n            img.style.maxWidth = 'calc(100% - 4px)';  \/\/ \u2705 v2.4.5 : 2px retrait inset box-shadow\r\n            img.style.maxHeight = '115px';\r\n            \r\n            const container = $dropZone[0];\r\n            while (container.firstChild) {\r\n                container.removeChild(container.firstChild);\r\n            }\r\n            container.appendChild(img);\r\n        }\r\n        \r\n        StateManager.setMultiple({\r\n            'Commande_Format': 'Vid\u00e9o',\r\n            'Commande_Format_Transmis': 'Vid\u00e9o',\r\n            'videoSrc': objectUrl,\r\n            'FormatAnnonceSelection': 'Yes',\r\n            'PositionAnnonceSelection': 'Yes'\r\n        });\r\n        \r\n        jQuery('#FormatDataStep3').html('Vid\u00e9o').css({'color': '#56BE50'});\r\n        jQuery('#TarifDataStep3').css({'color': '#96894D'});\r\n    },\r\n    \r\n    renderImage(objectUrl, $dropZone) {\r\n        const maxHeight = UIManager.isMobile() ? 105 : $dropZone.closest('.HTMLUploadfileConteneur').height();\r\n    \r\n        $dropZone.css({\r\n            'display': 'flex',\r\n            'justify-content': 'center',\r\n            'align-items': 'center',\r\n            'width': '100%',\r\n            'height': maxHeight + 'px',\r\n            'overflow': 'hidden',\r\n            'position': UIManager.isMobile() ? 'relative' : '',\r\n            'top': UIManager.isMobile() ? '45px' : '',\r\n            'padding': UIManager.isMobile() ? '0 2px' : ''  \/\/ \u2705 v2.4.5 : 2px retrait inset box-shadow mobile\r\n        });\r\n    \r\n        \/\/ \u2705 v1.19.2 : Image charg\u00e9e en arri\u00e8re-plan, remplace le message d'attente au onload\r\n        \/\/ \u2705 v2.4.5 : max-width calc(100%-4px) sur mobile pour ne pas recouvrir le box-shadow inset 2px\r\n        var _mxw = UIManager.isMobile() ? 'calc(100% - 4px)' : '100%';\r\n        var img = new Image();\r\n        img.style.cssText = 'max-width:' + _mxw + '; max-height:' + maxHeight + 'px; width:auto; height:auto; object-fit:contain;';\r\n        img.onload = function() {\r\n            $dropZone.empty().append(img);\r\n        };\r\n        img.onerror = function() {\r\n            $dropZone.html('<img decoding=\"async\" src=\"' + objectUrl + '\" style=\"max-width:' + _mxw + '; max-height:' + maxHeight + 'px; width:auto; height:auto; object-fit:contain;\">');\r\n        };\r\n        img.src = objectUrl;\r\n    \r\n        StateManager.setMultiple({\r\n            'Commande_Format_Transmis': 'Image',\r\n            'FormatAnnonceSelection': 'Yes',\r\n            'PositionAnnonceSelection': 'Yes'\r\n        });\r\n    \r\n        console.log('Image ajout\u00e9e avec succ\u00e8s');\r\n    },\r\n    \r\n    async renderWord(fileObj, $dropZone) {\r\n        return new Promise((resolve, reject) => {\r\n            const reader = new FileReader();\r\n            \r\n            reader.onload = async (e) => {\r\n                try {\r\n                    const arrayBuffer = e.target.result;\r\n                    const result = await mammoth.convertToHtml({arrayBuffer: arrayBuffer});\r\n                    \r\n                    const htmlContent = result.value;\r\n                    const tempContainer = document.createElement('div');\r\n                    tempContainer.innerHTML = htmlContent;\r\n                    \r\n                    const textContent = tempContainer.textContent || \"\";\r\n                    const normalizedText = this.normalizeText(textContent);\r\n                    const firstImage = tempContainer.querySelector('img');\r\n                    \r\n                    const titleText = this.findDocumentTitle(normalizedText);\r\n                    \r\n                    if (firstImage) {\r\n                        this.renderDocumentPreview(\r\n                            $dropZone,\r\n                            firstImage.src,\r\n                            titleText,\r\n                            textContent,\r\n                            htmlContent\r\n                        );\r\n                    } else {\r\n                        \/\/ \u2705 v1.19.0 : Accepter les documents sans image\r\n                        this.renderDocumentPreview(\r\n                            $dropZone,\r\n                            null,\r\n                            titleText,\r\n                            textContent,\r\n                            htmlContent\r\n                        );\r\n                        console.log('\u2139\ufe0f Document Word sans image \u2014 aper\u00e7u texte seul');\r\n                    }\r\n                    resolve();\r\n                } catch (error) {\r\n                    $dropZone.html(`<p style=\"color: #FB5E2A; font-weight: 600; font-family: Roboto, Arial, sans-serif; font-size: 12px; text-align: center; padding: 15px;\">Erreur lors de la lecture du document<\/p>`);\r\n                    reject(error);\r\n                }\r\n            };\r\n            \r\n            reader.readAsArrayBuffer(fileObj);\r\n        });\r\n        \r\n        this.finalizeRedactionnelUpload();\r\n    },\r\n    \r\n    renderDocumentPreview($dropZone, imageSrc, title, text, htmlContent = null) {\r\n        \/\/ \u2705 v1.19.0 : Deux layouts \u2014 avec image ou texte seul\r\n        let previewHtml;\r\n\r\n        if (imageSrc) {\r\n            \/\/ Layout avec miniature image\r\n            previewHtml = `\r\n                <div class=\"doc-preview-container\">\r\n                    <div class=\"doc-preview-thumbnail\">\r\n                        <img decoding=\"async\" src=\"${imageSrc}\" alt=\"Document image\">\r\n                    <\/div>\r\n                    <div class=\"doc-preview-info\">\r\n                        <div class=\"doc-preview-title\" id=\"AdTitle\">${title}<\/div>\r\n                        <div class=\"doc-preview-description\" id=\"AdText\">${this.getTextPreview(text, 13)}<\/div>\r\n                        <div class=\"doc-preview-readmore\" id=\"AdLirelasuite\">Ouvrir et visualiser<\/div>\r\n                        <div class=\"doc-preview-FullPathAdFile\" id=\"AdFullPathAdFile\">${StateManager.get(\"FullPathAdFile\")}<\/div>\r\n                    <\/div>\r\n                <\/div>\r\n            `;\r\n        } else {\r\n            \/\/ Layout texte seul (sans image)\r\n            previewHtml = `\r\n                <div class=\"doc-preview-container doc-preview-noimage\">\r\n                    <div class=\"doc-preview-icon\">\r\n                        <svg width=\"36\" height=\"36\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#213864\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n                            <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"\/><polyline points=\"14 2 14 8 20 8\"\/><line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"\/><line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"\/><polyline points=\"10 9 9 9 8 9\"\/>\r\n                        <\/svg>\r\n                    <\/div>\r\n                    <div class=\"doc-preview-info doc-preview-info-full\">\r\n                        <div class=\"doc-preview-title\" id=\"AdTitle\">${title}<\/div>\r\n                        <div class=\"doc-preview-description\" id=\"AdText\">${this.getTextPreview(text, 25)}<\/div>\r\n                        <div class=\"doc-preview-readmore\" id=\"AdLirelasuite\">Ouvrir et visualiser<\/div>\r\n                        <div class=\"doc-preview-FullPathAdFile\" id=\"AdFullPathAdFile\">${StateManager.get(\"FullPathAdFile\")}<\/div>\r\n                    <\/div>\r\n                <\/div>\r\n            `;\r\n        }\r\n        \r\n        $dropZone.html(previewHtml + this.getPreviewStyles());\r\n        \r\n        if (htmlContent) {\r\n            this.attachWordPreviewHandler($dropZone, title, htmlContent);\r\n        }\r\n    },\r\n    \r\n    attachWordPreviewHandler($dropZone, titleText, htmlContent) {\r\n        var $droppable = $dropZone.closest('.droppable');\r\n\r\n        \/\/ \u2705 Adapter le libell\u00e9 selon le type de document\r\n        var isInterview = (titleText || '').toLowerCase().indexOf('interview') !== -1;\r\n        var formatLabel = isInterview ? 'l\\'interview' : 'le communiqu\u00e9';\r\n        $droppable.find('.doc-preview-readmore').text('Ouvrir et visualiser ' + formatLabel);\r\n\r\n        \/\/ \u2705 v2.0.11 : D\u00e9l\u00e9gation d'\u00e9v\u00e9nement \u2014 plus robuste sur mobile (survit aux manipulations DOM)\r\n        $droppable.off('click.docpreview').on('click.docpreview', '.doc-preview-readmore', (event) => {\r\n            event.preventDefault();\r\n            event.stopPropagation();\r\n            \r\n            if (htmlContent) {\r\n                var popupTitle = isInterview ? 'Interview' : 'Communiqu\u00e9';\r\n                PDFHandler.showInlineDocPopup($dropZone, {\r\n                    formatTitle: popupTitle,\r\n                    htmlContent: htmlContent\r\n                });\r\n            } else {\r\n                console.warn('Le document est encore en cours de traitement.');\r\n            }\r\n        });\r\n    },\r\n    \r\n    normalizeText(text) {\r\n        return text\r\n            .toLowerCase()\r\n            .normalize(\"NFD\")\r\n            .replace(\/[\\u0300-\\u036f]\/g, \"\");\r\n    },\r\n    \r\n    findDocumentTitle(normalizedText) {\r\n        const foundKeyword = CONFIG.keywords.find(keyword => \r\n            normalizedText.includes(keyword.normal)\r\n        );\r\n        if (foundKeyword) return foundKeyword.display;\r\n        \r\n        \/\/ \u2705 v1.19.1 : Fallback \u2014 utiliser le format s\u00e9lectionn\u00e9 (FormatSelect)\r\n        var formatSelect = (sessionStorage.getItem('FormatSelect') || '').toLowerCase();\r\n        if (formatSelect.indexOf('interview') !== -1) return 'Interview';\r\n        if (formatSelect.indexOf('communiq') !== -1) return 'Communiqu\u00e9';\r\n        \r\n        return \"Document\";\r\n    },\r\n    \r\n    getTextPreview(text, maxWords) {\r\n        const words = text.split(' ');\r\n        if (words.length > maxWords) {\r\n            return words.slice(0, maxWords).join(' ') + ' ...';\r\n        }\r\n        return text;\r\n    },\r\n    \r\n    getPreviewStyles() {\r\n        return `\r\n            <style>\r\n                @import url('https:\/\/fonts.googleapis.com\/css2?family=Roboto:wght@400;600&display=swap');\r\n                \r\n                .doc-preview-container {\r\n                    margin: 0px 0;\r\n                    display: flex;\r\n                    width: 100%;\r\n                    max-height: 140px;\r\n                    overflow: hidden;\r\n                    box-sizing: border-box;  \/* \u2705 v2.4.5 *\/\r\n                    background: white;\r\n                    background-color: #f8f8f8;\r\n                }\r\n                .doc-preview-thumbnail {\r\n                    width: 50%; \r\n                    height: 130px;\r\n                    overflow: hidden;\r\n                    display: flex;\r\n                    align-items: center;\r\n                    justify-content: center;\r\n                    margin-top: 0px;\r\n                }\r\n                .doc-preview-thumbnail img {\r\n                    max-width: 75%;\r\n                    max-height: 75%;\r\n                    object-position: center;\r\n                    object-fit: fill;\r\n                }\r\n                .doc-preview-info {\r\n                    width: 50%;\r\n                    height: 130px; \r\n                    flex: 1;\r\n                    padding: 10px;\r\n                    display: flex;\r\n                    flex-direction: column; \r\n                }\r\n                .doc-preview-title {\r\n                    font-family: 'Roboto', sans-serif;\r\n                    color: #213864;\r\n                    font-size: 14px;\r\n                    font-weight: 600;\r\n                    text-align: left;\r\n                    margin-bottom: 5px;\r\n                }\r\n                .doc-preview-description {\r\n                    font-family: 'Roboto', sans-serif;\r\n                    color: #213864;\r\n                    font-size: 11px;\r\n                    font-weight: 400;\r\n                    text-align: left;\r\n                    overflow: hidden;\r\n                    margin-bottom: 5px;\r\n                    flex: 1;\r\n                }\r\n                .doc-preview-readmore {\r\n                    font-family: 'Roboto', sans-serif;\r\n                    color: #958848;\r\n                    font-size: 13px;\r\n                    font-weight: 600;\r\n                    text-align: left;\r\n                    cursor: pointer;\r\n                    padding: 4px 0;\r\n                    -webkit-tap-highlight-color: rgba(149,136,72,0.2);\r\n                }\r\n                @media (max-width: 999px) {\r\n                    .doc-preview-readmore { font-size: 12px; }\r\n                    \/* \u2705 Laisser 3px tout autour pour que le liser\u00e9 vert (box-shadow\/outline sur parent) soit visible *\/\r\n                    .doc-preview-container {\r\n                        width: calc(100% - 16px) !important;\r\n                        max-height: 109px !important;\r\n                        margin: 3px !important;\r\n                        margin-top: 23px !important;\r\n                        box-sizing: border-box !important;\r\n                    }\r\n                }\r\n                .doc-preview-FullPathAdFile {\r\n                    display: none;\r\n                }\r\n                \/* \u2705 v1.19.0 : Layout sans image *\/\r\n                .doc-preview-noimage {\r\n                    flex-direction: row;\r\n                    align-items: flex-start;\r\n                    gap: 10px;\r\n                    padding: 8px 10px;\r\n                }\r\n                .doc-preview-icon {\r\n                    flex-shrink: 0;\r\n                    display: flex;\r\n                    align-items: center;\r\n                    justify-content: center;\r\n                    width: 44px;\r\n                    height: 44px;\r\n                    background: #eef2f7;\r\n                    border-radius: 6px;\r\n                    margin-top: 4px;\r\n                }\r\n                .doc-preview-info-full {\r\n                    width: 100%;\r\n                    height: auto;\r\n                    max-height: 130px;\r\n                }\r\n                .doc-preview-noimage .doc-preview-description {\r\n                    font-size: 11px;\r\n                    line-height: 1.35;\r\n                    max-height: 60px;\r\n                    overflow: hidden;\r\n                }\r\n            <\/style>\r\n        `;\r\n    },\r\n    \r\n    finalizeRedactionnelUpload() {\r\n        \/\/ \u2705 v1.19.5 : D\u00e9terminer le format r\u00e9dactionnel correct\r\n        \/\/ Si le format s\u00e9lectionn\u00e9 est \"Interview\", on garde \"Interview\"\r\n        \/\/ Sinon on met \"Communiqu\u00e9\" par d\u00e9faut (au lieu de \"R\u00e9dactionnel\" qui n'est pas un format tarifaire valide)\r\n        var formatSelect = sessionStorage.getItem('FormatSelect') || '';\r\n        var formatTransmis = 'Communiqu\u00e9'; \/\/ Par d\u00e9faut\r\n        \r\n        if (formatSelect.toLowerCase().indexOf('interview') !== -1) {\r\n            formatTransmis = 'Interview';\r\n        } else if (formatSelect.toLowerCase().indexOf('communiq') !== -1) {\r\n            formatTransmis = 'Communiqu\u00e9';\r\n        }\r\n        \r\n        StateManager.set('Commande_Format_Transmis', formatTransmis);\r\n        console.log('\u2705 Format r\u00e9dactionnel d\u00e9termin\u00e9:', formatTransmis, '(FormatSelect:', formatSelect, ')');\r\n        \r\n        if (StateManager.get(\"TarifDirectSelectionne\") === 'Yes') {\r\n            const formatText = jQuery('#FormatDataStep3').text();\r\n            if (formatText !== 'Vid\u00e9o' && formatText !== 'Banni\u00e8re') {\r\n                jQuery('#form-field-RedactionnelSelection')\r\n                    .val(formatText)\r\n                    .css({'color': '#56BE50'});\r\n            }\r\n        }\r\n        \r\n        RedactionnelDepose();\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'upload\r\n *\/\r\nconst UploadManager = {\r\n    isRunning: false,\r\n    \r\n    \/\/ \u2705 Reset manuel espace publicitaire\r\n    resetEspaceManuel: function($droppable) {\r\n        console.log('\ud83d\udd27 Reset manuel espace publicitaire');\r\n        \r\n        var $dropZone = $droppable.find('#drop_file_zone_achat');\r\n        var $uploadContainer = $droppable.find('.HTMLUploadfileConteneur');\r\n        var $container = $droppable.find('.OrdiMobileConteneurClass');\r\n        \r\n        \/\/ 1. Vider la zone de drop et restaurer le HTML par d\u00e9faut\r\n        $dropZone.empty().html(\r\n            '<div id=\"drag_upload_file_achat\">' +\r\n                '<p class=\"UploadIci\" style=\"color: #FB5E2A; font-weight: 600;\">Ici glisser \u2013 d\u00e9poser ou<br>t\u00e9l\u00e9charger une annonce<\/p>' +\r\n            '<\/div>'\r\n        );\r\n        \r\n        \/\/ 2. Afficher les \u00e9l\u00e9ments cach\u00e9s lors de l'upload\r\n        $droppable.find('.UploadIci').show();\r\n        $droppable.find('.EnvoiUlterieurTexte').show();\r\n        $droppable.find('.EnvoiUlterieurContainer').show();\r\n        $droppable.find('.EspPubFormatMainContainer').show();\r\n        $droppable.find('.EspPubFormatListe').show();\r\n        $droppable.find('.ChoisirEspacePublicitaireClass').show();\r\n        $droppable.find('.GlisserDeposerConteneur').show();\r\n        $droppable.find('.OUClass').show();\r\n        $droppable.find('.TexteMobileAnnonce').show();\r\n        $droppable.find('.PositionReference').show();\r\n        $droppable.find('.ClassHdpCdp').show();\r\n        $droppable.find('.ClassRefEsp').show();\r\n        \r\n        \/\/ 3. Cacher les \u00e9l\u00e9ments d'annonce upload\u00e9e\r\n        $droppable.find('.AdUploadedTitle').hide();\r\n        $droppable.find('#CroixResetAnnonce').hide();\r\n        $droppable.find('.CroixResetAnnonceContainer').hide();\r\n        $droppable.find('.DeplaceAnnonce').hide();\r\n        $droppable.find('.RefEspacePublicitaire').hide();\r\n        $droppable.find('.AdDroppedTextNotDisplayed').hide();\r\n        \r\n        \/\/ 4. Reset des styles\r\n        $uploadContainer.css({\r\n            'border': 'none',\r\n            'background-color': '',\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'min-height': ''\r\n        });\r\n        \r\n        $container.css({\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'top': '',\r\n            'height': ''\r\n        });\r\n        \r\n        \/\/ \u2705 Reset des positionnements desktop appliqu\u00e9s par adjustDesktopLayout\r\n        $droppable.closest('.ToBeHidden').css({'top': '', 'min-height': ''});\r\n        $droppable.parent().css('overflow', '');\r\n        \/\/ \u2705 v2.0.11 : Cleanup event namespace docpreview\r\n        $droppable.off('click.docpreview');\r\n        \r\n        \/\/ 5. Reset des formats s\u00e9lectionn\u00e9s\r\n        $droppable.find('.EspPubFormatContainer').css({\r\n            'background-color': '',\r\n            'border': ''\r\n        });\r\n        \r\n        \/\/ 6. Supprimer le bouton \"R\u00e9server\" dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ 7. Restaurer .PositionEspacePublicitaireContainer et .ReserverContainer\r\n        $droppable.find('.PositionEspacePublicitaireContainer').show();\r\n        $droppable.find('.ReserverContainer').hide();\r\n        \r\n        console.log('\u2705 Reset manuel termin\u00e9');\r\n    },\r\n    \r\n    async handleFileUpload(fileObj, $dropZone) {\r\n        console.log('fileObj:', fileObj);\r\n        \r\n        \/\/ \u2705 v2.4.6 : Contr\u00f4les d'extension EN PREMIER \u2014 avant tout affichage\r\n        const extension = FileManager.getExtension(fileObj.name);\r\n        StateManager.set('FileExtension', extension);\r\n        console.log('FileExtension:', extension);\r\n        \r\n        \/\/ \u2705 v2.6 : jpg\/jpeg accept\u00e9s sur desktop et mobile\r\n        \r\n        if (!FileManager.isAllowedExtension(extension)) {\r\n            UIManager.showFormatError($dropZone);\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 v1.19.5 : Afficher le message d'attente seulement si le format est valide\r\n        var _waitMsg = 'Loading in progress <span class=\"dot-container\"><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><\/span>';\r\n        $dropZone.html('<div class=\"ad-loading-msg\" style=\"color:#00ff19; background:white; padding:12px 20px; border-radius:6px; font-weight:700; text-align:center; font-size:18px; line-height:1.4;\">' + _waitMsg + '<\/div>');\r\n        \r\n        this.prepareUIForUpload($dropZone);\r\n        \r\n        const formData = new FormData();\r\n        formData.append('file', fileObj);\r\n        formData.append('action', 'upload_annonce_file_v3');\r\n        \r\n        UIManager.showUploadProgress($dropZone);\r\n        \r\n        try {\r\n            const response = await this.sendUploadRequest(formData);\r\n            await this.handleUploadResponse(response, fileObj, $dropZone, extension);\r\n        } catch (error) {\r\n            console.error('Upload error:', error);\r\n        }\r\n    },\r\n    \r\n    prepareUIForUpload($dropZone) {\r\n        if (!UIManager.isMobile()) {\r\n            jQuery('.ChoisirEspacePublicitaireClass').show();\r\n            jQuery('.ChoisirEspacePublicitaire2ndLigne').show();\r\n            jQuery('.GlisserDeposerConteneur').show();\r\n            jQuery('.OUClass').show();\r\n            \/\/ \u2705 Cibler uniquement le droppable courant \u2014 ne pas r\u00e9afficher sur les espaces d\u00e9j\u00e0 upload\u00e9s\r\n            $dropZone.closest('.droppable').find('.UploadIci').show();\r\n        }\r\n        \r\n        if (StateManager.get(\"PopUpChoice\") === 'Yes') {\r\n            \/\/ \u2705 Ne masquer DeplaceAnnonce QUE sur Ele0A \u2014 pas sur Ele1A qui a deja une annonce chargee\r\n            $dropZone.closest('.OrdiMobileConteneurClass').find('.DeplaceAnnonce').each(function() {\r\n                var _d = jQuery(this).closest('.droppable')[0];\r\n                if (_d && _d.getAttribute('data-via-ad-loaded') === 'true') { return; }\r\n                jQuery(this).hide();\r\n            });\r\n            $('.AnnonceDragIcone').show().find('img').attr('alt', '');\r\n        } else {\r\n            $('.AnnonceDragIcone').hide();\r\n        }\r\n        \r\n        if (StateManager.get(\"Commande_Page\") === 'Home Page') {\r\n            jQuery('#HPTarifConteneur').css({'background-color': '#B5FFB1'});\r\n        }\r\n        \r\n        jQuery('.ChoisirEspacePublicitaireClass').css({'color': '#ffffff'});\r\n        jQuery('.InterfaceTitreDore').not('#PageWebTitreDore')\r\n            .html(\"Merci de choisir les \u00e9l\u00e9ments de votre campagne publicitaire\");\r\n        jQuery('#ProcessCommande').show();\r\n    },\r\n    \r\n    sendUploadRequest(formData) {\r\n        \/\/ \u2705 v2.6 : dataType 'text' pour eviter parsererror si texte parasite apres le JSON\r\n        return jQuery.ajax({\r\n            url: CONFIG.ajaxUrl,\r\n            type: 'POST',\r\n            data: formData,\r\n            cache: false,\r\n            contentType: false,\r\n            processData: false,\r\n            dataType: 'text'\r\n        }).then(function(text) {\r\n            \/\/ Extraire le JSON meme si du texte parasite suit\r\n            var _json = null;\r\n            try {\r\n                var _match = text.match(\/(\\{[\\s\\S]*?\\})(?:[^{]|$)\/);\r\n                _json = JSON.parse(_match ? _match[1] : text);\r\n            } catch(_e) {\r\n                return jQuery.Deferred().reject({ responseText: text }).promise();\r\n            }\r\n            \/\/ Normaliser le format vers {success, data} attendu par handleUploadResponse\r\n            if (_json.status === 'success') {\r\n                var _fp = _json.file_path || '';\r\n                var _baseUrl = CONFIG.ajaxUrl.replace('\/wp-admin\/admin-ajax.php', '\/wp-content\/');\r\n                return {\r\n                    success: true,\r\n                    data: {\r\n                        file_url:  _baseUrl + _fp,\r\n                        file_name: _fp.replace(\/^.*\\\/\/, ''),\r\n                        file_path: _fp\r\n                    }\r\n                };\r\n            }\r\n            \/\/ Format WordPress standard {success, data} - retourner tel quel\r\n            return _json;\r\n        });\r\n    },\r\n    \r\n    async handleUploadResponse(response, fileObj, $dropZone, extension) {\r\n        console.log('\u2705 R\u00e9ponse re\u00e7ue');\r\n        \r\n        if (response.responseJSON) {\r\n            response = response.responseJSON;\r\n        }\r\n        \r\n        console.log('\u2705 Response pars\u00e9e:', response);\r\n        \r\n        if (!response.success || !response.data) {\r\n            \/\/ \u2705 v2.1.2 : Si c'est une restauration (_isAdRestoration = 'Yes'),\r\n            \/\/ le fichier existe d\u00e9j\u00e0 sur le serveur \u2192 afficher l'image depuis le fileObj local\r\n            if (StateManager.get('_isAdRestoration') === 'Yes' && fileObj) {\r\n                console.log('\ud83d\udd04 Restauration: upload \u00e9chou\u00e9 (fichier existant) \u2192 rendu local');\r\n                \r\n                FileManager.createObjectUrl(fileObj);\r\n                StateManager.set('FileReceived', 'Yes');\r\n                \r\n                \/\/ \u2705 v2.1.2 : Restaurer l'\u00e9tat EnvoiUlterieur depuis le sessionStorage parent\r\n                var _restoredEnvoi = sessionStorage.getItem('_restoredEnvoiUlterieur');\r\n                if (_restoredEnvoi === 'true') {\r\n                    StateManager.set('EnvoiUlterieur', 'true');\r\n                    StateManager.set('FileReceived', 'No');\r\n                    StateManager.set('FullPathAdFile', '');\r\n                    console.log('\ud83d\udce4 Restauration EnvoiUlterieur = true');\r\n                }\r\n                \r\n                var _objUrl = StateManager.get('objectUrl');\r\n                var _fileType = FileManager.getFileType(extension);\r\n                \r\n                StateManager.set('FormatReconnu', 'No');\r\n                \r\n                switch (_fileType) {\r\n                    case 'video':\r\n                        PreviewRenderer.renderVideo(_objUrl, fileObj.name, $dropZone);\r\n                        StateManager.set('FormatReconnu', 'Yes');\r\n                        break;\r\n                    case 'image':\r\n                        PreviewRenderer.renderImage(_objUrl, $dropZone);\r\n                        StateManager.set('FormatReconnu', 'Yes');\r\n                        break;\r\n                    case 'document':\r\n                        \/\/ \u2705 v2.1.2 : Documents Word\/PDF aussi en restauration\r\n                        await this.handleDocumentUpload(extension, fileObj, $dropZone);\r\n                        break;\r\n                }\r\n                \r\n                UIManager.updateAfterSuccessfulUpload($dropZone);\r\n                \r\n                if (StateManager.get('FormatReconnu') === 'Yes') {\r\n                    this.finalizeUpload($dropZone);\r\n                    $('#MsgSelectEspace').hide();\r\n                }\r\n                \r\n                FormatUIManager.updateReserverCheckboxState($dropZone.closest('.droppable'));\r\n                console.log('\u2705 Restauration visuelle termin\u00e9e (upload bypass)');\r\n                StateManager.set('_isAdRestoration', 'No');\r\n            }\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 SAUVEGARDER les infos de d\u00e9placement AVANT updateStateAfterUpload\r\n        const isMoved = StateManager.get('FirstUploadFileorMoved') === 'Moved';\r\n        const dragstartRankId = StateManager.get('dragstart_Rank_Emplacement_Page_Web');\r\n        const currentRankId = StateManager.get('Rank_Emplacement_Page_Web');\r\n        const shouldResetOldSpace = isMoved && dragstartRankId && dragstartRankId !== currentRankId;\r\n        \r\n        console.log('\ud83d\udd0d D\u00e9placement?', { isMoved, dragstartRankId, currentRankId, shouldResetOldSpace });\r\n        \r\n        this.updateStateAfterUploadWithoutReset(response, fileObj);\r\n        \r\n        const fileType = FileManager.getFileType(extension);\r\n        \r\n        StateManager.set('FormatReconnu', 'No');\r\n        \r\n        \/\/ \u2705 v1.19.2 : Message d'attente IMM\u00c9DIAT avant le rendu de l'annonce\r\n        var _waitMsg = 'Loading in progress <span class=\"dot-container\"><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><\/span>';\r\n        $dropZone.html('<div class=\"ad-loading-msg\" style=\"color:#00ff19; background:white; padding:12px 20px; border-radius:6px; font-weight:700; text-align:center; font-size:18px; line-height:1.4;\">' + _waitMsg + '<\/div>');\r\n        \r\n        switch (fileType) {\r\n            case 'video':\r\n                PreviewRenderer.renderVideo(StateManager.get('objectUrl'), fileObj.name, $dropZone);\r\n                StateManager.set('FormatReconnu', 'Yes');\r\n                break;\r\n                \r\n            case 'image':\r\n                PreviewRenderer.renderImage(StateManager.get('objectUrl'), $dropZone);\r\n                StateManager.set('FormatReconnu', 'Yes');\r\n                break;\r\n                \r\n            case 'document':\r\n                await this.handleDocumentUpload(extension, fileObj, $dropZone);\r\n                break;\r\n        }\r\n        \r\n        UIManager.updateAfterSuccessfulUpload($dropZone);\r\n        \r\n        if (StateManager.get('FormatReconnu') === 'Yes') {\r\n            this.finalizeUpload($dropZone);\r\n            $('#MsgSelectEspace').hide();\r\n        }\r\n        \r\n        \/\/ \u2705 RESET L'ANCIEN ESPACE ICI - APR\u00c8S avoir affich\u00e9 la nouvelle image\r\n        \/\/ \u2705 v2.4.5 : Toujours initialiser \u00e0 false avant le bloc (\u00e9vite la valeur r\u00e9siduelle)\r\n        var _sourceWasReserved = false;\r\n        StateManager.set('_sourceWasReserved', 'No');\r\n        \r\n        if (shouldResetOldSpace) {\r\n            console.log('\ud83d\udd04 Reset ancien espace:', dragstartRankId);\r\n            \r\n            var $oldDroppable = $('#' + dragstartRankId);\r\n            \r\n            if ($oldDroppable.length) {\r\n                var $container = $oldDroppable.find('.OrdiMobileConteneurClass').first();\r\n                \r\n                \/\/ \u2705 v2.4.5 : Utiliser l'\u00e9tat captur\u00e9 au dragstart (fiable vs re-check async)\r\n                if ($container.length) {\r\n                    _sourceWasReserved = StateManager.get('dragstart_ReserverChecked') === 'Yes';\r\n                    console.log('[d\u00e9placement] ReserverChecked au dragstart:', _sourceWasReserved, '| rank:', dragstartRankId);\r\n                    StateManager.set('_sourceWasReserved', _sourceWasReserved ? 'Yes' : 'No');\r\n                    RestoreadSpaceTemplateLocal($container[0]);\r\n                }\r\n            }\r\n        }\r\n        StateManager.set(\"EnvoiUlterieur\", 'false');\r\n        \r\n        \/\/ \u2705 v1.19.1 : Positionner l'espace \u00e0 10px du haut du viewport apr\u00e8s upload\r\n        setTimeout(function() {\r\n            var el = $dropZone.closest('.droppable').find('.HTMLUploadfileConteneur')[0]\r\n                     || $dropZone.closest('.droppable')[0];\r\n            if (el) {\r\n                ScrollHelper.scrollElementTo(el, 10);\r\n            }\r\n        }, 400);\r\n        \r\n        \/\/ \u2705 NE PLUS envoyer automatiquement - c'est la checkbox \"R\u00e9server\" qui d\u00e9clenche\r\n        \/\/ On met \u00e0 jour l'\u00e9tat de la checkbox pour qu'elle devienne activable\r\n        FormatUIManager.updateReserverCheckboxState($dropZone.closest('.droppable'));\r\n        \r\n        \/\/ \u2705 v2.4.5 : Si l'espace source \u00e9tait r\u00e9serv\u00e9, cocher la checkbox de l'espace cible\r\n        if (StateManager.get('_sourceWasReserved') === 'Yes') {\r\n            var $targetCb = $dropZone.closest('.droppable').find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]');\r\n            if ($targetCb.length && !$targetCb.prop('checked')) {\r\n                $targetCb.prop('checked', true).trigger('change');\r\n                console.log('\u2705 [d\u00e9placement] Checkbox R\u00e9server coch\u00e9e sur espace cible');\r\n            }\r\n            StateManager.set('_sourceWasReserved', 'No');\r\n        }\r\n        \r\n        console.log('\ud83d\udccb Upload termin\u00e9 - en attente de validation via checkbox \"R\u00e9server\"');\r\n    },\r\n    \r\n    updateStateAfterUploadWithoutReset(response, fileObj) {\r\n        StateManager.setMultiple({\r\n            \"PageWhithADType\": StateManager.get('SelectedPageType'),\r\n            \"PageWhithADSecteur\": StateManager.get('SelectedPageSecteur')\r\n        });\r\n        \r\n        $('#BackPageWebWithADCroix').hide();\r\n        jQuery('#ApercuMobile').empty().css({\r\n            'display': 'flex',\r\n            'justify-content': 'center',\r\n            'align-items': 'center'\r\n        });\r\n        \r\n        const firstUploadOrMoved = StateManager.get('FirstUploadFileorMoved');\r\n        \r\n        if (firstUploadOrMoved === 'FirstUpload') {\r\n            StateManager.setMultiple({\r\n                \"FullPathAdFile\": response.data.file_url,\r\n                \"fileObj\": fileObj,\r\n                \"Upload_File_Name\": fileObj.name\r\n            });\r\n            \r\n            FileManager.createObjectUrl(fileObj);\r\n            \r\n            console.log('\ud83d\udcc1 Fichier upload\u00e9:', {\r\n                fullUrl: response.data.file_url,\r\n                fileName: response.data.file_name,\r\n                filePath: response.data.file_path\r\n            });\r\n        }\r\n    },\r\n    \r\n    updateStateAfterUpload(response, fileObj) {\r\n        StateManager.setMultiple({\r\n            \"PageWhithADType\": StateManager.get('SelectedPageType'),\r\n            \"PageWhithADSecteur\": StateManager.get('SelectedPageSecteur')\r\n        });\r\n        \r\n        $('#BackPageWebWithADCroix').hide();\r\n        jQuery('#ApercuMobile').empty().css({\r\n            'display': 'flex',\r\n            'justify-content': 'center',\r\n            'align-items': 'center'\r\n        });\r\n        \r\n        const firstUploadOrMoved = StateManager.get('FirstUploadFileorMoved');\r\n        console.log('\ud83d\udd0d FirstUploadFileorMoved:', firstUploadOrMoved);\r\n        \r\n        if (firstUploadOrMoved === 'FirstUpload') {\r\n            StateManager.setMultiple({\r\n                \"FullPathAdFile\": response.data.file_url,\r\n                \"fileObj\": fileObj,\r\n                \"Upload_File_Name\": fileObj.name\r\n            });\r\n            \r\n            FileManager.createObjectUrl(fileObj);\r\n            \r\n            console.log('\ud83d\udcc1 Fichier upload\u00e9:', {\r\n                fullUrl: response.data.file_url,\r\n                fileName: response.data.file_name,\r\n                filePath: response.data.file_path\r\n            });\r\n        } else if (firstUploadOrMoved === 'Moved') {\r\n            const dragstartRankId = StateManager.get('dragstart_Rank_Emplacement_Page_Web');\r\n            const currentRankId = StateManager.get('Rank_Emplacement_Page_Web');\r\n            \r\n            console.log('\ud83d\udd04 D\u00c9PLACEMENT D\u00c9TECT\u00c9');\r\n            console.log('   Ancien espace (dragstart):', dragstartRankId);\r\n            console.log('   Nouvel espace (current):', currentRankId);\r\n            \r\n            if (dragstartRankId && dragstartRankId !== currentRankId) {\r\n                const $oldDroppable = $('#' + dragstartRankId);\r\n                \r\n                console.log('   $oldDroppable trouv\u00e9:', $oldDroppable.length > 0);\r\n                \r\n                if ($oldDroppable.length) {\r\n                    const $container = $oldDroppable.find('.OrdiMobileConteneurClass');\r\n                    \r\n                    console.log('   $container trouv\u00e9:', $container.length > 0);\r\n                    \r\n                    if ($container.length) {\r\n                        console.log('\ud83d\udd27 Appel RestoreadSpaceTemplate sur:', $container[0]);\r\n                        \r\n                        if (typeof window.RestoreadSpaceTemplate === 'function') {\r\n                            window.RestoreadSpaceTemplate($container[0]);\r\n                            console.log('\u2705 RestoreadSpaceTemplate ex\u00e9cut\u00e9');\r\n                        }\r\n                    } else {\r\n                        console.warn('\u26a0\ufe0f .OrdiMobileConteneurClass non trouv\u00e9 dans', dragstartRankId);\r\n                    }\r\n                }\r\n            } else {\r\n                console.log('\u23ed\ufe0f M\u00eame espace ou dragstartRankId invalide, pas de reset');\r\n            }\r\n        }\r\n    },\r\n        \r\n    async handleDocumentUpload(extension, fileObj, $dropZone) {\r\n        StateManager.set('FormatReconnu', 'Yes');\r\n        \r\n        \/\/ \u2705 Cacher le File r\u00e9dactionnel pour r\u00e9utilisation lors des d\u00e9placements (\u00e9vite CORS)\r\n        window._lastRedactionnelFile = fileObj;\r\n        \r\n        if (extension === 'doc' || extension === 'docx') {\r\n            await new Promise(resolve => window.VIALibraries.loadMammoth(resolve));\r\n            await PreviewRenderer.renderWord(fileObj, $dropZone);\r\n        } else if (extension === 'ppt' || extension === 'pptx') {\r\n            this.renderPowerPoint($dropZone);\r\n            PreviewRenderer.finalizeRedactionnelUpload();\r\n        } else if (extension === 'pdf') {\r\n            await new Promise(resolve => window.VIALibraries.loadPdfJs(resolve));\r\n            await PDFHandler.renderPDF(fileObj, $dropZone);\r\n            PreviewRenderer.finalizeRedactionnelUpload();\r\n        }\r\n    },\r\n    \r\n    renderPowerPoint($dropZone) {\r\n        const img = jQuery('<img \/>', {\r\n            src: '\/wp-content\/uploads\/2024\/06\/microsoft-powerpoint.png',\r\n            css: {\r\n                'width': 'auto',\r\n                'height': 'auto',\r\n                'margin-bottom': '20px',\r\n                'max-width': '150px',\r\n                'max-height': '160px'\r\n            }\r\n        });\r\n        $dropZone.empty().append(img.clone());\r\n        jQuery('#ApercuMobile').append(img);\r\n    },\r\n    \r\n    finalizeUpload($dropZone) {\r\n        \/\/ \u2705 Reset sendDataToParentFlag : nouvel upload = pas encore r\u00e9serv\u00e9\r\n        StateManager.set('sendDataToParentFlag', 'No');\r\n        \r\n        StateManager.setMultiple({\r\n            \"PageAnnonceSelection\": 'Yes',\r\n            \"FormatReconnu\": 'Yes'\r\n        });\r\n        \r\n        jQuery('#MsgChoixPageWeb, #MsgInsererAnnonceConteneur').hide();\r\n        \r\n        if (StateManager.get(\"Commande_Format\") === 'R\u00e9dactionnel') {\r\n            StateManager.set('Commande_Format', '\u00e0 choisir');\r\n            RedactionnelDepose();\r\n        }\r\n        \r\n        if (StateManager.get(\"Commande_Page\") === ' ') {\r\n            jQuery('#HPTarifConteneur').css({'background-color': '#BCFFAD'});\r\n            jQuery('#EmplacementDataStep3').html(\"Home Page\");\r\n            StateManager.setMultiple({\r\n                \"Commande_Page\": 'Home Page',\r\n                \"PageAnnonceSelection\": 'Yes'\r\n            });\r\n        }\r\n        \r\n        $('#PageWeb').css('zoom', '70%');\r\n        $('#PageWebTitreDore').css({'font-size': '14px'});\r\n        \r\n        if (!UIManager.isMobile()) {\r\n            $('#PageWebTitreDore').css({'color': '#213864'});\r\n        }\r\n        \r\n        StateManager.set(\"Page_Web_with_AD_URL\", StateManager.get(\"Page_Web_URL\"));\r\n        \r\n        UIManager.finalizeAdDisplay($dropZone);\r\n        \r\n        \/\/ \u2705 Notifier le parent de l'annonce d\u00e9pos\u00e9e non r\u00e9serv\u00e9e \u2014 pour restauration au retour sur la page\r\n        var _fileRcv = StateManager.get('FileReceived');\r\n        var _isRestoring = StateManager.get('_isAdRestoration') === 'Yes';\r\n        console.log('\ud83d\udfe1 [finalizeUpload] FileReceived:', _fileRcv, '| _isAdRestoration:', _isRestoring);\r\n        if (_fileRcv === 'Yes' && !_isRestoring) {\r\n            var _pendingRank = StateManager.get('Rank_Emplacement_Page_Web') || $dropZone.closest('.droppable').attr('id') || '';\r\n            console.log('\ud83d\udfe1 [finalizeUpload] pendingRank:', _pendingRank, '| FullPathAdFile:', StateManager.get('FullPathAdFile'));\r\n            if (_pendingRank) {\r\n                console.log('\ud83d\udce4 [finalizeUpload] annonceDeposeeSansReservation \u2192 parent rank:', _pendingRank);\r\n                \/\/ \u2705 D\u00e9terminer le vrai format commercial selon le type de fichier d\u00e9pos\u00e9 + format s\u00e9lectionn\u00e9\r\n                var _formatSelect = sessionStorage.getItem('FormatSelect') || StateManager.get('Commande_Format_Transmis') || '';\r\n                var _uploadedExt = (StateManager.get('Upload_File_Name') || '').split('.').pop().toLowerCase();\r\n                var _fileKind = CONFIG.allowedExtensions.video.indexOf(_uploadedExt) !== -1 ? 'video'\r\n                              : CONFIG.allowedExtensions.image.indexOf(_uploadedExt) !== -1 ? 'image'\r\n                              : CONFIG.allowedExtensions.document.indexOf(_uploadedExt) !== -1 ? 'document'\r\n                              : '';\r\n                var _formatPending;\r\n                if (_fileKind === 'video') {\r\n                    \/\/ Vid\u00e9o \u2192 toujours Vid\u00e9o\r\n                    _formatPending = 'Vid\u00e9o';\r\n                } else if (_fileKind === 'image') {\r\n                    \/\/ Image \u2192 Banni\u00e8re ou Parrainage si s\u00e9lectionn\u00e9, sinon Banni\u00e8re par d\u00e9faut\r\n                    var _imgFormats = ['Banni\u00e8re', 'Banniere', 'Parrainage'];\r\n                    _formatPending = (_imgFormats.indexOf(_formatSelect) !== -1) ? _formatSelect : 'Banni\u00e8re';\r\n                } else if (_fileKind === 'document') {\r\n                    \/\/ Document \u2192 Communiqu\u00e9 ou Interview si s\u00e9lectionn\u00e9, sinon Communiqu\u00e9 par d\u00e9faut\r\n                    var _docFormats = ['Communiqu\u00e9', 'Communique', 'Interview'];\r\n                    _formatPending = (_docFormats.indexOf(_formatSelect) !== -1) ? _formatSelect : 'Communiqu\u00e9';\r\n                } else {\r\n                    \/\/ Fallback\r\n                    _formatPending = _formatSelect || StateManager.get('Commande_Format_Transmis') || '';\r\n                }\r\n                \/\/ \u2705 v2.4.9 : Si le format d\u00e9duit diff\u00e8re du format s\u00e9lectionn\u00e9 \u2192 mettre \u00e0 jour vignette + sessionStorage\r\n                if (_formatPending && _formatPending !== _formatSelect) {\r\n                    StateManager.set('FormatSelect', _formatPending);\r\n                    StateManager.set('Commande_Format_Transmis', _formatPending);\r\n                    StateManager.set('Formatchoisi', 'Yes');\r\n                    \/\/ Mettre \u00e0 jour visuellement la vignette dans le droppable courant\r\n                    var _fmtNorm = _formatPending.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    var $_drp = $dropZone.closest('.droppable');\r\n                    $_drp.find('.EspPubFormatContainer').each(function() {\r\n                        var _cls = this.className.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                        if (_cls.includes(_fmtNorm)) {\r\n                            jQuery(this).css({'background-color': '#ffffff'});\r\n                            jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                        } else if (!jQuery(this).hasClass('FormatIdPopUp')) {\r\n                            jQuery(this).css({'background-color': ''});\r\n                            jQuery(this).find('.EspPubFormat').css({'color': ''});\r\n                        }\r\n                    });\r\n                    \/\/ Mettre \u00e0 jour aussi le bandeau parent via postMessage\r\n                    MessageManager.sendToParent('formatChangedInIframe', { formatSelect: _formatPending, rank: _pendingRank });\r\n                    console.log('\ud83d\udd04 [finalizeUpload] Format corrig\u00e9:', _formatSelect, '\u2192', _formatPending);\r\n                }\r\n                var _firstUploadOrMoved = StateManager.get('FirstUploadFileorMoved');\r\n                var _isMoved = _firstUploadOrMoved === 'Moved';\r\n                var _oldRankMoved = _isMoved ? (StateManager.get('dragstart_Rank_Emplacement_Page_Web') || '') : '';\r\n                MessageManager.sendToParent('annonceDeposeeSansReservation', {\r\n                    Rank_Emplacement_Page_Web: _pendingRank,\r\n                    FullPathAdFile: StateManager.get('FullPathAdFile') || '',\r\n                    Upload_File_Name: StateManager.get('Upload_File_Name') || '',\r\n                    LoadedPageUrl: window.location.href,\r\n                    FileReceived: 'Yes',\r\n                    \/\/ \u2705 Lire EnvoiUlterieur depuis la checkbox du droppable courant (pas le StateManager global)\r\n                    \/\/ StateManager.get('EnvoiUlterieur') est global \u2192 peut valoir 'true' si un autre espace a sa checkbox coch\u00e9e\r\n                    EnvoiUlterieur: ($dropZone.closest('.droppable').find('input[name*=\"EnvoiUlterieur\"]').prop('checked') ? 'true' : 'false'),\r\n                    Commande_Format_Transmis: _formatPending,\r\n                    codeSite: StateManager.get('codeSite') || '',\r\n                    codePage: StateManager.get('codePage') || '',\r\n                    Commande_Emplacement_Page_Web: StateManager.buildEmplacementReference(_pendingRank),\r\n                    isMoved: _isMoved,\r\n                    oldRank: _oldRankMoved\r\n                });\r\n            }\r\n        }\r\n    },\r\n    \r\n    activateSendDataToParent($dropZone) {\r\n        if (StateManager.get(\"sendDataToParentFlag\") !== 'Yes') {\r\n            return;\r\n        }\r\n        \r\n        if (StateManager.get(\"FirstUploadFileorMoved\") === 'Moved') {\r\n            const dragstartRef = StateManager.buildEmplacementReference(\r\n                StateManager.get(\"dragstart_Rank_Emplacement_Page_Web\")\r\n            );\r\n            StateManager.set('dragstart_Commande_Emplacement_Page_Web', dragstartRef);\r\n        }\r\n        \r\n        console.log('Esp Pub Ref FirstUploadFileorMoved:', StateManager.get(\"FirstUploadFileorMoved\"));\r\n        console.log('Esp Pub dragstart_Commande:', StateManager.get(\"dragstart_Commande_Emplacement_Page_Web\"));\r\n        \r\n        if (StateManager.get(\"PageAjoutModifAnnonce\") === 'Yes') {\r\n            this.handlePageModification($dropZone);\r\n        } else {\r\n            this.handleNormalUpload();\r\n        }\r\n        \r\n        StateManager.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        setTimeout(() => {\r\n            StateManager.set(\"AddNewRefInVosCampagnes\", 'Yes');\r\n        }, 4000);\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            StateManager.set('Commande_Format_Transmis', '');\r\n        }\r\n    },\r\n    \r\n    handlePageModification($dropZone) {\r\n        $('#CroixResetAnnonce, .DeplaceAnnonce').hide();\r\n        $('.PageAjoutModifAnnonceCroixResetAnnonce').show();\r\n        \r\n        const emplacementRef = $dropZone.closest('.CampagnesTemplateClass')\r\n            .find('.ReferenceEspace').text();\r\n        \r\n        console.log('Commande_Emplacement_Page_Web:', emplacementRef);\r\n        \r\n        jQuery.ajax({\r\n            type: \"POST\",\r\n            url: CONFIG.ajaxUrl,\r\n            data: {\r\n                action: 'via_update_fichier_annonce',\r\n                commande_ref_url: StateManager.get(\"commande_ref_url\"),\r\n                emplacement_page_web: emplacementRef,\r\n                chemin_fichier: StateManager.get(\"FullPathAdFile\")\r\n            },\r\n            xhrFields: { withCredentials: true },\r\n            success: (response) => {\r\n                if (response.success) {\r\n                    console.log('\u2705 Fichier annonce mis \u00e0 jour:', response.data.message);\r\n                    location.reload();\r\n                } else {\r\n                    console.error('\u274c Erreur:', response.data.message);\r\n                }\r\n            },\r\n            error: (xhr, status, error) => {\r\n                console.error('\u274c Erreur AJAX:', error);\r\n            }\r\n        });\r\n    },\r\n    \r\n    handleNormalUpload() {\r\n        if (StateManager.get(\"EnvoiUlterieur\") === 'true') {\r\n            StateManager.setMultiple({\r\n                \"FullPathAdFile\": '',\r\n                \"Upload_File_Name\": ''\r\n            });\r\n        }\r\n        \r\n        StateManager.set(\"LoadedPageUrl\", window.location.href);\r\n        \r\n        console.log('EnvoiUlterieur:', StateManager.get(\"EnvoiUlterieur\"));\r\n        console.log('LoadedPageUrl:', StateManager.get(\"LoadedPageUrl\"));\r\n        console.log('FileReceived:', StateManager.get(\"FileReceived\"));\r\n        \r\n        const data = MessageManager.prepareUploadData();\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            MessageManager.sendDataToParent(data);\r\n        } else {\r\n            const formatChoisi = StateManager.get(\"Formatchoisi\") === 'Yes';\r\n            const fichierDepose = StateManager.get(\"FileReceived\") === 'Yes';\r\n            const envoiDiffere = StateManager.get(\"EnvoiUlterieur\") === 'true';\r\n            \r\n            console.log('\ud83d\udd0d handleNormalUpload - Conditions:', { formatChoisi, fichierDepose, envoiDiffere });\r\n            \r\n            if (formatChoisi && (fichierDepose || envoiDiffere)) {\r\n                if (typeof window.handleEspacePubData === 'function') {\r\n                    window.handleEspacePubData(data);\r\n                } else {\r\n                    console.warn('\u26a0\ufe0f handleEspacePubData non disponible, fallback direct');\r\n                    if (typeof window.executeWithProcessLoaded === 'function') {\r\n                        window.executeWithProcessLoaded(function() {\r\n                            jQuery('#PopupProcessCommandeContainer').show();\r\n                        });\r\n                    } else {\r\n                        jQuery('#PopupProcessCommandeContainer').show();\r\n                    }\r\n                }\r\n            } else if (formatChoisi) {\r\n                console.log('\ud83d\udcdd Mise \u00e0 jour format uniquement');\r\n                \r\n                const borderStyle = {'box-shadow': 'inset 0 0 0 2px #00FF19', 'box-sizing': 'border-box'};  \/\/ \u2705 v2.4.5\r\n                \r\n                jQuery(\".FormatClassique, .FormatPopup\").css({'border': 'none'});\r\n                \r\n                jQuery('.FormatClassique, .FormatPopup').each(function() {\r\n                    \/\/ \u2705 v2.1.1 : NFD normalize both sides\r\n                    var _cn = this.className.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    var _cf = (data.Commande_Format_Transmis || '').normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    if (_cn.includes(_cf) && _cf) {\r\n                        jQuery(this).css(borderStyle);\r\n                    }\r\n                });\r\n            }\r\n        }\r\n        \r\n        StateManager.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        setTimeout(() => {\r\n            StateManager.set(\"AddNewRefInVosCampagnes\", 'Yes');\r\n        }, 4000);\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            StateManager.set('Commande_Format_Transmis', '');\r\n        }\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion des fichiers PDF (s\u00e9par\u00e9 pour \u00e9viter la complexit\u00e9)\r\n *\/\r\nconst PDFHandler = {\r\n    pdfData: null,\r\n    pdfDataForViewer: null,\r\n    \r\n    async renderPDF(fileObj, $dropZone) {\r\n        return new Promise((resolve, reject) => {\r\n            const reader = new FileReader();\r\n            \r\n            reader.onload = async (e) => {\r\n                try {\r\n                    const arrayBuffer = e.target.result;\r\n                    this.pdfData = new Uint8Array(arrayBuffer);\r\n                    this.pdfDataForViewer = arrayBuffer;\r\n                    \r\n                    console.log(\"Initial PDF load, size:\", this.pdfData.byteLength);\r\n                    \r\n                    const pdfjsLib = window['pdfjs-dist\/build\/pdf'];\r\n                    pdfjsLib.GlobalWorkerOptions.workerSrc = \r\n                        '\/\/cdn.jsdelivr.net\/npm\/pdfjs-dist@latest\/build\/pdf.worker.min.js';\r\n                    \r\n                    const pdf = await pdfjsLib.getDocument({ data: new Uint8Array(this.pdfData) }).promise;\r\n                    const page = await pdf.getPage(1);\r\n                    \r\n                    const { titleText, pageText } = await this.extractTextFromPage(page);\r\n                    const imageData = await this.extractImageFromPage(page, pdfjsLib);\r\n                    \r\n                    if (imageData) {\r\n                        PreviewRenderer.renderDocumentPreview(\r\n                            $dropZone,\r\n                            imageData.dataUrl,\r\n                            titleText,\r\n                            pageText\r\n                        );\r\n                    } else {\r\n                        \/\/ \u2705 v1.19.0 : Accepter les PDF sans image\r\n                        PreviewRenderer.renderDocumentPreview(\r\n                            $dropZone,\r\n                            null,\r\n                            titleText,\r\n                            pageText\r\n                        );\r\n                        console.log('\u2139\ufe0f PDF sans image \u2014 aper\u00e7u texte seul');\r\n                    }\r\n                    \r\n                    this.attachPDFPreviewHandler($dropZone, titleText);\r\n                    resolve();\r\n                } catch (error) {\r\n                    console.error('Error extracting from PDF:', error);\r\n                    \/\/ \u2705 v1.19.0 : Message d'erreur en fran\u00e7ais\r\n                    $dropZone.html(`\r\n                        <div style=\"padding: 15px; background-color: #f8f8f8; border-radius: 4px; text-align: center;\">\r\n                            <p style=\"color: #FB5E2A; font-weight: 600; font-family: Roboto, Arial, sans-serif; font-size: 12px;\">\r\n                                Erreur lors de la lecture du document\r\n                            <\/p>\r\n                        <\/div>\r\n                    `);\r\n                    reject(error);\r\n                }\r\n            };\r\n            \r\n            reader.readAsArrayBuffer(fileObj);\r\n        });\r\n    },\r\n    \r\n    async extractTextFromPage(page) {\r\n        const textContent = await page.getTextContent();\r\n        \r\n        let text = '';\r\n        let lastX = -1;\r\n        let lastY = -1;\r\n        \r\n        for (const item of textContent.items) {\r\n            if (lastY !== -1 && (Math.abs(lastY - item.transform[5]) > 5)) {\r\n                text += '\\n';\r\n            } else if (lastX !== -1 && (item.transform[4] - lastX > 10)) {\r\n                text += ' ';\r\n            }\r\n            \r\n            text += item.str;\r\n            \r\n            lastX = item.transform[4] + (item.width || 0);\r\n            lastY = item.transform[5];\r\n        }\r\n        \r\n        text = text\r\n            .replace(\/(\\w) (\\w)\/g, (match, p1, p2) => {\r\n                if (\/[\u00e9\u00e8\u00ea\u00eb\u00e0\u00e2\u00e4\u00f4\u00f6\u00fb\u00fc\u00ef\u00ee\u00e7]\/i.test(p2)) {\r\n                    return p1 + p2;\r\n                }\r\n                return match;\r\n            })\r\n            .replace(\/ ([.,;:!?])\/g, '$1');\r\n        \r\n        const normalizedText = PreviewRenderer.normalizeText(text);\r\n        const titleText = PreviewRenderer.findDocumentTitle(normalizedText);\r\n        \r\n        return { titleText, pageText: text };\r\n    },\r\n    \r\n    async extractImageFromPage(page, pdfjsLib) {\r\n        const opList = await page.getOperatorList();\r\n        const imageInfo = [];\r\n        let currentTransform = null;\r\n        \r\n        for (let i = 0; i < opList.fnArray.length; i++) {\r\n            const operator = opList.fnArray[i];\r\n            const args = opList.argsArray[i];\r\n            \r\n            if (operator === pdfjsLib.OPS.transform) {\r\n                currentTransform = args;\r\n            } else if (operator === pdfjsLib.OPS.paintImageXObject) {\r\n                const imageName = args[0];\r\n                \r\n                if (!imageInfo.some(info => info.name === imageName)) {\r\n                    const position = currentTransform ? {\r\n                        x: currentTransform[4] || 0,\r\n                        y: currentTransform[5] || 0\r\n                    } : { x: 0, y: 0 };\r\n                    \r\n                    imageInfo.push({ name: imageName, position: position });\r\n                }\r\n            }\r\n        }\r\n        \r\n        if (imageInfo.length === 0) {\r\n            return null;\r\n        }\r\n        \r\n        imageInfo.sort((a, b) => b.position.y - a.position.y);\r\n        \r\n        const targetImageName = imageInfo[0].name;\r\n        const imageObj = page.objs.get(targetImageName);\r\n        \r\n        if (!imageObj) {\r\n            const img = await page.objs.get(targetImageName, true);\r\n            return this.processImageObject(img);\r\n        }\r\n        \r\n        return this.processImageObject(imageObj);\r\n    },\r\n    \r\n    processImageObject(imageObj) {\r\n        if (!imageObj) {\r\n            throw new Error('Image object is null');\r\n        }\r\n        \r\n        if (imageObj.bitmap instanceof ImageBitmap) {\r\n            const width = imageObj.bitmap.width || imageObj.width || imageObj.w;\r\n            const height = imageObj.bitmap.height || imageObj.height || imageObj.h;\r\n            \r\n            const canvas = document.createElement('canvas');\r\n            canvas.width = width;\r\n            canvas.height = height;\r\n            const ctx = canvas.getContext('2d');\r\n            \r\n            ctx.drawImage(imageObj.bitmap, 0, 0);\r\n            \r\n            return {\r\n                canvas: canvas,\r\n                width: width,\r\n                height: height,\r\n                dataUrl: canvas.toDataURL('image\/jpeg', 0.92)\r\n            };\r\n        }\r\n        \r\n        const width = imageObj.width || imageObj.w;\r\n        const height = imageObj.height || imageObj.h;\r\n        \r\n        if (!width || !height) {\r\n            throw new Error('Could not determine image dimensions');\r\n        }\r\n        \r\n        let imgData = imageObj.data || imageObj.bitmap;\r\n        \r\n        if (!imgData) {\r\n            throw new Error('No valid image data found');\r\n        }\r\n        \r\n        const canvas = document.createElement('canvas');\r\n        canvas.width = width;\r\n        canvas.height = height;\r\n        const ctx = canvas.getContext('2d');\r\n        \r\n        ctx.fillStyle = 'white';\r\n        ctx.fillRect(0, 0, width, height);\r\n        \r\n        const imageData = ctx.createImageData(width, height);\r\n        \r\n        this.fillImageData(imageData, imgData, imageObj.kind, width, height);\r\n        \r\n        ctx.putImageData(imageData, 0, 0);\r\n        \r\n        return {\r\n            canvas: canvas,\r\n            width: width,\r\n            height: height,\r\n            dataUrl: canvas.toDataURL('image\/jpeg', 0.92)\r\n        };\r\n    },\r\n    \r\n    fillImageData(imageData, imgData, kind, width, height) {\r\n        if (kind === 'GRAY') {\r\n            for (let i = 0, j = 0; i < imgData.length; i++, j += 4) {\r\n                const value = imgData[i];\r\n                imageData.data[j] = value;\r\n                imageData.data[j + 1] = value;\r\n                imageData.data[j + 2] = value;\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else if (kind === 'CMYK') {\r\n            for (let i = 0, j = 0; i < imgData.length; i += 4, j += 4) {\r\n                const c = imgData[i] \/ 255;\r\n                const m = imgData[i + 1] \/ 255;\r\n                const y = imgData[i + 2] \/ 255;\r\n                const k = imgData[i + 3] \/ 255;\r\n                \r\n                imageData.data[j] = 255 * (1 - c) * (1 - k);\r\n                imageData.data[j + 1] = 255 * (1 - m) * (1 - k);\r\n                imageData.data[j + 2] = 255 * (1 - y) * (1 - k);\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else if (kind === 'RGB24') {\r\n            for (let i = 0, j = 0; i < imgData.length; i += 3, j += 4) {\r\n                imageData.data[j] = imgData[i];\r\n                imageData.data[j + 1] = imgData[i + 1];\r\n                imageData.data[j + 2] = imgData[i + 2];\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else if (imgData.length === width * height * 3) {\r\n            for (let i = 0, j = 0; i < imgData.length; i += 3, j += 4) {\r\n                imageData.data[j] = imgData[i];\r\n                imageData.data[j + 1] = imgData[i + 1];\r\n                imageData.data[j + 2] = imgData[i + 2];\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else {\r\n            const tempArray = new Uint8ClampedArray(imgData.length);\r\n            for (let i = 0; i < imgData.length; i++) {\r\n                tempArray[i] = imgData[i];\r\n            }\r\n            \r\n            if (tempArray.length === imageData.data.length \/ 4 * 3) {\r\n                for (let i = 0, j = 0; i < tempArray.length; i += 3, j += 4) {\r\n                    imageData.data[j] = tempArray[i];\r\n                    imageData.data[j + 1] = tempArray[i + 1];\r\n                    imageData.data[j + 2] = tempArray[i + 2];\r\n                    imageData.data[j + 3] = 255;\r\n                }\r\n            } else if (tempArray.length === imageData.data.length) {\r\n                imageData.data.set(tempArray);\r\n            } else {\r\n                console.warn('Unknown image format - creating placeholder');\r\n                for (let i = 0; i < imageData.data.length; i += 4) {\r\n                    const x = (i\/4) % width;\r\n                    const y = Math.floor((i\/4) \/ width);\r\n                    imageData.data[i] = x % 256;\r\n                    imageData.data[i + 1] = y % 256;\r\n                    imageData.data[i + 2] = 100;\r\n                    imageData.data[i + 3] = 255;\r\n                }\r\n            }\r\n        }\r\n    },\r\n    \r\n    attachPDFPreviewHandler($dropZone, titleText) {\r\n        var $droppable = $dropZone.closest('.droppable');\r\n        var self = this;\r\n\r\n        \/\/ \u2705 Adapter le libell\u00e9 selon le format (communiqu\u00e9 \/ interview)\r\n        var kitFormat = $droppable.data('kitFormatSelect') || '';\r\n        var isInterview = (kitFormat || titleText || '').toLowerCase().indexOf('interview') !== -1;\r\n        var formatLabel = isInterview ? 'l\\'interview' : 'le communiqu\u00e9';\r\n        $droppable.find('.doc-preview-readmore').text('Ouvrir et visualiser ' + formatLabel);\r\n\r\n        \/\/ \u2705 v2.0.11 : D\u00e9l\u00e9gation d'\u00e9v\u00e9nement \u2014 plus robuste sur mobile\r\n        $droppable.off('click.docpreview').on('click.docpreview', '.doc-preview-readmore', (event) => {\r\n            event.preventDefault();\r\n            event.stopPropagation();\r\n            var popupTitle = isInterview ? 'Interview' : 'Communiqu\u00e9';\r\n\r\n            \/\/ \u2705 Priorit\u00e9 1 : pdfImageDataURL dispo (Kit)\r\n            var kitPdfImage = $droppable.data('kitPdfImageDataURL');\r\n            if (kitPdfImage) {\r\n                PDFHandler.showInlineDocPopup($dropZone, {\r\n                    formatTitle: popupTitle,\r\n                    pdfDataURL: kitPdfImage\r\n                });\r\n                return;\r\n            }\r\n\r\n            \/\/ \u2705 Priorit\u00e9 2 : PDF upload\u00e9 manuellement \u2192 popup inline aussi\r\n            if (self.pdfDataForViewer && self.pdfDataForViewer.byteLength > 0) {\r\n                PDFHandler.showInlineDocPopup($dropZone, {\r\n                    formatTitle: popupTitle,\r\n                    pdfArrayBuffer: self.pdfDataForViewer\r\n                });\r\n                return;\r\n            }\r\n\r\n            console.error('PDF data is not available');\r\n        });\r\n    },\r\n\r\n    \/\/ \u2705 v1.19.1 : Popup inline document \u2014 position:absolute + ScrollHelper.getVisibleTop()\r\n    \/\/ Le parent envoie visibleTopIframe dans le message scroll \u2192 positionnement fiable.\r\n    showInlineDocPopup($dropZone, options) {\r\n        var existing = document.getElementById('via-pdf-inline-popup');\r\n        if (existing) existing.remove();\r\n\r\n        var $droppable = $dropZone.closest('.droppable');\r\n        var droppableW = $droppable.outerWidth() || 300;\r\n        var popupW = Math.round(droppableW * 1.15);\r\n        \/\/ \u2705 v2.0.11 : Contraindre la largeur au viewport sur mobile (\u00e9vite troncature gauche\/droite)\r\n        var viewportW = document.documentElement.clientWidth || window.innerWidth;\r\n        if (UIManager.isMobile()) {\r\n            popupW = Math.min(popupW, viewportW - 8);\r\n        }\r\n        var popupH = Math.round(popupW * 2.5 * 0.51);\r\n\r\n        \/\/ \u2500\u2500 Position visible r\u00e9elle \u2500\u2500\r\n        var visibleTop = ScrollHelper.getVisibleTop();\r\n        var popupTop = Math.round(visibleTop + 284);\r\n\r\n        \/\/ \u2500\u2500 Popup position:absolute (positionn\u00e9 dans le document iframe) \u2500\u2500\r\n        var popup = document.createElement('div');\r\n        popup.id = 'via-pdf-inline-popup';\r\n        popup.style.cssText =\r\n            'position:absolute;z-index:99999;top:' + popupTop + 'px;' +\r\n            'width:' + popupW + 'px;height:' + popupH + 'px;' +\r\n            'background:#fff;border-radius:8px 8px 0 0;padding:0;' +\r\n            'box-shadow:0 8px 32px rgba(0,0,0,0.35);display:flex;flex-direction:column;' +\r\n            'min-width:200px;min-height:150px;touch-action:none;';\r\n\r\n        \/\/ Centrer horizontalement sur le droppable (coordonn\u00e9es absolues)\r\n        var droppableRect = $droppable[0].getBoundingClientRect();\r\n        var scrollX = window.scrollX || 0;\r\n        var initLeft = Math.round(droppableRect.left + scrollX + (droppableRect.width - popupW) \/ 2);\r\n        initLeft = Math.max(4, initLeft);\r\n        \/\/ \u2705 v2.0.11 : Contraindre \u00e0 droite aussi sur mobile\r\n        if (UIManager.isMobile()) {\r\n            initLeft = Math.min(initLeft, viewportW - popupW - 4);\r\n            initLeft = Math.max(4, initLeft);\r\n        }\r\n        popup.style.left = initLeft + 'px';\r\n\r\n        \/\/ \u2500\u2500 Header \u2500\u2500\r\n        var header = document.createElement('div');\r\n        header.style.cssText =\r\n            'display:flex;align-items:center;justify-content:center;position:relative;' +\r\n            'padding:10px 14px;background:#f0f0f0;color:#494949;flex-shrink:0;' +\r\n            'cursor:grab;user-select:none;border-radius:8px 8px 0 0;';\r\n        var titleEl = document.createElement('span');\r\n        titleEl.style.cssText = 'font-family:Roboto,Arial,sans-serif;font-size:15px;font-weight:600;';\r\n        titleEl.textContent = options.formatTitle || 'Document';\r\n        header.appendChild(titleEl);\r\n\r\n        var closeBtn = document.createElement('button');\r\n        closeBtn.textContent = '\u00d7';\r\n        closeBtn.style.cssText =\r\n            'position:absolute;right:10px;top:50%;transform:translateY(-50%);' +\r\n            'background:transparent;border:none;color:#494949;font-size:20px;' +\r\n            'cursor:pointer;line-height:1;padding:0 4px;';\r\n        closeBtn.addEventListener('click', cleanup);\r\n        header.appendChild(closeBtn);\r\n        popup.appendChild(header);\r\n\r\n        \/\/ \u2500\u2500 Zone scrollable \u2014 pleine largeur \u2500\u2500\r\n        var scrollZone = document.createElement('div');\r\n        scrollZone.style.cssText =\r\n            'flex:1;overflow-y:auto;overflow-x:hidden;padding:0;margin:0;touch-action:pan-y;';\r\n        popup.appendChild(scrollZone);\r\n\r\n        var loader = document.createElement('div');\r\n        loader.style.cssText =\r\n            'text-align:center;padding:30px;font-family:Roboto,Arial,sans-serif;font-size:12px;color:#666;';\r\n        loader.textContent = 'Chargement du document\u2026';\r\n        scrollZone.appendChild(loader);\r\n\r\n        \/\/ \u2500\u2500 8 poign\u00e9es de redimensionnement \u2500\u2500\r\n        var handles = [\r\n            { cursor:'nw-resize', pos:'top:-4px;left:-4px;',       dx:-1, dy:-1 },\r\n            { cursor:'n-resize',  pos:'top:-4px;left:50%;',        dx:0,  dy:-1 },\r\n            { cursor:'ne-resize', pos:'top:-4px;right:-4px;',      dx:1,  dy:-1 },\r\n            { cursor:'w-resize',  pos:'top:50%;left:-4px;',        dx:-1, dy:0  },\r\n            { cursor:'e-resize',  pos:'top:50%;right:-4px;',       dx:1,  dy:0  },\r\n            { cursor:'sw-resize', pos:'bottom:-4px;left:-4px;',    dx:-1, dy:1  },\r\n            { cursor:'s-resize',  pos:'bottom:-4px;left:50%;',     dx:0,  dy:1  },\r\n            { cursor:'se-resize', pos:'bottom:-4px;right:-4px;',   dx:1,  dy:1  }\r\n        ];\r\n        handles.forEach(function(h) {\r\n            var handle = document.createElement('div');\r\n            var isCorner = (h.dx !== 0 && h.dy !== 0);\r\n            handle.style.cssText =\r\n                'position:absolute;touch-action:none;' + h.pos +\r\n                'width:' + (isCorner ? '12px' : (h.dy === 0 ? '8px' : '30px')) + ';' +\r\n                'height:' + (isCorner ? '12px' : (h.dy === 0 ? '30px' : '8px')) + ';' +\r\n                'cursor:' + h.cursor + ';z-index:10;';\r\n            (function(hInfo) {\r\n                handle.addEventListener('pointerdown', function(e) {\r\n                    e.preventDefault(); e.stopPropagation();\r\n                    handle.setPointerCapture(e.pointerId);\r\n                    var startX = e.clientX, startY = e.clientY;\r\n                    var rect0 = popup.getBoundingClientRect();\r\n                    var sY = window.scrollY || 0, sX = window.scrollX || 0;\r\n                    var startW = rect0.width, startH = rect0.height;\r\n                    var startL = rect0.left + sX, startT = rect0.top + sY;\r\n                    function onResize(ev) {\r\n                        ev.preventDefault();\r\n                        var ddx = ev.clientX - startX, ddy = ev.clientY - startY;\r\n                        var newW = startW, newH = startH, newL = startL, newT = startT;\r\n                        if (hInfo.dx === 1)  newW = Math.max(200, startW + ddx);\r\n                        if (hInfo.dx === -1) { newW = Math.max(200, startW - ddx); newL = startL + ddx; }\r\n                        if (hInfo.dy === 1)  newH = Math.max(150, startH + ddy);\r\n                        if (hInfo.dy === -1) { newH = Math.max(150, startH - ddy); newT = startT + ddy; }\r\n                        popup.style.width  = newW + 'px';\r\n                        popup.style.height = newH + 'px';\r\n                        popup.style.left   = newL + 'px';\r\n                        popup.style.top    = newT + 'px';\r\n                    }\r\n                    function onResizeEnd(ev) {\r\n                        handle.releasePointerCapture(ev.pointerId);\r\n                        handle.removeEventListener('pointermove', onResize);\r\n                        handle.removeEventListener('pointerup', onResizeEnd);\r\n                    }\r\n                    handle.addEventListener('pointermove', onResize);\r\n                    handle.addEventListener('pointerup', onResizeEnd);\r\n                });\r\n            })(h);\r\n            popup.appendChild(handle);\r\n        });\r\n\r\n        \/\/ \u2500\u2500 Drag via header \u2500\u2500\r\n        header.style.touchAction = 'none';\r\n        header.addEventListener('pointerdown', function(e) {\r\n            if (e.target === closeBtn) return;\r\n            e.preventDefault();\r\n            header.setPointerCapture(e.pointerId);\r\n            var mx = e.clientX, my = e.clientY;\r\n            var popupRect = popup.getBoundingClientRect();\r\n            var scrollY = window.scrollY || 0;\r\n            var scrollX = window.scrollX || 0;\r\n            var curLeft = popupRect.left + scrollX;\r\n            var curTop  = popupRect.top  + scrollY;\r\n            header.style.cursor = 'grabbing';\r\n            function onMove(ev) {\r\n                ev.preventDefault();\r\n                var dx = ev.clientX - mx;\r\n                var dy = ev.clientY - my;\r\n                curLeft += dx;\r\n                curTop  += dy;\r\n                popup.style.left = curLeft + 'px';\r\n                popup.style.top  = curTop  + 'px';\r\n                mx = ev.clientX;\r\n                my = ev.clientY;\r\n            }\r\n            function onUp(ev) {\r\n                header.releasePointerCapture(ev.pointerId);\r\n                header.style.cursor = 'grab';\r\n                header.removeEventListener('pointermove', onMove);\r\n                header.removeEventListener('pointerup', onUp);\r\n            }\r\n            header.addEventListener('pointermove', onMove);\r\n            header.addEventListener('pointerup', onUp);\r\n        });\r\n\r\n        \/\/ \u2500\u2500 Cleanup \u2500\u2500\r\n        function cleanup() {\r\n            popup.remove();\r\n            document.removeEventListener('keydown', escHandler);\r\n        }\r\n        var escHandler = function(e) { if (e.key === 'Escape') cleanup(); };\r\n        document.addEventListener('keydown', escHandler);\r\n\r\n        document.body.appendChild(popup);\r\n\r\n        \/\/ \u2500\u2500 Rendre le contenu \u2500\u2500\r\n        if (options.pdfDataURL)          this.renderPdfInPopup(scrollZone, options.pdfDataURL, popupW, 'dataurl');\r\n        else if (options.pdfArrayBuffer) this.renderPdfInPopup(scrollZone, options.pdfArrayBuffer, popupW, 'arraybuffer');\r\n        else if (options.htmlContent)    this.renderHtmlInPopup(scrollZone, options.htmlContent);\r\n    },\r\n\r\n    \/\/ Alias pour compatibilit\u00e9\r\n    showInlinePdfPopup($dropZone, pdfImageDataURL, formatTitle) {\r\n        this.showInlineDocPopup($dropZone, { formatTitle: formatTitle, pdfDataURL: pdfImageDataURL });\r\n    },\r\n\r\n    \/\/ \u2705 Rendu PDF dans popup (dataurl ou arraybuffer) \u2014 avec crop des marges blanches\r\n    async renderPdfInPopup(container, pdfData, popupWidth, mode) {\r\n        try {\r\n            var u8;\r\n            if (mode === 'dataurl') {\r\n                var b64 = pdfData.split(',')[1];\r\n                var bstr = atob(b64);\r\n                u8 = new Uint8Array(bstr.length);\r\n                for (var i = 0; i < bstr.length; i++) { u8[i] = bstr.charCodeAt(i); }\r\n            } else {\r\n                u8 = new Uint8Array(pdfData);\r\n            }\r\n\r\n            var pdfjsLib = window['pdfjs-dist\/build\/pdf'];\r\n            if (!pdfjsLib) {\r\n                container.innerHTML = '<div style=\"padding:20px;text-align:center;color:#c00;\">pdf.js non charg\u00e9<\/div>';\r\n                return;\r\n            }\r\n            pdfjsLib.GlobalWorkerOptions.workerSrc =\r\n                '\/\/cdn.jsdelivr.net\/npm\/pdfjs-dist@latest\/build\/pdf.worker.min.js';\r\n\r\n            var pdf = await pdfjsLib.getDocument({ data: u8 }).promise;\r\n            console.log('\ud83d\udcc4 PDF popup :', pdf.numPages, 'pages');\r\n            container.innerHTML = '';\r\n\r\n            var firstPage = await pdf.getPage(1);\r\n            var vpNative = firstPage.getViewport({ scale: 1 });\r\n            var scale = popupWidth \/ vpNative.width;\r\n\r\n            \/\/ \u2705 R\u00e9f\u00e9rence au popup pour ajuster sa hauteur apr\u00e8s rendu\r\n            var _popup = container.closest('#via-pdf-inline-popup');\r\n            var _headerH = _popup ? (_popup.querySelector('div[style*=\"grab\"]') || {offsetHeight: 44}).offsetHeight : 44;\r\n\r\n            \/\/ \u2705 D\u00e9tecte les marges blanches haut\/bas d'un canvas rendu et retourne {top, bottom}\r\n            function detectWhiteMargins(canvas) {\r\n                var ctx = canvas.getContext('2d');\r\n                var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;\r\n                var W = canvas.width, H = canvas.height;\r\n                var topRow = 0, bottomRow = H - 1;\r\n                \/\/ Chercher la premi\u00e8re ligne non-blanche (tol\u00e9rance 252 pour les artefacts anti-aliasing)\r\n                outer: for (var y = 0; y < H; y++) {\r\n                    for (var x = 0; x < W; x++) {\r\n                        var i = (y * W + x) * 4;\r\n                        if (data[i] < 252 || data[i+1] < 252 || data[i+2] < 252) { topRow = y; break outer; }\r\n                    }\r\n                }\r\n                outer2: for (var y2 = H - 1; y2 >= topRow; y2--) {\r\n                    for (var x2 = 0; x2 < W; x2++) {\r\n                        var i2 = (y2 * W + x2) * 4;\r\n                        if (data[i2] < 252 || data[i2+1] < 252 || data[i2+2] < 252) { bottomRow = y2; break outer2; }\r\n                    }\r\n                }\r\n                return { top: topRow, bottom: bottomRow };\r\n            }\r\n\r\n            for (var pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\r\n                var page = await pdf.getPage(pageNum);\r\n                var vp = page.getViewport({ scale: scale });\r\n                \/\/ Rendre dans un canvas temporaire\r\n                var tmpCanvas = document.createElement('canvas');\r\n                tmpCanvas.width = vp.width;\r\n                tmpCanvas.height = vp.height;\r\n                await page.render({ canvasContext: tmpCanvas.getContext('2d'), viewport: vp }).promise;\r\n\r\n                \/\/ \u2705 Crop marges blanches\r\n                var margins = detectWhiteMargins(tmpCanvas);\r\n                var cropTop = Math.max(0, margins.top - 4);\r\n                var cropBottom = Math.min(tmpCanvas.height - 1, margins.bottom + 4);\r\n                var croppedH = cropBottom - cropTop + 1;\r\n\r\n                \/\/ Canvas final crop\u00e9\r\n                var canvas = document.createElement('canvas');\r\n                canvas.width = tmpCanvas.width;\r\n                canvas.height = croppedH;\r\n                canvas.getContext('2d').drawImage(tmpCanvas, 0, cropTop, tmpCanvas.width, croppedH, 0, 0, tmpCanvas.width, croppedH);\r\n                canvas.style.cssText = 'display:block;width:100%;height:auto;margin:0;padding:0;';\r\n                container.appendChild(canvas);\r\n                console.log('\ud83d\udcc4 Page', pageNum, '- crop:', cropTop, '\u2192', cropBottom, '(', Math.round(cropTop\/vp.height*100), '% top trimmed)');\r\n            }\r\n\r\n            \/\/ \u2705 Ajuster la hauteur du popup \u00e0 la hauteur r\u00e9elle du contenu rendu\r\n            \/\/ (popup \u00e9tait calcul\u00e9 sur popupW*2.5*0.51 qui peut \u00eatre trop grand ou trop petit)\r\n            if (_popup) {\r\n                var _totalH = 0;\r\n                container.querySelectorAll('canvas').forEach(function(c) { _totalH += c.height * (popupWidth \/ c.width); });\r\n                var _viewportH = window.innerHeight || document.documentElement.clientHeight || 600;\r\n                var _maxPopupH = Math.round(_viewportH * 0.88);\r\n                var _idealH = Math.min(_totalH + _headerH + 8, _maxPopupH);\r\n                _popup.style.height = _idealH + 'px';\r\n                console.log('\ud83d\udcd0 Popup redimensionn\u00e9:', Math.round(_idealH), 'px (contenu:', Math.round(_totalH), ')');\r\n            }\r\n        } catch (err) {\r\n            console.error('\u274c Erreur rendu PDF popup:', err);\r\n            container.innerHTML =\r\n                '<div style=\"padding:20px;text-align:center;color:#c00;font-size:12px;\">Erreur lors du chargement du document<\/div>';\r\n        }\r\n    },\r\n\r\n    \/\/ \u2705 Rendu HTML (Word) dans popup \u2014 avec CSS complet pour mammoth\r\n    renderHtmlInPopup(container, htmlContent) {\r\n        container.innerHTML = '';\r\n        \/\/ \u2705 Nettoyer les <p> vides en d\u00e9but\/fin produits par mammoth (marges parasites)\r\n        htmlContent = htmlContent\r\n            .replace(\/^(\\s*<p[^>]*>\\s*(<br\\s*\\\/?>\\s*)*<\\\/p>\\s*)+\/i, '')\r\n            .replace(\/(\\s*<p[^>]*>\\s*(<br\\s*\\\/?>\\s*)*<\\\/p>\\s*)+$\/i, '');\r\n        \/\/ \u2500\u2500 Styles pour le HTML g\u00e9n\u00e9r\u00e9 par mammoth (titres, paragraphes, listes, images) \u2500\u2500\r\n        var style = document.createElement('style');\r\n        style.textContent = [\r\n            '.via-html-popup-body { padding:20px 24px; background:#fff; color:#222; font-family:Georgia,\"Times New Roman\",serif; font-size:15px; line-height:1.7; }',\r\n            '.via-html-popup-body h1 { font-size:22px; font-weight:700; margin:0 0 12px; line-height:1.3; }',\r\n            '.via-html-popup-body h2 { font-size:18px; font-weight:700; margin:18px 0 8px; line-height:1.3; }',\r\n            '.via-html-popup-body h3 { font-size:15px; font-weight:700; margin:14px 0 6px; }',\r\n            '.via-html-popup-body p  { margin:0 0 10px; }',\r\n            '.via-html-popup-body p:first-child { margin-top:0; }',\r\n            '.via-html-popup-body strong, .via-html-popup-body b { font-weight:700; }',\r\n            '.via-html-popup-body em, .via-html-popup-body i { font-style:italic; }',\r\n            '.via-html-popup-body ul, .via-html-popup-body ol { margin:6px 0 10px 22px; padding:0; }',\r\n            '.via-html-popup-body li { margin-bottom:4px; }',\r\n            '.via-html-popup-body img { max-width:100%; height:auto; display:block; margin:10px auto; border-radius:4px; }',\r\n            '.via-html-popup-body table { width:100%; border-collapse:collapse; margin:10px 0; font-size:13px; }',\r\n            '.via-html-popup-body td, .via-html-popup-body th { border:1px solid #ddd; padding:6px 8px; vertical-align:top; }',\r\n            '.via-html-popup-body th { background:#f0f4f8; font-weight:700; }',\r\n            '.via-html-popup-body a { color:#225da9; text-decoration:underline; }'\r\n        ].join('');\r\n        container.appendChild(style);\r\n        var wrapper = document.createElement('div');\r\n        wrapper.className = 'via-html-popup-body';\r\n        wrapper.innerHTML = htmlContent;\r\n        container.appendChild(wrapper);\r\n    },\r\n    \r\n    async renderPDFInWindow(childWindow, container) {\r\n        container.innerHTML = '';\r\n        \r\n        const script = childWindow.document.createElement('script');\r\n        script.src = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.4.120\/pdf.min.js';\r\n        childWindow.document.head.appendChild(script);\r\n        \r\n        script.onload = async () => {\r\n            const pdfjsLib = childWindow.pdfjsLib;\r\n            const viewerContainer = childWindow.document.createElement('div');\r\n            viewerContainer.style.width = '100%';\r\n            viewerContainer.style.backgroundColor = 'white';\r\n            viewerContainer.style.position = 'relative';\r\n            container.appendChild(viewerContainer);\r\n            \r\n            const loadingTask = pdfjsLib.getDocument({data: window.pdfDataToTransfer});\r\n            const pdf = await loadingTask.promise;\r\n            \r\n            const firstPage = await pdf.getPage(1);\r\n            const viewport = firstPage.getViewport({scale: 1.5});\r\n            const pageHeight = viewport.height;\r\n            \r\n            const spacing = -15;\r\n            const totalHeight = (pageHeight * pdf.numPages) + (spacing * (pdf.numPages - 1));\r\n            viewerContainer.style.height = `${totalHeight}px`;\r\n            \r\n            for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\r\n                const page = await pdf.getPage(pageNum);\r\n                const canvas = childWindow.document.createElement('canvas');\r\n                const context = canvas.getContext('2d');\r\n                \r\n                canvas.width = viewport.width;\r\n                canvas.height = viewport.height;\r\n                \r\n                canvas.style.position = 'absolute';\r\n                canvas.style.left = '50%';\r\n                canvas.style.transform = 'translateX(-50%)';\r\n                canvas.style.top = `${(pageNum - 1) * (pageHeight + spacing)}px`;\r\n                \r\n                await page.render({\r\n                    canvasContext: context,\r\n                    viewport: viewport\r\n                }).promise;\r\n                \r\n                viewerContainer.appendChild(canvas);\r\n            }\r\n        };\r\n    },\r\n    \r\n    arrayBufferToBase64(buffer) {\r\n        let binary = '';\r\n        const bytes = new Uint8Array(buffer);\r\n        const len = bytes.byteLength;\r\n        for (let i = 0; i < len; i++) {\r\n            binary += String.fromCharCode(bytes[i]);\r\n        }\r\n        return window.btoa(binary);\r\n    },\r\n    \r\n    base64ToArrayBuffer(base64) {\r\n        const binaryString = window.atob(base64);\r\n        const len = binaryString.length;\r\n        const bytes = new Uint8Array(len);\r\n        for (let i = 0; i < len; i++) {\r\n            bytes[i] = binaryString.charCodeAt(i);\r\n        }\r\n        return bytes.buffer;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion des \u00e9v\u00e9nements de drop et d'upload\r\n *\/\r\nconst DropHandler = {\r\n    async handleDrop(e) {\r\n        e.preventDefault();\r\n        \r\n        const $currentTarget = this.findDropTarget(e);\r\n        \r\n        if (!$currentTarget) {\r\n            console.log('No valid drop target found');\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 V\u00c9RIFIER SI C'EST UN D\u00c9PLACEMENT (pas besoin de v\u00e9rifier le format)\r\n        const isMoved = StateManager.get('FirstUploadFileorMoved') === 'Moved';\r\n        const dragstartRef = StateManager.get('dragstart_Commande_Emplacement_Page_Web');\r\n        let hasDragstartRef = false;\r\n        \r\n        if (dragstartRef) {\r\n            if (dragstartRef !== 'No') {\r\n                hasDragstartRef = true;\r\n            }\r\n        }\r\n        \r\n        let isDeplacementAnnonce = false;\r\n        if (isMoved) {\r\n            if (hasDragstartRef) {\r\n                isDeplacementAnnonce = true;\r\n            }\r\n        }\r\n        \r\n        if (isDeplacementAnnonce) {\r\n            console.log('\ud83d\udd04 D\u00e9placement d\u00e9tect\u00e9 - contr\u00f4le format ignor\u00e9');\r\n        } else {\r\n            \/\/ \u2705 CONTR\u00d4LE FORMAT SEULEMENT POUR NOUVEAU D\u00c9P\u00d4T\r\n            \/\/ Utilise FormatUIManager au lieu de showFormatWarning\r\n            if (StateManager.get('Formatchoisi') === 'No') {\r\n                FormatUIManager.flashTitle($currentTarget);\r\n                return;\r\n            }\r\n            \r\n            if (!FormatUIManager.hasSelectedFormat($currentTarget)) {\r\n                FormatUIManager.flashTitle($currentTarget);\r\n                return;\r\n            }\r\n        }\r\n    \r\n        console.log(\"Drop at:\", $currentTarget);\r\n        \r\n        this.updateEmplacementState($currentTarget);\r\n        \r\n        const shouldProcess = this.shouldProcessDrop(e, $currentTarget);\r\n        \r\n        if (shouldProcess) {\r\n            await this.processFileDrop(e, $currentTarget);\r\n        } else {\r\n            this.processVideoDrop($currentTarget);\r\n        }\r\n        \r\n        DragDropManager.clearDataTransferFiles(e);\r\n    },\r\n    \r\n    findDropTarget(e) {\r\n        \/\/ \u2705 v2.4.3 : Si Ele0A est actif et le drop arrive sur Ele1A \u2192 rediriger vers Ele0A\r\n        if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n            var _ele0ADrop = document.querySelector('#Ele0A #drop_file_zone_achat');\r\n            if (_ele0ADrop) {\r\n                console.log('\ud83c\udfaf findDropTarget \u2014 PopUpChoice=Yes \u2192 cible forc\u00e9e: Ele0A');\r\n                return jQuery(_ele0ADrop);\r\n            }\r\n        }\r\n\r\n        let target = e.target.closest('#drop_file_zone_achat');\r\n        \r\n        if (!target) {\r\n            target = e.currentTarget.closest('#drop_file_zone_achat');\r\n            console.log('Drop target found 1');\r\n        }\r\n        \r\n        if (!target) {\r\n            target = jQuery(e.target).closest('#drop_file_zone_achat')[0];\r\n            console.log('Drop target found 2');\r\n        }\r\n        \r\n        return target ? jQuery(target) : null;\r\n    },\r\n    \r\n    updateEmplacementState($target) {\r\n        const espaceId = $target.closest('.droppable').attr('id');\r\n        \r\n        StateManager.set('Rank_Emplacement_Page_Web', espaceId);\r\n        StateManager.set('Commande_Emplacement_Page_Web',\r\n            StateManager.buildEmplacementReference(espaceId));\r\n        \r\n        UIManager.updateEmplacementDisplay();\r\n        \r\n        console.log(\"Rank_Emplacement_Page_Web:\", StateManager.get('Rank_Emplacement_Page_Web'));\r\n        console.log(\"Droppable at:\", StateManager.get('Commande_Emplacement_Page_Web'));\r\n    },\r\n    \r\n    shouldProcessDrop(e, $target) {\r\n        const hasFiles = e.dataTransfer.files.length > 0;\r\n        const isRedactionnel = StateManager.get('Commande_Format_Transmis') === 'R\u00e9dactionnel';\r\n        const isValidBackground = window.getComputedStyle(\r\n            $target.closest('#UploadFileConteneur')[0]\r\n        ).backgroundColor !== 'rgba(0, 0, 0, 0)';\r\n        \r\n        return (hasFiles || isRedactionnel) && isValidBackground;\r\n    },\r\n    \r\n    async processFileDrop(e, $target) {\r\n        jQuery('.MsgAdNotDisplayed').hide();\r\n        StateManager.setMultiple({\r\n            \"AdDisplayed\": 'Yes',\r\n            \/\/ \u2705 NE PLUS mettre sendDataToParentFlag ici - c'est la checkbox \"R\u00e9server\" qui le fera\r\n            \/\/ \"sendDataToParentFlag\": 'Yes'\r\n        });\r\n        \r\n        console.log('ajaxFileUpload_achat launched');\r\n        console.log(\"FirstUploadFileorMoved:\", StateManager.get('FirstUploadFileorMoved'));\r\n        \r\n        if (UIManager.isMobile()) {\r\n            $target = jQuery('#Ele1A').find('#drop_file_zone_achat');\r\n        }\r\n        \r\n        if (StateManager.get('Commande_Format_Transmis') === 'R\u00e9dactionnel') {\r\n            const fileURL = StateManager.get('FullPathAdFile');\r\n            const filename = fileURL.substring(fileURL.indexOf('_') + 1);\r\n            \r\n            try {\r\n                \/\/ \u2705 R\u00e9utiliser le File cach\u00e9 (\u00e9vite CORS cross-domain)\r\n                let file;\r\n                if (window._lastRedactionnelFile) {\r\n                    file = window._lastRedactionnelFile;\r\n                    console.log('\u267b\ufe0f R\u00e9utilisation du File cach\u00e9:', file.name, Math.round(file.size \/ 1024) + 'KB');\r\n                } else {\r\n                    file = await FileManager.urlToFile(fileURL, filename);\r\n                }\r\n                await UploadManager.handleFileUpload(file, $target);\r\n            } catch (error) {\r\n                console.error('Error:', error);\r\n            }\r\n        } else {\r\n            await UploadManager.handleFileUpload(e.dataTransfer.files[0], $target);\r\n        }\r\n    },\r\n    \r\n    processVideoDrop($target) {\r\n        const isValidBackground = window.getComputedStyle(\r\n            $target.closest('#UploadFileConteneur')[0]\r\n        ).backgroundColor !== 'rgba(0, 0, 0, 0)';\r\n        \r\n        if (!isValidBackground) {\r\n            jQuery('.MsgAdNotDisplayed').show();\r\n            StateManager.set(\"AdDisplayed\", 'No');\r\n            return;\r\n        }\r\n        \r\n        StateManager.set(\"AdDisplayed\", 'Yes');\r\n        \r\n        const objectUrl = StateManager.get('videoSrc');\r\n        const $previousDropZone = $('.drop_file_zone_achat_class').has(`video[src=\"${objectUrl}\"]`);\r\n        window.RestoreadSpaceTemplate($previousDropZone);\r\n        \r\n        const videoElement = jQuery('<video controls autoplay muted>').attr({\r\n            'src': objectUrl,\r\n            'max-width': '100%',\r\n            'max-height': '100%',\r\n            'draggable': 'true'\r\n        }).css({\r\n            'max-width': '100%',\r\n            'max-height': '100%'\r\n        });\r\n        \r\n        $target.empty().append(videoElement);\r\n        \r\n        $target.closest('#UploadFileConteneur').css({'background-color': '#FFFFFF00'});\r\n        \r\n        $target.closest('.OrdiMobileConteneurClass')\r\n            .find('.RefEspacePublicitaire')\r\n            .html('R\u00e9f\u00e9rence de l\\'espace : ' + StateManager.get('Commande_Emplacement_Page_Web'))\r\n            .attr('id', 'RefEspacePublicitaire')\r\n            .each(function() {\r\n                var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                this.style.setProperty('display', 'block', 'important');\r\n            });\r\n        \/\/ \u2705 v2.4.5 : Renseigner et afficher .PositionEspacePublicitaire\r\n        (function() {\r\n            var _rankPosV = StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            var _posLibV = PreviewRenderer._getPositionLibelle(_rankPosV);\r\n            if (_posLibV) {\r\n                $target.closest('.OrdiMobileConteneurClass')\r\n                    .find('.PositionEspacePublicitaireDeplacer')\r\n                    .text(_posLibV)\r\n                    .each(function() {\r\n                        var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                        if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                        this.style.setProperty('display', 'block', 'important');\r\n                    });\r\n            }\r\n        })();\r\n        \r\n        $target.closest('.OrdiMobileConteneurClass').find('.AdUploadedTitle').show();\r\n        \r\n        $target.closest('.OrdiMobileConteneurClass')\r\n            .css({'top': '60px', 'margin-bottom': '80px'});\r\n        \r\n        $target.closest('.HTMLUploadfileConteneur')\r\n            .not('.AdUploadedTitle')\r\n            .css({\r\n                'top': '0px',\r\n                'margin-bottom': '0px',\r\n                'box-shadow': 'inset 0 0 0 2px #00FF19',  \/\/ \u2705 v2.4.5\r\n                'background-color': 'white'\r\n            });\r\n        \r\n        $target.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed, .ChoisirEspacePublicitaire2ndLigne, span.ClassHdpCdp, .ClassRefEsp, .HideFormButton, .EspPubFormatMainContainer, .EnvoiUlterieurContainer')\r\n            .hide();\r\n        \r\n        jQuery('#MsgElementsCommandeValides, #MessageOptionsacompleterConteneur').hide();\r\n        \r\n        StateManager.set(\"FirstUploadFileorMoved\", 'Moved');\r\n        \r\n        \/\/ \u2705 Mettre \u00e0 jour l'\u00e9tat de la checkbox R\u00e9server (au lieu d'envoyer automatiquement)\r\n        FormatUIManager.updateReserverCheckboxState($target.closest('.droppable'));\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'explorateur de fichiers\r\n *\/\r\nconst FileExplorer = {\r\n    isRunning: false,\r\n\r\n    open(e) {\r\n        if (this.isRunning) {\r\n            return;\r\n        }\r\n        \r\n        const $element = jQuery(e.target).closest('.droppable');\r\n        \r\n        \/\/ \u2705 V\u00e9rifier si un format est s\u00e9lectionn\u00e9 (utilise FormatUIManager)\r\n        if (!FormatUIManager.hasSelectedFormat($element)) {\r\n            FormatUIManager.flashTitle($element);\r\n            return;\r\n        }\r\n        \r\n        this.isRunning = true;\r\n        \r\n        const rankId = $element.attr('id');\r\n        \r\n        StateManager.set('Rank_Emplacement_Page_Web', rankId);\r\n        StateManager.set('Commande_Emplacement_Page_Web',\r\n            StateManager.buildEmplacementReference(rankId));\r\n        \r\n        UIManager.updateEmplacementDisplay();\r\n        \r\n        console.log(\"Drop at:\", StateManager.get('Commande_Emplacement_Page_Web'));\r\n        \r\n        StateManager.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        \r\n        const $currentTarget = jQuery(e.target).closest('#drop_file_zone_achat');\r\n        const $fileInput = jQuery('#selectfile_achat');\r\n        \r\n        console.log(\"currentTarget\", $currentTarget);\r\n        \r\n        $fileInput.off('change');\r\n        $fileInput.off('click');\r\n        \r\n        const onChange = (event) => {\r\n            this.isRunning = false;\r\n            $fileInput.off('change', onChange);\r\n            \r\n            \/\/ \u2705 NE PLUS mettre sendDataToParentFlag ici\r\n            \/\/ StateManager.set(\"sendDataToParentFlag\", 'Yes');\r\n            \r\n            if ($fileInput[0].files.length > 0) {\r\n                UploadManager.handleFileUpload($fileInput[0].files[0], $currentTarget);\r\n            }\r\n        };\r\n        \r\n        const onClick = () => {\r\n            $fileInput.off('click', onClick);\r\n            $fileInput.on('focus', function onFocus() {\r\n                setTimeout(() => {\r\n                    if (!$fileInput.val()) {\r\n                        FileExplorer.isRunning = false;\r\n                    }\r\n                }, 200);\r\n                $fileInput.off('focus', onFocus);\r\n            });\r\n        };\r\n        \r\n        $fileInput.on('change', onChange);\r\n        $fileInput.on('click', onClick);\r\n        \r\n        $fileInput.click();\r\n        \r\n        setTimeout(() => {\r\n            this.isRunning = false;\r\n        }, 300);\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion du reset d'annonce\r\n *\/\r\nconst AdResetHandler = {\r\n    handle(e) {\r\n        e.preventDefault();\r\n        console.log(\"CroixResetAnnonce click\");\r\n        \r\n        \/\/ Reset l'\u00e9tat EnvoiUlterieur\r\n        StateManager.set('EnvoiUlterieur', 'false');\r\n        \r\n        \/\/ \u2705 v1.19.6 : Reset FileReceived mais garder le format s\u00e9lectionn\u00e9\r\n        StateManager.set('FileReceived', 'No');\r\n        \r\n        const $element = jQuery(e.currentTarget);\r\n        const $droppable = $element.closest('.droppable');\r\n        const resetRef = StateManager.buildEmplacementReference($droppable.attr('id'));\r\n        \r\n        console.log(\"Reset_Commande_Emplacement_Page_Web:\", resetRef);\r\n        \r\n        \/\/ \u2705 Supprimer le bouton \"R\u00e9server\" dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        $droppable.find('.ReserverContainer').hide();\r\n        \r\n        var _rankForDel = $droppable.attr('id') || StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            MessageManager.sendDelAdToParent({\r\n                Commande_Emplacement_Page_Web: resetRef,\r\n                Rank_Emplacement_Page_Web: _rankForDel,\r\n                LoadedPageUrl: window.location.href\r\n            });\r\n        } else {\r\n            window.processdataDelAd({\r\n                Commande_Emplacement_Page_Web: resetRef,\r\n                Rank_Emplacement_Page_Web: _rankForDel,\r\n                LoadedPageUrl: window.location.href\r\n            });\r\n        }\r\n        \r\n        \/\/ \u2705 v1.16.0 : Appeler RestoreadSpaceTemplateLocal directement (accessible dans ce scope)\r\n        RestoreadSpaceTemplateLocal(e.currentTarget);\r\n        \r\n        window.FonctionCroixResetAnnonce(e.currentTarget);\r\n        \r\n        \/\/ \u2705 v2.1.1 : Sauf popup\r\n        var formatWasSelected = sessionStorage.getItem('FormatSelect') \r\n            || sessionStorage.getItem('Commande_Format_Transmis')\r\n            || $droppable.data('kitFormatSelect');\r\n        \r\n        if (sessionStorage.getItem('PopUpChoice') !== 'Yes' && (formatWasSelected || sessionStorage.getItem('Formatchoisi') === 'Yes')) {\r\n            sessionStorage.setItem('Formatchoisi', 'Yes');\r\n            console.log('\u2705 Formatchoisi forc\u00e9 \u00e0 Yes apr\u00e8s reset');\r\n        }\r\n        \r\n        \/\/ \u2705 v1.19.6 : Remettre \u00e0 jour le titre format et r\u00e9afficher la checkbox R\u00e9server\r\n        setTimeout(() => {\r\n            FormatUIManager.updateTitleColor($droppable);\r\n            FormatUIManager.updateReserverCheckboxState($droppable);\r\n            \r\n            \/\/ \u2705 R\u00e9afficher le .ReserverContainer statique\r\n            $droppable.find('.ReserverContainer').show();\r\n        }, 150);\r\n    }\r\n};\r\n\r\n\/**\r\n * \u2705 Template pour r\u00e9initialisation des espaces publicitaires (IFRAME)\r\n *\/\r\nvar adSpaceTemplatesLocal = {};\r\n\r\nfunction saveAdSpaceTemplateLocal() {\r\n    var saved = 0;\r\n    jQuery('.droppable').each(function() {\r\n        var droppableId = jQuery(this).attr('id');\r\n        if (!droppableId) return;\r\n        \r\n        \/\/ \u2705 Ne jamais sauvegarder Ele0A (clone temporaire popup, pas un template d'origine)\r\n        if (droppableId === 'Ele0A') return;\r\n        \r\n        \/\/ \u2705 Ne pas r\u00e9-\u00e9craser un template d\u00e9j\u00e0 sauvegard\u00e9\r\n        if (adSpaceTemplatesLocal[droppableId]) return;\r\n        \r\n        \/\/ \u2705 v2.3.4 : Ne pas sauvegarder si template d\u00e9j\u00e0 connu (\u00e9tat propre sauvegard\u00e9)\r\n        \/\/ Le guard hasAd est supprim\u00e9 \u2014 on veut capturer le template le plus t\u00f4t possible\r\n        \/\/ Si le template existe d\u00e9j\u00e0, on ne le r\u00e9\u00e9crase pas\r\n        \/\/ (le guard anti-\u00e9crasement if (adSpaceTemplatesLocal[droppableId]) return; suffit)\r\n        \r\n        var $content = jQuery(this).find('.OrdiMobileConteneurClass').first();\r\n        if ($content.length > 0) {\r\n            adSpaceTemplatesLocal[droppableId] = $content.clone(true, true);\r\n            saved++;\r\n        }\r\n    });\r\n    if (saved > 0) {\r\n        console.log('\u2705 Templates espaces pub sauvegard\u00e9s:', saved, 'espaces -', Object.keys(adSpaceTemplatesLocal));\r\n        return true;\r\n    }\r\n    return false;\r\n}\r\n\r\nfunction RestoreadSpaceTemplateLocal(element) {\r\n    console.log('\ud83d\udd04 RestoreadSpaceTemplateLocal', element);\r\n    \r\n    var $element = jQuery(element);\r\n    var $droppable = $element.closest('.droppable');\r\n    var droppableId = $droppable.attr('id');\r\n    \r\n    \/\/ \u2705 FIX Ele0A : pas de template sauvegard\u00e9 (clone temporaire popup)\r\n    \/\/ \u2192 pas de remplacement DOM, reset visuel direct sur le contenu existant\r\n    var _isEle0A = (droppableId === 'Ele0A');\r\n\r\n    \/\/ \u2705 v1.19.3 : Chercher le template sp\u00e9cifique \u00e0 CET espace (sauf Ele0A)\r\n    if (!_isEle0A) {\r\n        if (!droppableId || !adSpaceTemplatesLocal[droppableId]) {\r\n            if (!saveAdSpaceTemplateLocal()) {\r\n                console.error('\u274c Template non disponible');\r\n                return false;\r\n            }\r\n            if (!adSpaceTemplatesLocal[droppableId]) {\r\n                console.error('\u274c Template non trouv\u00e9 pour', droppableId);\r\n                return false;\r\n            }\r\n        }\r\n    }\r\n    \r\n    var adSpaceElement = $droppable.find('.OrdiMobileConteneurClass').first();\r\n    \r\n    if (!adSpaceElement || !adSpaceElement.length) {\r\n        console.error('\u274c OrdiMobileConteneurClass non trouv\u00e9');\r\n        return false;\r\n    }\r\n    \r\n    var newElement;\r\n    if (_isEle0A) {\r\n        \/\/ Ele0A : pas de clone \u2014 on remet en \u00e9tat le contenu existant directement\r\n        newElement = adSpaceElement;\r\n        console.log('\u2705 [Ele0A] reset visuel direct (pas de template clone)');\r\n        \/\/ \u2705 Vider le contenu du dropzone et restaurer le HTML par d\u00e9faut\r\n        \/\/ (le replaceWith n'ayant pas lieu, l'image d\u00e9pos\u00e9e et le fond blanc restent sinon)\r\n        var $dz0A = $droppable.find('#drop_file_zone_achat');\r\n        $dz0A.empty().html(\r\n            '<div id=\"drag_upload_file_achat\">' +\r\n                '<p class=\"UploadIci\" style=\"color:#FB5E2A;font-weight:600;\">Ici glisser \u2013 d\u00e9poser ou<br>t\u00e9l\u00e9charger une annonce<\/p>' +\r\n            '<\/div>'\r\n        );\r\n        \/\/ Restaurer le fond bleu #9FC5F3 et retirer les styles d'annonce upload\u00e9e\r\n        $droppable.find('#UploadFileConteneur').css({\r\n            'background-color': '#9FC5F3',\r\n            'border': '',\r\n            'box-sizing': ''\r\n        });\r\n        $droppable.find('.HTMLUploadfileConteneur').css({\r\n            'box-shadow': '',\r\n            'background-color': '',\r\n            'border': '',\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'min-height': '',\r\n            'overflow': '',\r\n            'height': '',\r\n            'max-height': ''\r\n        });\r\n        \/\/ Masquer la croix et le titre d'annonce upload\u00e9e\r\n        $droppable.find('.AdUploadedTitle, #CroixResetAnnonce, .CroixResetAnnonceContainer, .DeplaceAnnonce').hide();\r\n        $droppable.removeAttr('data-via-ad-loaded').removeAttr('data-from-miniature');\r\n        console.log('\u2705 [Ele0A] dropzone vid\u00e9 + fond restaur\u00e9');\r\n    } else {\r\n        \/\/ \u2705 v1.19.3 : Cloner le template SP\u00c9CIFIQUE \u00e0 cet espace (pas le premier)\r\n        newElement = adSpaceTemplatesLocal[droppableId].clone(true, true);\r\n        console.log('\u2705 Template utilis\u00e9 pour', droppableId);\r\n        adSpaceElement.replaceWith(newElement);\r\n        \/\/ \u2705 v2.4.12 : Effacer data-via-ad-loaded (sinon selectEspaceActif masque .ReserverContainer)\r\n        $droppable.removeAttr('data-via-ad-loaded').removeAttr('data-from-miniature');\r\n        if (window.outerWidth < 1000) {\r\n            newElement.css({'margin-top': '-25px', 'bottom': '0px'});\r\n        }\r\n    }\r\n    \r\n    \/\/ D\u00e9cocher la case Envoi diff\u00e9r\u00e9 si elle existe\r\n    newElement.find('input[name*=\"EnvoiUlterieur\"]').prop('checked', false);\r\n    \r\n    \/\/ \u2705 D\u00e9cocher la checkbox \"R\u00e9server\"\r\n    newElement.find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').prop('checked', false);\r\n    \r\n    \/\/ Reset l'\u00e9tat EnvoiUlterieur\r\n    StateManager.set('EnvoiUlterieur', 'false');\r\n    \r\n    \/\/ \u2705 v1.19.3 : R\u00e9initialiser TOUS les styles inline des conteneurs parents modifi\u00e9s pendant le d\u00e9p\u00f4t\r\n    if ($droppable.length) {\r\n        \/\/ \u2705 v2.0.9 : Restaurer les marges de l'algorithme de positionnement (sauvegard\u00e9es par styleUploadedAd)\r\n        var origMt = $droppable.data('orig-mt');\r\n        $droppable.css({\r\n            'margin-top': (origMt !== undefined) ? origMt + 'px' : '',\r\n            'margin-bottom': '',\r\n            'margin-left': '',\r\n            'margin-right': ''\r\n        });\r\n        \/\/ \u2705 v2.0.11 : Cleanup event namespace docpreview\r\n        $droppable.off('click.docpreview');\r\n        \r\n        \/\/ Reset .OrdiMobileConteneurClass margins\r\n        var $container = $droppable.find('.OrdiMobileConteneurClass');\r\n        var origMb = $container.data('orig-mb');\r\n        $container.css({\r\n            'margin-top': '',\r\n            'margin-bottom': (origMb !== undefined) ? origMb + 'px' : ''\r\n        });\r\n        \r\n        \/\/ Reset .HTMLUploadfileConteneur (set by styleUploadedAd: box-shadow inset, background-color:white)\r\n        $droppable.find('.HTMLUploadfileConteneur').css({\r\n            'border': '',\r\n            'box-shadow': '',\r\n            'outline': '',\r\n            'outline-offset': '',\r\n            'background-color': '',\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'min-height': '',\r\n            'overflow': '',\r\n            'padding': '',\r\n            'position': ''\r\n        });\r\n        $droppable.find('.via-green-border-overlay').remove();\r\n        \r\n        \/\/ \u2705 Restaurer pointer-events sur OrdiMobileConteneurClass et ses enfants\r\n        $droppable.find('.OrdiMobileConteneurClass').css('pointer-events', '');\r\n        $droppable.find('#CroixResetAnnonce').css({'pointer-events': '', 'position': '', 'z-index': ''});\r\n        \/\/ \u2705 v2.4.5 : Reset margin-right Ele0A (pos\u00e9 par adjustMobileLayout)\r\n        var _croixContReset = $droppable.find('.CroixResetAnnonceContainer')[0];\r\n        if (_croixContReset) { _croixContReset.style.removeProperty('margin-right'); _croixContReset.style.removeProperty('margin-top'); }\r\n        $droppable.find('#PopUpMessageAchattest').css('pointer-events', '');\r\n        \r\n        \/\/ \u2705 v2.0.9 : Restaurer le scale(1.4) sur .UploadFileConteneur (r\u00e9duit \u00e0 scale(1) par styleUploadedAd sur mobile)\r\n        $droppable.find('.UploadFileConteneur').css({\r\n            'transform': '',\r\n            'transform-origin': ''\r\n        });\r\n        \r\n        \/\/ Reset #UploadFileConteneur - Restaurer le fond bleu #9FC5F3 + retirer liser\u00e9 envoi diff\u00e9r\u00e9\r\n        $droppable.find('#UploadFileConteneur').css({\r\n            'width': '',\r\n            'background-color': '#9FC5F3',\r\n            'border': '',\r\n            'box-sizing': ''\r\n        });\r\n        \r\n        \/\/ Reset .ToBeHidden (set by adjustDesktopLayout: top:105px, min-height:300px + overflow mobile)\r\n        $droppable.closest('.ToBeHidden').css({\r\n            'top': '',\r\n            'min-height': '',\r\n            'overflow': ''\r\n        });\r\n        \r\n        \/\/ Reset overflow sur le parent du droppable (set by adjustDesktopLayout)\r\n        $droppable.parent().css('overflow', '');\r\n        \r\n        \/\/ \u2705 v1.19.5 : Gestion device-specific pour les textes\r\n        var isDesktop = window.outerWidth >= 1000;\r\n        \r\n        if (isDesktop) {\r\n            \/\/ Desktop : cacher les textes mobiles, afficher UploadIci\r\n            $droppable.find('.TexteMobile').hide();\r\n            $droppable.find('.TexteMobileAnnonce').hide();\r\n            $droppable.find('.TexteMobileAjoutAnnonce').hide();\r\n            $droppable.find('.UploadIci').show();\r\n        } else {\r\n            \/\/ Mobile : afficher TexteMobileAnnonce\r\n            $droppable.find('.TexteMobileAnnonce').show();\r\n        }\r\n        \r\n        \/\/ R\u00e9-afficher les \u00e9l\u00e9ments masqu\u00e9s pendant l'upload\r\n        $droppable.find('.PositionEspacePublicitaireContainer').show();\r\n        $droppable.find('.ChoisirEspacePublicitaireDisponibiliteConteneur').show();\r\n        $droppable.find('.PositionEspacePublicitaire, .ReferenceEspacePublicitaire, .ChoisirEspacePublicitaireDisponibiliteConteneur > div > .elementor-widget-text-editor').show();\r\n        $droppable.find('.AdDroppedTextNotDisplayed').hide();\r\n        \/\/ \u2705 v2.4.5 : Ele0A + PopUpChoice=Yes \u2192 ne pas r\u00e9-afficher le titre si format d\u00e9j\u00e0 s\u00e9lectionn\u00e9\r\n        var _skipTitre = (sessionStorage.getItem('PopUpChoice') === 'Yes' && $droppable.attr('id') === 'Ele0A');\r\n        $droppable.find('.SelectionFormatTitreBlanc').hide();\r\n        if (!_skipTitre) {\r\n            $droppable.find('.SelectionFormatTitre').show();\r\n        }\r\n        $droppable.find('span.ClassHdpCdp, .ClassRefEsp').show();\r\n        $droppable.find('.EspPubFormatMainContainer').show();\r\n        $droppable.find('.EspPubFormatListe').show();\r\n        $droppable.find('.ChoisirEspacePublicitaireClass').show();\r\n        $droppable.find('.GlisserDeposerConteneur').show();\r\n        $droppable.find('.OUClass').show();\r\n        $droppable.find('.PositionReference').show();\r\n        $droppable.find('.ClassHdpCdp').show();\r\n        $droppable.find('.ClassRefEsp').show();\r\n        $droppable.find('.EnvoiUlterieurTexte').show();\r\n        $droppable.find('.EnvoiUlterieurContainer').show();\r\n        \r\n        \/\/ \u2705 v1.19.5 : R\u00e9afficher le .ReserverContainer (bouton Elementor statique)\r\n        $droppable.find('.ReserverContainer').show();\r\n        newElement.find('.ReserverContainer').show();\r\n        \r\n        \/\/ Masquer les \u00e9l\u00e9ments sp\u00e9cifiques \u00e0 l'annonce upload\u00e9e\r\n        $droppable.find('.AdUploadedTitle, #CroixResetAnnonce, .CroixResetAnnonceContainer, .DeplaceAnnonce').hide();\r\n        $droppable.find('#CroixResetAnnonce').css({'position': '', 'z-index': ''});\r\n        $droppable.find('.RefEspacePublicitaire').hide();\r\n        \r\n        \/\/ Supprimer le bouton \"R\u00e9server\" dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ \u2705 v1.19.6 : Restaurer le format s\u00e9lectionn\u00e9 visuellement\r\n        \/\/ Chercher le format dans plusieurs sources possibles\r\n        var formatSelect = sessionStorage.getItem('FormatSelect') \r\n            || sessionStorage.getItem('Commande_Format_Transmis')\r\n            || $droppable.data('kitFormatSelect')\r\n            || '';\r\n        \r\n        var formatchoisi = sessionStorage.getItem('Formatchoisi');\r\n        console.log('\ud83d\udcd0 Format \u00e0 restaurer:', formatSelect, '| Formatchoisi:', formatchoisi);\r\n        \r\n        \/\/ D'abord reset tous les formats visuellement (sur newElement ET $droppable)\r\n        var $allFormats = newElement.find('.EspPubFormatContainer').add($droppable.find('.EspPubFormatContainer'));\r\n        $allFormats.css({\r\n            'background-color': '',\r\n            'border': ''\r\n        });\r\n        newElement.find('.EspPubFormat').add($droppable.find('.EspPubFormat')).css({\r\n            'color': ''\r\n        });\r\n        \r\n        \/\/ Si un format \u00e9tait s\u00e9lectionn\u00e9 (via sessionStorage OU visuellement avant)\r\n        \/\/ \u2705 v2.1.1 : Sauf popup\r\n        if ((formatSelect || formatchoisi === 'Yes') && sessionStorage.getItem('PopUpChoice') !== 'Yes') {\r\n            var formatFound = false;\r\n            \r\n            if (formatSelect) {\r\n                \/\/ \u2705 v2.1.1 : Normaliser via NFD (plus fiable que les replace manuels)\r\n                var formatLower = formatSelect.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase().replace(\/ \/g, '');\r\n                \r\n                \/\/ Appliquer sur newElement ET $droppable pour \u00eatre s\u00fbr\r\n                var $allContainers = newElement.find('.EspPubFormatContainer').add($droppable.find('.EspPubFormatContainer'));\r\n                \r\n                $allContainers.each(function() {\r\n                    var className = this.className.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    \r\n                    if (className.includes(formatLower)) {\r\n                        jQuery(this).css({'background-color': '#ffffff'});\r\n                        jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                        formatFound = true;\r\n                        \/\/ \u2705 v2.4.12 : M\u00e9moriser le format restaur\u00e9 (lu par selectEspaceActif pour re-surligner apr\u00e8s reset global)\r\n                        $droppable.attr('data-restored-format', formatSelect);\r\n                        console.log('\u2705 Format restaur\u00e9 visuellement:', formatSelect, '- classe:', this.className);\r\n                    }\r\n                });\r\n            }\r\n            \r\n            \/\/ \u2705 IMPORTANT : Pr\u00e9server Formatchoisi = Yes pour permettre l'upload\r\n            sessionStorage.setItem('Formatchoisi', 'Yes');\r\n            console.log('\u2705 Formatchoisi maintenu \u00e0 Yes');\r\n            \r\n            \/\/ Basculer les titres format (sur newElement ET $droppable)\r\n            newElement.find('.SelectionFormatTitre').hide();\r\n            newElement.find('.SelectionFormatTitreBlanc').show();\r\n            $droppable.find('.SelectionFormatTitre').hide();\r\n            $droppable.find('.SelectionFormatTitreBlanc').show();\r\n        }\r\n    }\r\n    \r\n    \/\/ \u2705 v1.19.2 : Relancer InitLoadedPage pour recalculer positions et tailles\r\n    setTimeout(function() {\r\n        if (typeof window.InitLoadedPage === 'function') {\r\n            window.InitLoadedPage();\r\n        }\r\n        \r\n        \/\/ \u2705 v1.19.6 : R\u00e9attacher les MutationObservers sur les formats\r\n        if (typeof FormatUIManager !== 'undefined' && FormatUIManager.observeFormatChanges) {\r\n            FormatUIManager.observeFormatChanges();\r\n        }\r\n    }, 100);\r\n    \r\n    console.log('\u2705 Espace publicitaire r\u00e9initialis\u00e9');\r\n    return true;\r\n}\r\n\r\n\/\/ \u2705 Exposer pour appel depuis yearbook-media.js (suppression popup mode=popup)\r\nwindow.RestoreadSpaceTemplateLocal = RestoreadSpaceTemplateLocal;\r\n\r\nwindow.verifierAffichageMsgSelectEspaceLocal = function() {\r\n    const formatChoisi = StateManager.get('Formatchoisi') === 'Yes';\r\n    const fileReceived = StateManager.get('FileReceived');\r\n    const envoiUlterieur = StateManager.get('EnvoiUlterieur');\r\n    \r\n    var dateDebut, dateFin, pays;\r\n    try {\r\n        dateDebut = window.parent.$('#form-field-DebutCampagne').val();\r\n        dateFin = window.parent.$('#form-field-FinCampagne').val();\r\n        pays = window.parent.$('#form-field-Nationalite_Societe').val();\r\n    } catch(e) {\r\n        jQuery('#MsgSelectEspace').hide();\r\n        return;\r\n    }\r\n    \r\n    if (!dateDebut || !dateFin || !pays || !formatChoisi) {\r\n        jQuery('#MsgSelectEspace').hide();\r\n        return;\r\n    }\r\n    \r\n    if (fileReceived !== 'Yes') {\r\n        if (envoiUlterieur !== 'true') {\r\n            jQuery('#MsgSelectEspace').show();\r\n        } else {\r\n            jQuery('#MsgSelectEspace').hide();\r\n        }\r\n    } else {\r\n        jQuery('#MsgSelectEspace').hide();\r\n    }\r\n};\r\n\r\n\/\/ Sauvegarder les templates au chargement (apr\u00e8s rendu complet Elementor)\r\njQuery(document).ready(function() {\r\n    \/\/ \u2705 v1.19.3 : D\u00e9lai augment\u00e9 + double sauvegarde pour garantir les bonnes dimensions\r\n    setTimeout(saveAdSpaceTemplateLocal, 3000);\r\n    setTimeout(saveAdSpaceTemplateLocal, 6000);\r\n    \/\/ \u2705 v2.3.4 : Sauvegarde imm\u00e9diate d\u00e8s que la page est pr\u00eate dans l'iframe\r\n    \/\/ (avant toute interaction utilisateur)\r\n    setTimeout(saveAdSpaceTemplateLocal, 100);\r\n    setTimeout(saveAdSpaceTemplateLocal, 500);\r\n});\r\n\r\n\/\/ \u2705 v2.3.4 : Forcer sauvegarde \u00e0 la r\u00e9ception de elementsRemoved (espaces visibles + vierges)\r\nwindow.addEventListener('message', function(e) {\r\n    if (e.data && e.data.type === 'elementsRemoved') {\r\n        \/\/ Les espaces sont vierges \u00e0 ce stade \u2192 sauvegarder imm\u00e9diatement\r\n        setTimeout(saveAdSpaceTemplateLocal, 50);\r\n        setTimeout(saveAdSpaceTemplateLocal, 300);\r\n    }\r\n});\r\n\r\n\/**\r\n * Fonction helper pour le d\u00e9p\u00f4t r\u00e9dactionnel\r\n *\/\r\nfunction RedactionnelDepose() {\r\n    jQuery('#Tariftobedisplayed').html('-');\r\n    jQuery('#TarifDataStep3').html('\u00e0 choisir').css({'color': '#FB5E2A'});\r\n    jQuery('#FormatDataStep3').html('\u00e0 choisir').css({'color': '#FB5E2A'});\r\n    jQuery('#ListePaysDirect, #ListeThemeDirect, .ListeArticles, #PageAfficheeMessage').hide();\r\n    StateManager.set(\"PositionAnnonceSelection\", 'Yes');\r\n}\r\n\r\n\/**\r\n * Exposition des fonctions globales n\u00e9cessaires\r\n *\/\r\nwindow.uploadFile_achat = (e) => DropHandler.handleDrop(e);\r\nwindow.fileExplorer_achat = (e) => FileExplorer.open(e);\r\nwindow.ajaxFileUpload_achat = (fileObj, dropZone) => UploadManager.handleFileUpload(fileObj, dropZone);\r\nwindow.ActivatesendDataToParent = (dropZone) => UploadManager.activateSendDataToParent(dropZone);\r\n\/\/ \u2705 v2.3.4 : Exposer FormatUIManager pour appel depuis Entete.txt (selectEspaceActif)\r\nwindow.FormatUIManagerRef = FormatUIManager;\r\n\r\n\/**\r\n * Initialisation de l'application\r\n *\/\r\njQuery(document).ready(() => {\r\n    StateManager.init();\r\n    ScrollHelper.init();\r\n    DragDropManager.init();\r\n    FormatUIManager.init();\r\n    \r\n    if (UIManager.isMobile()) {\r\n        UIManager.initMobileUI();\r\n    } else {\r\n        UIManager.initDesktopUI();\r\n    }\r\n    \r\n    jQuery(document).on('click', '#CroixResetAnnonce', (e) => AdResetHandler.handle(e));\r\n    \r\n    \/\/ \u2705 Clic sur le texte du label \u2192 toggle manuel de la checkbox du m\u00eame conteneur\r\n    jQuery(document).on('click', '.reserver-dynamic-label', function(e) {\r\n        e.preventDefault();\r\n        e.stopPropagation();\r\n        const $cb = $(this).closest('.reserver-dynamic-option, .reserver-dynamic-container').find('.reserver-dynamic-checkbox');\r\n        if ($cb.length) {\r\n            $cb.prop('checked', !$cb.prop('checked')).trigger('change');\r\n        }\r\n    });\r\n\r\n    \/\/ \u2705 CHECKBOX \"R\u00e9server cet espace publicitaire\" \u2014 VALIDATION ET ENVOI DES DONN\u00c9ES\r\n    \/\/ \u2705 v2.4.13 : iOS touchend\r\n    \/\/ \u2705 v2.4.13 : Mobile \u2014 \u00e9couter touchend sur input ET click\/touchend sur label\r\n    jQuery(document).on('touchend', 'input[name=\"form_fields[ReserverEspacePublicitaire]\"]', function() {\r\n        if (this._viaResTouch) { return; }\r\n        this._viaResTouch = true;\r\n        var _self = this;\r\n        setTimeout(function() { _self._viaResTouch = false; }, 500);\r\n        setTimeout(function() { jQuery(_self).trigger('change'); }, 100);\r\n    });\r\n    jQuery(document).on('touchend click', '.elementor-field-group-ReserverEspacePublicitaire label, .reserver-dynamic-label, .reserver-dynamic-option label', function(e) {\r\n        \/\/ Trouver l'input associ\u00e9\r\n        var $input = jQuery(this).closest('.elementor-field-option, .reserver-dynamic-option').find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]');\r\n        if (!$input.length) { $input = jQuery(this).siblings('input[name=\"form_fields[ReserverEspacePublicitaire]\"]'); }\r\n        if (!$input.length) { $input = jQuery('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').first(); }\r\n        if ($input.length) {\r\n            if (e.type === 'touchend') { e.preventDefault(); }\r\n            var _wasChecked = $input.prop('checked');\r\n            $input.prop('checked', !_wasChecked);\r\n            setTimeout(function() {\r\n                $input.trigger('change');\r\n            }, 50);\r\n        }\r\n    });\r\n    jQuery(document).on('change', 'input[name=\"form_fields[ReserverEspacePublicitaire]\"]', function(e) {\r\n        const $checkbox = $(this);\r\n        let $droppable = $checkbox.closest('.droppable');\r\n        if (!$droppable.length) {\r\n            $droppable = $checkbox.closest('.reserver-dynamic-container').prev('.droppable');\r\n        }\r\n        \/\/ \u2705 v2.4.13 : Fallback mobile \u2014 checkbox dans body > .reserver-dynamic-container[data-droppable-id]\r\n        if (!$droppable.length) {\r\n            const $dynContainer = $checkbox.closest('.reserver-dynamic-container');\r\n            const _droppableId = $dynContainer.attr('data-droppable-id') || '';\r\n            if (_droppableId) {\r\n                $droppable = $('#' + _droppableId);\r\n            }\r\n        }\r\n        \/\/ Dernier recours : utiliser le rank en sessionStorage\r\n        if (!$droppable.length) {\r\n            const _rankFallback = StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            if (_rankFallback) { $droppable = $('#' + _rankFallback); }\r\n        }\r\n        \r\n        \/\/ Si on d\u00e9coche\r\n        if (!$checkbox.is(':checked')) {\r\n            console.log('\u2610 Checkbox \"R\u00e9server\" d\u00e9coch\u00e9e');\r\n            \/\/ \u2705 Mettre \u00e0 jour le label\r\n            const $lbl = $checkbox.closest('.reserver-dynamic-option, .elementor-field-option').find('.reserver-dynamic-label, label').not('input');\r\n            $lbl.text('R\u00e9server cet espace publicitaire').css('color', '');\r\n            \/\/ \u2705 Notifier le parent pour d\u00e9-r\u00e9server l'item dans le r\u00e9cap\r\n            const _rankDecoche = $droppable.attr('id') || StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            const _emplacementDecoche = StateManager.buildEmplacementReference(_rankDecoche);\r\n            MessageManager.sendToParent('annulationReservation', {\r\n                Rank_Emplacement_Page_Web: _rankDecoche,\r\n                Commande_Emplacement_Page_Web: _emplacementDecoche,\r\n                LoadedPageUrl: window.location.href\r\n            });\r\n            \/\/ \u2705 v2.4.5 : M\u00e9moriser que ce rank a \u00e9t\u00e9 explicitement d\u00e9coch\u00e9\r\n            StateManager.set('_reserverDecoche_' + _rankDecoche, 'Yes');\r\n            console.log('\ud83d\udce4 annulationReservation envoy\u00e9 \u2192 parent | rank:', _rankDecoche, '| emplacement:', _emplacementDecoche);\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 V\u00e9rifier les conditions : format s\u00e9lectionn\u00e9 ET (fichier d\u00e9pos\u00e9 OU envoi diff\u00e9r\u00e9)\r\n        const hasFormat = FormatUIManager.hasSelectedFormat($droppable);\r\n        const hasFile = StateManager.get('FileReceived') === 'Yes';\r\n        const hasEnvoiDiffere = $droppable.find('input[name*=\"EnvoiUlterieur\"]:checked').length > 0;\r\n        \r\n        console.log('\ud83d\udd0d Checkbox \"R\u00e9server\" - Validation:', { hasFormat, hasFile, hasEnvoiDiffere });\r\n        \r\n        if (!hasFormat) {\r\n            \/\/ \u2705 Si un fichier est d\u00e9j\u00e0 d\u00e9pos\u00e9 \u2192 d\u00e9duire le format depuis l'extension (ne pas bloquer)\r\n            if (hasFile) {\r\n                const _uploadedName = StateManager.get('Upload_File_Name') || '';\r\n                const _ext = _uploadedName.split('.').pop().toLowerCase();\r\n                const _fileType = FileManager.getFileType(_ext);\r\n                let _deducedFormat = '';\r\n                if (_fileType === 'video') {\r\n                    _deducedFormat = sessionStorage.getItem('SiteLangue') === 'EN' ? 'Video' : 'Vid\u00e9o';\r\n                } else if (_fileType === 'image') {\r\n                    _deducedFormat = sessionStorage.getItem('SiteLangue') === 'EN' ? 'Banner' : 'Banni\u00e8re';\r\n                } else if (_fileType === 'document') {\r\n                    _deducedFormat = sessionStorage.getItem('SiteLangue') === 'EN' ? 'Press release' : 'Communiqu\u00e9';\r\n                }\r\n                if (_deducedFormat) {\r\n                    StateManager.set('Commande_Format_Transmis', _deducedFormat);\r\n                    StateManager.set('FormatSelect', _deducedFormat);\r\n                    StateManager.set('Formatchoisi', 'Yes');\r\n                    console.log('\u2705 Format d\u00e9duit depuis extension (' + _ext + '):', _deducedFormat);\r\n                    \/\/ Continuer vers l'envoi (pas de return false)\r\n                } else {\r\n                    e.preventDefault();\r\n                    $checkbox.prop('checked', false);\r\n                    FormatUIManager.flashTitle($droppable);\r\n                    console.log('\u274c R\u00e9servation bloqu\u00e9e : format non d\u00e9ductible depuis extension:', _ext);\r\n                    return false;\r\n                }\r\n            } else {\r\n                e.preventDefault();\r\n                $checkbox.prop('checked', false);\r\n                FormatUIManager.flashTitle($droppable);\r\n                console.log('\u274c R\u00e9servation bloqu\u00e9e : aucun format s\u00e9lectionn\u00e9');\r\n                return false;\r\n            }\r\n        }\r\n        \r\n        if (!hasFile && !hasEnvoiDiffere) {\r\n            e.preventDefault();\r\n            $checkbox.prop('checked', false);\r\n            console.log('\u274c R\u00e9servation bloqu\u00e9e : ni annonce d\u00e9pos\u00e9e ni envoi diff\u00e9r\u00e9');\r\n            return false;\r\n        }\r\n        \r\n        \/\/ \u2705 Conditions remplies \u2014 Pr\u00e9parer et envoyer les donn\u00e9es\r\n        console.log('\u2705 Checkbox \"R\u00e9server\" valid\u00e9e \u2014 envoi des donn\u00e9es');\r\n        \r\n        const rankId = $droppable.attr('id');\r\n        \r\n        StateManager.setMultiple({\r\n            \"sendDataToParentFlag\": \"Yes\",\r\n            \"Formatchoisi\": \"Yes\",\r\n            \"Rank_Emplacement_Page_Web\": rankId,\r\n            \"Commande_Emplacement_Page_Web\": StateManager.buildEmplacementReference(rankId),\r\n            \"LoadedPageUrl\": window.location.href,\r\n            \/\/ \u2705 v2.3.0 : Forcer avant l'envoi \u2014 le setTimeout(4000) dans activateSendDataToParent\r\n            \/\/ arrive trop tard sur le 1er clic \u2192 AddNewRefInVosCampagnes restait null\r\n            \"AddNewRefInVosCampagnes\": \"Yes\"\r\n        });\r\n        \r\n        \/\/ \u2705 D\u00e9clencher l'envoi des donn\u00e9es via activateSendDataToParent\r\n        const $dropZone = $droppable.find('#drop_file_zone_achat');\r\n        UploadManager.activateSendDataToParent($dropZone);\r\n    });\r\n    \r\n    \/\/ G\u00c9RER \"Envoi diff\u00e9r\u00e9\" \u2014 marquer l'\u00e9tat sans envoyer (c'est \"R\u00e9server\" qui envoie)\r\n    \/\/ \u2705 v2.4.13 : iOS touchend\r\n    jQuery(document).on('touchend', 'input[name*=\"EnvoiUlterieur\"]', function() {\r\n        if (this._viaTouch) { return; }\r\n        this._viaTouch = true;\r\n        var _self = this;\r\n        setTimeout(function() { _self._viaTouch = false; }, 500);\r\n        setTimeout(function() { jQuery(_self).trigger('change'); }, 100);\r\n    });\r\n    jQuery(document).on('change', 'input[name*=\"EnvoiUlterieur\"]', function(e) {\r\n        const $checkbox = $(this);\r\n        let $droppable = $checkbox.closest('.droppable');\r\n        \/\/ \u2705 v2.4.13 : Fallback mobile\r\n        if (!$droppable.length) {\r\n            const $dynContainer = $checkbox.closest('.reserver-dynamic-container');\r\n            const _droppableId = $dynContainer.attr('data-droppable-id') || '';\r\n            if (_droppableId) { $droppable = $('#' + _droppableId); }\r\n        }\r\n        if (!$droppable.length) {\r\n            const _rankFallback = StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            if (_rankFallback) { $droppable = $('#' + _rankFallback); }\r\n        }\r\n  \r\n        \/\/ Si on d\u00e9coche\r\n        if (!$checkbox.is(':checked')) {\r\n            StateManager.set('EnvoiUlterieur', 'false');\r\n            \r\n            if (typeof window.verifierAffichageMsgSelectEspaceLocal === 'function') {\r\n                window.verifierAffichageMsgSelectEspaceLocal();\r\n            }\r\n            \r\n            \/\/ Mettre \u00e0 jour l'\u00e9tat de la checkbox R\u00e9server\r\n            FormatUIManager.updateReserverCheckboxState($droppable);\r\n            return;\r\n        }\r\n        \r\n        \/\/ Si on coche, masquer le message\r\n        jQuery('#MsgSelectEspace').hide();\r\n    \r\n        \/\/ V\u00e9rifier si un format est s\u00e9lectionn\u00e9\r\n        const hasSelectedFormat = FormatUIManager.hasSelectedFormat($droppable);\r\n        \r\n        if (!hasSelectedFormat) {\r\n            e.preventDefault();\r\n            $checkbox.prop('checked', false);\r\n            FormatUIManager.flashTitle($droppable);\r\n            return false;\r\n        }\r\n        \r\n        \/\/ \u2705 FORMAT OK \u2014 Marquer l'\u00e9tat envoi diff\u00e9r\u00e9 (sans envoyer les donn\u00e9es)\r\n        const rankId = $droppable.attr('id');\r\n        \r\n        StateManager.setMultiple({\r\n            \"EnvoiUlterieur\": 'true',\r\n            \"Rank_Emplacement_Page_Web\": rankId,\r\n            \"Commande_Emplacement_Page_Web\": StateManager.buildEmplacementReference(rankId),\r\n            \"LoadedPageUrl\": window.location.href,\r\n            \"FileReceived\": \"No\",\r\n            \"FullPathAdFile\": '',\r\n            \"Upload_File_Name\": '',\r\n            \"Formatchoisi\": 'Yes'\r\n        });\r\n        \r\n        console.log('\ud83d\udcdd Envoi diff\u00e9r\u00e9 coch\u00e9 \u2014 en attente de validation via checkbox \"R\u00e9server\"');\r\n        \r\n        \/\/ \u2705 Mettre \u00e0 jour l'\u00e9tat de la checkbox R\u00e9server (maintenant activable)\r\n        FormatUIManager.updateReserverCheckboxState($droppable);\r\n    });\r\n\r\n    \/\/ \u2705 v2.2.0 : Bouton \"Cr\u00e9ation\" dans espace publicitaire \u2192 Kit Ad Creator dans le parent\r\n    jQuery(document).on('click', '.FormatIdCreation', function(e) {\r\n        e.preventDefault();\r\n        var $btn = jQuery(this);\r\n        var isActive = $btn.data('creationActive') === true;\r\n\r\n        if (isActive) {\r\n            \/\/ D\u00e9sactiver\r\n            $btn.data('creationActive', false);\r\n            $btn.find('.EspPubFormat').css({'color': '#ffffff'});\r\n            $btn.css({'background-color': 'transparent'});\r\n            MessageManager.sendToParent('closeAdCreatorFromIframe', {});\r\n            console.log('\ud83c\udfa8 Cr\u00e9ation iframe \u2192 toggle OFF, fermeture popup parent');\r\n        } else {\r\n            \/\/ Activer : texte vert sur fond blanc\r\n            $btn.data('creationActive', true);\r\n            $btn.find('.EspPubFormat').css({'color': '#37D900'});\r\n            $btn.css({'background-color': '#ffffff'});\r\n            var formatSelect = sessionStorage.getItem('FormatSelect') || '';\r\n            var formatTransmis = sessionStorage.getItem('Commande_Format_Transmis') || '';\r\n            \/\/ \u2705 v2.2.1 : Envoyer aussi Commande_Format_Transmis (format cliqu\u00e9 dans l'iframe, sans accent)\r\n            var _rankKit = $btn.closest('.droppable').attr('id') || sessionStorage.getItem('Rank_Emplacement_Page_Web') || '';\r\n            var _cSite = sessionStorage.getItem('codeSite') || '';\r\n            var _cPage = sessionStorage.getItem('codePage') || '';\r\n            var _sfxKit = _rankKit.replace('Ele', '');\r\n            var _emplKit = (_cSite && _cPage && _sfxKit) ? (_cSite + _cPage + 'L' + _sfxKit) : (sessionStorage.getItem('Commande_Emplacement_Page_Web') || '');\r\n            MessageManager.sendToParent('openAdCreatorFromIframe', { formatSelect: formatSelect, formatTransmis: formatTransmis, rankId: _rankKit, emplacement: _emplKit });\r\n            console.log('\ud83c\udfa8 Cr\u00e9ation iframe \u2192 toggle ON (FormatSelect:', formatSelect, '| Commande_Format_Transmis:', formatTransmis, ')');\r\n        }\r\n    });\r\n\r\n    \/\/ \u2705 v2.2.0 : Messages depuis le parent concernant le bouton Cr\u00e9ation\r\n    window.addEventListener('message', function(event) {\r\n        var msg = event.data;\r\n        if (!msg) return;\r\n\r\n        \/\/ \u2705 v2.2.1 : Fournir la position du titre R\u00e9server pour positionner la miniature\r\n        if (msg.type === 'getReserverLabelRect') {\r\n            var $label = jQuery('.reserver-dynamic-label').first();\r\n            if ($label.length) {\r\n                var r = $label[0].getBoundingClientRect();\r\n                var iframeScale = (window.outerWidth > 1000) ? 0.75 : 0.80; \/\/ \u2705 v2.4.12 : 0.85 \u2192 0.75 (scale r\u00e9el du parent)\r\n                event.source.postMessage({\r\n                    type: 'reserVeurLabelRectResult',\r\n                    \/\/ Retourner bottom en coordonn\u00e9es iframe internes (non scal\u00e9es)\r\n                    bottom: r.bottom,\r\n                    left: r.left,\r\n                    right: r.right,\r\n                    iframeScale: iframeScale\r\n                }, '*');\r\n            } else {\r\n                event.source.postMessage({ type: 'reserVeurLabelRectResult', bottom: null }, '*');\r\n            }\r\n        }\r\n\r\n        \/\/ Fermeture du popup \u2192 d\u00e9s\u00e9lectionner le bouton Cr\u00e9ation\r\n        if (msg.type === 'adCreatorClosedFromParent') {\r\n            jQuery('.FormatIdCreation').each(function() {\r\n                jQuery(this).data('creationActive', false);\r\n                jQuery(this).find('.EspPubFormat').css({'color': '#ffffff'});\r\n                jQuery(this).css({'background-color': 'transparent'});\r\n            });\r\n            console.log('\ud83c\udfa8 adCreatorClosedFromParent re\u00e7u \u2192 bouton Cr\u00e9ation d\u00e9s\u00e9lectionn\u00e9');\r\n        }\r\n\r\n        \/\/ Restaurer le style du bouton Cr\u00e9ation apr\u00e8s un reset de removeElements\r\n        if (msg.type === 'restoreCreationButton') {\r\n            jQuery('.FormatIdCreation').each(function() {\r\n                if (jQuery(this).data('creationActive') === true) {\r\n                    jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                    jQuery(this).css({'background-color': '#ffffff'});\r\n                }\r\n            });\r\n            console.log('\ud83c\udfa8 restoreCreationButton re\u00e7u \u2192 style Cr\u00e9ation restaur\u00e9');\r\n        }\r\n    });\r\n\r\n});\r\n\r\n\/\/ =========================================================================\r\n\/\/ \u2705 Listener kitAdCreated \u2014 annonce cr\u00e9\u00e9e par le Kit overlay (mode=kit)\r\n\/\/ Injecte directement dans l'espace pub identifi\u00e9 par rankId\r\nwindow.addEventListener('message', function(event) {\r\n    var msg = event.data;\r\n    if (!msg || msg.action !== 'kitAdCreated') return;\r\n\r\n    var _rankId = msg.rankId || '';\r\n    var _emplacement = msg.emplacement || '';\r\n    console.log('\ud83c\udfa8 [espace_pub] kitAdCreated re\u00e7u | rankId:', _rankId, '| emplacement:', _emplacement);\r\n\r\n    if (!_rankId) { console.warn('\u26a0\ufe0f [kitAdCreated] rankId manquant'); return; }\r\n\r\n    var $droppable = jQuery('#' + _rankId);\r\n    if (!$droppable.length) { console.warn('\u26a0\ufe0f [kitAdCreated] droppable non trouv\u00e9:', _rankId); return; }\r\n    var $dropZone = $droppable.find('.drop_file_zone_achat_class').first();\r\n    if (!$dropZone.length) { $dropZone = $droppable.find('#drop_file_zone_achat').first(); }\r\n    if (!$dropZone.length) { console.warn('\u26a0\ufe0f [kitAdCreated] dropZone non trouv\u00e9e dans', _rankId); return; }\r\n\r\n    var _dataURL = msg.fullResDataURL || msg.pdfDataURL || null;\r\n    var _filename = msg.filename || 'annonce.png';\r\n    var _isPDF = msg.isPDF || false;\r\n    if (!_dataURL) { console.warn('\u26a0\ufe0f [kitAdCreated] aucune donn\u00e9e image'); return; }\r\n\r\n    var _parts = _dataURL.split(',');\r\n    var _mime = (_parts[0].match(\/:(.*?);\/) || [])[1] || (_isPDF ? 'application\/pdf' : 'image\/png');\r\n    var _bStr = atob(_parts[1]);\r\n    var _bytes = new Uint8Array(_bStr.length);\r\n    for (var _i = 0; _i < _bStr.length; _i++) { _bytes[_i] = _bStr.charCodeAt(_i); }\r\n    var _blob = new Blob([_bytes], { type: _mime });\r\n    \/\/ \u2705 Ajouter extension si absente\r\n    var _MIME_EXT = {'image\/png':'.png','image\/jpeg':'.jpg','image\/jpg':'.jpg','image\/webp':'.webp','application\/pdf':'.pdf'};\r\n    if (_filename.indexOf('.') === -1) { _filename = _filename + (_MIME_EXT[_mime] || (_isPDF ? '.pdf' : '.png')); }\r\n    var _file = new File([_blob], _filename, { type: _mime });\r\n\r\n    \/\/ \u2705 Pr\u00e9parer StateManager\r\n    StateManager.set('Rank_Emplacement_Page_Web', _rankId);\r\n    StateManager.set('Commande_Emplacement_Page_Web', _emplacement);\r\n    StateManager.set('Formatchoisi', 'Yes');\r\n    \/\/ \u2705 Marquer le droppable directement en DOM \u2014 r\u00e9siste \u00e0 l'async, lu par styleUploadedAd\r\n    $droppable[0].setAttribute('data-kit-drop', 'true');\r\n    window._dropFromMiniature = true;\r\n\r\n    console.log('\u2705 [kitAdCreated] \u2192 UploadManager.handleFileUpload | rankId:', _rankId);\r\n    UploadManager.handleFileUpload(_file, $dropZone).then(function() {\r\n        console.log('\u2705 [kitAdCreated] handleFileUpload termin\u00e9');\r\n    }).catch(function(err) {\r\n        window._dropFromMiniature = false;\r\n        $droppable[0].removeAttribute('data-kit-drop');\r\n        console.error('\u274c [kitAdCreated] handleFileUpload erreur:', err);\r\n    });\r\n});\r\n\r\n\/\/ \u2705 v1.17.0 : Listener \"thumbnailDropped\" \u2014 d\u00e9p\u00f4t de l'annonce depuis la miniature\r\n\/\/ =========================================================================\r\n\/**\r\n * Re\u00e7oit le drop de l'image-annonce depuis la miniature dans la page parente.\r\n * Identifie l'espace publicitaire sous le curseur, s\u00e9lectionne cet espace,\r\n * et d\u00e9clenche le flux dataFromIframeEspacePub en mode \"envoi diff\u00e9r\u00e9\"\r\n * (l'utilisateur uploadera le vrai fichier depuis le formulaire de commande).\r\n *\r\n * Coordonn\u00e9es re\u00e7ues : viewport de l'iframe (clientX\/clientY relatifs \u00e0 l'iframe)\r\n *\/\r\nwindow.addEventListener('message', function(event) {\r\n    var msg = event.data;\r\n    if (!msg || msg.action !== 'thumbnailDropped') return;\r\n\r\n    console.log('\ud83d\udce8 thumbnailDropped re\u00e7u \u2014 coords iframe:', msg.xRel, msg.yRel);\r\n\r\n    \/\/ \u2705 v1.19.3 : Corriger les coordonn\u00e9es pour le facteur de scale de l'iframe\r\n    \/\/ \u2705 v2.4.10 : 0.75 = scale appliqu\u00e9 par le PARENT sur l'\u00e9l\u00e9ment iframe (et non 0.85 qui est le scale interne OrdiMobileConteneurClass)\r\n    \/\/ Les coords xRel\/yRel viennent de getBoundingClientRect() sur l'iframe scal\u00e9 \u00e0 0.75 dans le parent \u2192 diviser par 0.75\r\n    var iframeScale = (window.outerWidth > 1000) ? 0.75 : 0.80;\r\n    \/\/ \u2705 v2.4.3 : Si Entete a intercept\u00e9 et pos\u00e9 un redirect vers Ele0A, utiliser ces coords\r\n    var _redirect = window._thumbnailDropRedirect || null;\r\n    window._thumbnailDropRedirect = null;\r\n    \/\/ \u2705 v2.4.4 : Les coords de redirect viennent de getBoundingClientRect() dans l'iframe (espace logique)\r\n    \/\/            \u2192 ne pas re-diviser par iframeScale (d\u00e9j\u00e0 en coords iframe-logiques)\r\n    var xAdjusted = _redirect ? _redirect.xRel : (msg.xRel \/ iframeScale);\r\n    var yAdjusted = _redirect ? _redirect.yRel : (msg.yRel \/ iframeScale);\r\n    if (_redirect) { console.log('\ud83d\udd00 [thumbnailDropped] coords redirig\u00e9es vers Ele0A:', Math.round(xAdjusted), Math.round(yAdjusted)); }\r\n    else { console.log('\ud83d\udcd0 Coords ajust\u00e9es (scale', iframeScale, '):', Math.round(xAdjusted), Math.round(yAdjusted)); }\r\n\r\n    \/\/ 1. Identifier l'espace publicitaire le plus proche du point de drop\r\n    \/\/    \u2705 v1.18.1 : Recherche par distance \u2014 coords \u00e9ventuellement redirig\u00e9es par Entete.txt\r\n    var allDroppables = document.querySelectorAll('.droppable');\r\n    var droppableEl = null;\r\n    var closestDist = Infinity;\r\n\r\n    \/\/ \u2705 v2.4.4 : Guard rect Ele0A \u2014 si PopUpChoice=Yes ET curseur dans le rect d'Ele0A \u2192 forcer\r\n    \/\/            (Ele0A est un popup flottant : son centre peut \u00eatre loin du curseur \u2192 algo distance l'ignore)\r\n    \/\/            Ne force PAS si le drop est hors d'Ele0A \u2192 les autres espaces restent accessibles\r\n    if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n        var _ele0ACheck = document.getElementById('Ele0A');\r\n        if (_ele0ACheck) {\r\n            var _r0A = _ele0ACheck.getBoundingClientRect();\r\n            var _margin = 30;\r\n            var _inR0A = (xAdjusted >= _r0A.left - _margin);\r\n            if (_inR0A) { _inR0A = (xAdjusted <= _r0A.right + _margin); }\r\n            if (_inR0A) { _inR0A = (yAdjusted >= _r0A.top - _margin); }\r\n            if (_inR0A) { _inR0A = (yAdjusted <= _r0A.bottom + _margin); }\r\n            if (_inR0A) {\r\n                droppableEl = _ele0ACheck;\r\n                closestDist = 0;\r\n                console.log('\ud83c\udfaf [thumbnailDropped] Ele0A forc\u00e9 (curseur dans rect Ele0A +30px)');\r\n            }\r\n        }\r\n    }\r\n\r\n    if (!droppableEl) {\r\n        allDroppables.forEach(function(d) {\r\n            var r = d.getBoundingClientRect();\r\n            var dCenterX = r.left + r.width  \/ 2;\r\n            var dCenterY = r.top  + r.height \/ 2;\r\n            var dist = Math.abs(dCenterX - xAdjusted) + Math.abs(dCenterY - yAdjusted);\r\n            if (dist < closestDist) { closestDist = dist; droppableEl = d; }\r\n        });\r\n        \/\/ \u2705 v2.4.3 : Si Entete a d\u00e9tect\u00e9 un drop sur Ele0A \u2192 forcer directement\r\n        if (_redirect) { if (_redirect.forceEle0A) {\r\n            var _ele0AForced = document.getElementById('Ele0A');\r\n            if (_ele0AForced) { droppableEl = _ele0AForced; console.log('\ud83c\udfaf [thumbnailDropped] Ele0A forc\u00e9 (redirect Entete)'); }\r\n        } }\r\n    }\r\n\r\n    if (!droppableEl || closestDist > 800) {\r\n        console.warn('thumbnailDropped \u2014 aucun droppable proche (dist min:', closestDist, ')');\r\n        return;\r\n    }\r\n    console.log('\ud83d\udccd Droppable trouv\u00e9:', droppableEl.id, '(dist:', Math.round(closestDist), ')');\r\n\r\n    var $droppable = jQuery(droppableEl);\r\n    var rankId = $droppable.attr('id');\r\n    if (!rankId) { console.warn('thumbnailDropped \u2014 .droppable sans id'); return; }\r\n\r\n    var $dropZone = $droppable.find('#drop_file_zone_achat').first();\r\n    if (!$dropZone.length) { console.warn('thumbnailDropped \u2014 #drop_file_zone_achat introuvable dans', rankId); return; }\r\n\r\n    var emplacementRef = StateManager.buildEmplacementReference(rankId);\r\n    console.log('\u2705 thumbnailDropped \u2014 espace pub:', rankId, '\u2192', emplacementRef);\r\n\r\n    \/\/ 2. Pr\u00e9parer l'\u00e9tat SessionStorage (comme un vrai drop de fichier)\r\n    StateManager.setMultiple({\r\n        'Rank_Emplacement_Page_Web':     rankId,\r\n        'Commande_Emplacement_Page_Web': emplacementRef,\r\n        'FirstUploadFileorMoved':        'FirstUpload',\r\n        'Formatchoisi':                  'Yes',\r\n        'Commande_Format_Transmis':      'Image',\r\n        'EnvoiUlterieur':                'false',\r\n        'FileReceived':                  'No',\r\n        'AdDisplayed':                   'Yes'\r\n    });\r\n\r\n    UIManager.updateEmplacementDisplay();\r\n\r\n    \/\/ 3. Construire le File \u00e0 partir du PDF (communiqu\u00e9\/interview) ou de l'image PNG (autres formats)\r\n    \/\/    puis appeler handleFileUpload \u2192 m\u00eame flux qu'un vrai drag&drop : liser\u00e9 vert, aper\u00e7u, R\u00e9server\r\n    var dataURL, mime, ext;\r\n\r\n    \/\/ \u2705 Stocker le PDF image et le format sur le droppable pour le popup de visualisation inline\r\n    if (msg.pdfImageDataURL) {\r\n        $droppable.data('kitPdfImageDataURL', msg.pdfImageDataURL);\r\n        $droppable.data('kitFormatSelect', msg.FormatSelect || '');\r\n        console.log('\ud83d\udcce pdfImageDataURL stock\u00e9 sur', rankId, '| format:', msg.FormatSelect);\r\n    } else {\r\n        $droppable.removeData('kitPdfImageDataURL');\r\n        $droppable.removeData('kitFormatSelect');\r\n    }\r\n\r\n    if (msg.isPDF && msg.pdfDataURL) {\r\n        \/\/ \u2500\u2500 Format PDF (communiqu\u00e9 \/ interview) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        dataURL = msg.pdfDataURL;                         \/\/ \"data:application\/pdf;base64,\u2026\"\r\n        mime    = 'application\/pdf';\r\n        ext     = '.pdf';\r\n    } else if (msg.imageDataURL) {\r\n        \/\/ \u2500\u2500 Format image (banni\u00e8re \/ parrainage) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        dataURL = msg.imageDataURL;\r\n        var mimeMatch = dataURL.match(\/^data:([^;]+);base64,\/);\r\n        mime    = mimeMatch ? mimeMatch[1] : 'image\/png';\r\n        ext     = mime === 'image\/jpeg' ? '.jpg' : '.png';\r\n    } else {\r\n        console.warn('thumbnailDropped \u2014 aucune donn\u00e9e image\/pdf disponible');\r\n        return;\r\n    }\r\n\r\n    var baseName = msg.filename ? msg.filename.replace(\/\\.[^.]+$\/, '') : 'annonce-kit';\r\n    var fileName = baseName + ext;\r\n\r\n    \/\/ dataURL \u2192 Uint8Array \u2192 Blob \u2192 File\r\n    var b64  = dataURL.split(',')[1];\r\n    var bstr = atob(b64);\r\n    var u8   = new Uint8Array(bstr.length);\r\n    for (var i = 0; i < bstr.length; i++) { u8[i] = bstr.charCodeAt(i); }\r\n    var blob    = new Blob([u8], { type: mime });\r\n    var fileObj = new File([blob], fileName, { type: mime });\r\n\r\n    console.log('thumbnailDropped \u2192 handleFileUpload:', fileName, Math.round(fileObj.size \/ 1024) + 'KB');\r\n\r\n    \/\/ \u2705 Cacher le File pour r\u00e9utilisation lors des d\u00e9placements (\u00e9vite CORS)\r\n    window._lastRedactionnelFile = fileObj;\r\n\r\n    \/\/ \u2705 v2.4.10 : Signaler \u00e0 adjustDesktopLayout que c'est un drop depuis la miniature\r\n    \/\/ \u2192 applique max-height sur HTMLUploadfileConteneur pour \u00e9viter le d\u00e9bordement vertical (homepage corps de page)\r\n    window._dropFromMiniature = true;\r\n    UploadManager.handleFileUpload(fileObj, $dropZone);\r\n\r\n    \/\/ \u2705 v1.19.1 : Positionner l'espace \u00e0 10px du haut du viewport (tous formats)\r\n    \/\/ \u2705 v2.4.13 : Skip si drop depuis miniature \u2014 selectEspaceActif g\u00e8re d\u00e9j\u00e0 le scroll\r\n    if (!window._dropFromMiniature) {\r\n        setTimeout(function() {\r\n            var el = $droppable.find('.HTMLUploadfileConteneur')[0] || $droppable[0];\r\n            if (el) {\r\n                ScrollHelper.scrollElementTo(el, 10);\r\n            }\r\n        }, 400);\r\n    }\r\n});\r\n\r\nconsole.log('This is a ' + (UIManager.isDesktop() ? 'desktop' : 'non-desktop') + ' device.');\r\n\r\n} \/\/ end _espPubScriptLoaded guard\r\n<\/script>\r\n\r\n<style>\r\n\/* Les styles CSS restent inchang\u00e9s *\/\r\n#drop_file_zone_achat {\r\n    background-color: #FFFFFF00;\r\n    color: #225DA9;\r\n    font-weight: 500;\r\n    text-align: center;\r\n    border: #999 0px dashed;\r\n    width: 100%;\r\n    height: 180px;\r\n    font-size: 11.5px;\r\n    display: flex;\r\n    justify-content: center; \r\n    align-items: center; \r\n    flex-wrap: wrap;\r\n}\r\n\r\n#drag_upload_file_achat {\r\n    margin: 0 auto;\r\n    width: 90%;\r\n    height: 60px;\r\n}\r\n\r\n#drag_upload_file_achat p {\r\n    text-align: center;\r\n}\r\n\r\n\/* \u2705 v1.16.0 : Liser\u00e9 noir fin autour du texte \"Ici glisser \u2013 d\u00e9poser\" *\/\r\n.GlisserDeposerConteneur .elementor-widget-container p {\r\n    border: 1px solid #000000;\r\n    border-radius: 4px;\r\n    padding: 4px 10px;\r\n    display: inline-block;\r\n}\r\n\r\n#selectfile_achat {\r\n    display: none;\r\n}\r\n\r\n.button-2_achat, .button-2_achat-after-reset {\r\n    background-color: #ffffff00!important;\r\n    border: 1px solid white!important;\r\n    border-radius: 8px;\r\n    color: #225DA9!important;\r\n    cursor: pointer;\r\n    display: inline-block;\r\n    font-size: 11px;\r\n    font-weight: 500;\r\n    list-style: none;\r\n    width: 390px;\r\n    height: 62px;\r\n    top: 0px!important; \r\n    margin-top: 0px!important; \r\n    padding-left: 5px!important;\r\n    padding-right: 5px!important;\r\n    margin-bottom: 70px!important;\r\n    margin: 0;\r\n    text-align: center;\r\n    transition: all 200ms;\r\n    vertical-align: baseline;\r\n    white-space: wrap!important;\r\n}\r\n\r\n@media only screen and (max-width: 1000px) {\r\n    .button-2_achat, .button-2_achat-after-reset {\r\n        width: 95%;\r\n        height: 50px;\r\n    }\r\n}\r\n\r\n.newMessageClass {\r\n    background-color: #FFFFFF00!important;\r\n    font-size: 13px; \r\n    font-weight: 600;\r\n    color: #56BE50;\r\n    height: 35px;\r\n    width: 550px; \r\n    position: relative;\r\n    z-index: 99;\r\n    top: 45px;\r\n    bottom: 0px;\r\n    right: 0px;\r\n    left: 0px;\r\n    display: flex;\r\n    justify-content: center;\r\n    align-items: center;\r\n    text-align: center;\r\n}\r\n\r\n.MessageClassFormatnonReconnuTitre {\r\n    background-color: #FFFFFF00!important;\r\n    font-size: 13px; \r\n    font-weight: 600;\r\n    color: #FB5E2A;\r\n    height: 35px;\r\n    width: 550px; \r\n    position: relative;\r\n    z-index: 99;\r\n    margin-top: -300px;\r\n    right: 0px;\r\n    text-align: center;\r\n    line-height: 15px;\r\n}\r\n\r\n.MessageClassFormatnonReconnu {\r\n    background-color: #FFFFFF00!important;\r\n    font-size: 13px; \r\n    font-weight: 600;\r\n    color: #ffffff;\r\n    height: 35px;\r\n    width: 550px; \r\n    position: relative;\r\n    z-index: 99;\r\n    margin-top: -280px;\r\n    right: 0px;\r\n    text-align: center;\r\n    line-height: 15px;\r\n}\r\n\r\n.newButtonClass {\r\n    font-size: 12px; \r\n    font-weight: 500;\r\n    background-color: #ffffff00;\r\n    color: #717171;\r\n    height: 10px;\r\n    width: 100%; \r\n    position: relative;\r\n    z-index: 99;\r\n    top: 45px;\r\n    bottom: 0px;\r\n    text-align: center;\r\n    right:  50px;\r\n    line-height: 10px;\r\n    border-radius: 3px;\r\n    border: 0px solid #E8ECF1;\r\n}\r\n\r\n.linkClass {\r\n    width: 15px; \r\n    height: 15px;\r\n    margin-top: -310px;\r\n    margin-bottom: -25px;\r\n    margin-right: -50px;\r\n    position: relative;\r\n    top: 0; \r\n    z-index: 99;\r\n    display: block;\r\n    background-image: url('https:\/\/rdc.via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-blanc.jpg');\r\n    background-size: cover;\r\n}\r\n\r\n.newButtonClassVideo {\r\n    font-size: 12px; \r\n    font-weight: 500;\r\n    background-color: #ffffff00;\r\n    color: #717171;\r\n    height: 10px;\r\n    width: 100%; \r\n    position: relative;\r\n    z-index: 99;\r\n    top: 0px;\r\n    bottom: 0px;\r\n    right: 10px;\r\n    text-align: center;\r\n    line-height: 10px;\r\n    border-radius: 3px;\r\n    border: 0px solid #E8ECF1;\r\n}\r\n\r\n.linkClassVideo {\r\n    width: 15px; \r\n    height: 15px;\r\n    margin-top: -438px;\r\n    margin-bottom: -25px;\r\n    margin-right: -15px;\r\n    position: relative;\r\n    top: 0; \r\n    z-index: 99;\r\n    display: block;\r\n    background-image: url('https:\/\/rdc.via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-blanc.jpg');\r\n    background-size: cover;\r\n}\r\n\r\n.FinCampagneMobileClass .elementor-button,\r\n.DebutCampagneMobileClass .elementor-button,\r\n.FormSelectDevisesMobile .elementor-button,\r\n.HideFormButton .elementor-button {\r\n    display: none !important;\r\n}\r\n\r\n#drag_upload_file_achat {\r\n    margin: 0;\r\n    padding: 0;\r\n    position: relative;\r\n}\r\n\r\n.dot-container {\r\n    display: inline-block;\r\n}\r\n\r\n.dot {\r\n    opacity: 0;\r\n    transition: opacity 0.3s ease;\r\n}\r\n\r\n@keyframes firstDot {\r\n    0%, 100% { opacity: 0; }\r\n    10%, 70% { opacity: 1; }\r\n    90% { opacity: 0; }\r\n}\r\n\r\n@keyframes secondDot {\r\n    0%, 20%, 100% { opacity: 0; }\r\n    30%, 70% { opacity: 1; }\r\n    90% { opacity: 0; }\r\n}\r\n\r\n@keyframes thirdDot {\r\n    0%, 40%, 100% { opacity: 0; }\r\n    50%, 70% { opacity: 1; }\r\n    90% { opacity: 0; }\r\n}\r\n\r\n.dot:nth-child(1) {\r\n    animation: firstDot 3s infinite;\r\n}\r\n\r\n.dot:nth-child(2) {\r\n    animation: secondDot 3s infinite;\r\n}\r\n\r\n.dot:nth-child(3) {\r\n    animation: thirdDot 3s infinite;\r\n}\r\n\r\n.droppable .elementor-field-type-checkbox .elementor-field-option {\r\n    display: flex;\r\n    flex-direction: row-reverse;\r\n    align-items: center;\r\n    gap: 8px;\r\n}\r\n\r\n.droppable .elementor-field-type-checkbox .elementor-field-option input[type=\"checkbox\"] {\r\n    width: 12px;\r\n    height: 12px;\r\n    min-width: 12px;\r\n    min-height: 12px;\r\n}\r\n\r\n\/* \u2705 Bouton \"R\u00e9server\" dynamique *\/\r\n.reserver-dynamic-container {\r\n    text-align: center;\r\n    margin-top: -7px;\r\n    margin-bottom: 15px;\r\n    padding: 5px 0;\r\n    transform: scale(1.4);\r\n    transform-origin: center top;\r\n    position: relative;\r\n    z-index: 200;\r\n}\r\n\r\n@media only screen and (min-width: 1001px) {\r\n    .reserver-dynamic-container {\r\n        transform: scale(1);\r\n        margin-top: -200px;\r\n        margin-bottom: 0;\r\n    }\r\n}\r\n\r\n.reserver-dynamic-option {\r\n    display: inline-flex;\r\n    flex-direction: row-reverse;\r\n    align-items: center;\r\n    gap: 8px;\r\n    cursor: pointer;\r\n    color: #213864;\r\n    background-color: #ffffff;\r\n    padding: 2px 4px;\r\n    border-radius: 6px;\r\n}\r\n\r\n.reserver-dynamic-checkbox {\r\n    width: 16px;\r\n    height: 16px;\r\n    min-width: 16px;\r\n    min-height: 16px;\r\n    cursor: pointer;\r\n    pointer-events: auto;\r\n}\r\n\r\n.reserver-dynamic-label {\r\n    cursor: pointer;\r\n    color: #213864;\r\n    font-size: 16px;\r\n    font-weight: 600;\r\n    user-select: none;\r\n}\r\n\r\n@media only screen and (max-width: 1000px) {\r\n    .reserver-dynamic-container {\r\n        transform: scale(0.98);\r\n        margin-bottom: 20px;\r\n        white-space: nowrap;\r\n        z-index: 300;\r\n        pointer-events: auto;\r\n    }\r\n    .reserver-dynamic-option {\r\n        padding-top: 0px;\r\n        padding-bottom: 0px;\r\n    }\r\n}\r\n\r\n\/* \u2705 v2.1.3 : DeplaceAnnonceText \/ DeplaceAnnonce \u2014 desktop uniquement *\/\r\n@media only screen and (min-width: 1001px) {\r\n    .DeplaceAnnonceText {\r\n        margin-top: -5px;\r\n        position: relative;\r\n        z-index: 201;\r\n    }\r\n    .DeplaceAnnonce {\r\n        margin-bottom: -150px;\r\n    }\r\n}\r\n<\/style>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-54e4e530 e-con-full MsgFormatIncorrectConteneur elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile e-flex e-con e-child\" data-id=\"54e4e530\" data-element_type=\"container\" id=\"NotusedAnymore\">\n\t\t\t\t<div class=\"elementor-element elementor-element-531f3cb1 MsgFormatIncorrect elementor-widget__width-inherit elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"531f3cb1\" data-element_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 style=\"text-align: center;\">Le format du fichier n&rsquo;est pas reconnu<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3a352c3f elementor-hidden-desktop TexteMobile TexteMobileAnnonce elementor-widget elementor-widget-text-editor\" data-id=\"3a352c3f\" data-element_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\tGlisser-d\u00e9poser ou cliquer ici<br>pour t\u00e9l\u00e9charger une annonce\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7abb0aba elementor-hidden-desktop TexteMobileAjoutAnnonce elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"7abb0aba\" data-element_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 style=\"text-align: center;\">Cliquer ici pour t\u00e9l\u00e9charger une annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-68e2b2ca UploadIci elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"68e2b2ca\" data-element_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>Ici glisser-d\u00e9poser ou t\u00e9l\u00e9charger une annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-8d50d33 e-con-full e-flex e-con e-child\" data-id=\"8d50d33\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6ae6ef83 elementor-button-align-center elementor-widget__width-initial HideFormButton EspPubLienAnnonce elementor-widget-mobile__width-initial elementor-widget elementor-widget-form\" data-id=\"6ae6ef83\" data-element_type=\"widget\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_URL_annonce\" aria-label=\"Formulaire_URL_annonce\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249679\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"6ae6ef83\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-text elementor-field-group elementor-column elementor-field-group-LienAnnonce elementor-col-100 elementor-sm-100 elementor-field-required\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-LienAnnonce\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tIci renseigner si n\u00e9cessaire le lien hypertexte de l\u2019annonce\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<input size=\"1\" type=\"text\" name=\"form_fields[LienAnnonce]\" id=\"form-field-LienAnnonce\" class=\"elementor-field elementor-size-xs  elementor-field-textual\" placeholder=\"Ici renseigner si n\u00e9cessaire le lien hypertexte de l\u2019annonce\" required=\"required\">\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidURLAnnonce\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-66fd4d36 e-con-full EnvoiUlterieurContainer e-flex e-con e-child\" data-id=\"66fd4d36\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4ea8e2b4 elementor-button-align-center elementor-widget__width-auto HideFormButton EnvoiUlterieur elementor-widget elementor-widget-form\" data-id=\"4ea8e2b4\" data-element_type=\"widget\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_Envoi_Ulterieur\" aria-label=\"Formulaire_Envoi_Ulterieur\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249679\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"4ea8e2b4\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-checkbox elementor-field-group elementor-column elementor-field-group-EnvoiUlterieur elementor-col-100 elementor-sm-100\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-EnvoiUlterieur\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tEnvoi diff\u00e9r\u00e9 de l'annonce\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t<div class=\"elementor-field-subgroup\"><span class=\"elementor-field-option\"><input type=\"checkbox\" value=\"Envoi diff\u00e9r\u00e9 de l&#039;annonce\" id=\"form-field-EnvoiUlterieur-0\" name=\"form_fields[EnvoiUlterieur]\"> <label for=\"form-field-EnvoiUlterieur-0\">Envoi diff\u00e9r\u00e9 de l'annonce<\/label><\/span><\/div>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidEnvoiUlterieur\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\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-4a59cf88 EnvoiUlterieurTexte elementor-widget elementor-widget-text-editor\" data-id=\"4a59cf88\" data-element_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 style=\"text-align: center;\">Envoyer l\u2019annonce jusqu\u2019\u00e0 8 jours apr\u00e8s paiement<br>\nUn lien vous sera adress\u00e9 par <span style=\"color: #ffffff;\"><a style=\"color: #ffffff;\" href=\"mailto:contact@via-agency.media\">contact@via-agency.media<\/a><\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-17d3ad0c e-con-full ReserverContainer e-flex e-con e-child\" data-id=\"17d3ad0c\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-177c9b71 elementor-button-align-center elementor-widget__width-auto HideFormButton ReserverBouton elementor-widget elementor-widget-form\" data-id=\"177c9b71\" data-element_type=\"widget\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_Envoi_Ulterieur\" aria-label=\"Formulaire_Envoi_Ulterieur\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249679\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"177c9b71\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-checkbox elementor-field-group elementor-column elementor-field-group-ReserverEspacePublicitaire elementor-col-100 elementor-sm-100\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-ReserverEspacePublicitaire\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tR\u00e9server cet espace publicitaire\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t<div class=\"elementor-field-subgroup\"><span class=\"elementor-field-option\"><input type=\"checkbox\" value=\"R\u00e9server cet espace publicitaire\" id=\"form-field-ReserverEspacePublicitaire-0\" name=\"form_fields[ReserverEspacePublicitaire]\"> <label for=\"form-field-ReserverEspacePublicitaire-0\">R\u00e9server cet espace publicitaire<\/label><\/span><\/div>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidEnvoiUlterieur\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-5bafe1f3 e-con-full AdUploadedTitle DeplaceAnnonce elementor-hidden-tablet elementor-hidden-mobile elementor-hidden-desktop e-flex e-con e-child\" data-id=\"5bafe1f3\" data-element_type=\"container\" id=\"DeplaceAnnonceId\">\n\t\t<div class=\"elementor-element elementor-element-432cc2a1 e-con-full DeplaceAnnonceSubContainer e-flex e-con e-child\" data-id=\"432cc2a1\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-446e8565 elementor-hidden-tablet elementor-hidden-mobile EspaceReserve elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"446e8565\" data-element_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>Espace r\u00e9serv\u00e9<br \/>Annonce transmise<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-60df49d0 elementor-hidden-tablet elementor-hidden-mobile DeplaceAnnonceText elementor-widget elementor-widget-text-editor\" data-id=\"60df49d0\" data-element_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\tSi vous souhaitez un autre emplacement, vous pouvez d\u00e9placer cette annonce\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-62ef38f0 e-con-full e-flex e-con e-child\" data-id=\"62ef38f0\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f4f51cb elementor-hidden-tablet elementor-hidden-mobile PositionEspacePublicitaireDeplacer elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"f4f51cb\" data-element_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>Position<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f214306 elementor-hidden-tablet elementor-hidden-mobile RefEspacePublicitaire elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"f214306\" data-element_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>R\u00e9f\u00e9rence<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1c5a5ed5 e-con-full AdUploadedOverlay elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile e-flex e-con e-child\" data-id=\"1c5a5ed5\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-4740d3e8 e-con-full OverlayHeader e-flex e-con e-child\" data-id=\"4740d3e8\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e964c6b elementor-hidden-tablet elementor-hidden-mobile OverlayRefEspace elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"e964c6b\" data-element_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>R\u00e9f\u00e9rence<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-30eb836c OverlayCroixReset elementor-widget elementor-widget-image\" data-id=\"30eb836c\" data-element_type=\"widget\" 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\t<a href=\"#\">\n\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-transparent.png\" title=\"\" alt=\"\" loading=\"lazy\" \/>\t\t\t\t\t\t\t\t<\/a>\n\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<\/div>\n\t\t<div class=\"elementor-element elementor-element-342c88b1 e-con-full OverlayPreviewZone e-flex e-con e-child\" data-id=\"342c88b1\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3c7e790f OverlayDeplaceTexte elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"3c7e790f\" data-element_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>Si vous souhaitez un autre emplacement, vous pouvez d\u00e9placer cette annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-51f00578 elementor-button-align-center elementor-widget__width-auto HideFormButton OverlayReserverForm elementor-widget elementor-widget-form\" data-id=\"51f00578\" data-element_type=\"widget\" id=\"Formulaire_Reserver_Overlay\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_Envoi_Ulterieur\" aria-label=\"Formulaire_Envoi_Ulterieur\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249679\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"51f00578\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-checkbox elementor-field-group elementor-column elementor-field-group-ReserverEspacePublicitaire elementor-col-100 elementor-sm-100\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-ReserverEspacePublicitaire\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tR\u00e9server cet espace publicitaire\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t<div class=\"elementor-field-subgroup\"><span class=\"elementor-field-option\"><input type=\"checkbox\" value=\"R\u00e9server cet espace publicitaire\" id=\"form-field-ReserverEspacePublicitaire-0\" name=\"form_fields[ReserverEspacePublicitaire]\"> <label for=\"form-field-ReserverEspacePublicitaire-0\">R\u00e9server cet espace publicitaire<\/label><\/span><\/div>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidEnvoiUlterieur\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<\/p>\t\t\t\t\t\t\t\t<\/div>\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-4919b6f5 e-flex e-con-boxed e-con e-child\" data-id=\"4919b6f5\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-68806dd7 e-con-full elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile e-flex e-con e-child\" data-id=\"68806dd7\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-5bca92d3 e-con-full e-flex e-con e-child\" data-id=\"5bca92d3\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-6045bf9b e-con-full elementor-hidden-desktop elementor-hidden-tablet e-flex e-con e-child\" data-id=\"6045bf9b\" data-element_type=\"container\">\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-2f4e3044 elementor-widget__width-initial elementor-pagination-position-inside CarrouselLoop elementor-pagination-type-bullets elementor-widget elementor-widget-loop-carousel\" data-id=\"2f4e3044\" data-element_type=\"widget\" data-settings=\"{&quot;template_id&quot;:&quot;46309&quot;,&quot;speed&quot;:0,&quot;image_spacing_custom&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:2,&quot;sizes&quot;:[]},&quot;offset_sides&quot;:&quot;both&quot;,&quot;offset_width&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;slides_to_show&quot;:&quot;1&quot;,&quot;slides_to_show_tablet&quot;:&quot;1&quot;,&quot;_skin&quot;:&quot;post&quot;,&quot;slides_to_show_mobile&quot;:&quot;1&quot;,&quot;slides_to_scroll&quot;:&quot;1&quot;,&quot;edit_handle_selector&quot;:&quot;.elementor-loop-container&quot;,&quot;infinite&quot;:&quot;yes&quot;,&quot;offset_width_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;offset_width_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;pagination&quot;:&quot;bullets&quot;,&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;:[]}}\" data-widget_type=\"loop-carousel.post\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"e-loop-nothing-found-message\">\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-7a17b83a e-con-full elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile e-flex e-con e-child\" data-id=\"7a17b83a\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-6ecc9626 e-con-full droppable e-flex e-con e-child\" data-id=\"6ecc9626\" data-element_type=\"container\" id=\"Ele3A\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6c5286eb elementor-widget__width-inherit elementor-widget elementor-widget-text-editor\" data-id=\"6c5286eb\" data-element_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>\t\t<div data-elementor-type=\"page\" data-elementor-id=\"83347\" class=\"elementor elementor-83347\" data-elementor-post-type=\"elementor_library\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6442de91 e-con-full OrdiMobileConteneurClass e-flex e-con e-child\" data-id=\"6442de91\" data-element_type=\"container\" id=\"testIdTest\">\n\t\t\t\t<div class=\"elementor-element elementor-element-57de103 elementor-widget elementor-widget-text-editor\" data-id=\"57de103\" data-element_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><style>.elementor-249680 .elementor-element.elementor-element-6da64a60{--display:flex;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--justify-content:space-around;--align-items:center;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:50px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-6da64a60.e-con{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-45f807e0{--display:flex;--min-height:0px;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:-100px;--margin-bottom:62px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:3;}.elementor-249680 .elementor-element.elementor-element-45f807e0.e-con{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-61dcced4{--display:flex;--margin-top:0px;--margin-bottom:-11px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-6c65b106{--display:flex;--margin-top:0px;--margin-bottom:-30px;--margin-left:-25px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-eb74aa8{--display:flex;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-eb74aa8:not(.elementor-motion-effects-element-type-background), .elementor-249680 .elementor-element.elementor-element-eb74aa8 > .elementor-motion-effects-container > .elementor-motion-effects-layer{background-color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-1c762c45{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--flex-wrap:nowrap;--margin-top:-3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-5be6a53a{--display:flex;--align-items:flex-start;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-5be6a53a.e-con{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-75917e71{--display:flex;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-widget-image .widget-image-caption{color:var( --e-global-color-text );font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-249680 .elementor-element.elementor-element-6be76773 > .elementor-widget-container{margin:38px 5px -38px -40px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-6be76773.elementor-element{--align-self:flex-start;}.elementor-249680 .elementor-element.elementor-element-6be76773{text-align:right;}.elementor-249680 .elementor-element.elementor-element-6be76773 img{width:17px;}.elementor-249680 .elementor-element.elementor-element-5ad25a69{--display:flex;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-5ad25a69.e-con{--align-self:flex-end;}.elementor-249680 .elementor-element.elementor-element-52dec736 > .elementor-widget-container{margin:45px -18px -55px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-52dec736{z-index:101;text-align:right;}.elementor-249680 .elementor-element.elementor-element-469b1a7c{--display:flex;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:-25px;--margin-bottom:90px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-469b1a7c:not(.elementor-motion-effects-element-type-background), .elementor-249680 .elementor-element.elementor-element-469b1a7c > .elementor-motion-effects-container > .elementor-motion-effects-layer{background-color:#9FC5F3;}.elementor-249680 .elementor-element.elementor-element-3f5f9124{--display:flex;--min-height:30px;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:center;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:1px;--margin-bottom:-6px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:99;}.elementor-249680 .elementor-element.elementor-element-3f5f9124.e-con{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-48a37689{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:flex-start;--margin-top:3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-widget-text-editor{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );color:var( --e-global-color-text );}.elementor-widget-text-editor.elementor-drop-cap-view-stacked .elementor-drop-cap{background-color:var( --e-global-color-primary );}.elementor-widget-text-editor.elementor-drop-cap-view-framed .elementor-drop-cap, .elementor-widget-text-editor.elementor-drop-cap-view-default .elementor-drop-cap{color:var( --e-global-color-primary );border-color:var( --e-global-color-primary );}.elementor-249680 .elementor-element.elementor-element-4b68287 > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249680 .elementor-element.elementor-element-4b68287.elementor-element{--align-self:flex-start;}.elementor-249680 .elementor-element.elementor-element-4b68287{text-align:start;font-family:\"Roboto\", Sans-serif;font-size:12px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-79a46db6{--display:flex;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-47d25f98 > .elementor-widget-container{margin:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-47d25f98{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:18px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-3aa42503{--display:flex;--flex-direction:row;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:flex-end;--align-items:flex-end;--margin-top:4px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-12d5dc39 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-12d5dc39.elementor-element{--align-self:flex-start;}.elementor-249680 .elementor-element.elementor-element-12d5dc39{text-align:end;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-21535e15{--display:flex;--justify-content:flex-start;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--flex-wrap:wrap;--margin-top:-2px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-21535e15.e-con{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-de420c1{--display:flex;--min-height:30px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-2f60f3f > .elementor-widget-container{margin:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-2f60f3f.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-2f60f3f{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:500;line-height:1.1em;color:#FB5E2A;}.elementor-249680 .elementor-element.elementor-element-6b485447 > .elementor-widget-container{margin:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-6b485447.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-6b485447{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-78e1d9f5{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:center;--gap:010px 9px;--row-gap:010px;--column-gap:9px;--flex-wrap:wrap;--margin-top:-14px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:100;}.elementor-249680 .elementor-element.elementor-element-78e1d9f5.e-con{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-cf3602e{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-7a1bb33 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-7a1bb33.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-7a1bb33{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-6bf72a5{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-1a57dd9 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-1a57dd9.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-1a57dd9{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-34d8bbba{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-32bd35c6 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-32bd35c6.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-32bd35c6{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-5a9252c3{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-8722042 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-8722042.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-8722042{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-19ecc2b3{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-6071d405 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-6071d405.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-6071d405{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-3617569c{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-4b013e71 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-4b013e71.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-4b013e71{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-7450a6f8{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-30970f89 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-30970f89.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-30970f89{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-6aac67a6{--display:flex;--margin-top:-46px;--margin-bottom:-20px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:2;}.elementor-249680 .elementor-element.elementor-element-40d299c{width:100%;max-width:100%;}.elementor-249680 .elementor-element.elementor-element-40d299c.elementor-element{--align-self:flex-end;}.elementor-249680 .elementor-element.elementor-element-1fd15d20{width:100%;max-width:100%;}.elementor-249680 .elementor-element.elementor-element-1fd15d20.elementor-element{--align-self:flex-end;}.elementor-249680 .elementor-element.elementor-element-54e4e530{--display:flex;--justify-content:center;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-531f3cb1{width:100%;max-width:100%;font-family:\"Roboto\", Sans-serif;font-size:10px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249680 .elementor-element.elementor-element-531f3cb1 > .elementor-widget-container{margin:-37px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-531f3cb1.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-3a352c3f > .elementor-widget-container{margin:7px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-3a352c3f.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-3a352c3f{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:15px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249680 .elementor-element.elementor-element-7abb0aba > .elementor-widget-container{margin:7px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-7abb0aba.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-7abb0aba{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:15px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249680 .elementor-element.elementor-element-68e2b2ca > .elementor-widget-container{margin:-110px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-68e2b2ca.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-68e2b2ca{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:18px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249680 .elementor-element.elementor-element-8d50d33{--display:flex;--margin-top:-85px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-8d50d33.e-con{--align-self:center;}.elementor-widget-form .elementor-field-group > label, .elementor-widget-form .elementor-field-subgroup label{color:var( --e-global-color-text );}.elementor-widget-form .elementor-field-group > label{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .elementor-field-type-html{color:var( --e-global-color-text );font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .elementor-field-group .elementor-field{color:var( --e-global-color-text );}.elementor-widget-form .elementor-field-group .elementor-field, .elementor-widget-form .elementor-field-subgroup label{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .elementor-button{font-family:var( --e-global-typography-accent-font-family ), Sans-serif;font-weight:var( --e-global-typography-accent-font-weight );}.elementor-widget-form .e-form__buttons__wrapper__button-next{background-color:var( --e-global-color-accent );}.elementor-widget-form .elementor-button[type=\"submit\"]{background-color:var( --e-global-color-accent );}.elementor-widget-form .e-form__buttons__wrapper__button-previous{background-color:var( --e-global-color-accent );}.elementor-widget-form .elementor-message{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .e-form__indicators__indicator, .elementor-widget-form .e-form__indicators__indicator__label{font-family:var( --e-global-typography-accent-font-family ), Sans-serif;font-weight:var( --e-global-typography-accent-font-weight );}.elementor-widget-form{--e-form-steps-indicator-inactive-primary-color:var( --e-global-color-text );--e-form-steps-indicator-active-primary-color:var( --e-global-color-accent );--e-form-steps-indicator-completed-primary-color:var( --e-global-color-accent );--e-form-steps-indicator-progress-color:var( --e-global-color-accent );--e-form-steps-indicator-progress-background-color:var( --e-global-color-text );--e-form-steps-indicator-progress-meter-color:var( --e-global-color-text );}.elementor-widget-form .e-form__indicators__indicator__progress__meter{font-family:var( --e-global-typography-accent-font-family ), Sans-serif;font-weight:var( --e-global-typography-accent-font-weight );}.elementor-249680 .elementor-element.elementor-element-6ae6ef83{width:var( --container-widget-width, 75% );max-width:75%;--container-widget-width:75%;--container-widget-flex-grow:0;z-index:120;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group{padding-right:calc( 10px\/2 );padding-left:calc( 10px\/2 );margin-bottom:6px;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-form-fields-wrapper{margin-left:calc( -10px\/2 );margin-right:calc( -10px\/2 );margin-bottom:-6px;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group > label, .elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{color:#7B88A3;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-type-html{padding-bottom:0px;color:#7A7A7A;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field{color:#484848;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field, .elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:01px 01px 01px 01px;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:01px 01px 01px 01px;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-message.elementor-message-success{color:#00FF2700;}.elementor-249680 .elementor-element.elementor-element-66fd4d36{--display:flex;--min-height:58px;--gap:0px 0px;--row-gap:0px;--column-gap:0px;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:8px 8px 8px 8px;--margin-top:12px;--margin-bottom:10px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:151;}.elementor-249680 .elementor-element.elementor-element-66fd4d36.e-con{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4{width:auto;max-width:auto;z-index:120;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 > .elementor-widget-container{margin:2px 0px 2px 1px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group{padding-right:calc( 0px\/2 );padding-left:calc( 0px\/2 );margin-bottom:0px;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-form-fields-wrapper{margin-left:calc( -0px\/2 );margin-right:calc( -0px\/2 );margin-bottom:-0px;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group > label, .elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-type-html{padding-bottom:0px;color:#FFFFFF;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field{color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field, .elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:600;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-message.elementor-message-success{color:#00FF2700;}.elementor-249680 .elementor-element.elementor-element-4a59cf88 > .elementor-widget-container{margin:-3px 0px -24px 0px;}.elementor-249680 .elementor-element.elementor-element-4a59cf88.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-4a59cf88{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-17d3ad0c{--display:flex;--gap:0px 0px;--row-gap:0px;--column-gap:0px;border-style:none;--border-style:none;--border-radius:8px 8px 8px 8px;--margin-top:-4px;--margin-bottom:05px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:151;}.elementor-249680 .elementor-element.elementor-element-17d3ad0c.e-con{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-177c9b71{width:auto;max-width:auto;z-index:5;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249680 .elementor-element.elementor-element-177c9b71 > .elementor-widget-container{margin:2px 0px 2px 1px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-177c9b71.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-group{padding-right:calc( 0px\/2 );padding-left:calc( 0px\/2 );margin-bottom:0px;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-form-fields-wrapper{margin-left:calc( -0px\/2 );margin-right:calc( -0px\/2 );margin-bottom:-0px;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-group > label, .elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{color:#000000;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:400;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-type-html{padding-bottom:0px;color:#FFFFFF;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field{color:#000000;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field, .elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:16px;font-weight:600;line-height:1.1em;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-message.elementor-message-success{color:#00FF2700;}.elementor-249680 .elementor-element.elementor-element-5bafe1f3{--display:flex;--min-height:0px;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--gap:0px 0px;--row-gap:0px;--column-gap:0px;--overlay-opacity:1;--margin-top:230px;--margin-bottom:-220px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:10;}.elementor-249680 .elementor-element.elementor-element-5bafe1f3::before, .elementor-249680 .elementor-element.elementor-element-5bafe1f3 > .elementor-background-video-container::before, .elementor-249680 .elementor-element.elementor-element-5bafe1f3 > .e-con-inner > .elementor-background-video-container::before, .elementor-249680 .elementor-element.elementor-element-5bafe1f3 > .elementor-background-slideshow::before, .elementor-249680 .elementor-element.elementor-element-5bafe1f3 > .e-con-inner > .elementor-background-slideshow::before, .elementor-249680 .elementor-element.elementor-element-5bafe1f3 > .elementor-motion-effects-container > .elementor-motion-effects-layer::before{--background-overlay:'';background-size:cover;}.elementor-249680 .elementor-element.elementor-element-5bafe1f3.e-con{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-432cc2a1{--display:flex;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-446e8565 > .elementor-widget-container{margin:0px 3px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-446e8565.elementor-element{--align-self:flex-end;}.elementor-249680 .elementor-element.elementor-element-446e8565{z-index:5;text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249680 .elementor-element.elementor-element-60df49d0 > .elementor-widget-container{margin:35px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-60df49d0.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-60df49d0{z-index:5;text-align:center;font-family:\"Roboto\", Sans-serif;font-size:15px;font-weight:500;line-height:1.1em;color:#6185C0;}.elementor-249680 .elementor-element.elementor-element-62ef38f0{--display:flex;--flex-direction:row;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:space-between;--align-items:flex-start;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:-287px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-f4f51cb > .elementor-widget-container{margin:0px 3px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-f4f51cb.elementor-element{--align-self:flex-end;}.elementor-249680 .elementor-element.elementor-element-f4f51cb{z-index:5;text-align:left;font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249680 .elementor-element.elementor-element-f214306 > .elementor-widget-container{margin:0px 0px 0px 3px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-f214306.elementor-element{--align-self:flex-end;}.elementor-249680 .elementor-element.elementor-element-f214306{z-index:5;text-align:start;font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249680 .elementor-element.elementor-element-1c5a5ed5{--display:flex;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--justify-content:flex-start;--align-items:center;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-1c5a5ed5.e-con{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-4740d3e8{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:space-between;--margin-top:5px;--margin-bottom:5px;--margin-left:010px;--margin-right:10px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-e964c6b > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-e964c6b.elementor-element{--align-self:flex-end;}.elementor-249680 .elementor-element.elementor-element-e964c6b{z-index:5;text-align:left;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249680 .elementor-element.elementor-element-30eb836c > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-30eb836c{z-index:101;text-align:right;}.elementor-249680 .elementor-element.elementor-element-342c88b1{--display:flex;--min-height:180px;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--justify-content:center;--align-items:center;--overflow:hidden;border-style:solid;--border-style:solid;border-width:4px 4px 4px 4px;--border-top-width:4px;--border-right-width:4px;--border-bottom-width:4px;--border-left-width:4px;border-color:#00FF19;--border-color:#00FF19;--border-radius:0px 0px 0px 0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-342c88b1:not(.elementor-motion-effects-element-type-background), .elementor-249680 .elementor-element.elementor-element-342c88b1 > .elementor-motion-effects-container > .elementor-motion-effects-layer{background-color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-3c7e790f > .elementor-widget-container{padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-3c7e790f{font-family:\"Roboto\", Sans-serif;font-weight:500;color:#6185C0;}.elementor-249680 .elementor-element.elementor-element-51f00578{width:auto;max-width:auto;z-index:5;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249680 .elementor-element.elementor-element-51f00578 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-51f00578.elementor-element{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-group{padding-right:calc( 0px\/2 );padding-left:calc( 0px\/2 );margin-bottom:0px;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-form-fields-wrapper{margin-left:calc( -0px\/2 );margin-right:calc( -0px\/2 );margin-bottom:-0px;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-group > label, .elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{color:#000000;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:400;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-type-html{padding-bottom:0px;color:#FFFFFF;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field{color:#213864;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field, .elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:15.5px;font-weight:600;line-height:1.1em;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249680 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249680 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249680 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249680 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-message.elementor-message-success{color:#00FF2700;}@media(max-width:1001px){.elementor-249680 .elementor-element.elementor-element-6ae6ef83{z-index:11;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field, .elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{font-size:10px;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-button{font-size:12px;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4{z-index:11;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field, .elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{font-size:10px;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-button{font-size:12px;}.elementor-249680 .elementor-element.elementor-element-177c9b71{z-index:11;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field, .elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{font-size:10px;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-button{font-size:12px;}.elementor-249680 .elementor-element.elementor-element-51f00578{z-index:11;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field, .elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{font-size:10px;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-button{font-size:12px;}}@media(min-width:1001px){.elementor-249680 .elementor-element.elementor-element-6da64a60{--width:500px;}.elementor-249680 .elementor-element.elementor-element-45f807e0{--width:100%;}.elementor-249680 .elementor-element.elementor-element-6c65b106{--width:500px;}.elementor-249680 .elementor-element.elementor-element-75917e71{--width:10px;}.elementor-249680 .elementor-element.elementor-element-5ad25a69{--width:100%;}.elementor-249680 .elementor-element.elementor-element-469b1a7c{--width:500px;}.elementor-249680 .elementor-element.elementor-element-48a37689{--width:22%;}.elementor-249680 .elementor-element.elementor-element-79a46db6{--width:50%;}.elementor-249680 .elementor-element.elementor-element-3aa42503{--width:22%;}.elementor-249680 .elementor-element.elementor-element-78e1d9f5{--width:100%;}.elementor-249680 .elementor-element.elementor-element-cf3602e{--width:103px;}.elementor-249680 .elementor-element.elementor-element-6bf72a5{--width:103px;}.elementor-249680 .elementor-element.elementor-element-34d8bbba{--width:103px;}.elementor-249680 .elementor-element.elementor-element-5a9252c3{--width:103px;}.elementor-249680 .elementor-element.elementor-element-19ecc2b3{--width:103px;}.elementor-249680 .elementor-element.elementor-element-3617569c{--width:103px;}.elementor-249680 .elementor-element.elementor-element-7450a6f8{--width:103px;}.elementor-249680 .elementor-element.elementor-element-8d50d33{--width:100%;}.elementor-249680 .elementor-element.elementor-element-66fd4d36{--width:390px;}.elementor-249680 .elementor-element.elementor-element-17d3ad0c{--width:100%;}.elementor-249680 .elementor-element.elementor-element-5bafe1f3{--width:150%;}.elementor-249680 .elementor-element.elementor-element-62ef38f0{--width:95%;}.elementor-249680 .elementor-element.elementor-element-1c5a5ed5{--width:100%;}.elementor-249680 .elementor-element.elementor-element-4740d3e8{--width:100%;}}@media(max-width:1000px){.elementor-249680 .elementor-element.elementor-element-6da64a60{--width:390px;--margin-top:105px;--margin-bottom:-75px;--margin-left:0px;--margin-right:0px;}.elementor-249680 .elementor-element.elementor-element-45f807e0{--min-height:150px;--flex-direction:column;--container-widget-width:100%;--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--margin-top:-47px;--margin-bottom:-32px;--margin-left:0px;--margin-right:0px;--z-index:3;}.elementor-249680 .elementor-element.elementor-element-61dcced4{--width:25%;}.elementor-249680 .elementor-element.elementor-element-6c65b106{--width:100%;--flex-direction:row;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:center;--align-items:center;--flex-wrap:nowrap;--margin-top:3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249680 .elementor-element.elementor-element-6c65b106.e-con{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-eb74aa8{--width:75%;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--align-items:center;}.elementor-249680 .elementor-element.elementor-element-eb74aa8.e-con{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-1c762c45{--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249680 .elementor-element.elementor-element-6be76773 > .elementor-widget-container{margin:-3px 40px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-5ad25a69{--width:100%;--justify-content:flex-end;--align-items:flex-end;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-52dec736 > .elementor-widget-container{margin:40px 55px -30px 0px;}.elementor-249680 .elementor-element.elementor-element-52dec736{z-index:100;}.elementor-249680 .elementor-element.elementor-element-469b1a7c{--width:78%;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--flex-wrap:nowrap;--margin-top:-103px;--margin-bottom:-7px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-469b1a7c.e-con{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-3f5f9124{--justify-content:center;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249680 .elementor-element.elementor-element-48a37689{--width:25%;--margin-top:2px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-4b68287 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-4b68287{font-size:8px;}.elementor-249680 .elementor-element.elementor-element-79a46db6{--width:46%;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-47d25f98 > .elementor-widget-container{margin:0px -20px 0px -20px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-47d25f98{font-size:12px;}.elementor-249680 .elementor-element.elementor-element-3aa42503{--width:25%;--margin-top:4px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-12d5dc39 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-12d5dc39{font-size:7px;}.elementor-249680 .elementor-element.elementor-element-21535e15{--margin-top:-15px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249680 .elementor-element.elementor-element-de420c1{--min-height:15px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-2f60f3f{width:100%;max-width:100%;font-size:10px;}.elementor-249680 .elementor-element.elementor-element-2f60f3f > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-6b485447{width:100%;max-width:100%;font-size:10px;}.elementor-249680 .elementor-element.elementor-element-6b485447 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-78e1d9f5{--width:100%;--gap:6px 4px;--row-gap:6px;--column-gap:4px;--flex-wrap:wrap;--margin-top:-12px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249680 .elementor-element.elementor-element-cf3602e{--width:61px;--min-height:15px;}.elementor-249680 .elementor-element.elementor-element-7a1bb33{font-size:9px;}.elementor-249680 .elementor-element.elementor-element-6bf72a5{--width:61px;--min-height:15px;}.elementor-249680 .elementor-element.elementor-element-1a57dd9{font-size:9px;}.elementor-249680 .elementor-element.elementor-element-34d8bbba{--width:61px;--min-height:15px;}.elementor-249680 .elementor-element.elementor-element-32bd35c6{font-size:9px;}.elementor-249680 .elementor-element.elementor-element-5a9252c3{--width:61px;--min-height:15px;}.elementor-249680 .elementor-element.elementor-element-8722042{font-size:9px;}.elementor-249680 .elementor-element.elementor-element-19ecc2b3{--width:61px;--min-height:15px;}.elementor-249680 .elementor-element.elementor-element-6071d405{font-size:9px;}.elementor-249680 .elementor-element.elementor-element-3617569c{--width:61px;--min-height:15px;}.elementor-249680 .elementor-element.elementor-element-4b013e71{font-size:9px;}.elementor-249680 .elementor-element.elementor-element-7450a6f8{--width:61px;--min-height:15px;}.elementor-249680 .elementor-element.elementor-element-30970f89{font-size:9px;}.elementor-249680 .elementor-element.elementor-element-6aac67a6{--width:96%;--min-height:250px;--margin-top:-56px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-40d299c > .elementor-widget-container{margin:5px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-1fd15d20 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-54e4e530{--margin-top:3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249680 .elementor-element.elementor-element-54e4e530.e-con{--order:-99999 \/* order start hack *\/;}.elementor-249680 .elementor-element.elementor-element-531f3cb1 > .elementor-widget-container{margin:-30px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-3a352c3f > .elementor-widget-container{margin:-181px 0px 1px 0px;}.elementor-249680 .elementor-element.elementor-element-3a352c3f{text-align:center;font-size:10px;line-height:1.2em;}.elementor-249680 .elementor-element.elementor-element-7abb0aba > .elementor-widget-container{margin:-180px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-7abb0aba{text-align:center;font-size:14px;line-height:1.2em;}.elementor-249680 .elementor-element.elementor-element-68e2b2ca > .elementor-widget-container{margin:-110px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-68e2b2ca{font-size:10px;}.elementor-249680 .elementor-element.elementor-element-8d50d33{--width:184px;--margin-top:-156px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249680 .elementor-element.elementor-element-8d50d33.e-con{--align-self:center;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83{width:var( --container-widget-width, 100% );max-width:100%;--container-widget-width:100%;--container-widget-flex-grow:0;z-index:120;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group > label{font-size:12px;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field, .elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{font-size:8px;}.elementor-249680 .elementor-element.elementor-element-6ae6ef83 .elementor-button{font-size:10.5px;}.elementor-249680 .elementor-element.elementor-element-66fd4d36{--width:85%;--min-height:42px;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--align-items:center;--margin-top:10px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:151;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 > .elementor-widget-container{margin:2px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4{z-index:120;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group > label{font-size:12px;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-type-html{font-size:12px;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field, .elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{font-size:10px;}.elementor-249680 .elementor-element.elementor-element-4ea8e2b4 .elementor-button{font-size:10.5px;}.elementor-249680 .elementor-element.elementor-element-4a59cf88 > .elementor-widget-container{margin:2px 0px -10px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-4a59cf88{font-size:7.5px;}.elementor-249680 .elementor-element.elementor-element-17d3ad0c{--width:85%;--min-height:42px;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--align-items:center;--margin-top:2px;--margin-bottom:-20px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:251;}.elementor-249680 .elementor-element.elementor-element-177c9b71 > .elementor-widget-container{margin:2px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-177c9b71{z-index:120;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-group > label{font-size:12px;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-type-html{font-size:12px;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field, .elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{font-size:12px;}.elementor-249680 .elementor-element.elementor-element-177c9b71 .elementor-button{font-size:10.5px;}.elementor-249680 .elementor-element.elementor-element-5bafe1f3{--min-height:150px;--margin-top:-149px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249680 .elementor-element.elementor-element-446e8565 > .elementor-widget-container{margin:-133px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-446e8565.elementor-element{--align-self:flex-start;}.elementor-249680 .elementor-element.elementor-element-446e8565{text-align:left;font-size:10px;}.elementor-249680 .elementor-element.elementor-element-f4f51cb > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249680 .elementor-element.elementor-element-f4f51cb.elementor-element{--align-self:flex-start;}.elementor-249680 .elementor-element.elementor-element-f4f51cb{text-align:center;font-size:10px;}.elementor-249680 .elementor-element.elementor-element-f214306 > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249680 .elementor-element.elementor-element-f214306.elementor-element{--align-self:flex-start;}.elementor-249680 .elementor-element.elementor-element-f214306{text-align:center;font-size:10px;}.elementor-249680 .elementor-element.elementor-element-1c5a5ed5{--width:390px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-e964c6b > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249680 .elementor-element.elementor-element-e964c6b.elementor-element{--align-self:flex-start;}.elementor-249680 .elementor-element.elementor-element-e964c6b{text-align:center;font-size:10px;}.elementor-249680 .elementor-element.elementor-element-30eb836c > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-30eb836c{z-index:100;}.elementor-249680 .elementor-element.elementor-element-342c88b1{--min-height:112px;--margin-top:5px;--margin-bottom:5px;--margin-left:5px;--margin-right:5px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249680 .elementor-element.elementor-element-3c7e790f{text-align:center;font-size:15px;}.elementor-249680 .elementor-element.elementor-element-51f00578 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249680 .elementor-element.elementor-element-51f00578{z-index:120;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-group > label{font-size:12px;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-type-html{font-size:12px;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field, .elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{font-size:12px;}.elementor-249680 .elementor-element.elementor-element-51f00578 .elementor-button{font-size:10.5px;}}<\/style>\t\t<div data-elementor-type=\"loop-item\" data-elementor-id=\"249680\" class=\"elementor elementor-249680 elementor-bc-flex-widget e-loop-item e-loop-item-32630 post-32630 post type-post status-publish format-standard has-post-thumbnail hentry category-electricite category-togo category-togo-energie generate-columns tablet-grid-50 mobile-grid-100 grid-parent grid-20\" data-elementor-post-type=\"elementor_library\" data-custom-edit-handle=\"1\">\n\t\t\t<div class=\"elementor-element elementor-element-6da64a60 e-con-full OrdiMobileConteneurClass e-flex e-con e-child\" data-id=\"6da64a60\" data-element_type=\"container\" id=\"testIdTest\">\n\t\t<div class=\"elementor-element elementor-element-45f807e0 e-con-full UploadFileConteneur AdUploadedTitle elementor-hidden-tablet elementor-hidden-mobile elementor-hidden-desktop e-flex e-con e-child\" data-id=\"45f807e0\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-61dcced4 e-con-full e-flex e-con e-child\" data-id=\"61dcced4\" data-element_type=\"container\">\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-6c65b106 e-con-full e-flex e-con e-child\" data-id=\"6c65b106\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-eb74aa8 e-con-full e-flex e-con e-child\" data-id=\"eb74aa8\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1c762c45 e-con-full e-flex e-con e-child\" data-id=\"1c762c45\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-5be6a53a e-con-full e-flex e-con e-child\" data-id=\"5be6a53a\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-75917e71 e-con-full e-flex e-con e-child\" data-id=\"75917e71\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6be76773 AnnonceDragIcone elementor-widget elementor-widget-image\" data-id=\"6be76773\" data-element_type=\"widget\" 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 decoding=\"async\" src=\"https:\/\/via-agency.media\/wp-content\/uploads\/2025\/05\/arrow-drag-64-bleu.png\" title=\"\" alt=\"\" loading=\"lazy\" \/>\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<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-5ad25a69 e-con-full CroixResetAnnonceContainer e-flex e-con e-child\" data-id=\"5ad25a69\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-52dec736 elementor-widget elementor-widget-image\" data-id=\"52dec736\" data-element_type=\"widget\" id=\"CroixResetAnnonce\" 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\t<a href=\"#\">\n\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-transparent.png\" title=\"\" alt=\"\" loading=\"lazy\" \/>\t\t\t\t\t\t\t\t<\/a>\n\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<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-469b1a7c e-con-full UploadFileConteneur e-flex e-con e-child\" data-id=\"469b1a7c\" data-element_type=\"container\" id=\"UploadFileConteneur\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t<div class=\"elementor-element elementor-element-3f5f9124 e-con-full ChoisirEspacePublicitaireDisponibiliteConteneur e-flex e-con e-child\" data-id=\"3f5f9124\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-48a37689 e-con-full e-flex e-con e-child\" data-id=\"48a37689\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4b68287 PositionEspacePublicitaire elementor-widget elementor-widget-text-editor\" data-id=\"4b68287\" data-element_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\tPosition\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-79a46db6 e-con-full e-flex e-con e-child\" data-id=\"79a46db6\" data-element_type=\"container\" id=\"ChoixEspacePublicitaireTitre\">\n\t\t\t\t<div class=\"elementor-element elementor-element-47d25f98 elementor-widget elementor-widget-text-editor\" data-id=\"47d25f98\" data-element_type=\"widget\" id=\"ChoixEspacePublicitaireTexte\" 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\tChoix d&rsquo;espace publicitaire\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-3aa42503 e-con-full e-flex e-con e-child\" data-id=\"3aa42503\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-12d5dc39 ReferenceEspacePublicitaire elementor-widget elementor-widget-text-editor\" data-id=\"12d5dc39\" data-element_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>R\u00e9f\u00e9rence<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-21535e15 e-con-full EspPubFormatMainContainer e-flex e-con e-child\" data-id=\"21535e15\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-de420c1 e-con-full e-flex e-con e-child\" data-id=\"de420c1\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2f60f3f elementor-widget-mobile__width-inherit SelectionFormatTitre elementor-widget elementor-widget-text-editor\" data-id=\"2f60f3f\" data-element_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 style=\"text-align: center;\">Merci de s\u00e9lectionner un format d&rsquo;annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6b485447 elementor-widget-mobile__width-inherit elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile SelectionFormatTitreBlancOLD elementor-widget elementor-widget-text-editor\" data-id=\"6b485447\" data-element_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 style=\"text-align: center;\">Vous pouvez changer de format d&rsquo;annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-78e1d9f5 e-con-full EspPubFormatListe e-flex e-con e-child\" data-id=\"78e1d9f5\" data-element_type=\"container\">\n\t\t<a class=\"elementor-element elementor-element-cf3602e e-con-full EspPubFormatContainer FormatIdCreation e-flex e-con e-child\" data-id=\"cf3602e\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-7a1bb33 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"7a1bb33\" data-element_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\tCr\u00e9ation\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-6bf72a5 e-con-full EspPubFormatContainer FormatIdPopUp e-flex e-con e-child\" data-id=\"6bf72a5\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-1a57dd9 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"1a57dd9\" data-element_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\tPop-up\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-34d8bbba e-con-full EspPubFormatContainer FormatIdBanniere e-flex e-con e-child\" data-id=\"34d8bbba\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-32bd35c6 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"32bd35c6\" data-element_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\tBanni\u00e8re\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-5a9252c3 e-con-full EspPubFormatContainer FormatIdVideo e-flex e-con e-child\" data-id=\"5a9252c3\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8722042 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"8722042\" data-element_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\tVid\u00e9o\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-19ecc2b3 e-con-full EspPubFormatContainer FormatIdCommunique e-flex e-con e-child\" data-id=\"19ecc2b3\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6071d405 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"6071d405\" data-element_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\tCommuniqu\u00e9\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-3617569c e-con-full EspPubFormatContainer FormatIdInterview e-flex e-con e-child\" data-id=\"3617569c\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4b013e71 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"4b013e71\" data-element_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\tInterview\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-7450a6f8 e-con-full EspPubFormatContainer FormatIdParrainage e-flex e-con e-child\" data-id=\"7450a6f8\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-30970f89 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"30970f89\" data-element_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\tParrainage\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-6aac67a6 e-con-full HTMLUploadfileConteneur e-flex e-con e-child\" data-id=\"6aac67a6\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-40d299c elementor-widget__width-inherit HTMLUploadfileClass elementor-widget elementor-widget-html\" data-id=\"40d299c\" data-element_type=\"widget\" id=\"HTMLUploadfile\" 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=\"en\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <meta name=\"google\" content=\"notranslate\">\r\n    \r\n    <script data-jetpack-boost=\"ignore\" src=\"https:\/\/code.jquery.com\/jquery-3.6.0.min.js\"><\/script>\r\n    <script data-jetpack-boost=\"ignore\" src=\"https:\/\/code.jquery.com\/ui\/1.12.1\/jquery-ui.min.js\"><\/script>\r\n\r\n<script data-jetpack-boost=\"ignore\">\r\n\/\/ Lazy loading des biblioth\u00e8ques - charg\u00e9es uniquement au besoin\r\nwindow.VIALibraries = {\r\n    mammothLoaded: false,\r\n    pdfLoaded: false,\r\n    \r\n    loadMammoth: function(callback) {\r\n        if (this.mammothLoaded) { callback(); return; }\r\n        var script = document.createElement('script');\r\n        script.src = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/mammoth\/1.4.0\/mammoth.browser.min.js';\r\n        script.onload = function() { \r\n            window.VIALibraries.mammothLoaded = true; \r\n            callback(); \r\n        };\r\n        document.head.appendChild(script);\r\n    },\r\n    \r\n    loadPdfJs: function(callback) {\r\n        if (this.pdfLoaded) { callback(); return; }\r\n        var script = document.createElement('script');\r\n        script.src = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.11.174\/pdf.min.js';\r\n        script.onload = function() {\r\n            window.VIALibraries.pdfLoaded = true;\r\n            pdfjsLib.GlobalWorkerOptions.workerSrc = '\/\/cdn.jsdelivr.net\/npm\/pdfjs-dist@latest\/build\/pdf.worker.min.js';\r\n            callback();\r\n        };\r\n        document.head.appendChild(script);\r\n    }\r\n};\r\n<\/script>\r\n\r\n<\/head>\r\n<body>\r\n    <div id=\"PopUpMessageAchattest\" class=\"draggable\" draggable=\"true\" style=\"justify-content: center; align-items: flex-start;\">\r\n        <div id=\"drop_file_zone_achat\" class=\"drop_file_zone_achat_class\" ondrop=\"uploadFile_achat(event)\" ondragover=\"return false\">\r\n        <div id=\"drag_upload_file_achat\">\r\n            <p><input class=\"button-2_achat\" type=\"button\" value=\"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\" onclick=\"fileExplorer_achat(event);\" \/><\/p>\r\n                <input type=\"file\" id=\"selectfile_achat\" \/>\r\n        <\/div>\r\n        <\/div>\r\n        <div class=\"img-content\"><\/div>\r\n    <\/div>\r\n<\/body>\r\n<\/html>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1fd15d20 elementor-widget__width-inherit HTMLUploadfileClass elementor-widget elementor-widget-html\" data-id=\"1fd15d20\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<script data-jetpack-boost=\"ignore\">\r\nif (!window._espPubScriptLoaded) {\r\nwindow._espPubScriptLoaded = true;\r\n\/**\r\n * Configuration centralis\u00e9e\r\n *\/\r\nconst CONFIG = {\r\n    iframeId: 'yearbook-iframe',\r\n    ajaxUrl: 'https:\/\/via-agency.media\/wp-admin\/admin-ajax.php',\r\n    apercuUrl: 'https:\/\/rdc.yearbook-media.com\/apercu',\r\n    \r\n    allowedExtensions: {\r\n        video: ['mp4', 'mov', 'wmv', 'avi', 'flv', 'f4v', 'swf', 'mkv', 'webm', 'mpeg'],\r\n        image: ['jpg', 'jpeg', 'png', 'gif', 'tif', 'svg', 'webp'],\r\n        document: ['doc', 'docx', 'ppt', 'pptx', 'pdf']\r\n    },\r\n    \r\n    mimeTypes: {\r\n        docx: 'application\/vnd.openxmlformats-officedocument.wordprocessingml.document',\r\n        pdf: 'application\/pdf'\r\n    },\r\n    \r\n    dragScroll: {\r\n        threshold: 150,\r\n        maxSpeed: 65,\r\n        throttleDelay: 50\r\n    },\r\n    \r\n    breakpoints: {\r\n        mobile: 1000\r\n    },\r\n    \r\n    keywords: [\r\n        { normal: \"parrainage\", display: \"Parrainage\" },\r\n        { normal: \"communique\", display: \"Communiqu\u00e9\" },\r\n        { normal: \"interview\", display: \"Interview\" }\r\n    ]\r\n};\r\n\r\n\/**\r\n * \u2705 v1.19.1 : Module de positionnement dans l'iframe\r\n * \r\n * PROBL\u00c8ME : L'iframe ne scrolle pas en desktop \u2014 c'est le parent (#PageWebTitrePage) qui scrolle.\r\n * L'iframe est scal\u00e9e \u00e0 0.85 \u2192 les coordonn\u00e9es iframe \u2260 coordonn\u00e9es parent.\r\n * position:fixed dans l'iframe = relatif au CONTENU TOTAL, pas au viewport visible.\r\n * \r\n * SOLUTION : Le parent calcule visibleTopIframe (la position iframe du haut du viewport)\r\n * et l'envoie dans le message 'PageWebTitrePage-scroll'. L'iframe n'a qu'\u00e0 l'utiliser.\r\n * \r\n * Pour scroller, l'iframe envoie 'scrollToIframeY' au parent qui fait la conversion.\r\n *\/\r\nconst ScrollHelper = {\r\n    _visibleTopIframe: 0,\r\n    _iframeScale: 0.85,\r\n\r\n    init() {\r\n        \/\/ \u00c9couter les donn\u00e9es de scroll envoy\u00e9es par le parent\r\n        window.addEventListener('message', (event) => {\r\n            var msg = event.data;\r\n            if (msg && msg.action === 'PageWebTitrePage-scroll') {\r\n                if (typeof msg.visibleTopIframe === 'number') {\r\n                    this._visibleTopIframe = msg.visibleTopIframe;\r\n                }\r\n                if (typeof msg.iframeScale === 'number') {\r\n                    this._iframeScale = msg.iframeScale;\r\n                }\r\n            }\r\n        });\r\n        console.log('\u2705 ScrollHelper initialis\u00e9');\r\n    },\r\n\r\n    \/**\r\n     * Position Y dans le document iframe correspondant au haut du viewport visible\r\n     *\/\r\n    getVisibleTop() {\r\n        if (window === window.top) {\r\n            return window.scrollY || 0;\r\n        }\r\n        return this._visibleTopIframe;\r\n    },\r\n\r\n    \/**\r\n     * Demande au parent de scroller pour positionner `element` \u00e0 `offsetFromTop` px du viewport\r\n     *\/\r\n    scrollElementTo(element, offsetFromTop) {\r\n        if (!element) return;\r\n\r\n        \/\/ getBoundingClientRect().top dans une iframe sans scroll = position absolue Y\r\n        var elementAbsY = element.getBoundingClientRect().top;\r\n\r\n        if (window === window.top) {\r\n            window.scrollTo({ top: elementAbsY - offsetFromTop + (window.scrollY || 0), behavior: 'smooth' });\r\n            return;\r\n        }\r\n\r\n        \/\/ Envoyer au parent \u2014 le parent fait la conversion scale\r\n        window.parent.postMessage({\r\n            type: 'scrollToIframeY',\r\n            iframeId: CONFIG.iframeId,\r\n            iframeY: elementAbsY,\r\n            offsetFromTop: offsetFromTop\r\n        }, '*');\r\n        console.log('\ud83d\udcdc scrollToIframeY:', { iframeY: Math.round(elementAbsY), offsetFromTop });\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'\u00e9tat (SessionStorage)\r\n *\/\r\nconst StateManager = {\r\n    init() {\r\n        if (sessionStorage.getItem(\"AchatEspaceCall\") === 'No') {\r\n            sessionStorage.clear();\r\n        }\r\n        \r\n        this.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        this.set('dragstart_Rank_Emplacement_Page_Web', 'No');\r\n        this.set('dragstart_Commande_Emplacement_Page_Web', 'No');\r\n        \r\n        \/\/ \u2705 v2.1.1 : Popup \u2192 ne jamais pr\u00e9remplir le format\r\n        if (this.get('PopUpChoice') === 'Yes') {\r\n            this.set('Formatchoisi', 'No');\r\n            this.set('FormatSelect', '');\r\n            this.set('Commande_Format_Transmis', '');\r\n        }\r\n    },\r\n    \r\n    get(key) {\r\n        return sessionStorage.getItem(key);\r\n    },\r\n    \r\n    set(key, value) {\r\n        sessionStorage.setItem(key, value);\r\n    },\r\n    \r\n    getMultiple(keys) {\r\n        return keys.reduce((acc, key) => {\r\n            acc[key] = this.get(key);\r\n            return acc;\r\n        }, {});\r\n    },\r\n    \r\n    setMultiple(obj) {\r\n        Object.entries(obj).forEach(([key, value]) => {\r\n            this.set(key, value);\r\n        });\r\n    },\r\n    \r\n    buildEmplacementReference(rank) {\r\n        const codeSite = this.get('codeSite');\r\n        const codePage = this.get('codePage');\r\n        return `${codeSite}${codePage}L${rank.substring(3)}`;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion des fichiers\r\n *\/\r\nconst FileManager = {\r\n    getExtension(filename) {\r\n        console.log('filename:', filename);\r\n        const parts = filename.split('.');\r\n        return parts.length > 1 ? parts.pop().toLowerCase() : '';\r\n    },\r\n    \r\n    isAllowedExtension(extension) {\r\n        return Object.values(CONFIG.allowedExtensions)\r\n            .flat()\r\n            .includes(extension);\r\n    },\r\n    \r\n    getFileType(extension) {\r\n        for (const [type, extensions] of Object.entries(CONFIG.allowedExtensions)) {\r\n            if (extensions.includes(extension)) {\r\n                return type;\r\n            }\r\n        }\r\n        return null;\r\n    },\r\n    \r\n    async urlToFile(url, filename) {\r\n        console.log(\"Fetching from URL:\", url);\r\n        \r\n        const mimeType = filename.includes('.docx') \r\n            ? CONFIG.mimeTypes.docx \r\n            : filename.includes('.pdf') \r\n            ? CONFIG.mimeTypes.pdf \r\n            : null;\r\n        \r\n        try {\r\n            const response = await fetch(url);\r\n            \r\n            if (!response.ok) {\r\n                throw new Error(`Network response was not ok: ${response.status} ${response.statusText}`);\r\n            }\r\n            \r\n            const blob = await response.blob();\r\n            return new File([blob], filename, { type: mimeType });\r\n        } catch (error) {\r\n            console.error(\"Error in urlToFile:\", error);\r\n            alert(\"Erreur lors du chargement du fichier. Veuillez r\u00e9essayer.\");\r\n            throw error;\r\n        }\r\n    },\r\n    \r\n    createObjectUrl(file) {\r\n        \/\/ R\u00e9voquer l'ancien URL si existant\r\n        const oldUrl = StateManager.get('objectUrl');\r\n        if (oldUrl && oldUrl.startsWith('blob:')) {\r\n            URL.revokeObjectURL(oldUrl);\r\n            console.log('\ud83d\uddd1\ufe0f Old Object URL revoked');\r\n        }\r\n        \r\n        const url = URL.createObjectURL(file);\r\n        StateManager.set('objectUrl', url);\r\n        return url;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion du Drag & Drop\r\n *\/\r\nconst DragDropManager = {\r\n    state: {\r\n        isFileBeingDragged: false,\r\n        draggedFile: null,\r\n        dragInProgress: false,\r\n        throttleTimeout: null\r\n    },\r\n    \r\n    init() {\r\n        this.attachEventListeners();\r\n    },\r\n    \r\n    attachEventListeners() {\r\n        window.addEventListener('dragstart', (e) => this.handleDragStart(e), true);\r\n        jQuery(document).on('dragover', (e) => this.handleDragOver(e));\r\n        jQuery(document).on('dragleave drop', (e) => this.handleDragEnd(e));\r\n        jQuery(\"#drop_file_zone_achat\").on(\"dragover\", (e) => this.handleDropZoneDragOver(e));\r\n        jQuery(\".draggable\").on(\"dragend\", (e) => this.handleDraggableEnd(e));\r\n    },\r\n    \r\n    handleDragStart(e) {\r\n        console.log('Window-level dragstart', e);\r\n        this.state.dragInProgress = true;\r\n    \r\n        const $target = $(e.target);\r\n        const droppableParent = $target.closest('.droppable');\r\n        const parentId = droppableParent.length ? droppableParent.attr('id') : null;\r\n        \r\n        StateManager.set('dragstart_Rank_Emplacement_Page_Web', parentId);\r\n        console.log('dragstart_Rank_Emplacement_Page_Web', parentId);\r\n        \r\n        \/\/ \u2705 CALCULER IMM\u00c9DIATEMENT dragstart_Commande_Emplacement_Page_Web\r\n        if (parentId) {\r\n            const dragstartRef = StateManager.buildEmplacementReference(parentId);\r\n            StateManager.set('dragstart_Commande_Emplacement_Page_Web', dragstartRef);\r\n            console.log('dragstart_Commande_Emplacement_Page_Web', dragstartRef);\r\n            \/\/ \u2705 v2.4.5 : Capturer l'\u00e9tat checkbox R\u00e9server au moment du dragstart\r\n            \/\/ Si l'utilisateur a explicitement d\u00e9coch\u00e9, forcer \u00e0 No m\u00eame si DOM est coch\u00e9\r\n            var $_dragCb = $('#' + parentId).find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]');\r\n            var _dragCbChecked = $_dragCb.prop('checked') === true;\r\n            var _expliciteDecocheDrag = StateManager.get('_reserverDecoche_' + parentId) === 'Yes';\r\n            var _reserverDrag = _dragCbChecked && !_expliciteDecocheDrag;\r\n            StateManager.set('dragstart_ReserverChecked', _reserverDrag ? 'Yes' : 'No');\r\n            \/\/ R\u00e9initialiser le flag apr\u00e8s lecture\r\n            StateManager.set('_reserverDecoche_' + parentId, 'No');\r\n            console.log('[dragstart] ReserverChecked dom:', _dragCbChecked, '| d\u00e9coch\u00e9 explicitement:', _expliciteDecocheDrag, '| final:', _reserverDrag);\r\n        }\r\n    \r\n        const dataTransfer = e.dataTransfer || e.originalEvent?.dataTransfer;\r\n        const files = dataTransfer?.files || null;\r\n        \r\n        const imgSrc = $target.closest('.draggable').find('img').attr('src');\r\n        const videoSrc = $target.closest('.draggable').find('video').attr('src') || \r\n                        $target.closest('.draggable').find('video source').attr('src');\r\n        const mediaSrc = imgSrc || videoSrc;\r\n    \r\n        console.log('dragstart target:', e.target);\r\n        console.log('files:', files);\r\n        console.log('mediaSrc:', mediaSrc);\r\n    \r\n        if (!mediaSrc && (!files || files.length === 0)) {\r\n            console.log('No media source or files found, preventing drag');\r\n            e.preventDefault();\r\n            this.state.dragInProgress = false;\r\n            return false;\r\n        }\r\n    \r\n        if (mediaSrc) {\r\n            StateManager.set('objectUrl', mediaSrc);\r\n        }\r\n    \r\n        StateManager.set('Commande_Format_Transmis', '');\r\n        \r\n        if ($target.closest('.droppable').find('.doc-preview-container:visible').length > 0) {\r\n            StateManager.set('Commande_Format_Transmis', 'R\u00e9dactionnel');\r\n            StateManager.set('FullPathAdFile', \r\n                $target.closest('.droppable').find('.doc-preview-FullPathAdFile').text());\r\n        }\r\n    \r\n        if (files && files.length > 0) {\r\n            this.state.isFileBeingDragged = true;\r\n            this.state.draggedFile = files[0];\r\n        }\r\n        \r\n        \/\/ \u2705 TOUJOURS marquer comme \"Moved\" quand on drag depuis un espace existant\r\n        if (parentId && mediaSrc) {\r\n            StateManager.set('FirstUploadFileorMoved', 'Moved');\r\n            console.log('\u2705 Drag depuis espace existant - Moved');\r\n        }\r\n    \r\n        console.log('Drag Started', {\r\n            file: this.state.draggedFile,\r\n            mediaSrc: mediaSrc,\r\n            dragstartRef: StateManager.get('dragstart_Commande_Emplacement_Page_Web')\r\n        });\r\n    },\r\n    \r\n    handleDragOver(e) {\r\n        e.preventDefault();\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            this.handleIframeDragScroll(e);\r\n        } else {\r\n            this.handleDirectPageScroll(e);\r\n        }\r\n    },\r\n    \r\n    handleIframeDragScroll(e) {\r\n        if (!this.state.throttleTimeout) {\r\n            this.state.throttleTimeout = setTimeout(() => {\r\n                MessageManager.sendToParent('dragScroll', { clientY: e.clientY });\r\n                this.state.throttleTimeout = null;\r\n            }, CONFIG.dragScroll.throttleDelay);\r\n        }\r\n    },\r\n    \r\n    handleDirectPageScroll(e) {\r\n        const { threshold, maxSpeed } = CONFIG.dragScroll;\r\n        const windowHeight = window.innerHeight;\r\n        \r\n        if (e.clientY < threshold) {\r\n            const speed = Math.max(1, maxSpeed * (1 - e.clientY \/ threshold));\r\n            window.scrollBy(0, -speed);\r\n        } else if (e.clientY > windowHeight - threshold) {\r\n            const speed = Math.max(1, maxSpeed * (1 - (windowHeight - e.clientY) \/ threshold));\r\n            window.scrollBy(0, speed);\r\n        }\r\n    },\r\n    \r\n    handleDragEnd(e) {\r\n        e.preventDefault();\r\n        MessageManager.sendToParent('dragEnd', {});\r\n        console.log('dragleave drop');\r\n    },\r\n    \r\n    handleDropZoneDragOver(e) {\r\n        e.preventDefault();\r\n        console.log(\"FirstUploadFileorMoved:\", StateManager.get('FirstUploadFileorMoved'));\r\n    },\r\n    \r\n    handleDraggableEnd(e) {\r\n        e.preventDefault();\r\n        this.resetState();\r\n        console.log('dragend');\r\n    },\r\n    \r\n    resetState() {\r\n        this.state.isFileBeingDragged = false;\r\n        this.state.draggedFile = null;\r\n        this.state.dragInProgress = false;\r\n    },\r\n    \r\n    clearDataTransferFiles(e) {\r\n        e.dataTransfer = new DataTransfer();\r\n        console.log('DataTransfer files cleared');\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'interface utilisateur\r\n *\/\r\nconst UIManager = {\r\n    isMobile() {\r\n        return window.outerWidth < CONFIG.breakpoints.mobile;\r\n    },\r\n    \r\n    isDesktop() {\r\n        const userAgent = navigator.userAgent;\r\n        const isWindows = userAgent.indexOf('Windows') > -1;\r\n        const isMac = userAgent.indexOf('Macintosh') > -1;\r\n        const isLinux = userAgent.indexOf('Linux') > -1 && userAgent.indexOf('Android') === -1;\r\n        return isWindows || isMac || isLinux;\r\n    },\r\n    \r\n    initMobileUI() {\r\n        $(document).ready(() => {\r\n            $('label[for=\"form-field-LienAnnonce\"]').each(function() {\r\n                $(this).text('Renseigner le lien hypertexte de l\\'annonce');\r\n            });\r\n            \r\n            $('input[name=\"form_fields[LienAnnonce]\"]').each(function() {\r\n                $(this).attr('placeholder', 'Renseigner le lien hypertexte de l\\'annonce');\r\n            });\r\n        });\r\n        \r\n        jQuery('.MsgDatesText').hide();\r\n        this.attachMobileEventListeners();\r\n    },\r\n    \r\n    attachMobileEventListeners() {\r\n        jQuery('.TransmettreFichierAnnonceContainer').on('click', (e) => {\r\n            this.handleMobileSpaceSelection(e);\r\n        });\r\n        \r\n        jQuery('[id=\"form-field-selected_currency_Mobile\"]').off('change').on('change', (e) => {\r\n            this.handleMobileCurrencyChange(e);\r\n        });\r\n    },\r\n    \r\n    handleMobileSpaceSelection(e) {\r\n        e.preventDefault();\r\n        jQuery('#IndisponibilitesMsg').hide();\r\n        \r\n        jQuery('input[name=\"form_fields[SelectEspacePublicitaireMobile]\"]').prop('checked', false);\r\n        jQuery(e.currentTarget).find('input[name=\"form_fields[SelectEspacePublicitaireMobile]\"]').prop('checked', true);\r\n        \r\n        StateManager.set(\"PageWebDisplayed\", 'Yes');\r\n        \r\n        jQuery('.FormSelectDevisesMobile').hide();\r\n        jQuery(e.target).closest('.EspacePublicitaireMobile').find('.FormSelectDevisesMobile').show();\r\n        \r\n        const $droppable = jQuery(e.currentTarget).closest('.droppable');\r\n        const rankId = $droppable.attr('id');\r\n        \r\n        StateManager.set('Rank_Emplacement_Page_Web', rankId);\r\n        StateManager.set('Commande_Emplacement_Page_Web', \r\n            StateManager.buildEmplacementReference(rankId));\r\n        \r\n        this.updateEmplacementDisplay();\r\n        this.handleAvailabilityDisplay(e);\r\n        this.displayUploadedAdIfExists(e);\r\n        this.updateTariffDisplay(e);\r\n    },\r\n    \r\n    updateEmplacementDisplay() {\r\n        const emplacement = StateManager.get('Commande_Emplacement_Page_Web');\r\n        jQuery('#EmplacementAnnonceDataStep3').html(emplacement).css({'color': '#56BE50'});\r\n        console.log(\"Emplacement:\", emplacement);\r\n    },\r\n    \r\n    handleAvailabilityDisplay(e) {\r\n        const $espace = jQuery(e.target).closest('.EspacePublicitaireMobile');\r\n        const dispoText = $espace.find('.ChoisirEspacePublicitaireDisponibilite').text();\r\n        \r\n        if (dispoText.length > 46) {\r\n            const espacePublicitaireDispoFrom = dispoText.slice(-10);\r\n            console.log(\"espacePublicitaireDispoFrom:\", espacePublicitaireDispoFrom);\r\n            console.log(\"Date de debut:\", StateManager.get(\"Debut_de_campagne\"));\r\n        } else {\r\n            jQuery('#form-field-DebutCampagne').val(StateManager.get(\"Debut_de_campagne\"));\r\n        }\r\n    },\r\n    \r\n    displayUploadedAdIfExists(e) {\r\n        if (StateManager.get(\"FileReceived\") === 'Yes') {\r\n            jQuery('.VisualisationAnnonceMobile').hide();\r\n            \r\n            const espaceId = StateManager.get('espaceChoisi');\r\n            const $espace = document.querySelector(`[id=\"${espaceId}\"]`);\r\n            \r\n            jQuery($espace).find('.MessageAnnonceMobileTexte')\r\n                .html('Merci de choisir des dates de campagne<br>afin d\\'obtenir le tarif de cet espace publicitaire');\r\n            jQuery($espace).find('.VisualisationAnnonceMobile').show();\r\n        \r\n            const img = document.createElement('img');\r\n            img.src = StateManager.get('objectUrl');\r\n            img.style.width = 'auto';\r\n            img.style.height = 'auto';\r\n            img.style.maxWidth = '100%';\r\n            img.style.maxHeight = '200px';\r\n            \r\n            jQuery('.VisualisationAnnonceMobile').empty();\r\n            jQuery($espace).find('.VisualisationAnnonceMobile').append(img);\r\n        }\r\n    },\r\n    \r\n    updateTariffDisplay(e) {\r\n        jQuery('.TariftobedisplayedMobile').html('-');\r\n        const newTarif = StateManager.get('NewTarifformatted');\r\n        \r\n        if (newTarif && newTarif !== '-') {\r\n            jQuery(e.target).closest('.EspacePublicitaireMobile')\r\n                .find('.TariftobedisplayedMobile')\r\n                .html(newTarif);\r\n        }\r\n    },\r\n    \r\n    handleMobileCurrencyChange(e) {\r\n        event.preventDefault();\r\n        StateManager.setMultiple({\r\n            \"SelectionCatalogueOuAchat\": 'Catalogue',\r\n            \"selected_currency\": jQuery(e.currentTarget).val()\r\n        });\r\n        \r\n        jQuery('#form-field-selected_currency_2').val(StateManager.get(\"selected_currency\"));\r\n        console.log(\"selected currency:\", StateManager.get(\"selected_currency\"));\r\n        \r\n        setTimeout(() => {\r\n            jQuery(e.target).closest('.EspacePublicitaireMobile')\r\n                .find('.TariftobedisplayedMobile')\r\n                .html(StateManager.get(\"NewTarifformatted\"));\r\n        }, 500);\r\n    },\r\n    \r\n    initDesktopUI() {\r\n        StateManager.setMultiple({\r\n            \"FileReceived\": \"No\",\r\n            \"AdDisplayed\": \"No\"\r\n        });\r\n        jQuery('.MsgAdNotDisplayed').hide();\r\n    },\r\n    \r\n    showUploadProgress($dropZone) {\r\n        \/\/ Cacher les \u00e9l\u00e9ments\r\n        $dropZone.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed, span.ClassHdpCdp, .ClassRefEsp, .HideFormButton, .EspPubFormatMainContainer, .TexteMobileAnnonce')\r\n            .hide();\r\n        \r\n        \/\/ Afficher et styler le message de progression\r\n        var _uplMsg = 'Loading in progress <span class=\"dot-container\"><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><\/span>';\r\n        $dropZone.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed')\r\n            .show()\r\n            .html(_uplMsg)\r\n            .css({\r\n                'color': '#00ff19',\r\n                'background-color': 'white',\r\n                'padding': '12px 20px',\r\n                'border-radius': '6px',\r\n                'font-weight': '700',\r\n                'font-size': '18px',\r\n                'line-height': '1.4',\r\n                'display': 'inline-block',\r\n                'margin': '10px auto',\r\n                'text-align': 'center'\r\n            });\r\n        \r\n        \/\/ Cacher les autres \u00e9l\u00e9ments\r\n        $dropZone.closest('.droppable')\r\n            .find('.UploadIci, .EnvoiUlterieurTexte, .EnvoiUlterieurContainer')\r\n            .hide();\r\n            \r\n        $dropZone.closest('.droppable')\r\n            .find('.UploadFileConteneur')\r\n            .css({\r\n                'background-color': 'transparent'\r\n            });\r\n    },\r\n    \r\n    showFormatError($dropZone, message = 'Format de fichier incompatible') {\r\n        \/\/ \u2705 v2.4.6 : M\u00eame rendu overlay que le bloc jpeg \u2014 position absolute sur $dropZone\r\n        var _errId = 'fmt-error-msg-' + Date.now();\r\n        $dropZone.css('position', 'relative');\r\n        var _errHtml = '<div id=\"' + _errId + '\" style=\"'\r\n            + 'position:absolute;top:50px;left:50%;transform:translateX(-50%);width:auto;white-space:nowrap;'\r\n            + 'background:#fff;color:#FB5E2A;font-weight:700;font-size:13px;'\r\n            + 'text-align:center;padding:8px 10px;border-radius:6px;'\r\n            + 'border:2px solid #FB5E2A;box-sizing:border-box;'\r\n            + 'z-index:99999;line-height:1.4;'\r\n            + '\">' + message + '<\/div>';\r\n        $dropZone.append(_errHtml);\r\n        setTimeout(function() { jQuery('#' + _errId).remove(); }, 4000);\r\n    },\r\n    \r\n    updateAfterSuccessfulUpload($dropZone) {\r\n        jQuery('#errorMessageMobileText').hide();\r\n        \r\n        $dropZone.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed, span.ClassHdpCdp, .ClassRefEsp, .HideFormButton, .EspPubFormatMainContainer, .EnvoiUlterieurContainer')\r\n            .hide();\r\n        \r\n        \/\/ \u2705 Pas de margin-top:150px si d\u00e9p\u00f4t depuis miniature kit (d\u00e9j\u00e0 positionn\u00e9)\r\n        if (!window._dropFromMiniature) {\r\n            $dropZone.closest('.OrdiMobileConteneurClass')\r\n                .css({'margin-top': '150px', 'margin-bottom': '0px'});\r\n        }\r\n    },\r\n    \r\n    finalizeAdDisplay($dropZone) {\r\n        StateManager.setMultiple({\r\n            \"FileReceived\": \"Yes\",\r\n            \"PageWebDisplayed\": \"Yes\"\r\n        });\r\n        \r\n        jQuery('#MsgChoixPageWeb, #MsgInsererAnnonceConteneur').hide();\r\n        jQuery('#ChoixEspacePublicitaire')\r\n            .html('L\\'annonce est plac\u00e9e dans un espace publicitaire')\r\n            .show()\r\n            .css({'color': '#56BE50'});\r\n        \r\n        jQuery('#MsgPlacerAnnoncePosition').hide();\r\n        jQuery('#FonctionMenu4').show();\r\n        jQuery('.AnnonceData').html(\"Transmis\").css({'color': '#56BE50'});\r\n        \r\n        jQuery('#ProcederPaiementConteneur').hide();\r\n        jQuery('#ProcederPaiementTitreIconeUp').hide();\r\n        jQuery('#ProcederPaiementTitreIconeDown').show();\r\n        \r\n        jQuery('#message').remove();\r\n        \r\n        this.styleUploadedAd($dropZone);\r\n        this.adjustLayoutAfterUpload($dropZone);\r\n        \r\n        \/\/ \u2705 Mettre \u00e0 jour l'\u00e9tat de la checkbox \"R\u00e9server\" apr\u00e8s upload\r\n        FormatUIManager.updateReserverCheckboxState($dropZone.closest('.droppable'));\r\n    },\r\n    \r\n    styleUploadedAd($dropZone) {\r\n        const $container = $dropZone.closest('.OrdiMobileConteneurClass');\r\n        const $droppable = $dropZone.closest('.droppable');\r\n        \r\n        \/\/ \u2705 v1.19.5 : V\u00e9rifier si c'est une restauration via flag d\u00e9di\u00e9\r\n        const isRestoration = StateManager.get('_isAdRestoration') === 'Yes';\r\n        \r\n        $container\r\n            .find('.PositionReference, .TexteMobile, .EnvoiUlterieurContainer')\r\n            .hide();\r\n        \r\n        $container\r\n            .find('.AdUploadedTitle, .DimensionsMaximales')\r\n            .show();\r\n        \r\n        \/\/ \u2705 Bug 2 fix : montrer le conteneur parent + la croix (CroixResetAnnonceContainer cach\u00e9 par reset)\r\n        $droppable.find('.CroixResetAnnonceContainer').show();\r\n        $droppable.find('#CroixResetAnnonce').show();\r\n        \r\n        \/\/ \u2705 v2.2 : Marquer le droppable comme occup\u00e9 pour qu'Entete le skip\r\n        $droppable.attr('data-via-ad-loaded', 'true');\r\n        \r\n        \/\/ \u2705 v2.0.11 : AdUploadedTitle ne doit pas bloquer le touch sur doc-preview-readmore (mobile)\r\n        $container.find('.AdUploadedTitle').css('pointer-events', 'none');\r\n        \r\n        \/\/ \u2705 #CroixResetAnnonce au-dessus de tous les conteneurs superpos\u00e9s\r\n        $container.find('#CroixResetAnnonce').css({\r\n            'position': 'relative',\r\n            'z-index': '9999'\r\n        });\r\n        \r\n        \/\/ \u2705 Desktop : les conteneurs superpos\u00e9s bloquent la croix \u2014 les rendre transparents aux clics\r\n        if (!UIManager.isMobile()) {\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css('pointer-events', 'none');\r\n            \/\/ R\u00e9activer les \u00e9l\u00e9ments interactifs\r\n            $container.find('#CroixResetAnnonce').css('pointer-events', 'auto');\r\n            $dropZone.closest('#PopUpMessageAchattest').css('pointer-events', 'auto'); \/\/ drag annonce\r\n        }\r\n        \r\n        \/\/ \u2705 v2.4.3 : Sur mobile, masquer titre et logo drag quand annonce d\u00e9pos\u00e9e dans Ele0A\r\n        if (UIManager.isMobile()) {\r\n            if ($droppable.attr('id') === 'Ele0A') {\r\n                $droppable.find('#ChoixEspacePublicitaireTexte').hide();\r\n                $droppable.find('#Ele0ADragHandle').hide();\r\n                \/\/ \u2705 v2.4.12 : UploadFileConteneur a pointer-events:none \u2192 forcer auto sur la croix\r\n                $droppable.find('.CroixResetAnnonceContainer')[0] && $droppable.find('.CroixResetAnnonceContainer')[0].style.setProperty('pointer-events', 'auto', 'important');\r\n                $droppable.find('#CroixResetAnnonce')[0] && $droppable.find('#CroixResetAnnonce')[0].style.setProperty('pointer-events', 'auto', 'important');\r\n            }\r\n        }\r\n        \r\n        jQuery(\".HTMLUploadfileConteneur\").css({\r\n            'border': 'none',\r\n            'background-color': 'transparent'\r\n        });\r\n        \r\n        \/\/ \u2705 v2.4.12 : Retirer le liser\u00e9 envoi diff\u00e9r\u00e9 (#UploadFileConteneur) si pr\u00e9sent\r\n        \/\/ (le d\u00e9p\u00f4t d'une annonce cr\u00e9e son propre liser\u00e9 sur .HTMLUploadfileConteneur)\r\n        var $_ufcEd = $dropZone.closest('.droppable').find('#UploadFileConteneur');\r\n        if ($_ufcEd[0]) {\r\n            $_ufcEd[0].style.removeProperty('box-shadow');\r\n            $_ufcEd[0].style.removeProperty('box-sizing');\r\n            if (UIManager.isMobile()) {\r\n                $_ufcEd[0].style.removeProperty('transform');\r\n                $_ufcEd[0].style.removeProperty('transform-origin');\r\n            }\r\n        }\r\n        \r\n        $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n            'box-shadow': 'inset 0 0 0 2px #00FF19',  \/\/ \u2705 v2.4.5 : inset \u2192 jamais clipp\u00e9 par overflow:hidden\r\n            'background-color': 'white',\r\n            'box-sizing': 'border-box',\r\n            'overflow': 'hidden'\r\n        });\r\n        \r\n        \/\/ \u2705 v2.0.9 : Fix mobile \u2014 r\u00e9duire le scale pour que le liser\u00e9 vert soit visible\r\n        \/\/ \u2705 Pas de scale si annonce d\u00e9pos\u00e9e depuis la miniature kit (d\u00e9j\u00e0 aux bonnes dimensions)\r\n        \/\/ \u2705 v2.4.9 : Pas de scale si AchatEspaceCall=Yes (drop depuis miniature dans iframe)\r\n        \/\/ \u2705 data-kit-drop : marqueur DOM pos\u00e9 par kitAdCreated, r\u00e9siste \u00e0 l'async\r\n        var _fromKitDrop = $droppable[0] ? $droppable[0].getAttribute('data-kit-drop') === 'true' : false;\r\n        if (_fromKitDrop) { window._dropFromMiniature = true; } \/\/ sync le flag window\r\n        var _fromMiniature = window._dropFromMiniature || _fromKitDrop;\r\n        var _fromAchat = StateManager.get('AchatEspaceCall') === 'Yes';\r\n        if (UIManager.isMobile() && !_fromMiniature && !_fromAchat) {\r\n            $dropZone.closest('.UploadFileConteneur').css({\r\n                'transform': 'scale(1.35)',\r\n                'transform-origin': 'top center'\r\n            });\r\n            \/\/ \u2705 v2.4.11 : Corps de page mobile \u2014 le .ToBeHidden clippe le scale(1.35) c\u00f4t\u00e9 droit\r\n            \/\/ \u2192 overflow:visible pour que le liser\u00e9 vert soit visible sur les 4 c\u00f4t\u00e9s\r\n            $dropZone.closest('.ToBeHidden').css('overflow', 'visible');\r\n        }\r\n        \r\n        \/\/ \u2705 v2.2 : Sur restauration, Entete a d\u00e9j\u00e0 positionn\u00e9 le droppable correctement\r\n        \/\/ et est emp\u00each\u00e9 de le retoucher (data-via-ad-loaded). On ne touche pas aux marges.\r\n        \/\/ Sur premier upload, on applique les marges normalement.\r\n        \/\/ \u2705 Pas de marges si d\u00e9p\u00f4t depuis miniature kit (dimensions naturelles conserv\u00e9es)\r\n        if (!isRestoration && !_fromMiniature) {\r\n            if ($container.data('orig-mb') === undefined) {\r\n                $container.data('orig-mb', parseInt($container.css('margin-bottom')) || 0);\r\n            }\r\n            if ($droppable.data('orig-mt') === undefined) {\r\n                $droppable.data('orig-mt', parseInt($droppable.css('margin-top')) || 0);\r\n            }\r\n            var _isDocPreview = $dropZone.find('.doc-preview-container').length > 0;\r\n            var _marginAdd = _isDocPreview ? 60 : 130;\r\n            var _marginReduce = _isDocPreview ? 60 : 130;\r\n            $container.css({\r\n                'margin-bottom': ($container.data('orig-mb') + _marginAdd) + 'px'\r\n            });\r\n            $droppable.css({\r\n                'margin-top': ($droppable.data('orig-mt') - _marginReduce + 75) + 'px'\r\n            });\r\n        } else {\r\n            \/\/ \u2705 Sur restauration, ajouter 50px en dessous pour \u00e9viter que le contenu soit trop coll\u00e9\r\n            var _curMb = parseInt($container.css('margin-bottom')) || 0;\r\n            $container.css('margin-bottom', (_curMb + 50) + 'px');\r\n        }\r\n        \r\n        \/\/ \u2705 Masquer .PositionEspacePublicitaireContainer et l'ancien .ReserverContainer\r\n        $droppable.find('.PositionEspacePublicitaireContainer').hide();\r\n        $droppable.find('.ReserverContainer').hide();\r\n        \r\n        \/\/ \u2705 Supprimer tout ancien bouton dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ \u2705 v2.1.2 : Cr\u00e9er le bouton R\u00e9server m\u00eame lors d'une restauration\r\n        if (isRestoration) {\r\n            console.log('\ud83d\udd04 Restauration d\u00e9tect\u00e9e - affichage bouton R\u00e9server + DeplaceAnnonce');\r\n            $droppable.find('.DeplaceAnnonce').show();\r\n            \/\/ S'assurer que FileReceived est d\u00e9fini pour la validation\r\n            StateManager.set('FileReceived', 'Yes');\r\n            \/\/ Cocher automatiquement SEULEMENT si c'est une restauration de commande r\u00e9serv\u00e9e (pas pendingAd)\r\n            var _isPendingAdRestore = sessionStorage.getItem('_pendingAdRestoration') === 'Yes';\r\n            if (!_isPendingAdRestore) {\r\n                var _isReservedRestore = sessionStorage.getItem('_isReservedRestoration') === 'Yes';\r\n                setTimeout(function() {\r\n                    var $checkbox = $droppable.find('.reserver-dynamic-checkbox');\r\n                    if ($checkbox.length && _isReservedRestore) {\r\n                        $checkbox.prop('checked', true);\r\n                        $droppable.find('.reserver-dynamic-label').text('Espace publicitaire r\u00e9serv\u00e9').css('color', 'rgb(62, 170, 19)');\r\n                        console.log('\u2705 R\u00e9server coch\u00e9 automatiquement (restauration commande r\u00e9serv\u00e9e)');\r\n                    }\r\n                    sessionStorage.removeItem('_isReservedRestoration');\r\n                    StateManager.set('_isAdRestoration', 'No');\r\n                    \/\/ \u2705 v2.4.7 : updateReserverCheckboxState APR\u00c8S avoir coch\u00e9 la checkbox\r\n                    \/\/ (l'appel synchrone ligne 614 intervient avant le cocher \u2192 label incorrect)\r\n                    if (typeof FormatUIManager !== 'undefined') {\r\n                        FormatUIManager.updateReserverCheckboxState($droppable);\r\n                    }\r\n                }, 150);\r\n            } else {\r\n                \/\/ pendingAd : ne pas cocher, ne pas envoyer au parent\r\n                console.log('\u2705 pendingAd restaur\u00e9 \u2014 R\u00e9server NON coch\u00e9');\r\n                sessionStorage.removeItem('_pendingAdRestoration');\r\n                StateManager.set('_isAdRestoration', 'No');\r\n            }\r\n        }\r\n        \r\n        \/\/ \u2705 Supprimer tout bouton R\u00e9server existant avant insertion (\u00e9vite doublons sur restauration)\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ \u2705 Cr\u00e9er le bouton \"R\u00e9server\" dynamique avec id unique pour \u00e9viter conflit label\/for Elementor\r\n        const _rankId = $droppable.attr('id') || ('drop_' + Date.now());\r\n        const _cbId = 'reserver-cb-' + _rankId;\r\n        const reserverHTML = `\r\n            <div class=\"reserver-dynamic-container\">\r\n                <span class=\"reserver-dynamic-option\">\r\n                    <input type=\"checkbox\" id=\"${_cbId}\" value=\"R\u00e9server cet espace publicitaire\" \r\n                           class=\"reserver-dynamic-checkbox\"\r\n                           name=\"form_fields[ReserverEspacePublicitaire]\">\r\n                    <span class=\"reserver-dynamic-label\">R\u00e9server cet espace publicitaire<\/span>\r\n                <\/span>\r\n            <\/div>\r\n        `;\r\n        \r\n        \/\/ \u2705 Ins\u00e9rer juste avant .DeplaceAnnonceText (position stable)\r\n        const $anchor = $droppable.find('.DeplaceAnnonceText');\r\n        if ($anchor.length) {\r\n            $anchor.before(reserverHTML);\r\n            $anchor.prev('.reserver-dynamic-container').css('margin-bottom', '-40px');\r\n            if (!UIManager.isMobile()) {\r\n                $anchor.prev('.reserver-dynamic-container').find('.reserver-dynamic-label').css({'font-size': '20px', 'font-weight': '700'});\r\n            }\r\n        } else {\r\n            $droppable.after(reserverHTML);\r\n            const $btn = $droppable.next('.reserver-dynamic-container');\r\n            $btn.css('margin-top', UIManager.isMobile() ? '-10px' : '-140px');\r\n        }\r\n        \r\n        console.log('\u2705 Bouton \"R\u00e9server\" dynamique cr\u00e9\u00e9');\r\n    },\r\n    \r\n    adjustLayoutAfterUpload($dropZone) {\r\n        console.log('\ud83d\udcf1 adjustLayoutAfterUpload \u2014 isMobile():', this.isMobile(), 'outerWidth:', window.outerWidth);\r\n        if (this.isMobile()) {\r\n            this.adjustMobileLayout($dropZone);\r\n            \r\n            \/\/ Repositionner le bouton R\u00e9server APR\u00c8S les ajustements de layout\r\n            setTimeout(() => {\r\n                const $droppable = $dropZone.closest('.droppable');\r\n                const $btn = $droppable.find('.reserver-dynamic-container').add($droppable.next('.reserver-dynamic-container')).first();\r\n                const $lisere = $droppable.find('.HTMLUploadfileConteneur');\r\n                if ($btn.length && $lisere.length) {\r\n                    const lisereBottom = $lisere[0].getBoundingClientRect().bottom;\r\n                    const btnTop = $btn[0].getBoundingClientRect().top;\r\n                    const offset = lisereBottom - btnTop - 48;\r\n                    \r\n                    \/\/ 15px suppl\u00e9mentaires pour homepage et articles\r\n                    let extraOffset = 0;\r\n                    const isHomepage = window.location.pathname === \"\/\" || window.location.pathname === \"\/en\/\";\r\n                    const isSectorPage = $('body').hasClass('page');\r\n                    if (isHomepage) {\r\n                        extraOffset = 13;\r\n                    }\r\n                    if (!isSectorPage) {\r\n                        extraOffset = 15;\r\n                    }\r\n                    \r\n                    \/\/ \u2705 v2.0.9 : +4px pour documents (communiqu\u00e9\/interview\/PDF) avec pr\u00e9sentation HTML\r\n                    if ($droppable.find('.doc-preview-container:visible').length > 0) {\r\n                        extraOffset += 4;\r\n                    }\r\n                    \r\n                    $btn.css({\r\n                        'margin-top': (offset + extraOffset + 20) + 'px',\r\n                        'margin-bottom': (-(offset + extraOffset) - 100) + 'px'\r\n                    });\r\n                    console.log('\ud83d\udcd0 Repositionnement mobile R\u00e9server:', { lisereBottom, btnTop, offset });\r\n                }\r\n            }, 50);\r\n        } else {\r\n            this.adjustDesktopLayout($dropZone);\r\n        }\r\n    },\r\n    \r\n    adjustMobileLayout($dropZone) {\r\n        console.log('\ud83d\udcf1 adjustMobileLayout START');\r\n        console.log('\ud83d\udcf1 AchatEspaceCall:', StateManager.get(\"AchatEspaceCall\"));\r\n        console.log('\ud83d\udcf1 PageAjoutModifAnnonce:', StateManager.get(\"PageAjoutModifAnnonce\"));\r\n        console.log('\ud83d\udcf1 window===window.top:', window === window.top);\r\n        console.log('\ud83d\udcf1 pathname:', location.pathname);\r\n        \r\n        const $droppable = $dropZone.closest('.droppable');\r\n        \r\n        \/\/ \u2705 v2.4.3 : Masquer les textes position\/label\/r\u00e9f\u00e9rence (comme sur desktop)\r\n        $droppable\r\n            .find('.PositionEspacePublicitaire, .ReferenceEspacePublicitaire, .ChoisirEspacePublicitaireDisponibiliteConteneur')\r\n            .hide();\r\n        \r\n        \/\/ \u2705 v2.6 : Renseigner .PositionEspacePublicitaire sur mobile (manquait vs desktop)\r\n        (function() {\r\n            var _rankPosMob = StateManager.get('Rank_Emplacement_Page_Web') || $droppable.attr('id') || '';\r\n            var _posLibMob = PreviewRenderer._getPositionLibelle(_rankPosMob);\r\n            if (_posLibMob) {\r\n                $droppable\r\n                    .find('.PositionEspacePublicitaire')\r\n                    .text(_posLibMob)\r\n                    .each(function() {\r\n                        this.style.setProperty('display', 'block', 'important');\r\n                    });\r\n            }\r\n        })();\r\n        \r\n        \/\/ \u2705 Scop\u00e9 au $dropZone courant (\u00e9vite d'affecter les autres espaces pub)\r\n        $dropZone.closest('.droppable').find('#CroixResetAnnonce').css({'zoom': '75%'});\r\n\r\n        \/\/ \u2705 v2.4.3 : Remonter la croix reset sur mobile (override margin-top Elementor)\r\n        \/\/ \u2705 v2.4.5 : Poser aussi margin-right ici (Entete.txt ne l'atteint pas pour Ele0A)\r\n        var _croixContainer = $dropZone.closest('.OrdiMobileConteneurClass').find('.CroixResetAnnonceContainer')[0];\r\n        if (_croixContainer) {\r\n            var _isEle0ACroix = ($dropZone.closest('.droppable').attr('id') === 'Ele0A');\r\n            var _mtCroix = StateManager.get(\"PageAjoutModifAnnonce\") === 'Yes' ? '-88px' : '24px';\r\n            \/\/ Ele0A : +40px vers le bas, +15px vers la gauche (margin-right) par rapport \u00e0 Ele1A\r\n            \/\/ Ele0A : margin-top identique aux autres espaces (pas de d\u00e9calage suppl\u00e9mentaire)\r\n            _croixContainer.style.setProperty('margin-top', _mtCroix, 'important');\r\n            _croixContainer.style.setProperty('margin-right', _isEle0ACroix ? '17px' : '12px', 'important');\r\n        }\r\n        \r\n        var _isMiniatureAdj = window._dropFromMiniature;\r\n        window._dropFromMiniature = false;\r\n\r\n        if (_isMiniatureAdj && window.outerWidth <= 1000) {\r\n            \/\/ \u2705 Miniature doc-preview MOBILE : ajuster HTMLUploadfileConteneur \u00e0 la hauteur du contenu\r\n            \/\/ et neutraliser tous les margins Elementor qui d\u00e9calent le $dropZone hors du parent\r\n            var _isDocPreviewMob = $dropZone.find('.doc-preview-container').length > 0;\r\n            var _docH = _isDocPreviewMob ? 144 : 115;\r\n            $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n                'height':     _docH + 'px',\r\n                'min-height': _docH + 'px',\r\n                'max-height': _docH + 'px',\r\n                'margin-top': '-55px',\r\n                'margin-bottom': '0px',\r\n                'overflow': 'hidden'\r\n            });\r\n            $dropZone.css({'margin-top': '0px', 'margin-bottom': '0px', 'top': '0px', 'height': (_docH - 6) + 'px'});\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css({'margin-top': '65px', 'margin-bottom': '-10px'});\r\n            \/\/ \u2705 v2.4.9 : Doc-preview \u2014 overflow:visible pour que le liser\u00e9 du haut ne soit pas clipp\u00e9\r\n            if (_isDocPreviewMob) {\r\n                $dropZone.closest('.OrdiMobileConteneurClass').css('overflow', 'visible');\r\n                $dropZone.closest('.OrdiMobileConteneurClass').parent().css('overflow', 'visible');\r\n            }\r\n            \/\/ \u2705 v2.4.9 : Ele0A popup mobile \u2014 neutraliser translateY(-32px) pos\u00e9 par Entete sur EnvoiUlterieurTexte\r\n            var _isEle0AMob = ($dropZone.closest('.droppable').attr('id') === 'Ele0A');\r\n            if (_isEle0AMob) {\r\n                var $_euTxt = $dropZone.closest('.droppable').find('.EnvoiUlterieurTexte');\r\n                if ($_euTxt[0]) {\r\n                    $_euTxt[0].style.setProperty('transform', 'translateY(0px)', 'important');\r\n                    $_euTxt[0].style.setProperty('margin-top', '0px', 'important');\r\n                }\r\n            }\r\n            \/\/ \u2705 v2.4.12 : AchatEspaceCall=Yes \u2192 override margins (m\u00eame correction que pour upload direct)\r\n            if (StateManager.get('AchatEspaceCall') === 'Yes') {\r\n                $dropZone.css({'margin-top': '0px', 'margin-bottom': '0px', 'top': '0px'});\r\n                var _docHAchatMini = _isDocPreviewMob ? 150 : 112;\r\n                $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n                    'margin-top': '70px',\r\n                    'margin-bottom': '35px',\r\n                    'min-height': _docHAchatMini + 'px',\r\n                    'height': _isDocPreviewMob ? _docHAchatMini + 'px' : '',\r\n                    'max-height': _isDocPreviewMob ? _docHAchatMini + 'px' : ''\r\n                });\r\n                console.log('\ud83d\udcf1 [miniature] AchatEspaceCall=Yes OVERRIDE: mt=70px | docPreview:', _isDocPreviewMob);\r\n            }\r\n            return;\r\n        }\r\n        \/\/ \u2705 v2.4.10 : Miniature DESKTOP \u2192 layout normal appliqu\u00e9 ci-dessous\r\n        if (_isMiniatureAdj) {\r\n            \/\/ Pas de overflow:hidden \u2014 le liser\u00e9 box-shadow inset doit rester visible\r\n        }\r\n\r\n        $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n            'min-height': '112px',\r\n            'margin-top': '-85px',\r\n            \/\/ \u2705 v2.4.10 : Miniature desktop \u2014 pas de margin-bottom excessif qui fait grandir le droppable\r\n            'margin-bottom': _isMiniatureAdj ? '0px' : '20px' \/\/ \u2705 v2.6 : 195px \u2192 59px \u2192 20px (\u00f73) espace sous checkbox R\u00e9server\r\n        });\r\n        console.log('\ud83d\udcf1 HTMLUploadfileConteneur margins set: mt=-85px mb=20px, el found:', $dropZone.closest('.HTMLUploadfileConteneur').length);\r\n        \r\n        $dropZone.css({\r\n            'margin-top': '-50px',\r\n            'margin-bottom': '-140px'\r\n        });\r\n        \r\n        $dropZone.closest('.OrdiMobileConteneurClass').css({\r\n            'margin-top': '65px',\r\n            'margin-bottom': '-10px'\r\n        });\r\n        console.log('\ud83d\udcf1 OrdiMobile margins set: mt=65px mb=-10px');\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            \/\/ \u2705 v2.4.12 : Reset $dropZone margins (les -50px\/-140px tirent le contenu vers le haut dans l'iframe)\r\n            \/\/ Pour doc-preview (Communiqu\u00e9\/Interview), la hauteur est plus grande \u2192 ajuster min-height\r\n            var _isDocPreviewAchat = $dropZone.find('.doc-preview-container').length > 0;\r\n            var _docHAchat = _isDocPreviewAchat ? 150 : 112;\r\n            $dropZone.css({'margin-top': '0px', 'margin-bottom': '0px', 'top': '0px'});\r\n            $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n                \/\/ \u2705 v2.4.13 : Miniature desktop \u2192 +40px suppl\u00e9mentaires pour compenser le d\u00e9calage\r\n                'margin-top': _isMiniatureAdj ? '110px' : '70px',\r\n                'margin-bottom': '35px',\r\n                'min-height': _docHAchat + 'px',\r\n                'height': _isDocPreviewAchat ? _docHAchat + 'px' : '',\r\n                'max-height': _isDocPreviewAchat ? _docHAchat + 'px' : ''\r\n            });\r\n            console.log('\ud83d\udcf1 AchatEspaceCall=Yes OVERRIDE: mt=' + (_isMiniatureAdj ? '110px' : '70px') + ' | docPreview:', _isDocPreviewAchat, '| h:', _docHAchat);\r\n        }\r\n        \r\n        if (location.pathname === '\/annonce' || location.pathname === '\/annonce\/') {\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css({'margin-top': '70px'});\r\n        }\r\n        \r\n        if (window === window.top) {\r\n            console.log('\ud83d\udcf1 window===window.top OVERRIDE droppable margins');\r\n            $dropZone.closest('.droppable').css({\r\n                'margin-top': '-100px',\r\n                'margin-bottom': '-100px'\r\n            });\r\n            $dropZone.closest('#UploadFileConteneur').css({'width': '80%'});\r\n        }        \r\n    },\r\n    \r\n    adjustDesktopLayout($dropZone) {\r\n        const emplacement = StateManager.get('Commande_Emplacement_Page_Web');\r\n        const $droppable = $dropZone.closest('.droppable');\r\n        \/\/ \u2705 v2.4.13 : Lire et resetter _dropFromMiniature ici aussi (desktop)\r\n        var _fromMiniatureDesktop = window._dropFromMiniature || ($droppable[0] ? $droppable[0].getAttribute('data-kit-drop') === 'true' : false);\r\n        window._dropFromMiniature = false;\r\n        \/\/ \u2705 Nettoyer data-kit-drop apr\u00e8s lecture\r\n        if ($droppable[0]) { $droppable[0].removeAttribute('data-kit-drop'); }\r\n        \r\n        \/\/ \u2705 Masquer les textes enfants (position, label, r\u00e9f\u00e9rence) sans toucher au conteneur\r\n        $droppable\r\n            .find('.PositionEspacePublicitaire, .ReferenceEspacePublicitaire, .ChoisirEspacePublicitaireDisponibiliteConteneur > div > .elementor-widget-text-editor')\r\n            .hide();\r\n        \r\n        \/\/ \u2705 +15px sur .droppable \u2014 sauf si drop depuis miniature (dimensions naturelles)\r\n        if (!_fromMiniatureDesktop) {\r\n            const currentMt = parseInt($droppable.css('margin-top')) || 0;\r\n            $droppable.css('margin-top', (currentMt + 15) + 'px');\r\n        } else {\r\n            \/\/ \u2705 v2.4.13 : Drop depuis miniature Kit \u2014 d\u00e9caler de 30px vers le bas\r\n            const currentMt = parseInt($droppable.css('margin-top')) || 0;\r\n            \/\/ \u2705 Homepage : -20px (annonce trop basse sur r\u00e9gie) \u2014 autres pages : +70px\r\n            var _mtOffsetMini = (window.location.pathname === '\/' || window.location.pathname === '\/en\/' || window.location.pathname === '\/fr\/') ? -20 : 70;\r\n            $droppable.css('margin-top', (currentMt + _mtOffsetMini) + 'px');\r\n        }\r\n        \r\n        $dropZone.closest('.OrdiMobileConteneurClass')\r\n            .find('.RefEspacePublicitaire')\r\n            .html(emplacement)\r\n            .attr('id', 'RefEspacePublicitaire')\r\n            .each(function() {\r\n                \/\/ \u2705 Forcer aussi le parent .DeplaceAnnonce visible (display:none !important inline)\r\n                var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                this.style.setProperty('display', 'block', 'important');\r\n            });\r\n        \/\/ \u2705 v2.4.5 : Renseigner et afficher .PositionEspacePublicitaire\r\n        (function() {\r\n            var _rankPos = StateManager.get('Rank_Emplacement_Page_Web') || $droppable.attr('id') || '';\r\n            var _posLib = PreviewRenderer._getPositionLibelle(_rankPos);\r\n            if (_posLib) {\r\n                $dropZone.closest('.OrdiMobileConteneurClass')\r\n                    .find('.PositionEspacePublicitaireDeplacer')\r\n                    .text(_posLib)\r\n                    .each(function() {\r\n                        var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                        if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                        this.style.setProperty('display', 'block', 'important');\r\n                    });\r\n            }\r\n        })();\r\n        \r\n        if (window.location.pathname === \"\/\" || window.location.pathname === \"\/en\/\") {\r\n            \/\/ \u2705 v2.4.10 : top selon contexte \u2014 espaces hors .remainingContent d\u00e9calent de 60px, ceux dedans de 20px\r\n            var _inRemainingContent = $dropZone.closest('.remainingContent').length > 0;\r\n            var _topOffsetHP = _inRemainingContent ? '20px' : '100px';\r\n            $dropZone.closest('.ToBeHidden')\r\n                .css('top', _topOffsetHP)\r\n                .css('min-height', '300px');\r\n            \/\/ NB : pas de overflow:hidden ici \u2014 le liser\u00e9 vert (box-shadow inset sur HTMLUploadfileConteneur)\r\n            \/\/ doit rester visible sur les 4 c\u00f4t\u00e9s\r\n        }\r\n        \r\n        \/\/ \u2705 Toutes pages desktop : rendre le parent du droppable non-clippant\r\n        \/\/ Le bouton R\u00e9server est ins\u00e9r\u00e9 apr\u00e8s .droppable avec margin-top n\u00e9gatif \u2014\r\n        \/\/ overflow:hidden sur le parent Elementor le masque sinon.\r\n        $droppable.parent().css('overflow', 'visible');\r\n        \r\n        if (location.pathname === '\/annonce' || location.pathname === '\/annonce\/') {\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css({'margin-top': '0px'});\r\n        }\r\n    }\r\n};\r\n\r\n\/**\r\n * \u2705 Module de gestion des formats et du titre .SelectionFormatTitre\r\n *\/\r\nconst FormatUIManager = {\r\n    \r\n    \/**\r\n     * V\u00e9rifie si un format est s\u00e9lectionn\u00e9 dans un espace publicitaire\r\n     * V\u00e9rifie le background-color OU le sessionStorage (format venant de l'accord\u00e9on)\r\n     *\/\r\n    hasSelectedFormat($element) {\r\n        const $droppable = $element.closest('.droppable');\r\n        const isEle0A = $droppable.attr('id') === 'Ele0A';\r\n        if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n            if (isEle0A) {\r\n                \/\/ \u2705 v2.3.4 : Ele0A popup \u2014 vrai seulement si un format sous-jacent (hors FormatIdPopUp) est s\u00e9lectionn\u00e9\r\n                var _hasDomFmt = $droppable.find('.EspPubFormatContainer').not('.FormatIdPopUp').toArray().some(el => {\r\n                    return $(el).css('background-color') === 'rgb(255, 255, 255)';\r\n                });\r\n                if (_hasDomFmt) return true;\r\n                \/\/ \u2705 v2.4.5 : Fallback sessionStorage \u2014 DOM pas encore mis \u00e0 jour (timing MutationObserver)\r\n                return !!sessionStorage.getItem('FormatSelect');\r\n            }\r\n            \/\/ Autres espaces en mode popup \u2192 toujours vrai\r\n            return true;\r\n        }\r\n        const hasWhiteBg = $droppable.find('.EspPubFormatContainer').toArray().some(el => {\r\n            return $(el).css('background-color') === 'rgb(255, 255, 255)';\r\n        });\r\n        if (hasWhiteBg) return true;\r\n        \/\/ \u2705 v1.16.0 : Fallback sessionStorage Formatchoisi\r\n        if (sessionStorage.getItem('Formatchoisi') === 'Yes') return true;\r\n        \/\/ \u2705 v2.4.5 : Fallback FormatSelect \u2014 cas du chargement initial avec format d\u00e9j\u00e0 s\u00e9lectionn\u00e9\r\n        \/\/ (Formatchoisi peut \u00eatre remis \u00e0 No au chargement, mais FormatSelect persiste)\r\n        if (sessionStorage.getItem('FormatSelect')) return true;\r\n        \/\/ \u2705 v2.4.9 : Fallback _FormatSelectApplied \u2014 survit au clear de yearbook-media.js init\r\n        return !!sessionStorage.getItem('_FormatSelectApplied');\r\n    },\r\n    \r\n    \/**\r\n     * Met \u00e0 jour la couleur du titre .SelectionFormatTitre\r\n     * Blanc si un format est s\u00e9lectionn\u00e9, rouge #FB5E2A sinon\r\n     *\/\r\n    updateTitleColor($droppable) {\r\n        \/\/ \u2705 v2.4.5 : Ele0A \u2014 ne jamais afficher SelectionFormatTitre\r\n        if (sessionStorage.getItem('PopUpChoice') === 'Yes' && $droppable.attr('id') === 'Ele0A') {\r\n            $droppable.find('.SelectionFormatTitre').hide();\r\n            $droppable.find('.SelectionFormatTitreBlanc').show();\r\n            return;\r\n        }\r\n\r\n        if (this.hasSelectedFormat($droppable)) {\r\n            $droppable.find('.SelectionFormatTitre').hide();\r\n            $droppable.find('.SelectionFormatTitreBlanc').show();\r\n            console.log('\u2705 SelectionFormatTitreBlanc affich\u00e9 (format s\u00e9lectionn\u00e9)');\r\n        } else {\r\n            $droppable.find('.SelectionFormatTitre').show();\r\n            $droppable.find('.SelectionFormatTitreBlanc').hide();\r\n            console.log('\u26a0\ufe0f SelectionFormatTitre affich\u00e9 (aucun format s\u00e9lectionn\u00e9)');\r\n        }\r\n    },\r\n    \r\n    \/**\r\n     * Flash visuel sur le titre pour indiquer qu'un format est requis\r\n     *\/\r\n    flashTitle($element) {\r\n        const $droppable = $element.closest('.droppable');\r\n        const $titre = $droppable.find('.SelectionFormatTitre');\r\n        if (!$titre.length) return;\r\n        \r\n        \/\/ Flash rouge rapide 3 fois\r\n        let count = 0;\r\n        const originalColor = $titre.css('color');\r\n        \r\n        const flash = setInterval(() => {\r\n            $titre.css('color', count % 2 === 0 ? '#FF0000' : '#FB5E2A');\r\n            count++;\r\n            if (count >= 6) {\r\n                clearInterval(flash);\r\n                $titre.css('color', '#FB5E2A');\r\n            }\r\n        }, 250);\r\n        \r\n        console.log('\u26a0\ufe0f Flash titre format - action bloqu\u00e9e (aucun format s\u00e9lectionn\u00e9)');\r\n    },\r\n    \r\n    \/**\r\n     * Met \u00e0 jour l'\u00e9tat de la checkbox \"R\u00e9server cet espace publicitaire\"\r\n     * La checkbox est activable si : format s\u00e9lectionn\u00e9 ET (fichier d\u00e9pos\u00e9 OU envoi diff\u00e9r\u00e9)\r\n     *\/\r\n    updateReserverCheckboxState($droppable) {\r\n        \/\/ \u2705 Chercher le label : dynamique ou Elementor statique\r\n        let $label = null;\r\n        let $container = null;\r\n        \r\n        \/\/ 1. Bouton dynamique dans le droppable\r\n        $container = $droppable.find('.reserver-dynamic-container');\r\n        if (!$container.length) {\r\n            $container = $droppable.next('.reserver-dynamic-container');\r\n        }\r\n        if (!$container.length) {\r\n            \/\/ Mobile : checkbox attach\u00e9e au body avec data-droppable-id\r\n            $container = $('body > .reserver-dynamic-container[data-droppable-id=\"' + $droppable.attr('id') + '\"]');\r\n        }\r\n        if (!$container.length) {\r\n            $container = $('body > .reserver-dynamic-container');\r\n        }\r\n        \r\n        if ($container.length) {\r\n            $label = $container.find('.reserver-dynamic-label');\r\n            $container.find('.reserver-dynamic-option, .elementor-field-option').css('opacity', '1');\r\n        }\r\n        \r\n        \/\/ 2. Bouton Elementor statique - chercher dans le droppable puis globalement\r\n        let $reserverStatique = $droppable.find('.elementor-field-group-ReserverEspacePublicitaire label');\r\n        if (!$reserverStatique.length) {\r\n            $reserverStatique = $droppable.find('label[for^=\"form-field-ReserverEspacePublicitaire\"]');\r\n        }\r\n        if (!$reserverStatique.length) {\r\n            \/\/ Fallback global : le formulaire peut \u00eatre en dehors du droppable\r\n            $reserverStatique = $('.elementor-field-group-ReserverEspacePublicitaire .elementor-field-option label');\r\n        }\r\n        \r\n        const hasFormat = this.hasSelectedFormat($droppable);\r\n        const hasFile = StateManager.get('FileReceived') === 'Yes';\r\n        const hasEnvoiDiffere = $droppable.find('input[name*=\"EnvoiUlterieur\"]:checked').length > 0;\r\n        \r\n        const canReserve = hasFormat && (hasFile || hasEnvoiDiffere);\r\n        \r\n        \/\/ \u2705 Si la checkbox R\u00e9server est coch\u00e9e \u2192 label vert \"Espace publicitaire r\u00e9serv\u00e9\"\r\n        const isChecked = $droppable.find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').prop('checked') ||\r\n                          ($container.length && $container.find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').prop('checked'));\r\n        \/\/ \u2705 v2.4.7 : Signal de restauration r\u00e9serv\u00e9e \u2014 checkbox pas encore coch\u00e9e (setTimeout 150ms)\r\n        \/\/             mais on sait d\u00e9j\u00e0 que l'espace est r\u00e9serv\u00e9 \u2192 traiter comme coch\u00e9\r\n        const _isReservedRestoration = sessionStorage.getItem('_isReservedRestoration') === 'Yes';\r\n        const isCheckedOrReservedRestore = isChecked || _isReservedRestoration;\r\n        \r\n        if ($label && $label.length) {\r\n            if (isCheckedOrReservedRestore) {\r\n                $label.text('Espace publicitaire r\u00e9serv\u00e9').css('color', 'rgb(62, 170, 19)');\r\n            } else {\r\n                $label.text('R\u00e9server cet espace publicitaire').css('color', canReserve ? '#FB5E2A' : '');\r\n            }\r\n        }\r\n        if ($reserverStatique.length) {\r\n            if (isCheckedOrReservedRestore) {\r\n                $reserverStatique.attr('style', 'color: rgb(62, 170, 19) !important;');\r\n            } else if (canReserve) {\r\n                $reserverStatique.attr('style', 'color: #FB5E2A !important;');\r\n            } else {\r\n                $reserverStatique.removeAttr('style');\r\n            }\r\n        }\r\n        \r\n        console.log('\ud83d\udd04 updateReserverCheckboxState:', { hasFormat, hasFile, hasEnvoiDiffere, canReserve, dynamicLabel: !!($label && $label.length), staticLabel: $reserverStatique.length });\r\n    },\r\n    \r\n    \/**\r\n     * Initialise les listeners pour le changement de format et la checkbox R\u00e9server\r\n     *\/\r\n    init() {\r\n        \/\/ \u2705 \u00c9couter les clics sur les conteneurs de format et leurs parents\r\n        jQuery(document).on('click', '.EspPubFormatContainer, .EspPubFormatListe, .EspPubFormatMainContainer', (e) => {\r\n            const $droppable = jQuery(e.target).closest('.droppable');\r\n            if (!$droppable.length) return;\r\n            \r\n            \/\/ Multiples d\u00e9lais pour couvrir les traitements asynchrones\r\n            [50, 200, 500].forEach(delay => {\r\n                setTimeout(() => {\r\n                    this.updateTitleColor($droppable);\r\n                    this.updateReserverCheckboxState($droppable);\r\n                }, delay);\r\n            });\r\n\r\n            \/\/ \u2705 v2.2.0 : Si un format (non Cr\u00e9ation) est cliqu\u00e9, notifier le parent pour mettre \u00e0 jour le Kit\r\n            const $btn = jQuery(e.target).closest('.EspPubFormatContainer');\r\n            if ($btn.length && !$btn.hasClass('FormatIdCreation') && !$btn.hasClass('FormatIdPopUp')) {\r\n                \/\/ \u2705 v2.3.4 : FormatIdPopUp g\u00e9r\u00e9 par clickFormatFromIframe (Entete.txt) \u2014 ne pas doubler\r\n                var classes = $btn.attr('class') || '';\r\n                var match = classes.match(\/FormatId(\\w+)\/);\r\n                if (match && match[1]) {\r\n                    var _rankEP = $droppable.attr('id') || '';\r\n                    setTimeout(function() {\r\n                        MessageManager.sendToParent('formatChangedInIframe', { formatSelect: match[1], rank: _rankEP });\r\n                        console.log('\ud83d\udd04 formatChangedInIframe envoy\u00e9:', match[1], '| rank:', _rankEP);\r\n                    }, 100);\r\n                }\r\n            }\r\n        });\r\n        \r\n        \/\/ \u2705 MutationObserver sur les conteneurs de format pour d\u00e9tecter les changements de style\r\n        setTimeout(() => {\r\n            this.observeFormatChanges();\r\n            \r\n            \/\/ Initialiser les couleurs des titres au chargement\r\n            jQuery('.droppable').each((i, el) => {\r\n                this.updateTitleColor(jQuery(el));\r\n            });\r\n            \r\n            \/\/ \u2705 v2.3.4 : Popup \u2192 restaurer FormatIdPopUp + format sous-jacent (sans \u00e9craser applyFormatState)\r\n            if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n                jQuery('.FormatIdPopUp').css({'background-color': '#ffffff'});\r\n                jQuery('.FormatIdPopUp').find('.EspPubFormat').css({'color': '#37D900'});\r\n                \/\/ Restaurer aussi le format sous-jacent dans Ele0A\r\n                var _fmtSS = sessionStorage.getItem('FormatSelect') || '';\r\n                if (_fmtSS) {\r\n                    var _fmtSSNorm = _fmtSS.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                    jQuery('#Ele0A').find('.EspPubFormatContainer').not('.FormatIdCreation').each(function() {\r\n                        var _cls = this.className.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                        if (_cls.includes(_fmtSSNorm)) {\r\n                            jQuery(this).css({'background-color': '#ffffff'});\r\n                            jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                        }\r\n                    });\r\n                }\r\n                jQuery('.droppable').each((i, el) => {\r\n                    this.updateTitleColor(jQuery(el));\r\n                });\r\n            }\r\n        }, 500);\r\n        \r\n        \/\/ \u2705 v1.16.0 : Re-v\u00e9rifier apr\u00e8s un d\u00e9lai plus long (format venant de l'accord\u00e9on via postMessage)\r\n        [1500, 3000].forEach(delay => {\r\n            setTimeout(() => {\r\n                \/\/ \u2705 v2.3.4 : Popup \u2192 restaurer FormatIdPopUp + format sous-jacent\r\n                if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n                    jQuery('.FormatIdPopUp').css({'background-color': '#ffffff'});\r\n                    jQuery('.FormatIdPopUp').find('.EspPubFormat').css({'color': '#37D900'});\r\n                    var _fmtSSR = sessionStorage.getItem('FormatSelect') || '';\r\n                    if (_fmtSSR) {\r\n                        var _fmtSSRNorm = _fmtSSR.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                        jQuery('#Ele0A').find('.EspPubFormatContainer').not('.FormatIdCreation').each(function() {\r\n                            var _cls = this.className.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                            if (_cls.includes(_fmtSSRNorm)) {\r\n                                jQuery(this).css({'background-color': '#ffffff'});\r\n                                jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                            }\r\n                        });\r\n                    }\r\n                    jQuery('.droppable').each((i, el) => {\r\n                        this.updateTitleColor(jQuery(el));\r\n                    });\r\n                    return;\r\n                }\r\n                if (sessionStorage.getItem('Formatchoisi') === 'Yes') {\r\n                    jQuery('.droppable').each((i, el) => {\r\n                        this.updateTitleColor(jQuery(el));\r\n                    });\r\n                }\r\n            }, delay);\r\n        });\r\n    },\r\n    \r\n    \/**\r\n     * Attache un MutationObserver sur chaque .EspPubFormatContainer\r\n     * pour d\u00e9tecter tout changement de style (background-color) \r\n     * quel que soit le script qui le d\u00e9clenche\r\n     *\/\r\n    observeFormatChanges() {\r\n        \/\/ \u2705 Guard global anti-boucle \u2014 un seul verrou pour tous les observers\r\n        window._formatObserverLocked = false;\r\n        \r\n        jQuery('.EspPubFormatContainer').each((i, el) => {\r\n            const observer = new MutationObserver(() => {\r\n                if (window._formatObserverLocked) return;\r\n                window._formatObserverLocked = true;\r\n                \/\/ \u2705 v2.4.12 : Debounce 150ms \u2014 applyFormatState manipule plusieurs containers\r\n                \/\/ en s\u00e9quence rapide, le MutationObserver peut firer sur un \u00e9tat interm\u00e9diaire\r\n                clearTimeout(window._formatObserverTimer);\r\n                window._formatObserverTimer = setTimeout(() => {\r\n                    const $droppable = jQuery(el).closest('.droppable');\r\n                    this.updateTitleColor($droppable);\r\n                    this.updateReserverCheckboxState($droppable);\r\n                    window._formatObserverLocked = false;\r\n                }, 150);\r\n            });\r\n            observer.observe(el, { \r\n                attributes: true, \r\n                attributeFilter: ['style', 'class'] \r\n            });\r\n        });\r\n        console.log('\u2705 MutationObserver attach\u00e9 aux conteneurs de format');\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de communication avec la page parente\r\n *\/\r\nconst MessageManager = {\r\n    sendToParent(type, data = {}) {\r\n        try {\r\n            window.parent.postMessage({\r\n                type: type,\r\n                iframeId: CONFIG.iframeId,\r\n                data: data\r\n            }, '*');\r\n        } catch (error) {\r\n            console.error('Error sending message to parent:', error);\r\n            window.parent.postMessage({\r\n                type: 'error',\r\n                error: error.message,\r\n                iframeId: CONFIG.iframeId\r\n            }, '*');\r\n        }\r\n    },\r\n    \r\n    sendDataToParent(data) {\r\n        this.sendToParent('dataFromIframeEspacePub', data);\r\n    },\r\n    \r\n    sendDelAdToParent(data) {\r\n        this.sendToParent('dataDelAd', data);\r\n    },\r\n    \r\n    prepareUploadData() {\r\n        const keys = [\r\n            'AddNewRefInVosCampagnes',\r\n            'FirstUploadFileorMoved',\r\n            'LoadedPageUrl',\r\n            'codePage',\r\n            'Rank_Emplacement_Page_Web',\r\n            'Commande_Emplacement_Page_Web',\r\n            'dragstart_Commande_Emplacement_Page_Web',\r\n            'dragstart_Rank_Emplacement_Page_Web',  \r\n            'FullPathAdFile',\r\n            'Upload_File_Name',\r\n            'FileReceived',\r\n            'PageWebDisplayed',\r\n            'Commande_Format_Transmis',\r\n            'EspPubLienAnnonce',\r\n            'EnvoiUlterieur',\r\n            'Formatchoisi'\r\n        ];\r\n        \r\n        const data = StateManager.getMultiple(keys);\r\n        \r\n        \/\/ \u2705 v2.3.4 : Popup (Ele0A) \u2014 lire le format sous-jacent depuis le DOM\r\n        \/\/ StateManager contient 'PopUp' (virtuel), mais le vrai format est visuellement s\u00e9lectionn\u00e9 dans #Ele0A\r\n        if (data.Rank_Emplacement_Page_Web === 'Ele0A' || sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n            var _ele0AFormatDOM = '';\r\n            jQuery('#Ele0A').find('.EspPubFormatContainer').not('.FormatIdPopUp').each(function() {\r\n                if (jQuery(this).css('background-color') === 'rgb(255, 255, 255)') {\r\n                    var _cls = this.className || '';\r\n                    var _match = _cls.match(\/FormatId(\\S+)\/);\r\n                    if (_match) { _ele0AFormatDOM = _match[1]; return false; }\r\n                }\r\n            });\r\n            if (_ele0AFormatDOM) {\r\n                data.Commande_Format_Transmis = _ele0AFormatDOM;\r\n            }\r\n        }\r\n        \r\n        console.log('\ud83d\udce4 prepareUploadData:', {\r\n            FirstUploadFileorMoved: data.FirstUploadFileorMoved,\r\n            dragstart_Commande_Emplacement_Page_Web: data.dragstart_Commande_Emplacement_Page_Web,\r\n            Commande_Emplacement_Page_Web: data.Commande_Emplacement_Page_Web\r\n        });\r\n    \r\n        return data;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de rendu des aper\u00e7us de fichiers\r\n *\/\r\nconst PreviewRenderer = {\r\n    _getPositionLibelle(rankId) {\r\n        if (!rankId) return '';\r\n        var match = rankId.match(\/Ele(\\d+)[A-Z]\/);\r\n        if (!match) return '';\r\n        var rang = parseInt(match[1]);\r\n        if (rang === 0) return 'Pop-up';\r\n        if (rang === 1 || rang === 2) return 'Haut de page';\r\n        return 'Corps de page';\r\n    },\r\n    renderVideo(objectUrl, fileName, $dropZone) {\r\n        const videoElement = jQuery('<video controls autoplay muted>').attr({\r\n            'src': objectUrl,\r\n            'width': 'auto',\r\n            'height': 'auto',\r\n            'id': fileName\r\n        }).css({\r\n            'max-width': '100%',\r\n            'max-height': '100%'\r\n        });\r\n        \r\n        if (UIManager.isDesktop()) {\r\n            $dropZone.empty().append(videoElement.clone());\r\n            jQuery('#ApercuMobile').css({\r\n                'display': 'flex',\r\n                'justify-content': 'center',\r\n                'align-items': 'center'\r\n            }).append(videoElement);\r\n        } else {\r\n            const img = document.createElement('img');\r\n            img.src = objectUrl;\r\n            img.style.width = 'auto';\r\n            img.style.height = 'auto';\r\n            img.style.maxWidth = 'calc(100% - 4px)';  \/\/ \u2705 v2.4.5 : 2px retrait inset box-shadow\r\n            img.style.maxHeight = '115px';\r\n            \r\n            const container = $dropZone[0];\r\n            while (container.firstChild) {\r\n                container.removeChild(container.firstChild);\r\n            }\r\n            container.appendChild(img);\r\n        }\r\n        \r\n        StateManager.setMultiple({\r\n            'Commande_Format': 'Vid\u00e9o',\r\n            'Commande_Format_Transmis': 'Vid\u00e9o',\r\n            'videoSrc': objectUrl,\r\n            'FormatAnnonceSelection': 'Yes',\r\n            'PositionAnnonceSelection': 'Yes'\r\n        });\r\n        \r\n        jQuery('#FormatDataStep3').html('Vid\u00e9o').css({'color': '#56BE50'});\r\n        jQuery('#TarifDataStep3').css({'color': '#96894D'});\r\n    },\r\n    \r\n    renderImage(objectUrl, $dropZone) {\r\n        const maxHeight = UIManager.isMobile() ? 105 : $dropZone.closest('.HTMLUploadfileConteneur').height();\r\n    \r\n        $dropZone.css({\r\n            'display': 'flex',\r\n            'justify-content': 'center',\r\n            'align-items': 'center',\r\n            'width': '100%',\r\n            'height': maxHeight + 'px',\r\n            'overflow': 'hidden',\r\n            'position': UIManager.isMobile() ? 'relative' : '',\r\n            'top': UIManager.isMobile() ? '45px' : '',\r\n            'padding': UIManager.isMobile() ? '0 2px' : ''  \/\/ \u2705 v2.4.5 : 2px retrait inset box-shadow mobile\r\n        });\r\n    \r\n        \/\/ \u2705 v1.19.2 : Image charg\u00e9e en arri\u00e8re-plan, remplace le message d'attente au onload\r\n        \/\/ \u2705 v2.4.5 : max-width calc(100%-4px) sur mobile pour ne pas recouvrir le box-shadow inset 2px\r\n        var _mxw = UIManager.isMobile() ? 'calc(100% - 4px)' : '100%';\r\n        var img = new Image();\r\n        img.style.cssText = 'max-width:' + _mxw + '; max-height:' + maxHeight + 'px; width:auto; height:auto; object-fit:contain;';\r\n        img.onload = function() {\r\n            $dropZone.empty().append(img);\r\n        };\r\n        img.onerror = function() {\r\n            $dropZone.html('<img decoding=\"async\" src=\"' + objectUrl + '\" style=\"max-width:' + _mxw + '; max-height:' + maxHeight + 'px; width:auto; height:auto; object-fit:contain;\">');\r\n        };\r\n        img.src = objectUrl;\r\n    \r\n        StateManager.setMultiple({\r\n            'Commande_Format_Transmis': 'Image',\r\n            'FormatAnnonceSelection': 'Yes',\r\n            'PositionAnnonceSelection': 'Yes'\r\n        });\r\n    \r\n        console.log('Image ajout\u00e9e avec succ\u00e8s');\r\n    },\r\n    \r\n    async renderWord(fileObj, $dropZone) {\r\n        return new Promise((resolve, reject) => {\r\n            const reader = new FileReader();\r\n            \r\n            reader.onload = async (e) => {\r\n                try {\r\n                    const arrayBuffer = e.target.result;\r\n                    const result = await mammoth.convertToHtml({arrayBuffer: arrayBuffer});\r\n                    \r\n                    const htmlContent = result.value;\r\n                    const tempContainer = document.createElement('div');\r\n                    tempContainer.innerHTML = htmlContent;\r\n                    \r\n                    const textContent = tempContainer.textContent || \"\";\r\n                    const normalizedText = this.normalizeText(textContent);\r\n                    const firstImage = tempContainer.querySelector('img');\r\n                    \r\n                    const titleText = this.findDocumentTitle(normalizedText);\r\n                    \r\n                    if (firstImage) {\r\n                        this.renderDocumentPreview(\r\n                            $dropZone,\r\n                            firstImage.src,\r\n                            titleText,\r\n                            textContent,\r\n                            htmlContent\r\n                        );\r\n                    } else {\r\n                        \/\/ \u2705 v1.19.0 : Accepter les documents sans image\r\n                        this.renderDocumentPreview(\r\n                            $dropZone,\r\n                            null,\r\n                            titleText,\r\n                            textContent,\r\n                            htmlContent\r\n                        );\r\n                        console.log('\u2139\ufe0f Document Word sans image \u2014 aper\u00e7u texte seul');\r\n                    }\r\n                    resolve();\r\n                } catch (error) {\r\n                    $dropZone.html(`<p style=\"color: #FB5E2A; font-weight: 600; font-family: Roboto, Arial, sans-serif; font-size: 12px; text-align: center; padding: 15px;\">Erreur lors de la lecture du document<\/p>`);\r\n                    reject(error);\r\n                }\r\n            };\r\n            \r\n            reader.readAsArrayBuffer(fileObj);\r\n        });\r\n        \r\n        this.finalizeRedactionnelUpload();\r\n    },\r\n    \r\n    renderDocumentPreview($dropZone, imageSrc, title, text, htmlContent = null) {\r\n        \/\/ \u2705 v1.19.0 : Deux layouts \u2014 avec image ou texte seul\r\n        let previewHtml;\r\n\r\n        if (imageSrc) {\r\n            \/\/ Layout avec miniature image\r\n            previewHtml = `\r\n                <div class=\"doc-preview-container\">\r\n                    <div class=\"doc-preview-thumbnail\">\r\n                        <img decoding=\"async\" src=\"${imageSrc}\" alt=\"Document image\">\r\n                    <\/div>\r\n                    <div class=\"doc-preview-info\">\r\n                        <div class=\"doc-preview-title\" id=\"AdTitle\">${title}<\/div>\r\n                        <div class=\"doc-preview-description\" id=\"AdText\">${this.getTextPreview(text, 13)}<\/div>\r\n                        <div class=\"doc-preview-readmore\" id=\"AdLirelasuite\">Ouvrir et visualiser<\/div>\r\n                        <div class=\"doc-preview-FullPathAdFile\" id=\"AdFullPathAdFile\">${StateManager.get(\"FullPathAdFile\")}<\/div>\r\n                    <\/div>\r\n                <\/div>\r\n            `;\r\n        } else {\r\n            \/\/ Layout texte seul (sans image)\r\n            previewHtml = `\r\n                <div class=\"doc-preview-container doc-preview-noimage\">\r\n                    <div class=\"doc-preview-icon\">\r\n                        <svg width=\"36\" height=\"36\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#213864\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n                            <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"\/><polyline points=\"14 2 14 8 20 8\"\/><line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"\/><line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"\/><polyline points=\"10 9 9 9 8 9\"\/>\r\n                        <\/svg>\r\n                    <\/div>\r\n                    <div class=\"doc-preview-info doc-preview-info-full\">\r\n                        <div class=\"doc-preview-title\" id=\"AdTitle\">${title}<\/div>\r\n                        <div class=\"doc-preview-description\" id=\"AdText\">${this.getTextPreview(text, 25)}<\/div>\r\n                        <div class=\"doc-preview-readmore\" id=\"AdLirelasuite\">Ouvrir et visualiser<\/div>\r\n                        <div class=\"doc-preview-FullPathAdFile\" id=\"AdFullPathAdFile\">${StateManager.get(\"FullPathAdFile\")}<\/div>\r\n                    <\/div>\r\n                <\/div>\r\n            `;\r\n        }\r\n        \r\n        $dropZone.html(previewHtml + this.getPreviewStyles());\r\n        \r\n        if (htmlContent) {\r\n            this.attachWordPreviewHandler($dropZone, title, htmlContent);\r\n        }\r\n    },\r\n    \r\n    attachWordPreviewHandler($dropZone, titleText, htmlContent) {\r\n        var $droppable = $dropZone.closest('.droppable');\r\n\r\n        \/\/ \u2705 Adapter le libell\u00e9 selon le type de document\r\n        var isInterview = (titleText || '').toLowerCase().indexOf('interview') !== -1;\r\n        var formatLabel = isInterview ? 'l\\'interview' : 'le communiqu\u00e9';\r\n        $droppable.find('.doc-preview-readmore').text('Ouvrir et visualiser ' + formatLabel);\r\n\r\n        \/\/ \u2705 v2.0.11 : D\u00e9l\u00e9gation d'\u00e9v\u00e9nement \u2014 plus robuste sur mobile (survit aux manipulations DOM)\r\n        $droppable.off('click.docpreview').on('click.docpreview', '.doc-preview-readmore', (event) => {\r\n            event.preventDefault();\r\n            event.stopPropagation();\r\n            \r\n            if (htmlContent) {\r\n                var popupTitle = isInterview ? 'Interview' : 'Communiqu\u00e9';\r\n                PDFHandler.showInlineDocPopup($dropZone, {\r\n                    formatTitle: popupTitle,\r\n                    htmlContent: htmlContent\r\n                });\r\n            } else {\r\n                console.warn('Le document est encore en cours de traitement.');\r\n            }\r\n        });\r\n    },\r\n    \r\n    normalizeText(text) {\r\n        return text\r\n            .toLowerCase()\r\n            .normalize(\"NFD\")\r\n            .replace(\/[\\u0300-\\u036f]\/g, \"\");\r\n    },\r\n    \r\n    findDocumentTitle(normalizedText) {\r\n        const foundKeyword = CONFIG.keywords.find(keyword => \r\n            normalizedText.includes(keyword.normal)\r\n        );\r\n        if (foundKeyword) return foundKeyword.display;\r\n        \r\n        \/\/ \u2705 v1.19.1 : Fallback \u2014 utiliser le format s\u00e9lectionn\u00e9 (FormatSelect)\r\n        var formatSelect = (sessionStorage.getItem('FormatSelect') || '').toLowerCase();\r\n        if (formatSelect.indexOf('interview') !== -1) return 'Interview';\r\n        if (formatSelect.indexOf('communiq') !== -1) return 'Communiqu\u00e9';\r\n        \r\n        return \"Document\";\r\n    },\r\n    \r\n    getTextPreview(text, maxWords) {\r\n        const words = text.split(' ');\r\n        if (words.length > maxWords) {\r\n            return words.slice(0, maxWords).join(' ') + ' ...';\r\n        }\r\n        return text;\r\n    },\r\n    \r\n    getPreviewStyles() {\r\n        return `\r\n            <style>\r\n                @import url('https:\/\/fonts.googleapis.com\/css2?family=Roboto:wght@400;600&display=swap');\r\n                \r\n                .doc-preview-container {\r\n                    margin: 0px 0;\r\n                    display: flex;\r\n                    width: 100%;\r\n                    max-height: 140px;\r\n                    overflow: hidden;\r\n                    box-sizing: border-box;  \/* \u2705 v2.4.5 *\/\r\n                    background: white;\r\n                    background-color: #f8f8f8;\r\n                }\r\n                .doc-preview-thumbnail {\r\n                    width: 50%; \r\n                    height: 130px;\r\n                    overflow: hidden;\r\n                    display: flex;\r\n                    align-items: center;\r\n                    justify-content: center;\r\n                    margin-top: 0px;\r\n                }\r\n                .doc-preview-thumbnail img {\r\n                    max-width: 75%;\r\n                    max-height: 75%;\r\n                    object-position: center;\r\n                    object-fit: fill;\r\n                }\r\n                .doc-preview-info {\r\n                    width: 50%;\r\n                    height: 130px; \r\n                    flex: 1;\r\n                    padding: 10px;\r\n                    display: flex;\r\n                    flex-direction: column; \r\n                }\r\n                .doc-preview-title {\r\n                    font-family: 'Roboto', sans-serif;\r\n                    color: #213864;\r\n                    font-size: 14px;\r\n                    font-weight: 600;\r\n                    text-align: left;\r\n                    margin-bottom: 5px;\r\n                }\r\n                .doc-preview-description {\r\n                    font-family: 'Roboto', sans-serif;\r\n                    color: #213864;\r\n                    font-size: 11px;\r\n                    font-weight: 400;\r\n                    text-align: left;\r\n                    overflow: hidden;\r\n                    margin-bottom: 5px;\r\n                    flex: 1;\r\n                }\r\n                .doc-preview-readmore {\r\n                    font-family: 'Roboto', sans-serif;\r\n                    color: #958848;\r\n                    font-size: 13px;\r\n                    font-weight: 600;\r\n                    text-align: left;\r\n                    cursor: pointer;\r\n                    padding: 4px 0;\r\n                    -webkit-tap-highlight-color: rgba(149,136,72,0.2);\r\n                }\r\n                @media (max-width: 999px) {\r\n                    .doc-preview-readmore { font-size: 12px; }\r\n                    \/* \u2705 Laisser 3px tout autour pour que le liser\u00e9 vert (box-shadow\/outline sur parent) soit visible *\/\r\n                    .doc-preview-container {\r\n                        width: calc(100% - 16px) !important;\r\n                        max-height: 109px !important;\r\n                        margin: 3px !important;\r\n                        margin-top: 23px !important;\r\n                        box-sizing: border-box !important;\r\n                    }\r\n                }\r\n                .doc-preview-FullPathAdFile {\r\n                    display: none;\r\n                }\r\n                \/* \u2705 v1.19.0 : Layout sans image *\/\r\n                .doc-preview-noimage {\r\n                    flex-direction: row;\r\n                    align-items: flex-start;\r\n                    gap: 10px;\r\n                    padding: 8px 10px;\r\n                }\r\n                .doc-preview-icon {\r\n                    flex-shrink: 0;\r\n                    display: flex;\r\n                    align-items: center;\r\n                    justify-content: center;\r\n                    width: 44px;\r\n                    height: 44px;\r\n                    background: #eef2f7;\r\n                    border-radius: 6px;\r\n                    margin-top: 4px;\r\n                }\r\n                .doc-preview-info-full {\r\n                    width: 100%;\r\n                    height: auto;\r\n                    max-height: 130px;\r\n                }\r\n                .doc-preview-noimage .doc-preview-description {\r\n                    font-size: 11px;\r\n                    line-height: 1.35;\r\n                    max-height: 60px;\r\n                    overflow: hidden;\r\n                }\r\n            <\/style>\r\n        `;\r\n    },\r\n    \r\n    finalizeRedactionnelUpload() {\r\n        \/\/ \u2705 v1.19.5 : D\u00e9terminer le format r\u00e9dactionnel correct\r\n        \/\/ Si le format s\u00e9lectionn\u00e9 est \"Interview\", on garde \"Interview\"\r\n        \/\/ Sinon on met \"Communiqu\u00e9\" par d\u00e9faut (au lieu de \"R\u00e9dactionnel\" qui n'est pas un format tarifaire valide)\r\n        var formatSelect = sessionStorage.getItem('FormatSelect') || '';\r\n        var formatTransmis = 'Communiqu\u00e9'; \/\/ Par d\u00e9faut\r\n        \r\n        if (formatSelect.toLowerCase().indexOf('interview') !== -1) {\r\n            formatTransmis = 'Interview';\r\n        } else if (formatSelect.toLowerCase().indexOf('communiq') !== -1) {\r\n            formatTransmis = 'Communiqu\u00e9';\r\n        }\r\n        \r\n        StateManager.set('Commande_Format_Transmis', formatTransmis);\r\n        console.log('\u2705 Format r\u00e9dactionnel d\u00e9termin\u00e9:', formatTransmis, '(FormatSelect:', formatSelect, ')');\r\n        \r\n        if (StateManager.get(\"TarifDirectSelectionne\") === 'Yes') {\r\n            const formatText = jQuery('#FormatDataStep3').text();\r\n            if (formatText !== 'Vid\u00e9o' && formatText !== 'Banni\u00e8re') {\r\n                jQuery('#form-field-RedactionnelSelection')\r\n                    .val(formatText)\r\n                    .css({'color': '#56BE50'});\r\n            }\r\n        }\r\n        \r\n        RedactionnelDepose();\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'upload\r\n *\/\r\nconst UploadManager = {\r\n    isRunning: false,\r\n    \r\n    \/\/ \u2705 Reset manuel espace publicitaire\r\n    resetEspaceManuel: function($droppable) {\r\n        console.log('\ud83d\udd27 Reset manuel espace publicitaire');\r\n        \r\n        var $dropZone = $droppable.find('#drop_file_zone_achat');\r\n        var $uploadContainer = $droppable.find('.HTMLUploadfileConteneur');\r\n        var $container = $droppable.find('.OrdiMobileConteneurClass');\r\n        \r\n        \/\/ 1. Vider la zone de drop et restaurer le HTML par d\u00e9faut\r\n        $dropZone.empty().html(\r\n            '<div id=\"drag_upload_file_achat\">' +\r\n                '<p class=\"UploadIci\" style=\"color: #FB5E2A; font-weight: 600;\">Ici glisser \u2013 d\u00e9poser ou<br>t\u00e9l\u00e9charger une annonce<\/p>' +\r\n            '<\/div>'\r\n        );\r\n        \r\n        \/\/ 2. Afficher les \u00e9l\u00e9ments cach\u00e9s lors de l'upload\r\n        $droppable.find('.UploadIci').show();\r\n        $droppable.find('.EnvoiUlterieurTexte').show();\r\n        $droppable.find('.EnvoiUlterieurContainer').show();\r\n        $droppable.find('.EspPubFormatMainContainer').show();\r\n        $droppable.find('.EspPubFormatListe').show();\r\n        $droppable.find('.ChoisirEspacePublicitaireClass').show();\r\n        $droppable.find('.GlisserDeposerConteneur').show();\r\n        $droppable.find('.OUClass').show();\r\n        $droppable.find('.TexteMobileAnnonce').show();\r\n        $droppable.find('.PositionReference').show();\r\n        $droppable.find('.ClassHdpCdp').show();\r\n        $droppable.find('.ClassRefEsp').show();\r\n        \r\n        \/\/ 3. Cacher les \u00e9l\u00e9ments d'annonce upload\u00e9e\r\n        $droppable.find('.AdUploadedTitle').hide();\r\n        $droppable.find('#CroixResetAnnonce').hide();\r\n        $droppable.find('.CroixResetAnnonceContainer').hide();\r\n        $droppable.find('.DeplaceAnnonce').hide();\r\n        $droppable.find('.RefEspacePublicitaire').hide();\r\n        $droppable.find('.AdDroppedTextNotDisplayed').hide();\r\n        \r\n        \/\/ 4. Reset des styles\r\n        $uploadContainer.css({\r\n            'border': 'none',\r\n            'background-color': '',\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'min-height': ''\r\n        });\r\n        \r\n        $container.css({\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'top': '',\r\n            'height': ''\r\n        });\r\n        \r\n        \/\/ \u2705 Reset des positionnements desktop appliqu\u00e9s par adjustDesktopLayout\r\n        $droppable.closest('.ToBeHidden').css({'top': '', 'min-height': ''});\r\n        $droppable.parent().css('overflow', '');\r\n        \/\/ \u2705 v2.0.11 : Cleanup event namespace docpreview\r\n        $droppable.off('click.docpreview');\r\n        \r\n        \/\/ 5. Reset des formats s\u00e9lectionn\u00e9s\r\n        $droppable.find('.EspPubFormatContainer').css({\r\n            'background-color': '',\r\n            'border': ''\r\n        });\r\n        \r\n        \/\/ 6. Supprimer le bouton \"R\u00e9server\" dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ 7. Restaurer .PositionEspacePublicitaireContainer et .ReserverContainer\r\n        $droppable.find('.PositionEspacePublicitaireContainer').show();\r\n        $droppable.find('.ReserverContainer').hide();\r\n        \r\n        console.log('\u2705 Reset manuel termin\u00e9');\r\n    },\r\n    \r\n    async handleFileUpload(fileObj, $dropZone) {\r\n        console.log('fileObj:', fileObj);\r\n        \r\n        \/\/ \u2705 v2.4.6 : Contr\u00f4les d'extension EN PREMIER \u2014 avant tout affichage\r\n        const extension = FileManager.getExtension(fileObj.name);\r\n        StateManager.set('FileExtension', extension);\r\n        console.log('FileExtension:', extension);\r\n        \r\n        \/\/ \u2705 v2.6 : jpg\/jpeg accept\u00e9s sur desktop et mobile\r\n        \r\n        if (!FileManager.isAllowedExtension(extension)) {\r\n            UIManager.showFormatError($dropZone);\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 v1.19.5 : Afficher le message d'attente seulement si le format est valide\r\n        var _waitMsg = 'Loading in progress <span class=\"dot-container\"><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><\/span>';\r\n        $dropZone.html('<div class=\"ad-loading-msg\" style=\"color:#00ff19; background:white; padding:12px 20px; border-radius:6px; font-weight:700; text-align:center; font-size:18px; line-height:1.4;\">' + _waitMsg + '<\/div>');\r\n        \r\n        this.prepareUIForUpload($dropZone);\r\n        \r\n        const formData = new FormData();\r\n        formData.append('file', fileObj);\r\n        formData.append('action', 'upload_annonce_file_v3');\r\n        \r\n        UIManager.showUploadProgress($dropZone);\r\n        \r\n        try {\r\n            const response = await this.sendUploadRequest(formData);\r\n            await this.handleUploadResponse(response, fileObj, $dropZone, extension);\r\n        } catch (error) {\r\n            console.error('Upload error:', error);\r\n        }\r\n    },\r\n    \r\n    prepareUIForUpload($dropZone) {\r\n        if (!UIManager.isMobile()) {\r\n            jQuery('.ChoisirEspacePublicitaireClass').show();\r\n            jQuery('.ChoisirEspacePublicitaire2ndLigne').show();\r\n            jQuery('.GlisserDeposerConteneur').show();\r\n            jQuery('.OUClass').show();\r\n            \/\/ \u2705 Cibler uniquement le droppable courant \u2014 ne pas r\u00e9afficher sur les espaces d\u00e9j\u00e0 upload\u00e9s\r\n            $dropZone.closest('.droppable').find('.UploadIci').show();\r\n        }\r\n        \r\n        if (StateManager.get(\"PopUpChoice\") === 'Yes') {\r\n            \/\/ \u2705 Ne masquer DeplaceAnnonce QUE sur Ele0A \u2014 pas sur Ele1A qui a deja une annonce chargee\r\n            $dropZone.closest('.OrdiMobileConteneurClass').find('.DeplaceAnnonce').each(function() {\r\n                var _d = jQuery(this).closest('.droppable')[0];\r\n                if (_d && _d.getAttribute('data-via-ad-loaded') === 'true') { return; }\r\n                jQuery(this).hide();\r\n            });\r\n            $('.AnnonceDragIcone').show().find('img').attr('alt', '');\r\n        } else {\r\n            $('.AnnonceDragIcone').hide();\r\n        }\r\n        \r\n        if (StateManager.get(\"Commande_Page\") === 'Home Page') {\r\n            jQuery('#HPTarifConteneur').css({'background-color': '#B5FFB1'});\r\n        }\r\n        \r\n        jQuery('.ChoisirEspacePublicitaireClass').css({'color': '#ffffff'});\r\n        jQuery('.InterfaceTitreDore').not('#PageWebTitreDore')\r\n            .html(\"Merci de choisir les \u00e9l\u00e9ments de votre campagne publicitaire\");\r\n        jQuery('#ProcessCommande').show();\r\n    },\r\n    \r\n    sendUploadRequest(formData) {\r\n        \/\/ \u2705 v2.6 : dataType 'text' pour eviter parsererror si texte parasite apres le JSON\r\n        return jQuery.ajax({\r\n            url: CONFIG.ajaxUrl,\r\n            type: 'POST',\r\n            data: formData,\r\n            cache: false,\r\n            contentType: false,\r\n            processData: false,\r\n            dataType: 'text'\r\n        }).then(function(text) {\r\n            \/\/ Extraire le JSON meme si du texte parasite suit\r\n            var _json = null;\r\n            try {\r\n                var _match = text.match(\/(\\{[\\s\\S]*?\\})(?:[^{]|$)\/);\r\n                _json = JSON.parse(_match ? _match[1] : text);\r\n            } catch(_e) {\r\n                return jQuery.Deferred().reject({ responseText: text }).promise();\r\n            }\r\n            \/\/ Normaliser le format vers {success, data} attendu par handleUploadResponse\r\n            if (_json.status === 'success') {\r\n                var _fp = _json.file_path || '';\r\n                var _baseUrl = CONFIG.ajaxUrl.replace('\/wp-admin\/admin-ajax.php', '\/wp-content\/');\r\n                return {\r\n                    success: true,\r\n                    data: {\r\n                        file_url:  _baseUrl + _fp,\r\n                        file_name: _fp.replace(\/^.*\\\/\/, ''),\r\n                        file_path: _fp\r\n                    }\r\n                };\r\n            }\r\n            \/\/ Format WordPress standard {success, data} - retourner tel quel\r\n            return _json;\r\n        });\r\n    },\r\n    \r\n    async handleUploadResponse(response, fileObj, $dropZone, extension) {\r\n        console.log('\u2705 R\u00e9ponse re\u00e7ue');\r\n        \r\n        if (response.responseJSON) {\r\n            response = response.responseJSON;\r\n        }\r\n        \r\n        console.log('\u2705 Response pars\u00e9e:', response);\r\n        \r\n        if (!response.success || !response.data) {\r\n            \/\/ \u2705 v2.1.2 : Si c'est une restauration (_isAdRestoration = 'Yes'),\r\n            \/\/ le fichier existe d\u00e9j\u00e0 sur le serveur \u2192 afficher l'image depuis le fileObj local\r\n            if (StateManager.get('_isAdRestoration') === 'Yes' && fileObj) {\r\n                console.log('\ud83d\udd04 Restauration: upload \u00e9chou\u00e9 (fichier existant) \u2192 rendu local');\r\n                \r\n                FileManager.createObjectUrl(fileObj);\r\n                StateManager.set('FileReceived', 'Yes');\r\n                \r\n                \/\/ \u2705 v2.1.2 : Restaurer l'\u00e9tat EnvoiUlterieur depuis le sessionStorage parent\r\n                var _restoredEnvoi = sessionStorage.getItem('_restoredEnvoiUlterieur');\r\n                if (_restoredEnvoi === 'true') {\r\n                    StateManager.set('EnvoiUlterieur', 'true');\r\n                    StateManager.set('FileReceived', 'No');\r\n                    StateManager.set('FullPathAdFile', '');\r\n                    console.log('\ud83d\udce4 Restauration EnvoiUlterieur = true');\r\n                }\r\n                \r\n                var _objUrl = StateManager.get('objectUrl');\r\n                var _fileType = FileManager.getFileType(extension);\r\n                \r\n                StateManager.set('FormatReconnu', 'No');\r\n                \r\n                switch (_fileType) {\r\n                    case 'video':\r\n                        PreviewRenderer.renderVideo(_objUrl, fileObj.name, $dropZone);\r\n                        StateManager.set('FormatReconnu', 'Yes');\r\n                        break;\r\n                    case 'image':\r\n                        PreviewRenderer.renderImage(_objUrl, $dropZone);\r\n                        StateManager.set('FormatReconnu', 'Yes');\r\n                        break;\r\n                    case 'document':\r\n                        \/\/ \u2705 v2.1.2 : Documents Word\/PDF aussi en restauration\r\n                        await this.handleDocumentUpload(extension, fileObj, $dropZone);\r\n                        break;\r\n                }\r\n                \r\n                UIManager.updateAfterSuccessfulUpload($dropZone);\r\n                \r\n                if (StateManager.get('FormatReconnu') === 'Yes') {\r\n                    this.finalizeUpload($dropZone);\r\n                    $('#MsgSelectEspace').hide();\r\n                }\r\n                \r\n                FormatUIManager.updateReserverCheckboxState($dropZone.closest('.droppable'));\r\n                console.log('\u2705 Restauration visuelle termin\u00e9e (upload bypass)');\r\n                StateManager.set('_isAdRestoration', 'No');\r\n            }\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 SAUVEGARDER les infos de d\u00e9placement AVANT updateStateAfterUpload\r\n        const isMoved = StateManager.get('FirstUploadFileorMoved') === 'Moved';\r\n        const dragstartRankId = StateManager.get('dragstart_Rank_Emplacement_Page_Web');\r\n        const currentRankId = StateManager.get('Rank_Emplacement_Page_Web');\r\n        const shouldResetOldSpace = isMoved && dragstartRankId && dragstartRankId !== currentRankId;\r\n        \r\n        console.log('\ud83d\udd0d D\u00e9placement?', { isMoved, dragstartRankId, currentRankId, shouldResetOldSpace });\r\n        \r\n        this.updateStateAfterUploadWithoutReset(response, fileObj);\r\n        \r\n        const fileType = FileManager.getFileType(extension);\r\n        \r\n        StateManager.set('FormatReconnu', 'No');\r\n        \r\n        \/\/ \u2705 v1.19.2 : Message d'attente IMM\u00c9DIAT avant le rendu de l'annonce\r\n        var _waitMsg = 'Loading in progress <span class=\"dot-container\"><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><\/span>';\r\n        $dropZone.html('<div class=\"ad-loading-msg\" style=\"color:#00ff19; background:white; padding:12px 20px; border-radius:6px; font-weight:700; text-align:center; font-size:18px; line-height:1.4;\">' + _waitMsg + '<\/div>');\r\n        \r\n        switch (fileType) {\r\n            case 'video':\r\n                PreviewRenderer.renderVideo(StateManager.get('objectUrl'), fileObj.name, $dropZone);\r\n                StateManager.set('FormatReconnu', 'Yes');\r\n                break;\r\n                \r\n            case 'image':\r\n                PreviewRenderer.renderImage(StateManager.get('objectUrl'), $dropZone);\r\n                StateManager.set('FormatReconnu', 'Yes');\r\n                break;\r\n                \r\n            case 'document':\r\n                await this.handleDocumentUpload(extension, fileObj, $dropZone);\r\n                break;\r\n        }\r\n        \r\n        UIManager.updateAfterSuccessfulUpload($dropZone);\r\n        \r\n        if (StateManager.get('FormatReconnu') === 'Yes') {\r\n            this.finalizeUpload($dropZone);\r\n            $('#MsgSelectEspace').hide();\r\n        }\r\n        \r\n        \/\/ \u2705 RESET L'ANCIEN ESPACE ICI - APR\u00c8S avoir affich\u00e9 la nouvelle image\r\n        \/\/ \u2705 v2.4.5 : Toujours initialiser \u00e0 false avant le bloc (\u00e9vite la valeur r\u00e9siduelle)\r\n        var _sourceWasReserved = false;\r\n        StateManager.set('_sourceWasReserved', 'No');\r\n        \r\n        if (shouldResetOldSpace) {\r\n            console.log('\ud83d\udd04 Reset ancien espace:', dragstartRankId);\r\n            \r\n            var $oldDroppable = $('#' + dragstartRankId);\r\n            \r\n            if ($oldDroppable.length) {\r\n                var $container = $oldDroppable.find('.OrdiMobileConteneurClass').first();\r\n                \r\n                \/\/ \u2705 v2.4.5 : Utiliser l'\u00e9tat captur\u00e9 au dragstart (fiable vs re-check async)\r\n                if ($container.length) {\r\n                    _sourceWasReserved = StateManager.get('dragstart_ReserverChecked') === 'Yes';\r\n                    console.log('[d\u00e9placement] ReserverChecked au dragstart:', _sourceWasReserved, '| rank:', dragstartRankId);\r\n                    StateManager.set('_sourceWasReserved', _sourceWasReserved ? 'Yes' : 'No');\r\n                    RestoreadSpaceTemplateLocal($container[0]);\r\n                }\r\n            }\r\n        }\r\n        StateManager.set(\"EnvoiUlterieur\", 'false');\r\n        \r\n        \/\/ \u2705 v1.19.1 : Positionner l'espace \u00e0 10px du haut du viewport apr\u00e8s upload\r\n        setTimeout(function() {\r\n            var el = $dropZone.closest('.droppable').find('.HTMLUploadfileConteneur')[0]\r\n                     || $dropZone.closest('.droppable')[0];\r\n            if (el) {\r\n                ScrollHelper.scrollElementTo(el, 10);\r\n            }\r\n        }, 400);\r\n        \r\n        \/\/ \u2705 NE PLUS envoyer automatiquement - c'est la checkbox \"R\u00e9server\" qui d\u00e9clenche\r\n        \/\/ On met \u00e0 jour l'\u00e9tat de la checkbox pour qu'elle devienne activable\r\n        FormatUIManager.updateReserverCheckboxState($dropZone.closest('.droppable'));\r\n        \r\n        \/\/ \u2705 v2.4.5 : Si l'espace source \u00e9tait r\u00e9serv\u00e9, cocher la checkbox de l'espace cible\r\n        if (StateManager.get('_sourceWasReserved') === 'Yes') {\r\n            var $targetCb = $dropZone.closest('.droppable').find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]');\r\n            if ($targetCb.length && !$targetCb.prop('checked')) {\r\n                $targetCb.prop('checked', true).trigger('change');\r\n                console.log('\u2705 [d\u00e9placement] Checkbox R\u00e9server coch\u00e9e sur espace cible');\r\n            }\r\n            StateManager.set('_sourceWasReserved', 'No');\r\n        }\r\n        \r\n        console.log('\ud83d\udccb Upload termin\u00e9 - en attente de validation via checkbox \"R\u00e9server\"');\r\n    },\r\n    \r\n    updateStateAfterUploadWithoutReset(response, fileObj) {\r\n        StateManager.setMultiple({\r\n            \"PageWhithADType\": StateManager.get('SelectedPageType'),\r\n            \"PageWhithADSecteur\": StateManager.get('SelectedPageSecteur')\r\n        });\r\n        \r\n        $('#BackPageWebWithADCroix').hide();\r\n        jQuery('#ApercuMobile').empty().css({\r\n            'display': 'flex',\r\n            'justify-content': 'center',\r\n            'align-items': 'center'\r\n        });\r\n        \r\n        const firstUploadOrMoved = StateManager.get('FirstUploadFileorMoved');\r\n        \r\n        if (firstUploadOrMoved === 'FirstUpload') {\r\n            StateManager.setMultiple({\r\n                \"FullPathAdFile\": response.data.file_url,\r\n                \"fileObj\": fileObj,\r\n                \"Upload_File_Name\": fileObj.name\r\n            });\r\n            \r\n            FileManager.createObjectUrl(fileObj);\r\n            \r\n            console.log('\ud83d\udcc1 Fichier upload\u00e9:', {\r\n                fullUrl: response.data.file_url,\r\n                fileName: response.data.file_name,\r\n                filePath: response.data.file_path\r\n            });\r\n        }\r\n    },\r\n    \r\n    updateStateAfterUpload(response, fileObj) {\r\n        StateManager.setMultiple({\r\n            \"PageWhithADType\": StateManager.get('SelectedPageType'),\r\n            \"PageWhithADSecteur\": StateManager.get('SelectedPageSecteur')\r\n        });\r\n        \r\n        $('#BackPageWebWithADCroix').hide();\r\n        jQuery('#ApercuMobile').empty().css({\r\n            'display': 'flex',\r\n            'justify-content': 'center',\r\n            'align-items': 'center'\r\n        });\r\n        \r\n        const firstUploadOrMoved = StateManager.get('FirstUploadFileorMoved');\r\n        console.log('\ud83d\udd0d FirstUploadFileorMoved:', firstUploadOrMoved);\r\n        \r\n        if (firstUploadOrMoved === 'FirstUpload') {\r\n            StateManager.setMultiple({\r\n                \"FullPathAdFile\": response.data.file_url,\r\n                \"fileObj\": fileObj,\r\n                \"Upload_File_Name\": fileObj.name\r\n            });\r\n            \r\n            FileManager.createObjectUrl(fileObj);\r\n            \r\n            console.log('\ud83d\udcc1 Fichier upload\u00e9:', {\r\n                fullUrl: response.data.file_url,\r\n                fileName: response.data.file_name,\r\n                filePath: response.data.file_path\r\n            });\r\n        } else if (firstUploadOrMoved === 'Moved') {\r\n            const dragstartRankId = StateManager.get('dragstart_Rank_Emplacement_Page_Web');\r\n            const currentRankId = StateManager.get('Rank_Emplacement_Page_Web');\r\n            \r\n            console.log('\ud83d\udd04 D\u00c9PLACEMENT D\u00c9TECT\u00c9');\r\n            console.log('   Ancien espace (dragstart):', dragstartRankId);\r\n            console.log('   Nouvel espace (current):', currentRankId);\r\n            \r\n            if (dragstartRankId && dragstartRankId !== currentRankId) {\r\n                const $oldDroppable = $('#' + dragstartRankId);\r\n                \r\n                console.log('   $oldDroppable trouv\u00e9:', $oldDroppable.length > 0);\r\n                \r\n                if ($oldDroppable.length) {\r\n                    const $container = $oldDroppable.find('.OrdiMobileConteneurClass');\r\n                    \r\n                    console.log('   $container trouv\u00e9:', $container.length > 0);\r\n                    \r\n                    if ($container.length) {\r\n                        console.log('\ud83d\udd27 Appel RestoreadSpaceTemplate sur:', $container[0]);\r\n                        \r\n                        if (typeof window.RestoreadSpaceTemplate === 'function') {\r\n                            window.RestoreadSpaceTemplate($container[0]);\r\n                            console.log('\u2705 RestoreadSpaceTemplate ex\u00e9cut\u00e9');\r\n                        }\r\n                    } else {\r\n                        console.warn('\u26a0\ufe0f .OrdiMobileConteneurClass non trouv\u00e9 dans', dragstartRankId);\r\n                    }\r\n                }\r\n            } else {\r\n                console.log('\u23ed\ufe0f M\u00eame espace ou dragstartRankId invalide, pas de reset');\r\n            }\r\n        }\r\n    },\r\n        \r\n    async handleDocumentUpload(extension, fileObj, $dropZone) {\r\n        StateManager.set('FormatReconnu', 'Yes');\r\n        \r\n        \/\/ \u2705 Cacher le File r\u00e9dactionnel pour r\u00e9utilisation lors des d\u00e9placements (\u00e9vite CORS)\r\n        window._lastRedactionnelFile = fileObj;\r\n        \r\n        if (extension === 'doc' || extension === 'docx') {\r\n            await new Promise(resolve => window.VIALibraries.loadMammoth(resolve));\r\n            await PreviewRenderer.renderWord(fileObj, $dropZone);\r\n        } else if (extension === 'ppt' || extension === 'pptx') {\r\n            this.renderPowerPoint($dropZone);\r\n            PreviewRenderer.finalizeRedactionnelUpload();\r\n        } else if (extension === 'pdf') {\r\n            await new Promise(resolve => window.VIALibraries.loadPdfJs(resolve));\r\n            await PDFHandler.renderPDF(fileObj, $dropZone);\r\n            PreviewRenderer.finalizeRedactionnelUpload();\r\n        }\r\n    },\r\n    \r\n    renderPowerPoint($dropZone) {\r\n        const img = jQuery('<img \/>', {\r\n            src: '\/wp-content\/uploads\/2024\/06\/microsoft-powerpoint.png',\r\n            css: {\r\n                'width': 'auto',\r\n                'height': 'auto',\r\n                'margin-bottom': '20px',\r\n                'max-width': '150px',\r\n                'max-height': '160px'\r\n            }\r\n        });\r\n        $dropZone.empty().append(img.clone());\r\n        jQuery('#ApercuMobile').append(img);\r\n    },\r\n    \r\n    finalizeUpload($dropZone) {\r\n        \/\/ \u2705 Reset sendDataToParentFlag : nouvel upload = pas encore r\u00e9serv\u00e9\r\n        StateManager.set('sendDataToParentFlag', 'No');\r\n        \r\n        StateManager.setMultiple({\r\n            \"PageAnnonceSelection\": 'Yes',\r\n            \"FormatReconnu\": 'Yes'\r\n        });\r\n        \r\n        jQuery('#MsgChoixPageWeb, #MsgInsererAnnonceConteneur').hide();\r\n        \r\n        if (StateManager.get(\"Commande_Format\") === 'R\u00e9dactionnel') {\r\n            StateManager.set('Commande_Format', '\u00e0 choisir');\r\n            RedactionnelDepose();\r\n        }\r\n        \r\n        if (StateManager.get(\"Commande_Page\") === ' ') {\r\n            jQuery('#HPTarifConteneur').css({'background-color': '#BCFFAD'});\r\n            jQuery('#EmplacementDataStep3').html(\"Home Page\");\r\n            StateManager.setMultiple({\r\n                \"Commande_Page\": 'Home Page',\r\n                \"PageAnnonceSelection\": 'Yes'\r\n            });\r\n        }\r\n        \r\n        $('#PageWeb').css('zoom', '70%');\r\n        $('#PageWebTitreDore').css({'font-size': '14px'});\r\n        \r\n        if (!UIManager.isMobile()) {\r\n            $('#PageWebTitreDore').css({'color': '#213864'});\r\n        }\r\n        \r\n        StateManager.set(\"Page_Web_with_AD_URL\", StateManager.get(\"Page_Web_URL\"));\r\n        \r\n        UIManager.finalizeAdDisplay($dropZone);\r\n        \r\n        \/\/ \u2705 Notifier le parent de l'annonce d\u00e9pos\u00e9e non r\u00e9serv\u00e9e \u2014 pour restauration au retour sur la page\r\n        var _fileRcv = StateManager.get('FileReceived');\r\n        var _isRestoring = StateManager.get('_isAdRestoration') === 'Yes';\r\n        console.log('\ud83d\udfe1 [finalizeUpload] FileReceived:', _fileRcv, '| _isAdRestoration:', _isRestoring);\r\n        if (_fileRcv === 'Yes' && !_isRestoring) {\r\n            var _pendingRank = StateManager.get('Rank_Emplacement_Page_Web') || $dropZone.closest('.droppable').attr('id') || '';\r\n            console.log('\ud83d\udfe1 [finalizeUpload] pendingRank:', _pendingRank, '| FullPathAdFile:', StateManager.get('FullPathAdFile'));\r\n            if (_pendingRank) {\r\n                console.log('\ud83d\udce4 [finalizeUpload] annonceDeposeeSansReservation \u2192 parent rank:', _pendingRank);\r\n                \/\/ \u2705 D\u00e9terminer le vrai format commercial selon le type de fichier d\u00e9pos\u00e9 + format s\u00e9lectionn\u00e9\r\n                var _formatSelect = sessionStorage.getItem('FormatSelect') || StateManager.get('Commande_Format_Transmis') || '';\r\n                var _uploadedExt = (StateManager.get('Upload_File_Name') || '').split('.').pop().toLowerCase();\r\n                var _fileKind = CONFIG.allowedExtensions.video.indexOf(_uploadedExt) !== -1 ? 'video'\r\n                              : CONFIG.allowedExtensions.image.indexOf(_uploadedExt) !== -1 ? 'image'\r\n                              : CONFIG.allowedExtensions.document.indexOf(_uploadedExt) !== -1 ? 'document'\r\n                              : '';\r\n                var _formatPending;\r\n                if (_fileKind === 'video') {\r\n                    \/\/ Vid\u00e9o \u2192 toujours Vid\u00e9o\r\n                    _formatPending = 'Vid\u00e9o';\r\n                } else if (_fileKind === 'image') {\r\n                    \/\/ Image \u2192 Banni\u00e8re ou Parrainage si s\u00e9lectionn\u00e9, sinon Banni\u00e8re par d\u00e9faut\r\n                    var _imgFormats = ['Banni\u00e8re', 'Banniere', 'Parrainage'];\r\n                    _formatPending = (_imgFormats.indexOf(_formatSelect) !== -1) ? _formatSelect : 'Banni\u00e8re';\r\n                } else if (_fileKind === 'document') {\r\n                    \/\/ Document \u2192 Communiqu\u00e9 ou Interview si s\u00e9lectionn\u00e9, sinon Communiqu\u00e9 par d\u00e9faut\r\n                    var _docFormats = ['Communiqu\u00e9', 'Communique', 'Interview'];\r\n                    _formatPending = (_docFormats.indexOf(_formatSelect) !== -1) ? _formatSelect : 'Communiqu\u00e9';\r\n                } else {\r\n                    \/\/ Fallback\r\n                    _formatPending = _formatSelect || StateManager.get('Commande_Format_Transmis') || '';\r\n                }\r\n                \/\/ \u2705 v2.4.9 : Si le format d\u00e9duit diff\u00e8re du format s\u00e9lectionn\u00e9 \u2192 mettre \u00e0 jour vignette + sessionStorage\r\n                if (_formatPending && _formatPending !== _formatSelect) {\r\n                    StateManager.set('FormatSelect', _formatPending);\r\n                    StateManager.set('Commande_Format_Transmis', _formatPending);\r\n                    StateManager.set('Formatchoisi', 'Yes');\r\n                    \/\/ Mettre \u00e0 jour visuellement la vignette dans le droppable courant\r\n                    var _fmtNorm = _formatPending.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    var $_drp = $dropZone.closest('.droppable');\r\n                    $_drp.find('.EspPubFormatContainer').each(function() {\r\n                        var _cls = this.className.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                        if (_cls.includes(_fmtNorm)) {\r\n                            jQuery(this).css({'background-color': '#ffffff'});\r\n                            jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                        } else if (!jQuery(this).hasClass('FormatIdPopUp')) {\r\n                            jQuery(this).css({'background-color': ''});\r\n                            jQuery(this).find('.EspPubFormat').css({'color': ''});\r\n                        }\r\n                    });\r\n                    \/\/ Mettre \u00e0 jour aussi le bandeau parent via postMessage\r\n                    MessageManager.sendToParent('formatChangedInIframe', { formatSelect: _formatPending, rank: _pendingRank });\r\n                    console.log('\ud83d\udd04 [finalizeUpload] Format corrig\u00e9:', _formatSelect, '\u2192', _formatPending);\r\n                }\r\n                var _firstUploadOrMoved = StateManager.get('FirstUploadFileorMoved');\r\n                var _isMoved = _firstUploadOrMoved === 'Moved';\r\n                var _oldRankMoved = _isMoved ? (StateManager.get('dragstart_Rank_Emplacement_Page_Web') || '') : '';\r\n                MessageManager.sendToParent('annonceDeposeeSansReservation', {\r\n                    Rank_Emplacement_Page_Web: _pendingRank,\r\n                    FullPathAdFile: StateManager.get('FullPathAdFile') || '',\r\n                    Upload_File_Name: StateManager.get('Upload_File_Name') || '',\r\n                    LoadedPageUrl: window.location.href,\r\n                    FileReceived: 'Yes',\r\n                    \/\/ \u2705 Lire EnvoiUlterieur depuis la checkbox du droppable courant (pas le StateManager global)\r\n                    \/\/ StateManager.get('EnvoiUlterieur') est global \u2192 peut valoir 'true' si un autre espace a sa checkbox coch\u00e9e\r\n                    EnvoiUlterieur: ($dropZone.closest('.droppable').find('input[name*=\"EnvoiUlterieur\"]').prop('checked') ? 'true' : 'false'),\r\n                    Commande_Format_Transmis: _formatPending,\r\n                    codeSite: StateManager.get('codeSite') || '',\r\n                    codePage: StateManager.get('codePage') || '',\r\n                    Commande_Emplacement_Page_Web: StateManager.buildEmplacementReference(_pendingRank),\r\n                    isMoved: _isMoved,\r\n                    oldRank: _oldRankMoved\r\n                });\r\n            }\r\n        }\r\n    },\r\n    \r\n    activateSendDataToParent($dropZone) {\r\n        if (StateManager.get(\"sendDataToParentFlag\") !== 'Yes') {\r\n            return;\r\n        }\r\n        \r\n        if (StateManager.get(\"FirstUploadFileorMoved\") === 'Moved') {\r\n            const dragstartRef = StateManager.buildEmplacementReference(\r\n                StateManager.get(\"dragstart_Rank_Emplacement_Page_Web\")\r\n            );\r\n            StateManager.set('dragstart_Commande_Emplacement_Page_Web', dragstartRef);\r\n        }\r\n        \r\n        console.log('Esp Pub Ref FirstUploadFileorMoved:', StateManager.get(\"FirstUploadFileorMoved\"));\r\n        console.log('Esp Pub dragstart_Commande:', StateManager.get(\"dragstart_Commande_Emplacement_Page_Web\"));\r\n        \r\n        if (StateManager.get(\"PageAjoutModifAnnonce\") === 'Yes') {\r\n            this.handlePageModification($dropZone);\r\n        } else {\r\n            this.handleNormalUpload();\r\n        }\r\n        \r\n        StateManager.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        setTimeout(() => {\r\n            StateManager.set(\"AddNewRefInVosCampagnes\", 'Yes');\r\n        }, 4000);\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            StateManager.set('Commande_Format_Transmis', '');\r\n        }\r\n    },\r\n    \r\n    handlePageModification($dropZone) {\r\n        $('#CroixResetAnnonce, .DeplaceAnnonce').hide();\r\n        $('.PageAjoutModifAnnonceCroixResetAnnonce').show();\r\n        \r\n        const emplacementRef = $dropZone.closest('.CampagnesTemplateClass')\r\n            .find('.ReferenceEspace').text();\r\n        \r\n        console.log('Commande_Emplacement_Page_Web:', emplacementRef);\r\n        \r\n        jQuery.ajax({\r\n            type: \"POST\",\r\n            url: CONFIG.ajaxUrl,\r\n            data: {\r\n                action: 'via_update_fichier_annonce',\r\n                commande_ref_url: StateManager.get(\"commande_ref_url\"),\r\n                emplacement_page_web: emplacementRef,\r\n                chemin_fichier: StateManager.get(\"FullPathAdFile\")\r\n            },\r\n            xhrFields: { withCredentials: true },\r\n            success: (response) => {\r\n                if (response.success) {\r\n                    console.log('\u2705 Fichier annonce mis \u00e0 jour:', response.data.message);\r\n                    location.reload();\r\n                } else {\r\n                    console.error('\u274c Erreur:', response.data.message);\r\n                }\r\n            },\r\n            error: (xhr, status, error) => {\r\n                console.error('\u274c Erreur AJAX:', error);\r\n            }\r\n        });\r\n    },\r\n    \r\n    handleNormalUpload() {\r\n        if (StateManager.get(\"EnvoiUlterieur\") === 'true') {\r\n            StateManager.setMultiple({\r\n                \"FullPathAdFile\": '',\r\n                \"Upload_File_Name\": ''\r\n            });\r\n        }\r\n        \r\n        StateManager.set(\"LoadedPageUrl\", window.location.href);\r\n        \r\n        console.log('EnvoiUlterieur:', StateManager.get(\"EnvoiUlterieur\"));\r\n        console.log('LoadedPageUrl:', StateManager.get(\"LoadedPageUrl\"));\r\n        console.log('FileReceived:', StateManager.get(\"FileReceived\"));\r\n        \r\n        const data = MessageManager.prepareUploadData();\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            MessageManager.sendDataToParent(data);\r\n        } else {\r\n            const formatChoisi = StateManager.get(\"Formatchoisi\") === 'Yes';\r\n            const fichierDepose = StateManager.get(\"FileReceived\") === 'Yes';\r\n            const envoiDiffere = StateManager.get(\"EnvoiUlterieur\") === 'true';\r\n            \r\n            console.log('\ud83d\udd0d handleNormalUpload - Conditions:', { formatChoisi, fichierDepose, envoiDiffere });\r\n            \r\n            if (formatChoisi && (fichierDepose || envoiDiffere)) {\r\n                if (typeof window.handleEspacePubData === 'function') {\r\n                    window.handleEspacePubData(data);\r\n                } else {\r\n                    console.warn('\u26a0\ufe0f handleEspacePubData non disponible, fallback direct');\r\n                    if (typeof window.executeWithProcessLoaded === 'function') {\r\n                        window.executeWithProcessLoaded(function() {\r\n                            jQuery('#PopupProcessCommandeContainer').show();\r\n                        });\r\n                    } else {\r\n                        jQuery('#PopupProcessCommandeContainer').show();\r\n                    }\r\n                }\r\n            } else if (formatChoisi) {\r\n                console.log('\ud83d\udcdd Mise \u00e0 jour format uniquement');\r\n                \r\n                const borderStyle = {'box-shadow': 'inset 0 0 0 2px #00FF19', 'box-sizing': 'border-box'};  \/\/ \u2705 v2.4.5\r\n                \r\n                jQuery(\".FormatClassique, .FormatPopup\").css({'border': 'none'});\r\n                \r\n                jQuery('.FormatClassique, .FormatPopup').each(function() {\r\n                    \/\/ \u2705 v2.1.1 : NFD normalize both sides\r\n                    var _cn = this.className.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    var _cf = (data.Commande_Format_Transmis || '').normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    if (_cn.includes(_cf) && _cf) {\r\n                        jQuery(this).css(borderStyle);\r\n                    }\r\n                });\r\n            }\r\n        }\r\n        \r\n        StateManager.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        setTimeout(() => {\r\n            StateManager.set(\"AddNewRefInVosCampagnes\", 'Yes');\r\n        }, 4000);\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            StateManager.set('Commande_Format_Transmis', '');\r\n        }\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion des fichiers PDF (s\u00e9par\u00e9 pour \u00e9viter la complexit\u00e9)\r\n *\/\r\nconst PDFHandler = {\r\n    pdfData: null,\r\n    pdfDataForViewer: null,\r\n    \r\n    async renderPDF(fileObj, $dropZone) {\r\n        return new Promise((resolve, reject) => {\r\n            const reader = new FileReader();\r\n            \r\n            reader.onload = async (e) => {\r\n                try {\r\n                    const arrayBuffer = e.target.result;\r\n                    this.pdfData = new Uint8Array(arrayBuffer);\r\n                    this.pdfDataForViewer = arrayBuffer;\r\n                    \r\n                    console.log(\"Initial PDF load, size:\", this.pdfData.byteLength);\r\n                    \r\n                    const pdfjsLib = window['pdfjs-dist\/build\/pdf'];\r\n                    pdfjsLib.GlobalWorkerOptions.workerSrc = \r\n                        '\/\/cdn.jsdelivr.net\/npm\/pdfjs-dist@latest\/build\/pdf.worker.min.js';\r\n                    \r\n                    const pdf = await pdfjsLib.getDocument({ data: new Uint8Array(this.pdfData) }).promise;\r\n                    const page = await pdf.getPage(1);\r\n                    \r\n                    const { titleText, pageText } = await this.extractTextFromPage(page);\r\n                    const imageData = await this.extractImageFromPage(page, pdfjsLib);\r\n                    \r\n                    if (imageData) {\r\n                        PreviewRenderer.renderDocumentPreview(\r\n                            $dropZone,\r\n                            imageData.dataUrl,\r\n                            titleText,\r\n                            pageText\r\n                        );\r\n                    } else {\r\n                        \/\/ \u2705 v1.19.0 : Accepter les PDF sans image\r\n                        PreviewRenderer.renderDocumentPreview(\r\n                            $dropZone,\r\n                            null,\r\n                            titleText,\r\n                            pageText\r\n                        );\r\n                        console.log('\u2139\ufe0f PDF sans image \u2014 aper\u00e7u texte seul');\r\n                    }\r\n                    \r\n                    this.attachPDFPreviewHandler($dropZone, titleText);\r\n                    resolve();\r\n                } catch (error) {\r\n                    console.error('Error extracting from PDF:', error);\r\n                    \/\/ \u2705 v1.19.0 : Message d'erreur en fran\u00e7ais\r\n                    $dropZone.html(`\r\n                        <div style=\"padding: 15px; background-color: #f8f8f8; border-radius: 4px; text-align: center;\">\r\n                            <p style=\"color: #FB5E2A; font-weight: 600; font-family: Roboto, Arial, sans-serif; font-size: 12px;\">\r\n                                Erreur lors de la lecture du document\r\n                            <\/p>\r\n                        <\/div>\r\n                    `);\r\n                    reject(error);\r\n                }\r\n            };\r\n            \r\n            reader.readAsArrayBuffer(fileObj);\r\n        });\r\n    },\r\n    \r\n    async extractTextFromPage(page) {\r\n        const textContent = await page.getTextContent();\r\n        \r\n        let text = '';\r\n        let lastX = -1;\r\n        let lastY = -1;\r\n        \r\n        for (const item of textContent.items) {\r\n            if (lastY !== -1 && (Math.abs(lastY - item.transform[5]) > 5)) {\r\n                text += '\\n';\r\n            } else if (lastX !== -1 && (item.transform[4] - lastX > 10)) {\r\n                text += ' ';\r\n            }\r\n            \r\n            text += item.str;\r\n            \r\n            lastX = item.transform[4] + (item.width || 0);\r\n            lastY = item.transform[5];\r\n        }\r\n        \r\n        text = text\r\n            .replace(\/(\\w) (\\w)\/g, (match, p1, p2) => {\r\n                if (\/[\u00e9\u00e8\u00ea\u00eb\u00e0\u00e2\u00e4\u00f4\u00f6\u00fb\u00fc\u00ef\u00ee\u00e7]\/i.test(p2)) {\r\n                    return p1 + p2;\r\n                }\r\n                return match;\r\n            })\r\n            .replace(\/ ([.,;:!?])\/g, '$1');\r\n        \r\n        const normalizedText = PreviewRenderer.normalizeText(text);\r\n        const titleText = PreviewRenderer.findDocumentTitle(normalizedText);\r\n        \r\n        return { titleText, pageText: text };\r\n    },\r\n    \r\n    async extractImageFromPage(page, pdfjsLib) {\r\n        const opList = await page.getOperatorList();\r\n        const imageInfo = [];\r\n        let currentTransform = null;\r\n        \r\n        for (let i = 0; i < opList.fnArray.length; i++) {\r\n            const operator = opList.fnArray[i];\r\n            const args = opList.argsArray[i];\r\n            \r\n            if (operator === pdfjsLib.OPS.transform) {\r\n                currentTransform = args;\r\n            } else if (operator === pdfjsLib.OPS.paintImageXObject) {\r\n                const imageName = args[0];\r\n                \r\n                if (!imageInfo.some(info => info.name === imageName)) {\r\n                    const position = currentTransform ? {\r\n                        x: currentTransform[4] || 0,\r\n                        y: currentTransform[5] || 0\r\n                    } : { x: 0, y: 0 };\r\n                    \r\n                    imageInfo.push({ name: imageName, position: position });\r\n                }\r\n            }\r\n        }\r\n        \r\n        if (imageInfo.length === 0) {\r\n            return null;\r\n        }\r\n        \r\n        imageInfo.sort((a, b) => b.position.y - a.position.y);\r\n        \r\n        const targetImageName = imageInfo[0].name;\r\n        const imageObj = page.objs.get(targetImageName);\r\n        \r\n        if (!imageObj) {\r\n            const img = await page.objs.get(targetImageName, true);\r\n            return this.processImageObject(img);\r\n        }\r\n        \r\n        return this.processImageObject(imageObj);\r\n    },\r\n    \r\n    processImageObject(imageObj) {\r\n        if (!imageObj) {\r\n            throw new Error('Image object is null');\r\n        }\r\n        \r\n        if (imageObj.bitmap instanceof ImageBitmap) {\r\n            const width = imageObj.bitmap.width || imageObj.width || imageObj.w;\r\n            const height = imageObj.bitmap.height || imageObj.height || imageObj.h;\r\n            \r\n            const canvas = document.createElement('canvas');\r\n            canvas.width = width;\r\n            canvas.height = height;\r\n            const ctx = canvas.getContext('2d');\r\n            \r\n            ctx.drawImage(imageObj.bitmap, 0, 0);\r\n            \r\n            return {\r\n                canvas: canvas,\r\n                width: width,\r\n                height: height,\r\n                dataUrl: canvas.toDataURL('image\/jpeg', 0.92)\r\n            };\r\n        }\r\n        \r\n        const width = imageObj.width || imageObj.w;\r\n        const height = imageObj.height || imageObj.h;\r\n        \r\n        if (!width || !height) {\r\n            throw new Error('Could not determine image dimensions');\r\n        }\r\n        \r\n        let imgData = imageObj.data || imageObj.bitmap;\r\n        \r\n        if (!imgData) {\r\n            throw new Error('No valid image data found');\r\n        }\r\n        \r\n        const canvas = document.createElement('canvas');\r\n        canvas.width = width;\r\n        canvas.height = height;\r\n        const ctx = canvas.getContext('2d');\r\n        \r\n        ctx.fillStyle = 'white';\r\n        ctx.fillRect(0, 0, width, height);\r\n        \r\n        const imageData = ctx.createImageData(width, height);\r\n        \r\n        this.fillImageData(imageData, imgData, imageObj.kind, width, height);\r\n        \r\n        ctx.putImageData(imageData, 0, 0);\r\n        \r\n        return {\r\n            canvas: canvas,\r\n            width: width,\r\n            height: height,\r\n            dataUrl: canvas.toDataURL('image\/jpeg', 0.92)\r\n        };\r\n    },\r\n    \r\n    fillImageData(imageData, imgData, kind, width, height) {\r\n        if (kind === 'GRAY') {\r\n            for (let i = 0, j = 0; i < imgData.length; i++, j += 4) {\r\n                const value = imgData[i];\r\n                imageData.data[j] = value;\r\n                imageData.data[j + 1] = value;\r\n                imageData.data[j + 2] = value;\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else if (kind === 'CMYK') {\r\n            for (let i = 0, j = 0; i < imgData.length; i += 4, j += 4) {\r\n                const c = imgData[i] \/ 255;\r\n                const m = imgData[i + 1] \/ 255;\r\n                const y = imgData[i + 2] \/ 255;\r\n                const k = imgData[i + 3] \/ 255;\r\n                \r\n                imageData.data[j] = 255 * (1 - c) * (1 - k);\r\n                imageData.data[j + 1] = 255 * (1 - m) * (1 - k);\r\n                imageData.data[j + 2] = 255 * (1 - y) * (1 - k);\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else if (kind === 'RGB24') {\r\n            for (let i = 0, j = 0; i < imgData.length; i += 3, j += 4) {\r\n                imageData.data[j] = imgData[i];\r\n                imageData.data[j + 1] = imgData[i + 1];\r\n                imageData.data[j + 2] = imgData[i + 2];\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else if (imgData.length === width * height * 3) {\r\n            for (let i = 0, j = 0; i < imgData.length; i += 3, j += 4) {\r\n                imageData.data[j] = imgData[i];\r\n                imageData.data[j + 1] = imgData[i + 1];\r\n                imageData.data[j + 2] = imgData[i + 2];\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else {\r\n            const tempArray = new Uint8ClampedArray(imgData.length);\r\n            for (let i = 0; i < imgData.length; i++) {\r\n                tempArray[i] = imgData[i];\r\n            }\r\n            \r\n            if (tempArray.length === imageData.data.length \/ 4 * 3) {\r\n                for (let i = 0, j = 0; i < tempArray.length; i += 3, j += 4) {\r\n                    imageData.data[j] = tempArray[i];\r\n                    imageData.data[j + 1] = tempArray[i + 1];\r\n                    imageData.data[j + 2] = tempArray[i + 2];\r\n                    imageData.data[j + 3] = 255;\r\n                }\r\n            } else if (tempArray.length === imageData.data.length) {\r\n                imageData.data.set(tempArray);\r\n            } else {\r\n                console.warn('Unknown image format - creating placeholder');\r\n                for (let i = 0; i < imageData.data.length; i += 4) {\r\n                    const x = (i\/4) % width;\r\n                    const y = Math.floor((i\/4) \/ width);\r\n                    imageData.data[i] = x % 256;\r\n                    imageData.data[i + 1] = y % 256;\r\n                    imageData.data[i + 2] = 100;\r\n                    imageData.data[i + 3] = 255;\r\n                }\r\n            }\r\n        }\r\n    },\r\n    \r\n    attachPDFPreviewHandler($dropZone, titleText) {\r\n        var $droppable = $dropZone.closest('.droppable');\r\n        var self = this;\r\n\r\n        \/\/ \u2705 Adapter le libell\u00e9 selon le format (communiqu\u00e9 \/ interview)\r\n        var kitFormat = $droppable.data('kitFormatSelect') || '';\r\n        var isInterview = (kitFormat || titleText || '').toLowerCase().indexOf('interview') !== -1;\r\n        var formatLabel = isInterview ? 'l\\'interview' : 'le communiqu\u00e9';\r\n        $droppable.find('.doc-preview-readmore').text('Ouvrir et visualiser ' + formatLabel);\r\n\r\n        \/\/ \u2705 v2.0.11 : D\u00e9l\u00e9gation d'\u00e9v\u00e9nement \u2014 plus robuste sur mobile\r\n        $droppable.off('click.docpreview').on('click.docpreview', '.doc-preview-readmore', (event) => {\r\n            event.preventDefault();\r\n            event.stopPropagation();\r\n            var popupTitle = isInterview ? 'Interview' : 'Communiqu\u00e9';\r\n\r\n            \/\/ \u2705 Priorit\u00e9 1 : pdfImageDataURL dispo (Kit)\r\n            var kitPdfImage = $droppable.data('kitPdfImageDataURL');\r\n            if (kitPdfImage) {\r\n                PDFHandler.showInlineDocPopup($dropZone, {\r\n                    formatTitle: popupTitle,\r\n                    pdfDataURL: kitPdfImage\r\n                });\r\n                return;\r\n            }\r\n\r\n            \/\/ \u2705 Priorit\u00e9 2 : PDF upload\u00e9 manuellement \u2192 popup inline aussi\r\n            if (self.pdfDataForViewer && self.pdfDataForViewer.byteLength > 0) {\r\n                PDFHandler.showInlineDocPopup($dropZone, {\r\n                    formatTitle: popupTitle,\r\n                    pdfArrayBuffer: self.pdfDataForViewer\r\n                });\r\n                return;\r\n            }\r\n\r\n            console.error('PDF data is not available');\r\n        });\r\n    },\r\n\r\n    \/\/ \u2705 v1.19.1 : Popup inline document \u2014 position:absolute + ScrollHelper.getVisibleTop()\r\n    \/\/ Le parent envoie visibleTopIframe dans le message scroll \u2192 positionnement fiable.\r\n    showInlineDocPopup($dropZone, options) {\r\n        var existing = document.getElementById('via-pdf-inline-popup');\r\n        if (existing) existing.remove();\r\n\r\n        var $droppable = $dropZone.closest('.droppable');\r\n        var droppableW = $droppable.outerWidth() || 300;\r\n        var popupW = Math.round(droppableW * 1.15);\r\n        \/\/ \u2705 v2.0.11 : Contraindre la largeur au viewport sur mobile (\u00e9vite troncature gauche\/droite)\r\n        var viewportW = document.documentElement.clientWidth || window.innerWidth;\r\n        if (UIManager.isMobile()) {\r\n            popupW = Math.min(popupW, viewportW - 8);\r\n        }\r\n        var popupH = Math.round(popupW * 2.5 * 0.51);\r\n\r\n        \/\/ \u2500\u2500 Position visible r\u00e9elle \u2500\u2500\r\n        var visibleTop = ScrollHelper.getVisibleTop();\r\n        var popupTop = Math.round(visibleTop + 284);\r\n\r\n        \/\/ \u2500\u2500 Popup position:absolute (positionn\u00e9 dans le document iframe) \u2500\u2500\r\n        var popup = document.createElement('div');\r\n        popup.id = 'via-pdf-inline-popup';\r\n        popup.style.cssText =\r\n            'position:absolute;z-index:99999;top:' + popupTop + 'px;' +\r\n            'width:' + popupW + 'px;height:' + popupH + 'px;' +\r\n            'background:#fff;border-radius:8px 8px 0 0;padding:0;' +\r\n            'box-shadow:0 8px 32px rgba(0,0,0,0.35);display:flex;flex-direction:column;' +\r\n            'min-width:200px;min-height:150px;touch-action:none;';\r\n\r\n        \/\/ Centrer horizontalement sur le droppable (coordonn\u00e9es absolues)\r\n        var droppableRect = $droppable[0].getBoundingClientRect();\r\n        var scrollX = window.scrollX || 0;\r\n        var initLeft = Math.round(droppableRect.left + scrollX + (droppableRect.width - popupW) \/ 2);\r\n        initLeft = Math.max(4, initLeft);\r\n        \/\/ \u2705 v2.0.11 : Contraindre \u00e0 droite aussi sur mobile\r\n        if (UIManager.isMobile()) {\r\n            initLeft = Math.min(initLeft, viewportW - popupW - 4);\r\n            initLeft = Math.max(4, initLeft);\r\n        }\r\n        popup.style.left = initLeft + 'px';\r\n\r\n        \/\/ \u2500\u2500 Header \u2500\u2500\r\n        var header = document.createElement('div');\r\n        header.style.cssText =\r\n            'display:flex;align-items:center;justify-content:center;position:relative;' +\r\n            'padding:10px 14px;background:#f0f0f0;color:#494949;flex-shrink:0;' +\r\n            'cursor:grab;user-select:none;border-radius:8px 8px 0 0;';\r\n        var titleEl = document.createElement('span');\r\n        titleEl.style.cssText = 'font-family:Roboto,Arial,sans-serif;font-size:15px;font-weight:600;';\r\n        titleEl.textContent = options.formatTitle || 'Document';\r\n        header.appendChild(titleEl);\r\n\r\n        var closeBtn = document.createElement('button');\r\n        closeBtn.textContent = '\u00d7';\r\n        closeBtn.style.cssText =\r\n            'position:absolute;right:10px;top:50%;transform:translateY(-50%);' +\r\n            'background:transparent;border:none;color:#494949;font-size:20px;' +\r\n            'cursor:pointer;line-height:1;padding:0 4px;';\r\n        closeBtn.addEventListener('click', cleanup);\r\n        header.appendChild(closeBtn);\r\n        popup.appendChild(header);\r\n\r\n        \/\/ \u2500\u2500 Zone scrollable \u2014 pleine largeur \u2500\u2500\r\n        var scrollZone = document.createElement('div');\r\n        scrollZone.style.cssText =\r\n            'flex:1;overflow-y:auto;overflow-x:hidden;padding:0;margin:0;touch-action:pan-y;';\r\n        popup.appendChild(scrollZone);\r\n\r\n        var loader = document.createElement('div');\r\n        loader.style.cssText =\r\n            'text-align:center;padding:30px;font-family:Roboto,Arial,sans-serif;font-size:12px;color:#666;';\r\n        loader.textContent = 'Chargement du document\u2026';\r\n        scrollZone.appendChild(loader);\r\n\r\n        \/\/ \u2500\u2500 8 poign\u00e9es de redimensionnement \u2500\u2500\r\n        var handles = [\r\n            { cursor:'nw-resize', pos:'top:-4px;left:-4px;',       dx:-1, dy:-1 },\r\n            { cursor:'n-resize',  pos:'top:-4px;left:50%;',        dx:0,  dy:-1 },\r\n            { cursor:'ne-resize', pos:'top:-4px;right:-4px;',      dx:1,  dy:-1 },\r\n            { cursor:'w-resize',  pos:'top:50%;left:-4px;',        dx:-1, dy:0  },\r\n            { cursor:'e-resize',  pos:'top:50%;right:-4px;',       dx:1,  dy:0  },\r\n            { cursor:'sw-resize', pos:'bottom:-4px;left:-4px;',    dx:-1, dy:1  },\r\n            { cursor:'s-resize',  pos:'bottom:-4px;left:50%;',     dx:0,  dy:1  },\r\n            { cursor:'se-resize', pos:'bottom:-4px;right:-4px;',   dx:1,  dy:1  }\r\n        ];\r\n        handles.forEach(function(h) {\r\n            var handle = document.createElement('div');\r\n            var isCorner = (h.dx !== 0 && h.dy !== 0);\r\n            handle.style.cssText =\r\n                'position:absolute;touch-action:none;' + h.pos +\r\n                'width:' + (isCorner ? '12px' : (h.dy === 0 ? '8px' : '30px')) + ';' +\r\n                'height:' + (isCorner ? '12px' : (h.dy === 0 ? '30px' : '8px')) + ';' +\r\n                'cursor:' + h.cursor + ';z-index:10;';\r\n            (function(hInfo) {\r\n                handle.addEventListener('pointerdown', function(e) {\r\n                    e.preventDefault(); e.stopPropagation();\r\n                    handle.setPointerCapture(e.pointerId);\r\n                    var startX = e.clientX, startY = e.clientY;\r\n                    var rect0 = popup.getBoundingClientRect();\r\n                    var sY = window.scrollY || 0, sX = window.scrollX || 0;\r\n                    var startW = rect0.width, startH = rect0.height;\r\n                    var startL = rect0.left + sX, startT = rect0.top + sY;\r\n                    function onResize(ev) {\r\n                        ev.preventDefault();\r\n                        var ddx = ev.clientX - startX, ddy = ev.clientY - startY;\r\n                        var newW = startW, newH = startH, newL = startL, newT = startT;\r\n                        if (hInfo.dx === 1)  newW = Math.max(200, startW + ddx);\r\n                        if (hInfo.dx === -1) { newW = Math.max(200, startW - ddx); newL = startL + ddx; }\r\n                        if (hInfo.dy === 1)  newH = Math.max(150, startH + ddy);\r\n                        if (hInfo.dy === -1) { newH = Math.max(150, startH - ddy); newT = startT + ddy; }\r\n                        popup.style.width  = newW + 'px';\r\n                        popup.style.height = newH + 'px';\r\n                        popup.style.left   = newL + 'px';\r\n                        popup.style.top    = newT + 'px';\r\n                    }\r\n                    function onResizeEnd(ev) {\r\n                        handle.releasePointerCapture(ev.pointerId);\r\n                        handle.removeEventListener('pointermove', onResize);\r\n                        handle.removeEventListener('pointerup', onResizeEnd);\r\n                    }\r\n                    handle.addEventListener('pointermove', onResize);\r\n                    handle.addEventListener('pointerup', onResizeEnd);\r\n                });\r\n            })(h);\r\n            popup.appendChild(handle);\r\n        });\r\n\r\n        \/\/ \u2500\u2500 Drag via header \u2500\u2500\r\n        header.style.touchAction = 'none';\r\n        header.addEventListener('pointerdown', function(e) {\r\n            if (e.target === closeBtn) return;\r\n            e.preventDefault();\r\n            header.setPointerCapture(e.pointerId);\r\n            var mx = e.clientX, my = e.clientY;\r\n            var popupRect = popup.getBoundingClientRect();\r\n            var scrollY = window.scrollY || 0;\r\n            var scrollX = window.scrollX || 0;\r\n            var curLeft = popupRect.left + scrollX;\r\n            var curTop  = popupRect.top  + scrollY;\r\n            header.style.cursor = 'grabbing';\r\n            function onMove(ev) {\r\n                ev.preventDefault();\r\n                var dx = ev.clientX - mx;\r\n                var dy = ev.clientY - my;\r\n                curLeft += dx;\r\n                curTop  += dy;\r\n                popup.style.left = curLeft + 'px';\r\n                popup.style.top  = curTop  + 'px';\r\n                mx = ev.clientX;\r\n                my = ev.clientY;\r\n            }\r\n            function onUp(ev) {\r\n                header.releasePointerCapture(ev.pointerId);\r\n                header.style.cursor = 'grab';\r\n                header.removeEventListener('pointermove', onMove);\r\n                header.removeEventListener('pointerup', onUp);\r\n            }\r\n            header.addEventListener('pointermove', onMove);\r\n            header.addEventListener('pointerup', onUp);\r\n        });\r\n\r\n        \/\/ \u2500\u2500 Cleanup \u2500\u2500\r\n        function cleanup() {\r\n            popup.remove();\r\n            document.removeEventListener('keydown', escHandler);\r\n        }\r\n        var escHandler = function(e) { if (e.key === 'Escape') cleanup(); };\r\n        document.addEventListener('keydown', escHandler);\r\n\r\n        document.body.appendChild(popup);\r\n\r\n        \/\/ \u2500\u2500 Rendre le contenu \u2500\u2500\r\n        if (options.pdfDataURL)          this.renderPdfInPopup(scrollZone, options.pdfDataURL, popupW, 'dataurl');\r\n        else if (options.pdfArrayBuffer) this.renderPdfInPopup(scrollZone, options.pdfArrayBuffer, popupW, 'arraybuffer');\r\n        else if (options.htmlContent)    this.renderHtmlInPopup(scrollZone, options.htmlContent);\r\n    },\r\n\r\n    \/\/ Alias pour compatibilit\u00e9\r\n    showInlinePdfPopup($dropZone, pdfImageDataURL, formatTitle) {\r\n        this.showInlineDocPopup($dropZone, { formatTitle: formatTitle, pdfDataURL: pdfImageDataURL });\r\n    },\r\n\r\n    \/\/ \u2705 Rendu PDF dans popup (dataurl ou arraybuffer) \u2014 avec crop des marges blanches\r\n    async renderPdfInPopup(container, pdfData, popupWidth, mode) {\r\n        try {\r\n            var u8;\r\n            if (mode === 'dataurl') {\r\n                var b64 = pdfData.split(',')[1];\r\n                var bstr = atob(b64);\r\n                u8 = new Uint8Array(bstr.length);\r\n                for (var i = 0; i < bstr.length; i++) { u8[i] = bstr.charCodeAt(i); }\r\n            } else {\r\n                u8 = new Uint8Array(pdfData);\r\n            }\r\n\r\n            var pdfjsLib = window['pdfjs-dist\/build\/pdf'];\r\n            if (!pdfjsLib) {\r\n                container.innerHTML = '<div style=\"padding:20px;text-align:center;color:#c00;\">pdf.js non charg\u00e9<\/div>';\r\n                return;\r\n            }\r\n            pdfjsLib.GlobalWorkerOptions.workerSrc =\r\n                '\/\/cdn.jsdelivr.net\/npm\/pdfjs-dist@latest\/build\/pdf.worker.min.js';\r\n\r\n            var pdf = await pdfjsLib.getDocument({ data: u8 }).promise;\r\n            console.log('\ud83d\udcc4 PDF popup :', pdf.numPages, 'pages');\r\n            container.innerHTML = '';\r\n\r\n            var firstPage = await pdf.getPage(1);\r\n            var vpNative = firstPage.getViewport({ scale: 1 });\r\n            var scale = popupWidth \/ vpNative.width;\r\n\r\n            \/\/ \u2705 R\u00e9f\u00e9rence au popup pour ajuster sa hauteur apr\u00e8s rendu\r\n            var _popup = container.closest('#via-pdf-inline-popup');\r\n            var _headerH = _popup ? (_popup.querySelector('div[style*=\"grab\"]') || {offsetHeight: 44}).offsetHeight : 44;\r\n\r\n            \/\/ \u2705 D\u00e9tecte les marges blanches haut\/bas d'un canvas rendu et retourne {top, bottom}\r\n            function detectWhiteMargins(canvas) {\r\n                var ctx = canvas.getContext('2d');\r\n                var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;\r\n                var W = canvas.width, H = canvas.height;\r\n                var topRow = 0, bottomRow = H - 1;\r\n                \/\/ Chercher la premi\u00e8re ligne non-blanche (tol\u00e9rance 252 pour les artefacts anti-aliasing)\r\n                outer: for (var y = 0; y < H; y++) {\r\n                    for (var x = 0; x < W; x++) {\r\n                        var i = (y * W + x) * 4;\r\n                        if (data[i] < 252 || data[i+1] < 252 || data[i+2] < 252) { topRow = y; break outer; }\r\n                    }\r\n                }\r\n                outer2: for (var y2 = H - 1; y2 >= topRow; y2--) {\r\n                    for (var x2 = 0; x2 < W; x2++) {\r\n                        var i2 = (y2 * W + x2) * 4;\r\n                        if (data[i2] < 252 || data[i2+1] < 252 || data[i2+2] < 252) { bottomRow = y2; break outer2; }\r\n                    }\r\n                }\r\n                return { top: topRow, bottom: bottomRow };\r\n            }\r\n\r\n            for (var pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\r\n                var page = await pdf.getPage(pageNum);\r\n                var vp = page.getViewport({ scale: scale });\r\n                \/\/ Rendre dans un canvas temporaire\r\n                var tmpCanvas = document.createElement('canvas');\r\n                tmpCanvas.width = vp.width;\r\n                tmpCanvas.height = vp.height;\r\n                await page.render({ canvasContext: tmpCanvas.getContext('2d'), viewport: vp }).promise;\r\n\r\n                \/\/ \u2705 Crop marges blanches\r\n                var margins = detectWhiteMargins(tmpCanvas);\r\n                var cropTop = Math.max(0, margins.top - 4);\r\n                var cropBottom = Math.min(tmpCanvas.height - 1, margins.bottom + 4);\r\n                var croppedH = cropBottom - cropTop + 1;\r\n\r\n                \/\/ Canvas final crop\u00e9\r\n                var canvas = document.createElement('canvas');\r\n                canvas.width = tmpCanvas.width;\r\n                canvas.height = croppedH;\r\n                canvas.getContext('2d').drawImage(tmpCanvas, 0, cropTop, tmpCanvas.width, croppedH, 0, 0, tmpCanvas.width, croppedH);\r\n                canvas.style.cssText = 'display:block;width:100%;height:auto;margin:0;padding:0;';\r\n                container.appendChild(canvas);\r\n                console.log('\ud83d\udcc4 Page', pageNum, '- crop:', cropTop, '\u2192', cropBottom, '(', Math.round(cropTop\/vp.height*100), '% top trimmed)');\r\n            }\r\n\r\n            \/\/ \u2705 Ajuster la hauteur du popup \u00e0 la hauteur r\u00e9elle du contenu rendu\r\n            \/\/ (popup \u00e9tait calcul\u00e9 sur popupW*2.5*0.51 qui peut \u00eatre trop grand ou trop petit)\r\n            if (_popup) {\r\n                var _totalH = 0;\r\n                container.querySelectorAll('canvas').forEach(function(c) { _totalH += c.height * (popupWidth \/ c.width); });\r\n                var _viewportH = window.innerHeight || document.documentElement.clientHeight || 600;\r\n                var _maxPopupH = Math.round(_viewportH * 0.88);\r\n                var _idealH = Math.min(_totalH + _headerH + 8, _maxPopupH);\r\n                _popup.style.height = _idealH + 'px';\r\n                console.log('\ud83d\udcd0 Popup redimensionn\u00e9:', Math.round(_idealH), 'px (contenu:', Math.round(_totalH), ')');\r\n            }\r\n        } catch (err) {\r\n            console.error('\u274c Erreur rendu PDF popup:', err);\r\n            container.innerHTML =\r\n                '<div style=\"padding:20px;text-align:center;color:#c00;font-size:12px;\">Erreur lors du chargement du document<\/div>';\r\n        }\r\n    },\r\n\r\n    \/\/ \u2705 Rendu HTML (Word) dans popup \u2014 avec CSS complet pour mammoth\r\n    renderHtmlInPopup(container, htmlContent) {\r\n        container.innerHTML = '';\r\n        \/\/ \u2705 Nettoyer les <p> vides en d\u00e9but\/fin produits par mammoth (marges parasites)\r\n        htmlContent = htmlContent\r\n            .replace(\/^(\\s*<p[^>]*>\\s*(<br\\s*\\\/?>\\s*)*<\\\/p>\\s*)+\/i, '')\r\n            .replace(\/(\\s*<p[^>]*>\\s*(<br\\s*\\\/?>\\s*)*<\\\/p>\\s*)+$\/i, '');\r\n        \/\/ \u2500\u2500 Styles pour le HTML g\u00e9n\u00e9r\u00e9 par mammoth (titres, paragraphes, listes, images) \u2500\u2500\r\n        var style = document.createElement('style');\r\n        style.textContent = [\r\n            '.via-html-popup-body { padding:20px 24px; background:#fff; color:#222; font-family:Georgia,\"Times New Roman\",serif; font-size:15px; line-height:1.7; }',\r\n            '.via-html-popup-body h1 { font-size:22px; font-weight:700; margin:0 0 12px; line-height:1.3; }',\r\n            '.via-html-popup-body h2 { font-size:18px; font-weight:700; margin:18px 0 8px; line-height:1.3; }',\r\n            '.via-html-popup-body h3 { font-size:15px; font-weight:700; margin:14px 0 6px; }',\r\n            '.via-html-popup-body p  { margin:0 0 10px; }',\r\n            '.via-html-popup-body p:first-child { margin-top:0; }',\r\n            '.via-html-popup-body strong, .via-html-popup-body b { font-weight:700; }',\r\n            '.via-html-popup-body em, .via-html-popup-body i { font-style:italic; }',\r\n            '.via-html-popup-body ul, .via-html-popup-body ol { margin:6px 0 10px 22px; padding:0; }',\r\n            '.via-html-popup-body li { margin-bottom:4px; }',\r\n            '.via-html-popup-body img { max-width:100%; height:auto; display:block; margin:10px auto; border-radius:4px; }',\r\n            '.via-html-popup-body table { width:100%; border-collapse:collapse; margin:10px 0; font-size:13px; }',\r\n            '.via-html-popup-body td, .via-html-popup-body th { border:1px solid #ddd; padding:6px 8px; vertical-align:top; }',\r\n            '.via-html-popup-body th { background:#f0f4f8; font-weight:700; }',\r\n            '.via-html-popup-body a { color:#225da9; text-decoration:underline; }'\r\n        ].join('');\r\n        container.appendChild(style);\r\n        var wrapper = document.createElement('div');\r\n        wrapper.className = 'via-html-popup-body';\r\n        wrapper.innerHTML = htmlContent;\r\n        container.appendChild(wrapper);\r\n    },\r\n    \r\n    async renderPDFInWindow(childWindow, container) {\r\n        container.innerHTML = '';\r\n        \r\n        const script = childWindow.document.createElement('script');\r\n        script.src = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.4.120\/pdf.min.js';\r\n        childWindow.document.head.appendChild(script);\r\n        \r\n        script.onload = async () => {\r\n            const pdfjsLib = childWindow.pdfjsLib;\r\n            const viewerContainer = childWindow.document.createElement('div');\r\n            viewerContainer.style.width = '100%';\r\n            viewerContainer.style.backgroundColor = 'white';\r\n            viewerContainer.style.position = 'relative';\r\n            container.appendChild(viewerContainer);\r\n            \r\n            const loadingTask = pdfjsLib.getDocument({data: window.pdfDataToTransfer});\r\n            const pdf = await loadingTask.promise;\r\n            \r\n            const firstPage = await pdf.getPage(1);\r\n            const viewport = firstPage.getViewport({scale: 1.5});\r\n            const pageHeight = viewport.height;\r\n            \r\n            const spacing = -15;\r\n            const totalHeight = (pageHeight * pdf.numPages) + (spacing * (pdf.numPages - 1));\r\n            viewerContainer.style.height = `${totalHeight}px`;\r\n            \r\n            for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\r\n                const page = await pdf.getPage(pageNum);\r\n                const canvas = childWindow.document.createElement('canvas');\r\n                const context = canvas.getContext('2d');\r\n                \r\n                canvas.width = viewport.width;\r\n                canvas.height = viewport.height;\r\n                \r\n                canvas.style.position = 'absolute';\r\n                canvas.style.left = '50%';\r\n                canvas.style.transform = 'translateX(-50%)';\r\n                canvas.style.top = `${(pageNum - 1) * (pageHeight + spacing)}px`;\r\n                \r\n                await page.render({\r\n                    canvasContext: context,\r\n                    viewport: viewport\r\n                }).promise;\r\n                \r\n                viewerContainer.appendChild(canvas);\r\n            }\r\n        };\r\n    },\r\n    \r\n    arrayBufferToBase64(buffer) {\r\n        let binary = '';\r\n        const bytes = new Uint8Array(buffer);\r\n        const len = bytes.byteLength;\r\n        for (let i = 0; i < len; i++) {\r\n            binary += String.fromCharCode(bytes[i]);\r\n        }\r\n        return window.btoa(binary);\r\n    },\r\n    \r\n    base64ToArrayBuffer(base64) {\r\n        const binaryString = window.atob(base64);\r\n        const len = binaryString.length;\r\n        const bytes = new Uint8Array(len);\r\n        for (let i = 0; i < len; i++) {\r\n            bytes[i] = binaryString.charCodeAt(i);\r\n        }\r\n        return bytes.buffer;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion des \u00e9v\u00e9nements de drop et d'upload\r\n *\/\r\nconst DropHandler = {\r\n    async handleDrop(e) {\r\n        e.preventDefault();\r\n        \r\n        const $currentTarget = this.findDropTarget(e);\r\n        \r\n        if (!$currentTarget) {\r\n            console.log('No valid drop target found');\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 V\u00c9RIFIER SI C'EST UN D\u00c9PLACEMENT (pas besoin de v\u00e9rifier le format)\r\n        const isMoved = StateManager.get('FirstUploadFileorMoved') === 'Moved';\r\n        const dragstartRef = StateManager.get('dragstart_Commande_Emplacement_Page_Web');\r\n        let hasDragstartRef = false;\r\n        \r\n        if (dragstartRef) {\r\n            if (dragstartRef !== 'No') {\r\n                hasDragstartRef = true;\r\n            }\r\n        }\r\n        \r\n        let isDeplacementAnnonce = false;\r\n        if (isMoved) {\r\n            if (hasDragstartRef) {\r\n                isDeplacementAnnonce = true;\r\n            }\r\n        }\r\n        \r\n        if (isDeplacementAnnonce) {\r\n            console.log('\ud83d\udd04 D\u00e9placement d\u00e9tect\u00e9 - contr\u00f4le format ignor\u00e9');\r\n        } else {\r\n            \/\/ \u2705 CONTR\u00d4LE FORMAT SEULEMENT POUR NOUVEAU D\u00c9P\u00d4T\r\n            \/\/ Utilise FormatUIManager au lieu de showFormatWarning\r\n            if (StateManager.get('Formatchoisi') === 'No') {\r\n                FormatUIManager.flashTitle($currentTarget);\r\n                return;\r\n            }\r\n            \r\n            if (!FormatUIManager.hasSelectedFormat($currentTarget)) {\r\n                FormatUIManager.flashTitle($currentTarget);\r\n                return;\r\n            }\r\n        }\r\n    \r\n        console.log(\"Drop at:\", $currentTarget);\r\n        \r\n        this.updateEmplacementState($currentTarget);\r\n        \r\n        const shouldProcess = this.shouldProcessDrop(e, $currentTarget);\r\n        \r\n        if (shouldProcess) {\r\n            await this.processFileDrop(e, $currentTarget);\r\n        } else {\r\n            this.processVideoDrop($currentTarget);\r\n        }\r\n        \r\n        DragDropManager.clearDataTransferFiles(e);\r\n    },\r\n    \r\n    findDropTarget(e) {\r\n        \/\/ \u2705 v2.4.3 : Si Ele0A est actif et le drop arrive sur Ele1A \u2192 rediriger vers Ele0A\r\n        if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n            var _ele0ADrop = document.querySelector('#Ele0A #drop_file_zone_achat');\r\n            if (_ele0ADrop) {\r\n                console.log('\ud83c\udfaf findDropTarget \u2014 PopUpChoice=Yes \u2192 cible forc\u00e9e: Ele0A');\r\n                return jQuery(_ele0ADrop);\r\n            }\r\n        }\r\n\r\n        let target = e.target.closest('#drop_file_zone_achat');\r\n        \r\n        if (!target) {\r\n            target = e.currentTarget.closest('#drop_file_zone_achat');\r\n            console.log('Drop target found 1');\r\n        }\r\n        \r\n        if (!target) {\r\n            target = jQuery(e.target).closest('#drop_file_zone_achat')[0];\r\n            console.log('Drop target found 2');\r\n        }\r\n        \r\n        return target ? jQuery(target) : null;\r\n    },\r\n    \r\n    updateEmplacementState($target) {\r\n        const espaceId = $target.closest('.droppable').attr('id');\r\n        \r\n        StateManager.set('Rank_Emplacement_Page_Web', espaceId);\r\n        StateManager.set('Commande_Emplacement_Page_Web',\r\n            StateManager.buildEmplacementReference(espaceId));\r\n        \r\n        UIManager.updateEmplacementDisplay();\r\n        \r\n        console.log(\"Rank_Emplacement_Page_Web:\", StateManager.get('Rank_Emplacement_Page_Web'));\r\n        console.log(\"Droppable at:\", StateManager.get('Commande_Emplacement_Page_Web'));\r\n    },\r\n    \r\n    shouldProcessDrop(e, $target) {\r\n        const hasFiles = e.dataTransfer.files.length > 0;\r\n        const isRedactionnel = StateManager.get('Commande_Format_Transmis') === 'R\u00e9dactionnel';\r\n        const isValidBackground = window.getComputedStyle(\r\n            $target.closest('#UploadFileConteneur')[0]\r\n        ).backgroundColor !== 'rgba(0, 0, 0, 0)';\r\n        \r\n        return (hasFiles || isRedactionnel) && isValidBackground;\r\n    },\r\n    \r\n    async processFileDrop(e, $target) {\r\n        jQuery('.MsgAdNotDisplayed').hide();\r\n        StateManager.setMultiple({\r\n            \"AdDisplayed\": 'Yes',\r\n            \/\/ \u2705 NE PLUS mettre sendDataToParentFlag ici - c'est la checkbox \"R\u00e9server\" qui le fera\r\n            \/\/ \"sendDataToParentFlag\": 'Yes'\r\n        });\r\n        \r\n        console.log('ajaxFileUpload_achat launched');\r\n        console.log(\"FirstUploadFileorMoved:\", StateManager.get('FirstUploadFileorMoved'));\r\n        \r\n        if (UIManager.isMobile()) {\r\n            $target = jQuery('#Ele1A').find('#drop_file_zone_achat');\r\n        }\r\n        \r\n        if (StateManager.get('Commande_Format_Transmis') === 'R\u00e9dactionnel') {\r\n            const fileURL = StateManager.get('FullPathAdFile');\r\n            const filename = fileURL.substring(fileURL.indexOf('_') + 1);\r\n            \r\n            try {\r\n                \/\/ \u2705 R\u00e9utiliser le File cach\u00e9 (\u00e9vite CORS cross-domain)\r\n                let file;\r\n                if (window._lastRedactionnelFile) {\r\n                    file = window._lastRedactionnelFile;\r\n                    console.log('\u267b\ufe0f R\u00e9utilisation du File cach\u00e9:', file.name, Math.round(file.size \/ 1024) + 'KB');\r\n                } else {\r\n                    file = await FileManager.urlToFile(fileURL, filename);\r\n                }\r\n                await UploadManager.handleFileUpload(file, $target);\r\n            } catch (error) {\r\n                console.error('Error:', error);\r\n            }\r\n        } else {\r\n            await UploadManager.handleFileUpload(e.dataTransfer.files[0], $target);\r\n        }\r\n    },\r\n    \r\n    processVideoDrop($target) {\r\n        const isValidBackground = window.getComputedStyle(\r\n            $target.closest('#UploadFileConteneur')[0]\r\n        ).backgroundColor !== 'rgba(0, 0, 0, 0)';\r\n        \r\n        if (!isValidBackground) {\r\n            jQuery('.MsgAdNotDisplayed').show();\r\n            StateManager.set(\"AdDisplayed\", 'No');\r\n            return;\r\n        }\r\n        \r\n        StateManager.set(\"AdDisplayed\", 'Yes');\r\n        \r\n        const objectUrl = StateManager.get('videoSrc');\r\n        const $previousDropZone = $('.drop_file_zone_achat_class').has(`video[src=\"${objectUrl}\"]`);\r\n        window.RestoreadSpaceTemplate($previousDropZone);\r\n        \r\n        const videoElement = jQuery('<video controls autoplay muted>').attr({\r\n            'src': objectUrl,\r\n            'max-width': '100%',\r\n            'max-height': '100%',\r\n            'draggable': 'true'\r\n        }).css({\r\n            'max-width': '100%',\r\n            'max-height': '100%'\r\n        });\r\n        \r\n        $target.empty().append(videoElement);\r\n        \r\n        $target.closest('#UploadFileConteneur').css({'background-color': '#FFFFFF00'});\r\n        \r\n        $target.closest('.OrdiMobileConteneurClass')\r\n            .find('.RefEspacePublicitaire')\r\n            .html('R\u00e9f\u00e9rence de l\\'espace : ' + StateManager.get('Commande_Emplacement_Page_Web'))\r\n            .attr('id', 'RefEspacePublicitaire')\r\n            .each(function() {\r\n                var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                this.style.setProperty('display', 'block', 'important');\r\n            });\r\n        \/\/ \u2705 v2.4.5 : Renseigner et afficher .PositionEspacePublicitaire\r\n        (function() {\r\n            var _rankPosV = StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            var _posLibV = PreviewRenderer._getPositionLibelle(_rankPosV);\r\n            if (_posLibV) {\r\n                $target.closest('.OrdiMobileConteneurClass')\r\n                    .find('.PositionEspacePublicitaireDeplacer')\r\n                    .text(_posLibV)\r\n                    .each(function() {\r\n                        var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                        if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                        this.style.setProperty('display', 'block', 'important');\r\n                    });\r\n            }\r\n        })();\r\n        \r\n        $target.closest('.OrdiMobileConteneurClass').find('.AdUploadedTitle').show();\r\n        \r\n        $target.closest('.OrdiMobileConteneurClass')\r\n            .css({'top': '60px', 'margin-bottom': '80px'});\r\n        \r\n        $target.closest('.HTMLUploadfileConteneur')\r\n            .not('.AdUploadedTitle')\r\n            .css({\r\n                'top': '0px',\r\n                'margin-bottom': '0px',\r\n                'box-shadow': 'inset 0 0 0 2px #00FF19',  \/\/ \u2705 v2.4.5\r\n                'background-color': 'white'\r\n            });\r\n        \r\n        $target.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed, .ChoisirEspacePublicitaire2ndLigne, span.ClassHdpCdp, .ClassRefEsp, .HideFormButton, .EspPubFormatMainContainer, .EnvoiUlterieurContainer')\r\n            .hide();\r\n        \r\n        jQuery('#MsgElementsCommandeValides, #MessageOptionsacompleterConteneur').hide();\r\n        \r\n        StateManager.set(\"FirstUploadFileorMoved\", 'Moved');\r\n        \r\n        \/\/ \u2705 Mettre \u00e0 jour l'\u00e9tat de la checkbox R\u00e9server (au lieu d'envoyer automatiquement)\r\n        FormatUIManager.updateReserverCheckboxState($target.closest('.droppable'));\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'explorateur de fichiers\r\n *\/\r\nconst FileExplorer = {\r\n    isRunning: false,\r\n\r\n    open(e) {\r\n        if (this.isRunning) {\r\n            return;\r\n        }\r\n        \r\n        const $element = jQuery(e.target).closest('.droppable');\r\n        \r\n        \/\/ \u2705 V\u00e9rifier si un format est s\u00e9lectionn\u00e9 (utilise FormatUIManager)\r\n        if (!FormatUIManager.hasSelectedFormat($element)) {\r\n            FormatUIManager.flashTitle($element);\r\n            return;\r\n        }\r\n        \r\n        this.isRunning = true;\r\n        \r\n        const rankId = $element.attr('id');\r\n        \r\n        StateManager.set('Rank_Emplacement_Page_Web', rankId);\r\n        StateManager.set('Commande_Emplacement_Page_Web',\r\n            StateManager.buildEmplacementReference(rankId));\r\n        \r\n        UIManager.updateEmplacementDisplay();\r\n        \r\n        console.log(\"Drop at:\", StateManager.get('Commande_Emplacement_Page_Web'));\r\n        \r\n        StateManager.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        \r\n        const $currentTarget = jQuery(e.target).closest('#drop_file_zone_achat');\r\n        const $fileInput = jQuery('#selectfile_achat');\r\n        \r\n        console.log(\"currentTarget\", $currentTarget);\r\n        \r\n        $fileInput.off('change');\r\n        $fileInput.off('click');\r\n        \r\n        const onChange = (event) => {\r\n            this.isRunning = false;\r\n            $fileInput.off('change', onChange);\r\n            \r\n            \/\/ \u2705 NE PLUS mettre sendDataToParentFlag ici\r\n            \/\/ StateManager.set(\"sendDataToParentFlag\", 'Yes');\r\n            \r\n            if ($fileInput[0].files.length > 0) {\r\n                UploadManager.handleFileUpload($fileInput[0].files[0], $currentTarget);\r\n            }\r\n        };\r\n        \r\n        const onClick = () => {\r\n            $fileInput.off('click', onClick);\r\n            $fileInput.on('focus', function onFocus() {\r\n                setTimeout(() => {\r\n                    if (!$fileInput.val()) {\r\n                        FileExplorer.isRunning = false;\r\n                    }\r\n                }, 200);\r\n                $fileInput.off('focus', onFocus);\r\n            });\r\n        };\r\n        \r\n        $fileInput.on('change', onChange);\r\n        $fileInput.on('click', onClick);\r\n        \r\n        $fileInput.click();\r\n        \r\n        setTimeout(() => {\r\n            this.isRunning = false;\r\n        }, 300);\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion du reset d'annonce\r\n *\/\r\nconst AdResetHandler = {\r\n    handle(e) {\r\n        e.preventDefault();\r\n        console.log(\"CroixResetAnnonce click\");\r\n        \r\n        \/\/ Reset l'\u00e9tat EnvoiUlterieur\r\n        StateManager.set('EnvoiUlterieur', 'false');\r\n        \r\n        \/\/ \u2705 v1.19.6 : Reset FileReceived mais garder le format s\u00e9lectionn\u00e9\r\n        StateManager.set('FileReceived', 'No');\r\n        \r\n        const $element = jQuery(e.currentTarget);\r\n        const $droppable = $element.closest('.droppable');\r\n        const resetRef = StateManager.buildEmplacementReference($droppable.attr('id'));\r\n        \r\n        console.log(\"Reset_Commande_Emplacement_Page_Web:\", resetRef);\r\n        \r\n        \/\/ \u2705 Supprimer le bouton \"R\u00e9server\" dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        $droppable.find('.ReserverContainer').hide();\r\n        \r\n        var _rankForDel = $droppable.attr('id') || StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            MessageManager.sendDelAdToParent({\r\n                Commande_Emplacement_Page_Web: resetRef,\r\n                Rank_Emplacement_Page_Web: _rankForDel,\r\n                LoadedPageUrl: window.location.href\r\n            });\r\n        } else {\r\n            window.processdataDelAd({\r\n                Commande_Emplacement_Page_Web: resetRef,\r\n                Rank_Emplacement_Page_Web: _rankForDel,\r\n                LoadedPageUrl: window.location.href\r\n            });\r\n        }\r\n        \r\n        \/\/ \u2705 v1.16.0 : Appeler RestoreadSpaceTemplateLocal directement (accessible dans ce scope)\r\n        RestoreadSpaceTemplateLocal(e.currentTarget);\r\n        \r\n        window.FonctionCroixResetAnnonce(e.currentTarget);\r\n        \r\n        \/\/ \u2705 v2.1.1 : Sauf popup\r\n        var formatWasSelected = sessionStorage.getItem('FormatSelect') \r\n            || sessionStorage.getItem('Commande_Format_Transmis')\r\n            || $droppable.data('kitFormatSelect');\r\n        \r\n        if (sessionStorage.getItem('PopUpChoice') !== 'Yes' && (formatWasSelected || sessionStorage.getItem('Formatchoisi') === 'Yes')) {\r\n            sessionStorage.setItem('Formatchoisi', 'Yes');\r\n            console.log('\u2705 Formatchoisi forc\u00e9 \u00e0 Yes apr\u00e8s reset');\r\n        }\r\n        \r\n        \/\/ \u2705 v1.19.6 : Remettre \u00e0 jour le titre format et r\u00e9afficher la checkbox R\u00e9server\r\n        setTimeout(() => {\r\n            FormatUIManager.updateTitleColor($droppable);\r\n            FormatUIManager.updateReserverCheckboxState($droppable);\r\n            \r\n            \/\/ \u2705 R\u00e9afficher le .ReserverContainer statique\r\n            $droppable.find('.ReserverContainer').show();\r\n        }, 150);\r\n    }\r\n};\r\n\r\n\/**\r\n * \u2705 Template pour r\u00e9initialisation des espaces publicitaires (IFRAME)\r\n *\/\r\nvar adSpaceTemplatesLocal = {};\r\n\r\nfunction saveAdSpaceTemplateLocal() {\r\n    var saved = 0;\r\n    jQuery('.droppable').each(function() {\r\n        var droppableId = jQuery(this).attr('id');\r\n        if (!droppableId) return;\r\n        \r\n        \/\/ \u2705 Ne jamais sauvegarder Ele0A (clone temporaire popup, pas un template d'origine)\r\n        if (droppableId === 'Ele0A') return;\r\n        \r\n        \/\/ \u2705 Ne pas r\u00e9-\u00e9craser un template d\u00e9j\u00e0 sauvegard\u00e9\r\n        if (adSpaceTemplatesLocal[droppableId]) return;\r\n        \r\n        \/\/ \u2705 v2.3.4 : Ne pas sauvegarder si template d\u00e9j\u00e0 connu (\u00e9tat propre sauvegard\u00e9)\r\n        \/\/ Le guard hasAd est supprim\u00e9 \u2014 on veut capturer le template le plus t\u00f4t possible\r\n        \/\/ Si le template existe d\u00e9j\u00e0, on ne le r\u00e9\u00e9crase pas\r\n        \/\/ (le guard anti-\u00e9crasement if (adSpaceTemplatesLocal[droppableId]) return; suffit)\r\n        \r\n        var $content = jQuery(this).find('.OrdiMobileConteneurClass').first();\r\n        if ($content.length > 0) {\r\n            adSpaceTemplatesLocal[droppableId] = $content.clone(true, true);\r\n            saved++;\r\n        }\r\n    });\r\n    if (saved > 0) {\r\n        console.log('\u2705 Templates espaces pub sauvegard\u00e9s:', saved, 'espaces -', Object.keys(adSpaceTemplatesLocal));\r\n        return true;\r\n    }\r\n    return false;\r\n}\r\n\r\nfunction RestoreadSpaceTemplateLocal(element) {\r\n    console.log('\ud83d\udd04 RestoreadSpaceTemplateLocal', element);\r\n    \r\n    var $element = jQuery(element);\r\n    var $droppable = $element.closest('.droppable');\r\n    var droppableId = $droppable.attr('id');\r\n    \r\n    \/\/ \u2705 FIX Ele0A : pas de template sauvegard\u00e9 (clone temporaire popup)\r\n    \/\/ \u2192 pas de remplacement DOM, reset visuel direct sur le contenu existant\r\n    var _isEle0A = (droppableId === 'Ele0A');\r\n\r\n    \/\/ \u2705 v1.19.3 : Chercher le template sp\u00e9cifique \u00e0 CET espace (sauf Ele0A)\r\n    if (!_isEle0A) {\r\n        if (!droppableId || !adSpaceTemplatesLocal[droppableId]) {\r\n            if (!saveAdSpaceTemplateLocal()) {\r\n                console.error('\u274c Template non disponible');\r\n                return false;\r\n            }\r\n            if (!adSpaceTemplatesLocal[droppableId]) {\r\n                console.error('\u274c Template non trouv\u00e9 pour', droppableId);\r\n                return false;\r\n            }\r\n        }\r\n    }\r\n    \r\n    var adSpaceElement = $droppable.find('.OrdiMobileConteneurClass').first();\r\n    \r\n    if (!adSpaceElement || !adSpaceElement.length) {\r\n        console.error('\u274c OrdiMobileConteneurClass non trouv\u00e9');\r\n        return false;\r\n    }\r\n    \r\n    var newElement;\r\n    if (_isEle0A) {\r\n        \/\/ Ele0A : pas de clone \u2014 on remet en \u00e9tat le contenu existant directement\r\n        newElement = adSpaceElement;\r\n        console.log('\u2705 [Ele0A] reset visuel direct (pas de template clone)');\r\n        \/\/ \u2705 Vider le contenu du dropzone et restaurer le HTML par d\u00e9faut\r\n        \/\/ (le replaceWith n'ayant pas lieu, l'image d\u00e9pos\u00e9e et le fond blanc restent sinon)\r\n        var $dz0A = $droppable.find('#drop_file_zone_achat');\r\n        $dz0A.empty().html(\r\n            '<div id=\"drag_upload_file_achat\">' +\r\n                '<p class=\"UploadIci\" style=\"color:#FB5E2A;font-weight:600;\">Ici glisser \u2013 d\u00e9poser ou<br>t\u00e9l\u00e9charger une annonce<\/p>' +\r\n            '<\/div>'\r\n        );\r\n        \/\/ Restaurer le fond bleu #9FC5F3 et retirer les styles d'annonce upload\u00e9e\r\n        $droppable.find('#UploadFileConteneur').css({\r\n            'background-color': '#9FC5F3',\r\n            'border': '',\r\n            'box-sizing': ''\r\n        });\r\n        $droppable.find('.HTMLUploadfileConteneur').css({\r\n            'box-shadow': '',\r\n            'background-color': '',\r\n            'border': '',\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'min-height': '',\r\n            'overflow': '',\r\n            'height': '',\r\n            'max-height': ''\r\n        });\r\n        \/\/ Masquer la croix et le titre d'annonce upload\u00e9e\r\n        $droppable.find('.AdUploadedTitle, #CroixResetAnnonce, .CroixResetAnnonceContainer, .DeplaceAnnonce').hide();\r\n        $droppable.removeAttr('data-via-ad-loaded').removeAttr('data-from-miniature');\r\n        console.log('\u2705 [Ele0A] dropzone vid\u00e9 + fond restaur\u00e9');\r\n    } else {\r\n        \/\/ \u2705 v1.19.3 : Cloner le template SP\u00c9CIFIQUE \u00e0 cet espace (pas le premier)\r\n        newElement = adSpaceTemplatesLocal[droppableId].clone(true, true);\r\n        console.log('\u2705 Template utilis\u00e9 pour', droppableId);\r\n        adSpaceElement.replaceWith(newElement);\r\n        \/\/ \u2705 v2.4.12 : Effacer data-via-ad-loaded (sinon selectEspaceActif masque .ReserverContainer)\r\n        $droppable.removeAttr('data-via-ad-loaded').removeAttr('data-from-miniature');\r\n        if (window.outerWidth < 1000) {\r\n            newElement.css({'margin-top': '-25px', 'bottom': '0px'});\r\n        }\r\n    }\r\n    \r\n    \/\/ D\u00e9cocher la case Envoi diff\u00e9r\u00e9 si elle existe\r\n    newElement.find('input[name*=\"EnvoiUlterieur\"]').prop('checked', false);\r\n    \r\n    \/\/ \u2705 D\u00e9cocher la checkbox \"R\u00e9server\"\r\n    newElement.find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').prop('checked', false);\r\n    \r\n    \/\/ Reset l'\u00e9tat EnvoiUlterieur\r\n    StateManager.set('EnvoiUlterieur', 'false');\r\n    \r\n    \/\/ \u2705 v1.19.3 : R\u00e9initialiser TOUS les styles inline des conteneurs parents modifi\u00e9s pendant le d\u00e9p\u00f4t\r\n    if ($droppable.length) {\r\n        \/\/ \u2705 v2.0.9 : Restaurer les marges de l'algorithme de positionnement (sauvegard\u00e9es par styleUploadedAd)\r\n        var origMt = $droppable.data('orig-mt');\r\n        $droppable.css({\r\n            'margin-top': (origMt !== undefined) ? origMt + 'px' : '',\r\n            'margin-bottom': '',\r\n            'margin-left': '',\r\n            'margin-right': ''\r\n        });\r\n        \/\/ \u2705 v2.0.11 : Cleanup event namespace docpreview\r\n        $droppable.off('click.docpreview');\r\n        \r\n        \/\/ Reset .OrdiMobileConteneurClass margins\r\n        var $container = $droppable.find('.OrdiMobileConteneurClass');\r\n        var origMb = $container.data('orig-mb');\r\n        $container.css({\r\n            'margin-top': '',\r\n            'margin-bottom': (origMb !== undefined) ? origMb + 'px' : ''\r\n        });\r\n        \r\n        \/\/ Reset .HTMLUploadfileConteneur (set by styleUploadedAd: box-shadow inset, background-color:white)\r\n        $droppable.find('.HTMLUploadfileConteneur').css({\r\n            'border': '',\r\n            'box-shadow': '',\r\n            'outline': '',\r\n            'outline-offset': '',\r\n            'background-color': '',\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'min-height': '',\r\n            'overflow': '',\r\n            'padding': '',\r\n            'position': ''\r\n        });\r\n        $droppable.find('.via-green-border-overlay').remove();\r\n        \r\n        \/\/ \u2705 Restaurer pointer-events sur OrdiMobileConteneurClass et ses enfants\r\n        $droppable.find('.OrdiMobileConteneurClass').css('pointer-events', '');\r\n        $droppable.find('#CroixResetAnnonce').css({'pointer-events': '', 'position': '', 'z-index': ''});\r\n        \/\/ \u2705 v2.4.5 : Reset margin-right Ele0A (pos\u00e9 par adjustMobileLayout)\r\n        var _croixContReset = $droppable.find('.CroixResetAnnonceContainer')[0];\r\n        if (_croixContReset) { _croixContReset.style.removeProperty('margin-right'); _croixContReset.style.removeProperty('margin-top'); }\r\n        $droppable.find('#PopUpMessageAchattest').css('pointer-events', '');\r\n        \r\n        \/\/ \u2705 v2.0.9 : Restaurer le scale(1.4) sur .UploadFileConteneur (r\u00e9duit \u00e0 scale(1) par styleUploadedAd sur mobile)\r\n        $droppable.find('.UploadFileConteneur').css({\r\n            'transform': '',\r\n            'transform-origin': ''\r\n        });\r\n        \r\n        \/\/ Reset #UploadFileConteneur - Restaurer le fond bleu #9FC5F3 + retirer liser\u00e9 envoi diff\u00e9r\u00e9\r\n        $droppable.find('#UploadFileConteneur').css({\r\n            'width': '',\r\n            'background-color': '#9FC5F3',\r\n            'border': '',\r\n            'box-sizing': ''\r\n        });\r\n        \r\n        \/\/ Reset .ToBeHidden (set by adjustDesktopLayout: top:105px, min-height:300px + overflow mobile)\r\n        $droppable.closest('.ToBeHidden').css({\r\n            'top': '',\r\n            'min-height': '',\r\n            'overflow': ''\r\n        });\r\n        \r\n        \/\/ Reset overflow sur le parent du droppable (set by adjustDesktopLayout)\r\n        $droppable.parent().css('overflow', '');\r\n        \r\n        \/\/ \u2705 v1.19.5 : Gestion device-specific pour les textes\r\n        var isDesktop = window.outerWidth >= 1000;\r\n        \r\n        if (isDesktop) {\r\n            \/\/ Desktop : cacher les textes mobiles, afficher UploadIci\r\n            $droppable.find('.TexteMobile').hide();\r\n            $droppable.find('.TexteMobileAnnonce').hide();\r\n            $droppable.find('.TexteMobileAjoutAnnonce').hide();\r\n            $droppable.find('.UploadIci').show();\r\n        } else {\r\n            \/\/ Mobile : afficher TexteMobileAnnonce\r\n            $droppable.find('.TexteMobileAnnonce').show();\r\n        }\r\n        \r\n        \/\/ R\u00e9-afficher les \u00e9l\u00e9ments masqu\u00e9s pendant l'upload\r\n        $droppable.find('.PositionEspacePublicitaireContainer').show();\r\n        $droppable.find('.ChoisirEspacePublicitaireDisponibiliteConteneur').show();\r\n        $droppable.find('.PositionEspacePublicitaire, .ReferenceEspacePublicitaire, .ChoisirEspacePublicitaireDisponibiliteConteneur > div > .elementor-widget-text-editor').show();\r\n        $droppable.find('.AdDroppedTextNotDisplayed').hide();\r\n        \/\/ \u2705 v2.4.5 : Ele0A + PopUpChoice=Yes \u2192 ne pas r\u00e9-afficher le titre si format d\u00e9j\u00e0 s\u00e9lectionn\u00e9\r\n        var _skipTitre = (sessionStorage.getItem('PopUpChoice') === 'Yes' && $droppable.attr('id') === 'Ele0A');\r\n        $droppable.find('.SelectionFormatTitreBlanc').hide();\r\n        if (!_skipTitre) {\r\n            $droppable.find('.SelectionFormatTitre').show();\r\n        }\r\n        $droppable.find('span.ClassHdpCdp, .ClassRefEsp').show();\r\n        $droppable.find('.EspPubFormatMainContainer').show();\r\n        $droppable.find('.EspPubFormatListe').show();\r\n        $droppable.find('.ChoisirEspacePublicitaireClass').show();\r\n        $droppable.find('.GlisserDeposerConteneur').show();\r\n        $droppable.find('.OUClass').show();\r\n        $droppable.find('.PositionReference').show();\r\n        $droppable.find('.ClassHdpCdp').show();\r\n        $droppable.find('.ClassRefEsp').show();\r\n        $droppable.find('.EnvoiUlterieurTexte').show();\r\n        $droppable.find('.EnvoiUlterieurContainer').show();\r\n        \r\n        \/\/ \u2705 v1.19.5 : R\u00e9afficher le .ReserverContainer (bouton Elementor statique)\r\n        $droppable.find('.ReserverContainer').show();\r\n        newElement.find('.ReserverContainer').show();\r\n        \r\n        \/\/ Masquer les \u00e9l\u00e9ments sp\u00e9cifiques \u00e0 l'annonce upload\u00e9e\r\n        $droppable.find('.AdUploadedTitle, #CroixResetAnnonce, .CroixResetAnnonceContainer, .DeplaceAnnonce').hide();\r\n        $droppable.find('#CroixResetAnnonce').css({'position': '', 'z-index': ''});\r\n        $droppable.find('.RefEspacePublicitaire').hide();\r\n        \r\n        \/\/ Supprimer le bouton \"R\u00e9server\" dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ \u2705 v1.19.6 : Restaurer le format s\u00e9lectionn\u00e9 visuellement\r\n        \/\/ Chercher le format dans plusieurs sources possibles\r\n        var formatSelect = sessionStorage.getItem('FormatSelect') \r\n            || sessionStorage.getItem('Commande_Format_Transmis')\r\n            || $droppable.data('kitFormatSelect')\r\n            || '';\r\n        \r\n        var formatchoisi = sessionStorage.getItem('Formatchoisi');\r\n        console.log('\ud83d\udcd0 Format \u00e0 restaurer:', formatSelect, '| Formatchoisi:', formatchoisi);\r\n        \r\n        \/\/ D'abord reset tous les formats visuellement (sur newElement ET $droppable)\r\n        var $allFormats = newElement.find('.EspPubFormatContainer').add($droppable.find('.EspPubFormatContainer'));\r\n        $allFormats.css({\r\n            'background-color': '',\r\n            'border': ''\r\n        });\r\n        newElement.find('.EspPubFormat').add($droppable.find('.EspPubFormat')).css({\r\n            'color': ''\r\n        });\r\n        \r\n        \/\/ Si un format \u00e9tait s\u00e9lectionn\u00e9 (via sessionStorage OU visuellement avant)\r\n        \/\/ \u2705 v2.1.1 : Sauf popup\r\n        if ((formatSelect || formatchoisi === 'Yes') && sessionStorage.getItem('PopUpChoice') !== 'Yes') {\r\n            var formatFound = false;\r\n            \r\n            if (formatSelect) {\r\n                \/\/ \u2705 v2.1.1 : Normaliser via NFD (plus fiable que les replace manuels)\r\n                var formatLower = formatSelect.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase().replace(\/ \/g, '');\r\n                \r\n                \/\/ Appliquer sur newElement ET $droppable pour \u00eatre s\u00fbr\r\n                var $allContainers = newElement.find('.EspPubFormatContainer').add($droppable.find('.EspPubFormatContainer'));\r\n                \r\n                $allContainers.each(function() {\r\n                    var className = this.className.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    \r\n                    if (className.includes(formatLower)) {\r\n                        jQuery(this).css({'background-color': '#ffffff'});\r\n                        jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                        formatFound = true;\r\n                        \/\/ \u2705 v2.4.12 : M\u00e9moriser le format restaur\u00e9 (lu par selectEspaceActif pour re-surligner apr\u00e8s reset global)\r\n                        $droppable.attr('data-restored-format', formatSelect);\r\n                        console.log('\u2705 Format restaur\u00e9 visuellement:', formatSelect, '- classe:', this.className);\r\n                    }\r\n                });\r\n            }\r\n            \r\n            \/\/ \u2705 IMPORTANT : Pr\u00e9server Formatchoisi = Yes pour permettre l'upload\r\n            sessionStorage.setItem('Formatchoisi', 'Yes');\r\n            console.log('\u2705 Formatchoisi maintenu \u00e0 Yes');\r\n            \r\n            \/\/ Basculer les titres format (sur newElement ET $droppable)\r\n            newElement.find('.SelectionFormatTitre').hide();\r\n            newElement.find('.SelectionFormatTitreBlanc').show();\r\n            $droppable.find('.SelectionFormatTitre').hide();\r\n            $droppable.find('.SelectionFormatTitreBlanc').show();\r\n        }\r\n    }\r\n    \r\n    \/\/ \u2705 v1.19.2 : Relancer InitLoadedPage pour recalculer positions et tailles\r\n    setTimeout(function() {\r\n        if (typeof window.InitLoadedPage === 'function') {\r\n            window.InitLoadedPage();\r\n        }\r\n        \r\n        \/\/ \u2705 v1.19.6 : R\u00e9attacher les MutationObservers sur les formats\r\n        if (typeof FormatUIManager !== 'undefined' && FormatUIManager.observeFormatChanges) {\r\n            FormatUIManager.observeFormatChanges();\r\n        }\r\n    }, 100);\r\n    \r\n    console.log('\u2705 Espace publicitaire r\u00e9initialis\u00e9');\r\n    return true;\r\n}\r\n\r\n\/\/ \u2705 Exposer pour appel depuis yearbook-media.js (suppression popup mode=popup)\r\nwindow.RestoreadSpaceTemplateLocal = RestoreadSpaceTemplateLocal;\r\n\r\nwindow.verifierAffichageMsgSelectEspaceLocal = function() {\r\n    const formatChoisi = StateManager.get('Formatchoisi') === 'Yes';\r\n    const fileReceived = StateManager.get('FileReceived');\r\n    const envoiUlterieur = StateManager.get('EnvoiUlterieur');\r\n    \r\n    var dateDebut, dateFin, pays;\r\n    try {\r\n        dateDebut = window.parent.$('#form-field-DebutCampagne').val();\r\n        dateFin = window.parent.$('#form-field-FinCampagne').val();\r\n        pays = window.parent.$('#form-field-Nationalite_Societe').val();\r\n    } catch(e) {\r\n        jQuery('#MsgSelectEspace').hide();\r\n        return;\r\n    }\r\n    \r\n    if (!dateDebut || !dateFin || !pays || !formatChoisi) {\r\n        jQuery('#MsgSelectEspace').hide();\r\n        return;\r\n    }\r\n    \r\n    if (fileReceived !== 'Yes') {\r\n        if (envoiUlterieur !== 'true') {\r\n            jQuery('#MsgSelectEspace').show();\r\n        } else {\r\n            jQuery('#MsgSelectEspace').hide();\r\n        }\r\n    } else {\r\n        jQuery('#MsgSelectEspace').hide();\r\n    }\r\n};\r\n\r\n\/\/ Sauvegarder les templates au chargement (apr\u00e8s rendu complet Elementor)\r\njQuery(document).ready(function() {\r\n    \/\/ \u2705 v1.19.3 : D\u00e9lai augment\u00e9 + double sauvegarde pour garantir les bonnes dimensions\r\n    setTimeout(saveAdSpaceTemplateLocal, 3000);\r\n    setTimeout(saveAdSpaceTemplateLocal, 6000);\r\n    \/\/ \u2705 v2.3.4 : Sauvegarde imm\u00e9diate d\u00e8s que la page est pr\u00eate dans l'iframe\r\n    \/\/ (avant toute interaction utilisateur)\r\n    setTimeout(saveAdSpaceTemplateLocal, 100);\r\n    setTimeout(saveAdSpaceTemplateLocal, 500);\r\n});\r\n\r\n\/\/ \u2705 v2.3.4 : Forcer sauvegarde \u00e0 la r\u00e9ception de elementsRemoved (espaces visibles + vierges)\r\nwindow.addEventListener('message', function(e) {\r\n    if (e.data && e.data.type === 'elementsRemoved') {\r\n        \/\/ Les espaces sont vierges \u00e0 ce stade \u2192 sauvegarder imm\u00e9diatement\r\n        setTimeout(saveAdSpaceTemplateLocal, 50);\r\n        setTimeout(saveAdSpaceTemplateLocal, 300);\r\n    }\r\n});\r\n\r\n\/**\r\n * Fonction helper pour le d\u00e9p\u00f4t r\u00e9dactionnel\r\n *\/\r\nfunction RedactionnelDepose() {\r\n    jQuery('#Tariftobedisplayed').html('-');\r\n    jQuery('#TarifDataStep3').html('\u00e0 choisir').css({'color': '#FB5E2A'});\r\n    jQuery('#FormatDataStep3').html('\u00e0 choisir').css({'color': '#FB5E2A'});\r\n    jQuery('#ListePaysDirect, #ListeThemeDirect, .ListeArticles, #PageAfficheeMessage').hide();\r\n    StateManager.set(\"PositionAnnonceSelection\", 'Yes');\r\n}\r\n\r\n\/**\r\n * Exposition des fonctions globales n\u00e9cessaires\r\n *\/\r\nwindow.uploadFile_achat = (e) => DropHandler.handleDrop(e);\r\nwindow.fileExplorer_achat = (e) => FileExplorer.open(e);\r\nwindow.ajaxFileUpload_achat = (fileObj, dropZone) => UploadManager.handleFileUpload(fileObj, dropZone);\r\nwindow.ActivatesendDataToParent = (dropZone) => UploadManager.activateSendDataToParent(dropZone);\r\n\/\/ \u2705 v2.3.4 : Exposer FormatUIManager pour appel depuis Entete.txt (selectEspaceActif)\r\nwindow.FormatUIManagerRef = FormatUIManager;\r\n\r\n\/**\r\n * Initialisation de l'application\r\n *\/\r\njQuery(document).ready(() => {\r\n    StateManager.init();\r\n    ScrollHelper.init();\r\n    DragDropManager.init();\r\n    FormatUIManager.init();\r\n    \r\n    if (UIManager.isMobile()) {\r\n        UIManager.initMobileUI();\r\n    } else {\r\n        UIManager.initDesktopUI();\r\n    }\r\n    \r\n    jQuery(document).on('click', '#CroixResetAnnonce', (e) => AdResetHandler.handle(e));\r\n    \r\n    \/\/ \u2705 Clic sur le texte du label \u2192 toggle manuel de la checkbox du m\u00eame conteneur\r\n    jQuery(document).on('click', '.reserver-dynamic-label', function(e) {\r\n        e.preventDefault();\r\n        e.stopPropagation();\r\n        const $cb = $(this).closest('.reserver-dynamic-option, .reserver-dynamic-container').find('.reserver-dynamic-checkbox');\r\n        if ($cb.length) {\r\n            $cb.prop('checked', !$cb.prop('checked')).trigger('change');\r\n        }\r\n    });\r\n\r\n    \/\/ \u2705 CHECKBOX \"R\u00e9server cet espace publicitaire\" \u2014 VALIDATION ET ENVOI DES DONN\u00c9ES\r\n    \/\/ \u2705 v2.4.13 : iOS touchend\r\n    \/\/ \u2705 v2.4.13 : Mobile \u2014 \u00e9couter touchend sur input ET click\/touchend sur label\r\n    jQuery(document).on('touchend', 'input[name=\"form_fields[ReserverEspacePublicitaire]\"]', function() {\r\n        if (this._viaResTouch) { return; }\r\n        this._viaResTouch = true;\r\n        var _self = this;\r\n        setTimeout(function() { _self._viaResTouch = false; }, 500);\r\n        setTimeout(function() { jQuery(_self).trigger('change'); }, 100);\r\n    });\r\n    jQuery(document).on('touchend click', '.elementor-field-group-ReserverEspacePublicitaire label, .reserver-dynamic-label, .reserver-dynamic-option label', function(e) {\r\n        \/\/ Trouver l'input associ\u00e9\r\n        var $input = jQuery(this).closest('.elementor-field-option, .reserver-dynamic-option').find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]');\r\n        if (!$input.length) { $input = jQuery(this).siblings('input[name=\"form_fields[ReserverEspacePublicitaire]\"]'); }\r\n        if (!$input.length) { $input = jQuery('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').first(); }\r\n        if ($input.length) {\r\n            if (e.type === 'touchend') { e.preventDefault(); }\r\n            var _wasChecked = $input.prop('checked');\r\n            $input.prop('checked', !_wasChecked);\r\n            setTimeout(function() {\r\n                $input.trigger('change');\r\n            }, 50);\r\n        }\r\n    });\r\n    jQuery(document).on('change', 'input[name=\"form_fields[ReserverEspacePublicitaire]\"]', function(e) {\r\n        const $checkbox = $(this);\r\n        let $droppable = $checkbox.closest('.droppable');\r\n        if (!$droppable.length) {\r\n            $droppable = $checkbox.closest('.reserver-dynamic-container').prev('.droppable');\r\n        }\r\n        \/\/ \u2705 v2.4.13 : Fallback mobile \u2014 checkbox dans body > .reserver-dynamic-container[data-droppable-id]\r\n        if (!$droppable.length) {\r\n            const $dynContainer = $checkbox.closest('.reserver-dynamic-container');\r\n            const _droppableId = $dynContainer.attr('data-droppable-id') || '';\r\n            if (_droppableId) {\r\n                $droppable = $('#' + _droppableId);\r\n            }\r\n        }\r\n        \/\/ Dernier recours : utiliser le rank en sessionStorage\r\n        if (!$droppable.length) {\r\n            const _rankFallback = StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            if (_rankFallback) { $droppable = $('#' + _rankFallback); }\r\n        }\r\n        \r\n        \/\/ Si on d\u00e9coche\r\n        if (!$checkbox.is(':checked')) {\r\n            console.log('\u2610 Checkbox \"R\u00e9server\" d\u00e9coch\u00e9e');\r\n            \/\/ \u2705 Mettre \u00e0 jour le label\r\n            const $lbl = $checkbox.closest('.reserver-dynamic-option, .elementor-field-option').find('.reserver-dynamic-label, label').not('input');\r\n            $lbl.text('R\u00e9server cet espace publicitaire').css('color', '');\r\n            \/\/ \u2705 Notifier le parent pour d\u00e9-r\u00e9server l'item dans le r\u00e9cap\r\n            const _rankDecoche = $droppable.attr('id') || StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            const _emplacementDecoche = StateManager.buildEmplacementReference(_rankDecoche);\r\n            MessageManager.sendToParent('annulationReservation', {\r\n                Rank_Emplacement_Page_Web: _rankDecoche,\r\n                Commande_Emplacement_Page_Web: _emplacementDecoche,\r\n                LoadedPageUrl: window.location.href\r\n            });\r\n            \/\/ \u2705 v2.4.5 : M\u00e9moriser que ce rank a \u00e9t\u00e9 explicitement d\u00e9coch\u00e9\r\n            StateManager.set('_reserverDecoche_' + _rankDecoche, 'Yes');\r\n            console.log('\ud83d\udce4 annulationReservation envoy\u00e9 \u2192 parent | rank:', _rankDecoche, '| emplacement:', _emplacementDecoche);\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 V\u00e9rifier les conditions : format s\u00e9lectionn\u00e9 ET (fichier d\u00e9pos\u00e9 OU envoi diff\u00e9r\u00e9)\r\n        const hasFormat = FormatUIManager.hasSelectedFormat($droppable);\r\n        const hasFile = StateManager.get('FileReceived') === 'Yes';\r\n        const hasEnvoiDiffere = $droppable.find('input[name*=\"EnvoiUlterieur\"]:checked').length > 0;\r\n        \r\n        console.log('\ud83d\udd0d Checkbox \"R\u00e9server\" - Validation:', { hasFormat, hasFile, hasEnvoiDiffere });\r\n        \r\n        if (!hasFormat) {\r\n            \/\/ \u2705 Si un fichier est d\u00e9j\u00e0 d\u00e9pos\u00e9 \u2192 d\u00e9duire le format depuis l'extension (ne pas bloquer)\r\n            if (hasFile) {\r\n                const _uploadedName = StateManager.get('Upload_File_Name') || '';\r\n                const _ext = _uploadedName.split('.').pop().toLowerCase();\r\n                const _fileType = FileManager.getFileType(_ext);\r\n                let _deducedFormat = '';\r\n                if (_fileType === 'video') {\r\n                    _deducedFormat = sessionStorage.getItem('SiteLangue') === 'EN' ? 'Video' : 'Vid\u00e9o';\r\n                } else if (_fileType === 'image') {\r\n                    _deducedFormat = sessionStorage.getItem('SiteLangue') === 'EN' ? 'Banner' : 'Banni\u00e8re';\r\n                } else if (_fileType === 'document') {\r\n                    _deducedFormat = sessionStorage.getItem('SiteLangue') === 'EN' ? 'Press release' : 'Communiqu\u00e9';\r\n                }\r\n                if (_deducedFormat) {\r\n                    StateManager.set('Commande_Format_Transmis', _deducedFormat);\r\n                    StateManager.set('FormatSelect', _deducedFormat);\r\n                    StateManager.set('Formatchoisi', 'Yes');\r\n                    console.log('\u2705 Format d\u00e9duit depuis extension (' + _ext + '):', _deducedFormat);\r\n                    \/\/ Continuer vers l'envoi (pas de return false)\r\n                } else {\r\n                    e.preventDefault();\r\n                    $checkbox.prop('checked', false);\r\n                    FormatUIManager.flashTitle($droppable);\r\n                    console.log('\u274c R\u00e9servation bloqu\u00e9e : format non d\u00e9ductible depuis extension:', _ext);\r\n                    return false;\r\n                }\r\n            } else {\r\n                e.preventDefault();\r\n                $checkbox.prop('checked', false);\r\n                FormatUIManager.flashTitle($droppable);\r\n                console.log('\u274c R\u00e9servation bloqu\u00e9e : aucun format s\u00e9lectionn\u00e9');\r\n                return false;\r\n            }\r\n        }\r\n        \r\n        if (!hasFile && !hasEnvoiDiffere) {\r\n            e.preventDefault();\r\n            $checkbox.prop('checked', false);\r\n            console.log('\u274c R\u00e9servation bloqu\u00e9e : ni annonce d\u00e9pos\u00e9e ni envoi diff\u00e9r\u00e9');\r\n            return false;\r\n        }\r\n        \r\n        \/\/ \u2705 Conditions remplies \u2014 Pr\u00e9parer et envoyer les donn\u00e9es\r\n        console.log('\u2705 Checkbox \"R\u00e9server\" valid\u00e9e \u2014 envoi des donn\u00e9es');\r\n        \r\n        const rankId = $droppable.attr('id');\r\n        \r\n        StateManager.setMultiple({\r\n            \"sendDataToParentFlag\": \"Yes\",\r\n            \"Formatchoisi\": \"Yes\",\r\n            \"Rank_Emplacement_Page_Web\": rankId,\r\n            \"Commande_Emplacement_Page_Web\": StateManager.buildEmplacementReference(rankId),\r\n            \"LoadedPageUrl\": window.location.href,\r\n            \/\/ \u2705 v2.3.0 : Forcer avant l'envoi \u2014 le setTimeout(4000) dans activateSendDataToParent\r\n            \/\/ arrive trop tard sur le 1er clic \u2192 AddNewRefInVosCampagnes restait null\r\n            \"AddNewRefInVosCampagnes\": \"Yes\"\r\n        });\r\n        \r\n        \/\/ \u2705 D\u00e9clencher l'envoi des donn\u00e9es via activateSendDataToParent\r\n        const $dropZone = $droppable.find('#drop_file_zone_achat');\r\n        UploadManager.activateSendDataToParent($dropZone);\r\n    });\r\n    \r\n    \/\/ G\u00c9RER \"Envoi diff\u00e9r\u00e9\" \u2014 marquer l'\u00e9tat sans envoyer (c'est \"R\u00e9server\" qui envoie)\r\n    \/\/ \u2705 v2.4.13 : iOS touchend\r\n    jQuery(document).on('touchend', 'input[name*=\"EnvoiUlterieur\"]', function() {\r\n        if (this._viaTouch) { return; }\r\n        this._viaTouch = true;\r\n        var _self = this;\r\n        setTimeout(function() { _self._viaTouch = false; }, 500);\r\n        setTimeout(function() { jQuery(_self).trigger('change'); }, 100);\r\n    });\r\n    jQuery(document).on('change', 'input[name*=\"EnvoiUlterieur\"]', function(e) {\r\n        const $checkbox = $(this);\r\n        let $droppable = $checkbox.closest('.droppable');\r\n        \/\/ \u2705 v2.4.13 : Fallback mobile\r\n        if (!$droppable.length) {\r\n            const $dynContainer = $checkbox.closest('.reserver-dynamic-container');\r\n            const _droppableId = $dynContainer.attr('data-droppable-id') || '';\r\n            if (_droppableId) { $droppable = $('#' + _droppableId); }\r\n        }\r\n        if (!$droppable.length) {\r\n            const _rankFallback = StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            if (_rankFallback) { $droppable = $('#' + _rankFallback); }\r\n        }\r\n  \r\n        \/\/ Si on d\u00e9coche\r\n        if (!$checkbox.is(':checked')) {\r\n            StateManager.set('EnvoiUlterieur', 'false');\r\n            \r\n            if (typeof window.verifierAffichageMsgSelectEspaceLocal === 'function') {\r\n                window.verifierAffichageMsgSelectEspaceLocal();\r\n            }\r\n            \r\n            \/\/ Mettre \u00e0 jour l'\u00e9tat de la checkbox R\u00e9server\r\n            FormatUIManager.updateReserverCheckboxState($droppable);\r\n            return;\r\n        }\r\n        \r\n        \/\/ Si on coche, masquer le message\r\n        jQuery('#MsgSelectEspace').hide();\r\n    \r\n        \/\/ V\u00e9rifier si un format est s\u00e9lectionn\u00e9\r\n        const hasSelectedFormat = FormatUIManager.hasSelectedFormat($droppable);\r\n        \r\n        if (!hasSelectedFormat) {\r\n            e.preventDefault();\r\n            $checkbox.prop('checked', false);\r\n            FormatUIManager.flashTitle($droppable);\r\n            return false;\r\n        }\r\n        \r\n        \/\/ \u2705 FORMAT OK \u2014 Marquer l'\u00e9tat envoi diff\u00e9r\u00e9 (sans envoyer les donn\u00e9es)\r\n        const rankId = $droppable.attr('id');\r\n        \r\n        StateManager.setMultiple({\r\n            \"EnvoiUlterieur\": 'true',\r\n            \"Rank_Emplacement_Page_Web\": rankId,\r\n            \"Commande_Emplacement_Page_Web\": StateManager.buildEmplacementReference(rankId),\r\n            \"LoadedPageUrl\": window.location.href,\r\n            \"FileReceived\": \"No\",\r\n            \"FullPathAdFile\": '',\r\n            \"Upload_File_Name\": '',\r\n            \"Formatchoisi\": 'Yes'\r\n        });\r\n        \r\n        console.log('\ud83d\udcdd Envoi diff\u00e9r\u00e9 coch\u00e9 \u2014 en attente de validation via checkbox \"R\u00e9server\"');\r\n        \r\n        \/\/ \u2705 Mettre \u00e0 jour l'\u00e9tat de la checkbox R\u00e9server (maintenant activable)\r\n        FormatUIManager.updateReserverCheckboxState($droppable);\r\n    });\r\n\r\n    \/\/ \u2705 v2.2.0 : Bouton \"Cr\u00e9ation\" dans espace publicitaire \u2192 Kit Ad Creator dans le parent\r\n    jQuery(document).on('click', '.FormatIdCreation', function(e) {\r\n        e.preventDefault();\r\n        var $btn = jQuery(this);\r\n        var isActive = $btn.data('creationActive') === true;\r\n\r\n        if (isActive) {\r\n            \/\/ D\u00e9sactiver\r\n            $btn.data('creationActive', false);\r\n            $btn.find('.EspPubFormat').css({'color': '#ffffff'});\r\n            $btn.css({'background-color': 'transparent'});\r\n            MessageManager.sendToParent('closeAdCreatorFromIframe', {});\r\n            console.log('\ud83c\udfa8 Cr\u00e9ation iframe \u2192 toggle OFF, fermeture popup parent');\r\n        } else {\r\n            \/\/ Activer : texte vert sur fond blanc\r\n            $btn.data('creationActive', true);\r\n            $btn.find('.EspPubFormat').css({'color': '#37D900'});\r\n            $btn.css({'background-color': '#ffffff'});\r\n            var formatSelect = sessionStorage.getItem('FormatSelect') || '';\r\n            var formatTransmis = sessionStorage.getItem('Commande_Format_Transmis') || '';\r\n            \/\/ \u2705 v2.2.1 : Envoyer aussi Commande_Format_Transmis (format cliqu\u00e9 dans l'iframe, sans accent)\r\n            var _rankKit = $btn.closest('.droppable').attr('id') || sessionStorage.getItem('Rank_Emplacement_Page_Web') || '';\r\n            var _cSite = sessionStorage.getItem('codeSite') || '';\r\n            var _cPage = sessionStorage.getItem('codePage') || '';\r\n            var _sfxKit = _rankKit.replace('Ele', '');\r\n            var _emplKit = (_cSite && _cPage && _sfxKit) ? (_cSite + _cPage + 'L' + _sfxKit) : (sessionStorage.getItem('Commande_Emplacement_Page_Web') || '');\r\n            MessageManager.sendToParent('openAdCreatorFromIframe', { formatSelect: formatSelect, formatTransmis: formatTransmis, rankId: _rankKit, emplacement: _emplKit });\r\n            console.log('\ud83c\udfa8 Cr\u00e9ation iframe \u2192 toggle ON (FormatSelect:', formatSelect, '| Commande_Format_Transmis:', formatTransmis, ')');\r\n        }\r\n    });\r\n\r\n    \/\/ \u2705 v2.2.0 : Messages depuis le parent concernant le bouton Cr\u00e9ation\r\n    window.addEventListener('message', function(event) {\r\n        var msg = event.data;\r\n        if (!msg) return;\r\n\r\n        \/\/ \u2705 v2.2.1 : Fournir la position du titre R\u00e9server pour positionner la miniature\r\n        if (msg.type === 'getReserverLabelRect') {\r\n            var $label = jQuery('.reserver-dynamic-label').first();\r\n            if ($label.length) {\r\n                var r = $label[0].getBoundingClientRect();\r\n                var iframeScale = (window.outerWidth > 1000) ? 0.75 : 0.80; \/\/ \u2705 v2.4.12 : 0.85 \u2192 0.75 (scale r\u00e9el du parent)\r\n                event.source.postMessage({\r\n                    type: 'reserVeurLabelRectResult',\r\n                    \/\/ Retourner bottom en coordonn\u00e9es iframe internes (non scal\u00e9es)\r\n                    bottom: r.bottom,\r\n                    left: r.left,\r\n                    right: r.right,\r\n                    iframeScale: iframeScale\r\n                }, '*');\r\n            } else {\r\n                event.source.postMessage({ type: 'reserVeurLabelRectResult', bottom: null }, '*');\r\n            }\r\n        }\r\n\r\n        \/\/ Fermeture du popup \u2192 d\u00e9s\u00e9lectionner le bouton Cr\u00e9ation\r\n        if (msg.type === 'adCreatorClosedFromParent') {\r\n            jQuery('.FormatIdCreation').each(function() {\r\n                jQuery(this).data('creationActive', false);\r\n                jQuery(this).find('.EspPubFormat').css({'color': '#ffffff'});\r\n                jQuery(this).css({'background-color': 'transparent'});\r\n            });\r\n            console.log('\ud83c\udfa8 adCreatorClosedFromParent re\u00e7u \u2192 bouton Cr\u00e9ation d\u00e9s\u00e9lectionn\u00e9');\r\n        }\r\n\r\n        \/\/ Restaurer le style du bouton Cr\u00e9ation apr\u00e8s un reset de removeElements\r\n        if (msg.type === 'restoreCreationButton') {\r\n            jQuery('.FormatIdCreation').each(function() {\r\n                if (jQuery(this).data('creationActive') === true) {\r\n                    jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                    jQuery(this).css({'background-color': '#ffffff'});\r\n                }\r\n            });\r\n            console.log('\ud83c\udfa8 restoreCreationButton re\u00e7u \u2192 style Cr\u00e9ation restaur\u00e9');\r\n        }\r\n    });\r\n\r\n});\r\n\r\n\/\/ =========================================================================\r\n\/\/ \u2705 Listener kitAdCreated \u2014 annonce cr\u00e9\u00e9e par le Kit overlay (mode=kit)\r\n\/\/ Injecte directement dans l'espace pub identifi\u00e9 par rankId\r\nwindow.addEventListener('message', function(event) {\r\n    var msg = event.data;\r\n    if (!msg || msg.action !== 'kitAdCreated') return;\r\n\r\n    var _rankId = msg.rankId || '';\r\n    var _emplacement = msg.emplacement || '';\r\n    console.log('\ud83c\udfa8 [espace_pub] kitAdCreated re\u00e7u | rankId:', _rankId, '| emplacement:', _emplacement);\r\n\r\n    if (!_rankId) { console.warn('\u26a0\ufe0f [kitAdCreated] rankId manquant'); return; }\r\n\r\n    var $droppable = jQuery('#' + _rankId);\r\n    if (!$droppable.length) { console.warn('\u26a0\ufe0f [kitAdCreated] droppable non trouv\u00e9:', _rankId); return; }\r\n    var $dropZone = $droppable.find('.drop_file_zone_achat_class').first();\r\n    if (!$dropZone.length) { $dropZone = $droppable.find('#drop_file_zone_achat').first(); }\r\n    if (!$dropZone.length) { console.warn('\u26a0\ufe0f [kitAdCreated] dropZone non trouv\u00e9e dans', _rankId); return; }\r\n\r\n    var _dataURL = msg.fullResDataURL || msg.pdfDataURL || null;\r\n    var _filename = msg.filename || 'annonce.png';\r\n    var _isPDF = msg.isPDF || false;\r\n    if (!_dataURL) { console.warn('\u26a0\ufe0f [kitAdCreated] aucune donn\u00e9e image'); return; }\r\n\r\n    var _parts = _dataURL.split(',');\r\n    var _mime = (_parts[0].match(\/:(.*?);\/) || [])[1] || (_isPDF ? 'application\/pdf' : 'image\/png');\r\n    var _bStr = atob(_parts[1]);\r\n    var _bytes = new Uint8Array(_bStr.length);\r\n    for (var _i = 0; _i < _bStr.length; _i++) { _bytes[_i] = _bStr.charCodeAt(_i); }\r\n    var _blob = new Blob([_bytes], { type: _mime });\r\n    \/\/ \u2705 Ajouter extension si absente\r\n    var _MIME_EXT = {'image\/png':'.png','image\/jpeg':'.jpg','image\/jpg':'.jpg','image\/webp':'.webp','application\/pdf':'.pdf'};\r\n    if (_filename.indexOf('.') === -1) { _filename = _filename + (_MIME_EXT[_mime] || (_isPDF ? '.pdf' : '.png')); }\r\n    var _file = new File([_blob], _filename, { type: _mime });\r\n\r\n    \/\/ \u2705 Pr\u00e9parer StateManager\r\n    StateManager.set('Rank_Emplacement_Page_Web', _rankId);\r\n    StateManager.set('Commande_Emplacement_Page_Web', _emplacement);\r\n    StateManager.set('Formatchoisi', 'Yes');\r\n    \/\/ \u2705 Marquer le droppable directement en DOM \u2014 r\u00e9siste \u00e0 l'async, lu par styleUploadedAd\r\n    $droppable[0].setAttribute('data-kit-drop', 'true');\r\n    window._dropFromMiniature = true;\r\n\r\n    console.log('\u2705 [kitAdCreated] \u2192 UploadManager.handleFileUpload | rankId:', _rankId);\r\n    UploadManager.handleFileUpload(_file, $dropZone).then(function() {\r\n        console.log('\u2705 [kitAdCreated] handleFileUpload termin\u00e9');\r\n    }).catch(function(err) {\r\n        window._dropFromMiniature = false;\r\n        $droppable[0].removeAttribute('data-kit-drop');\r\n        console.error('\u274c [kitAdCreated] handleFileUpload erreur:', err);\r\n    });\r\n});\r\n\r\n\/\/ \u2705 v1.17.0 : Listener \"thumbnailDropped\" \u2014 d\u00e9p\u00f4t de l'annonce depuis la miniature\r\n\/\/ =========================================================================\r\n\/**\r\n * Re\u00e7oit le drop de l'image-annonce depuis la miniature dans la page parente.\r\n * Identifie l'espace publicitaire sous le curseur, s\u00e9lectionne cet espace,\r\n * et d\u00e9clenche le flux dataFromIframeEspacePub en mode \"envoi diff\u00e9r\u00e9\"\r\n * (l'utilisateur uploadera le vrai fichier depuis le formulaire de commande).\r\n *\r\n * Coordonn\u00e9es re\u00e7ues : viewport de l'iframe (clientX\/clientY relatifs \u00e0 l'iframe)\r\n *\/\r\nwindow.addEventListener('message', function(event) {\r\n    var msg = event.data;\r\n    if (!msg || msg.action !== 'thumbnailDropped') return;\r\n\r\n    console.log('\ud83d\udce8 thumbnailDropped re\u00e7u \u2014 coords iframe:', msg.xRel, msg.yRel);\r\n\r\n    \/\/ \u2705 v1.19.3 : Corriger les coordonn\u00e9es pour le facteur de scale de l'iframe\r\n    \/\/ \u2705 v2.4.10 : 0.75 = scale appliqu\u00e9 par le PARENT sur l'\u00e9l\u00e9ment iframe (et non 0.85 qui est le scale interne OrdiMobileConteneurClass)\r\n    \/\/ Les coords xRel\/yRel viennent de getBoundingClientRect() sur l'iframe scal\u00e9 \u00e0 0.75 dans le parent \u2192 diviser par 0.75\r\n    var iframeScale = (window.outerWidth > 1000) ? 0.75 : 0.80;\r\n    \/\/ \u2705 v2.4.3 : Si Entete a intercept\u00e9 et pos\u00e9 un redirect vers Ele0A, utiliser ces coords\r\n    var _redirect = window._thumbnailDropRedirect || null;\r\n    window._thumbnailDropRedirect = null;\r\n    \/\/ \u2705 v2.4.4 : Les coords de redirect viennent de getBoundingClientRect() dans l'iframe (espace logique)\r\n    \/\/            \u2192 ne pas re-diviser par iframeScale (d\u00e9j\u00e0 en coords iframe-logiques)\r\n    var xAdjusted = _redirect ? _redirect.xRel : (msg.xRel \/ iframeScale);\r\n    var yAdjusted = _redirect ? _redirect.yRel : (msg.yRel \/ iframeScale);\r\n    if (_redirect) { console.log('\ud83d\udd00 [thumbnailDropped] coords redirig\u00e9es vers Ele0A:', Math.round(xAdjusted), Math.round(yAdjusted)); }\r\n    else { console.log('\ud83d\udcd0 Coords ajust\u00e9es (scale', iframeScale, '):', Math.round(xAdjusted), Math.round(yAdjusted)); }\r\n\r\n    \/\/ 1. Identifier l'espace publicitaire le plus proche du point de drop\r\n    \/\/    \u2705 v1.18.1 : Recherche par distance \u2014 coords \u00e9ventuellement redirig\u00e9es par Entete.txt\r\n    var allDroppables = document.querySelectorAll('.droppable');\r\n    var droppableEl = null;\r\n    var closestDist = Infinity;\r\n\r\n    \/\/ \u2705 v2.4.4 : Guard rect Ele0A \u2014 si PopUpChoice=Yes ET curseur dans le rect d'Ele0A \u2192 forcer\r\n    \/\/            (Ele0A est un popup flottant : son centre peut \u00eatre loin du curseur \u2192 algo distance l'ignore)\r\n    \/\/            Ne force PAS si le drop est hors d'Ele0A \u2192 les autres espaces restent accessibles\r\n    if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n        var _ele0ACheck = document.getElementById('Ele0A');\r\n        if (_ele0ACheck) {\r\n            var _r0A = _ele0ACheck.getBoundingClientRect();\r\n            var _margin = 30;\r\n            var _inR0A = (xAdjusted >= _r0A.left - _margin);\r\n            if (_inR0A) { _inR0A = (xAdjusted <= _r0A.right + _margin); }\r\n            if (_inR0A) { _inR0A = (yAdjusted >= _r0A.top - _margin); }\r\n            if (_inR0A) { _inR0A = (yAdjusted <= _r0A.bottom + _margin); }\r\n            if (_inR0A) {\r\n                droppableEl = _ele0ACheck;\r\n                closestDist = 0;\r\n                console.log('\ud83c\udfaf [thumbnailDropped] Ele0A forc\u00e9 (curseur dans rect Ele0A +30px)');\r\n            }\r\n        }\r\n    }\r\n\r\n    if (!droppableEl) {\r\n        allDroppables.forEach(function(d) {\r\n            var r = d.getBoundingClientRect();\r\n            var dCenterX = r.left + r.width  \/ 2;\r\n            var dCenterY = r.top  + r.height \/ 2;\r\n            var dist = Math.abs(dCenterX - xAdjusted) + Math.abs(dCenterY - yAdjusted);\r\n            if (dist < closestDist) { closestDist = dist; droppableEl = d; }\r\n        });\r\n        \/\/ \u2705 v2.4.3 : Si Entete a d\u00e9tect\u00e9 un drop sur Ele0A \u2192 forcer directement\r\n        if (_redirect) { if (_redirect.forceEle0A) {\r\n            var _ele0AForced = document.getElementById('Ele0A');\r\n            if (_ele0AForced) { droppableEl = _ele0AForced; console.log('\ud83c\udfaf [thumbnailDropped] Ele0A forc\u00e9 (redirect Entete)'); }\r\n        } }\r\n    }\r\n\r\n    if (!droppableEl || closestDist > 800) {\r\n        console.warn('thumbnailDropped \u2014 aucun droppable proche (dist min:', closestDist, ')');\r\n        return;\r\n    }\r\n    console.log('\ud83d\udccd Droppable trouv\u00e9:', droppableEl.id, '(dist:', Math.round(closestDist), ')');\r\n\r\n    var $droppable = jQuery(droppableEl);\r\n    var rankId = $droppable.attr('id');\r\n    if (!rankId) { console.warn('thumbnailDropped \u2014 .droppable sans id'); return; }\r\n\r\n    var $dropZone = $droppable.find('#drop_file_zone_achat').first();\r\n    if (!$dropZone.length) { console.warn('thumbnailDropped \u2014 #drop_file_zone_achat introuvable dans', rankId); return; }\r\n\r\n    var emplacementRef = StateManager.buildEmplacementReference(rankId);\r\n    console.log('\u2705 thumbnailDropped \u2014 espace pub:', rankId, '\u2192', emplacementRef);\r\n\r\n    \/\/ 2. Pr\u00e9parer l'\u00e9tat SessionStorage (comme un vrai drop de fichier)\r\n    StateManager.setMultiple({\r\n        'Rank_Emplacement_Page_Web':     rankId,\r\n        'Commande_Emplacement_Page_Web': emplacementRef,\r\n        'FirstUploadFileorMoved':        'FirstUpload',\r\n        'Formatchoisi':                  'Yes',\r\n        'Commande_Format_Transmis':      'Image',\r\n        'EnvoiUlterieur':                'false',\r\n        'FileReceived':                  'No',\r\n        'AdDisplayed':                   'Yes'\r\n    });\r\n\r\n    UIManager.updateEmplacementDisplay();\r\n\r\n    \/\/ 3. Construire le File \u00e0 partir du PDF (communiqu\u00e9\/interview) ou de l'image PNG (autres formats)\r\n    \/\/    puis appeler handleFileUpload \u2192 m\u00eame flux qu'un vrai drag&drop : liser\u00e9 vert, aper\u00e7u, R\u00e9server\r\n    var dataURL, mime, ext;\r\n\r\n    \/\/ \u2705 Stocker le PDF image et le format sur le droppable pour le popup de visualisation inline\r\n    if (msg.pdfImageDataURL) {\r\n        $droppable.data('kitPdfImageDataURL', msg.pdfImageDataURL);\r\n        $droppable.data('kitFormatSelect', msg.FormatSelect || '');\r\n        console.log('\ud83d\udcce pdfImageDataURL stock\u00e9 sur', rankId, '| format:', msg.FormatSelect);\r\n    } else {\r\n        $droppable.removeData('kitPdfImageDataURL');\r\n        $droppable.removeData('kitFormatSelect');\r\n    }\r\n\r\n    if (msg.isPDF && msg.pdfDataURL) {\r\n        \/\/ \u2500\u2500 Format PDF (communiqu\u00e9 \/ interview) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        dataURL = msg.pdfDataURL;                         \/\/ \"data:application\/pdf;base64,\u2026\"\r\n        mime    = 'application\/pdf';\r\n        ext     = '.pdf';\r\n    } else if (msg.imageDataURL) {\r\n        \/\/ \u2500\u2500 Format image (banni\u00e8re \/ parrainage) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        dataURL = msg.imageDataURL;\r\n        var mimeMatch = dataURL.match(\/^data:([^;]+);base64,\/);\r\n        mime    = mimeMatch ? mimeMatch[1] : 'image\/png';\r\n        ext     = mime === 'image\/jpeg' ? '.jpg' : '.png';\r\n    } else {\r\n        console.warn('thumbnailDropped \u2014 aucune donn\u00e9e image\/pdf disponible');\r\n        return;\r\n    }\r\n\r\n    var baseName = msg.filename ? msg.filename.replace(\/\\.[^.]+$\/, '') : 'annonce-kit';\r\n    var fileName = baseName + ext;\r\n\r\n    \/\/ dataURL \u2192 Uint8Array \u2192 Blob \u2192 File\r\n    var b64  = dataURL.split(',')[1];\r\n    var bstr = atob(b64);\r\n    var u8   = new Uint8Array(bstr.length);\r\n    for (var i = 0; i < bstr.length; i++) { u8[i] = bstr.charCodeAt(i); }\r\n    var blob    = new Blob([u8], { type: mime });\r\n    var fileObj = new File([blob], fileName, { type: mime });\r\n\r\n    console.log('thumbnailDropped \u2192 handleFileUpload:', fileName, Math.round(fileObj.size \/ 1024) + 'KB');\r\n\r\n    \/\/ \u2705 Cacher le File pour r\u00e9utilisation lors des d\u00e9placements (\u00e9vite CORS)\r\n    window._lastRedactionnelFile = fileObj;\r\n\r\n    \/\/ \u2705 v2.4.10 : Signaler \u00e0 adjustDesktopLayout que c'est un drop depuis la miniature\r\n    \/\/ \u2192 applique max-height sur HTMLUploadfileConteneur pour \u00e9viter le d\u00e9bordement vertical (homepage corps de page)\r\n    window._dropFromMiniature = true;\r\n    UploadManager.handleFileUpload(fileObj, $dropZone);\r\n\r\n    \/\/ \u2705 v1.19.1 : Positionner l'espace \u00e0 10px du haut du viewport (tous formats)\r\n    \/\/ \u2705 v2.4.13 : Skip si drop depuis miniature \u2014 selectEspaceActif g\u00e8re d\u00e9j\u00e0 le scroll\r\n    if (!window._dropFromMiniature) {\r\n        setTimeout(function() {\r\n            var el = $droppable.find('.HTMLUploadfileConteneur')[0] || $droppable[0];\r\n            if (el) {\r\n                ScrollHelper.scrollElementTo(el, 10);\r\n            }\r\n        }, 400);\r\n    }\r\n});\r\n\r\nconsole.log('This is a ' + (UIManager.isDesktop() ? 'desktop' : 'non-desktop') + ' device.');\r\n\r\n} \/\/ end _espPubScriptLoaded guard\r\n<\/script>\r\n\r\n<style>\r\n\/* Les styles CSS restent inchang\u00e9s *\/\r\n#drop_file_zone_achat {\r\n    background-color: #FFFFFF00;\r\n    color: #225DA9;\r\n    font-weight: 500;\r\n    text-align: center;\r\n    border: #999 0px dashed;\r\n    width: 100%;\r\n    height: 180px;\r\n    font-size: 11.5px;\r\n    display: flex;\r\n    justify-content: center; \r\n    align-items: center; \r\n    flex-wrap: wrap;\r\n}\r\n\r\n#drag_upload_file_achat {\r\n    margin: 0 auto;\r\n    width: 90%;\r\n    height: 60px;\r\n}\r\n\r\n#drag_upload_file_achat p {\r\n    text-align: center;\r\n}\r\n\r\n\/* \u2705 v1.16.0 : Liser\u00e9 noir fin autour du texte \"Ici glisser \u2013 d\u00e9poser\" *\/\r\n.GlisserDeposerConteneur .elementor-widget-container p {\r\n    border: 1px solid #000000;\r\n    border-radius: 4px;\r\n    padding: 4px 10px;\r\n    display: inline-block;\r\n}\r\n\r\n#selectfile_achat {\r\n    display: none;\r\n}\r\n\r\n.button-2_achat, .button-2_achat-after-reset {\r\n    background-color: #ffffff00!important;\r\n    border: 1px solid white!important;\r\n    border-radius: 8px;\r\n    color: #225DA9!important;\r\n    cursor: pointer;\r\n    display: inline-block;\r\n    font-size: 11px;\r\n    font-weight: 500;\r\n    list-style: none;\r\n    width: 390px;\r\n    height: 62px;\r\n    top: 0px!important; \r\n    margin-top: 0px!important; \r\n    padding-left: 5px!important;\r\n    padding-right: 5px!important;\r\n    margin-bottom: 70px!important;\r\n    margin: 0;\r\n    text-align: center;\r\n    transition: all 200ms;\r\n    vertical-align: baseline;\r\n    white-space: wrap!important;\r\n}\r\n\r\n@media only screen and (max-width: 1000px) {\r\n    .button-2_achat, .button-2_achat-after-reset {\r\n        width: 95%;\r\n        height: 50px;\r\n    }\r\n}\r\n\r\n.newMessageClass {\r\n    background-color: #FFFFFF00!important;\r\n    font-size: 13px; \r\n    font-weight: 600;\r\n    color: #56BE50;\r\n    height: 35px;\r\n    width: 550px; \r\n    position: relative;\r\n    z-index: 99;\r\n    top: 45px;\r\n    bottom: 0px;\r\n    right: 0px;\r\n    left: 0px;\r\n    display: flex;\r\n    justify-content: center;\r\n    align-items: center;\r\n    text-align: center;\r\n}\r\n\r\n.MessageClassFormatnonReconnuTitre {\r\n    background-color: #FFFFFF00!important;\r\n    font-size: 13px; \r\n    font-weight: 600;\r\n    color: #FB5E2A;\r\n    height: 35px;\r\n    width: 550px; \r\n    position: relative;\r\n    z-index: 99;\r\n    margin-top: -300px;\r\n    right: 0px;\r\n    text-align: center;\r\n    line-height: 15px;\r\n}\r\n\r\n.MessageClassFormatnonReconnu {\r\n    background-color: #FFFFFF00!important;\r\n    font-size: 13px; \r\n    font-weight: 600;\r\n    color: #ffffff;\r\n    height: 35px;\r\n    width: 550px; \r\n    position: relative;\r\n    z-index: 99;\r\n    margin-top: -280px;\r\n    right: 0px;\r\n    text-align: center;\r\n    line-height: 15px;\r\n}\r\n\r\n.newButtonClass {\r\n    font-size: 12px; \r\n    font-weight: 500;\r\n    background-color: #ffffff00;\r\n    color: #717171;\r\n    height: 10px;\r\n    width: 100%; \r\n    position: relative;\r\n    z-index: 99;\r\n    top: 45px;\r\n    bottom: 0px;\r\n    text-align: center;\r\n    right:  50px;\r\n    line-height: 10px;\r\n    border-radius: 3px;\r\n    border: 0px solid #E8ECF1;\r\n}\r\n\r\n.linkClass {\r\n    width: 15px; \r\n    height: 15px;\r\n    margin-top: -310px;\r\n    margin-bottom: -25px;\r\n    margin-right: -50px;\r\n    position: relative;\r\n    top: 0; \r\n    z-index: 99;\r\n    display: block;\r\n    background-image: url('https:\/\/rdc.via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-blanc.jpg');\r\n    background-size: cover;\r\n}\r\n\r\n.newButtonClassVideo {\r\n    font-size: 12px; \r\n    font-weight: 500;\r\n    background-color: #ffffff00;\r\n    color: #717171;\r\n    height: 10px;\r\n    width: 100%; \r\n    position: relative;\r\n    z-index: 99;\r\n    top: 0px;\r\n    bottom: 0px;\r\n    right: 10px;\r\n    text-align: center;\r\n    line-height: 10px;\r\n    border-radius: 3px;\r\n    border: 0px solid #E8ECF1;\r\n}\r\n\r\n.linkClassVideo {\r\n    width: 15px; \r\n    height: 15px;\r\n    margin-top: -438px;\r\n    margin-bottom: -25px;\r\n    margin-right: -15px;\r\n    position: relative;\r\n    top: 0; \r\n    z-index: 99;\r\n    display: block;\r\n    background-image: url('https:\/\/rdc.via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-blanc.jpg');\r\n    background-size: cover;\r\n}\r\n\r\n.FinCampagneMobileClass .elementor-button,\r\n.DebutCampagneMobileClass .elementor-button,\r\n.FormSelectDevisesMobile .elementor-button,\r\n.HideFormButton .elementor-button {\r\n    display: none !important;\r\n}\r\n\r\n#drag_upload_file_achat {\r\n    margin: 0;\r\n    padding: 0;\r\n    position: relative;\r\n}\r\n\r\n.dot-container {\r\n    display: inline-block;\r\n}\r\n\r\n.dot {\r\n    opacity: 0;\r\n    transition: opacity 0.3s ease;\r\n}\r\n\r\n@keyframes firstDot {\r\n    0%, 100% { opacity: 0; }\r\n    10%, 70% { opacity: 1; }\r\n    90% { opacity: 0; }\r\n}\r\n\r\n@keyframes secondDot {\r\n    0%, 20%, 100% { opacity: 0; }\r\n    30%, 70% { opacity: 1; }\r\n    90% { opacity: 0; }\r\n}\r\n\r\n@keyframes thirdDot {\r\n    0%, 40%, 100% { opacity: 0; }\r\n    50%, 70% { opacity: 1; }\r\n    90% { opacity: 0; }\r\n}\r\n\r\n.dot:nth-child(1) {\r\n    animation: firstDot 3s infinite;\r\n}\r\n\r\n.dot:nth-child(2) {\r\n    animation: secondDot 3s infinite;\r\n}\r\n\r\n.dot:nth-child(3) {\r\n    animation: thirdDot 3s infinite;\r\n}\r\n\r\n.droppable .elementor-field-type-checkbox .elementor-field-option {\r\n    display: flex;\r\n    flex-direction: row-reverse;\r\n    align-items: center;\r\n    gap: 8px;\r\n}\r\n\r\n.droppable .elementor-field-type-checkbox .elementor-field-option input[type=\"checkbox\"] {\r\n    width: 12px;\r\n    height: 12px;\r\n    min-width: 12px;\r\n    min-height: 12px;\r\n}\r\n\r\n\/* \u2705 Bouton \"R\u00e9server\" dynamique *\/\r\n.reserver-dynamic-container {\r\n    text-align: center;\r\n    margin-top: -7px;\r\n    margin-bottom: 15px;\r\n    padding: 5px 0;\r\n    transform: scale(1.4);\r\n    transform-origin: center top;\r\n    position: relative;\r\n    z-index: 200;\r\n}\r\n\r\n@media only screen and (min-width: 1001px) {\r\n    .reserver-dynamic-container {\r\n        transform: scale(1);\r\n        margin-top: -200px;\r\n        margin-bottom: 0;\r\n    }\r\n}\r\n\r\n.reserver-dynamic-option {\r\n    display: inline-flex;\r\n    flex-direction: row-reverse;\r\n    align-items: center;\r\n    gap: 8px;\r\n    cursor: pointer;\r\n    color: #213864;\r\n    background-color: #ffffff;\r\n    padding: 2px 4px;\r\n    border-radius: 6px;\r\n}\r\n\r\n.reserver-dynamic-checkbox {\r\n    width: 16px;\r\n    height: 16px;\r\n    min-width: 16px;\r\n    min-height: 16px;\r\n    cursor: pointer;\r\n    pointer-events: auto;\r\n}\r\n\r\n.reserver-dynamic-label {\r\n    cursor: pointer;\r\n    color: #213864;\r\n    font-size: 16px;\r\n    font-weight: 600;\r\n    user-select: none;\r\n}\r\n\r\n@media only screen and (max-width: 1000px) {\r\n    .reserver-dynamic-container {\r\n        transform: scale(0.98);\r\n        margin-bottom: 20px;\r\n        white-space: nowrap;\r\n        z-index: 300;\r\n        pointer-events: auto;\r\n    }\r\n    .reserver-dynamic-option {\r\n        padding-top: 0px;\r\n        padding-bottom: 0px;\r\n    }\r\n}\r\n\r\n\/* \u2705 v2.1.3 : DeplaceAnnonceText \/ DeplaceAnnonce \u2014 desktop uniquement *\/\r\n@media only screen and (min-width: 1001px) {\r\n    .DeplaceAnnonceText {\r\n        margin-top: -5px;\r\n        position: relative;\r\n        z-index: 201;\r\n    }\r\n    .DeplaceAnnonce {\r\n        margin-bottom: -150px;\r\n    }\r\n}\r\n<\/style>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-54e4e530 e-con-full MsgFormatIncorrectConteneur elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile e-flex e-con e-child\" data-id=\"54e4e530\" data-element_type=\"container\" id=\"NotusedAnymore\">\n\t\t\t\t<div class=\"elementor-element elementor-element-531f3cb1 MsgFormatIncorrect elementor-widget__width-inherit elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"531f3cb1\" data-element_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 style=\"text-align: center;\">Le format du fichier n&rsquo;est pas reconnu<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3a352c3f elementor-hidden-desktop TexteMobile TexteMobileAnnonce elementor-widget elementor-widget-text-editor\" data-id=\"3a352c3f\" data-element_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\tGlisser-d\u00e9poser ou cliquer ici<br>pour t\u00e9l\u00e9charger une annonce\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7abb0aba elementor-hidden-desktop TexteMobileAjoutAnnonce elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"7abb0aba\" data-element_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 style=\"text-align: center;\">Cliquer ici pour t\u00e9l\u00e9charger une annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-68e2b2ca UploadIci elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"68e2b2ca\" data-element_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>Ici glisser-d\u00e9poser ou t\u00e9l\u00e9charger une annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-8d50d33 e-con-full e-flex e-con e-child\" data-id=\"8d50d33\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6ae6ef83 elementor-button-align-center elementor-widget__width-initial HideFormButton EspPubLienAnnonce elementor-widget-mobile__width-initial elementor-widget elementor-widget-form\" data-id=\"6ae6ef83\" data-element_type=\"widget\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_URL_annonce\" aria-label=\"Formulaire_URL_annonce\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249680\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"6ae6ef83\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-text elementor-field-group elementor-column elementor-field-group-LienAnnonce elementor-col-100 elementor-sm-100 elementor-field-required\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-LienAnnonce\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tIci renseigner si n\u00e9cessaire le lien hypertexte de l\u2019annonce\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<input size=\"1\" type=\"text\" name=\"form_fields[LienAnnonce]\" id=\"form-field-LienAnnonce\" class=\"elementor-field elementor-size-xs  elementor-field-textual\" placeholder=\"Ici renseigner si n\u00e9cessaire le lien hypertexte de l\u2019annonce\" required=\"required\">\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidURLAnnonce\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-66fd4d36 e-con-full EnvoiUlterieurContainer e-flex e-con e-child\" data-id=\"66fd4d36\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4ea8e2b4 elementor-button-align-center elementor-widget__width-auto HideFormButton EnvoiUlterieur elementor-widget elementor-widget-form\" data-id=\"4ea8e2b4\" data-element_type=\"widget\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_Envoi_Ulterieur\" aria-label=\"Formulaire_Envoi_Ulterieur\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249680\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"4ea8e2b4\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-checkbox elementor-field-group elementor-column elementor-field-group-EnvoiUlterieur elementor-col-100 elementor-sm-100\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-EnvoiUlterieur\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tEnvoi diff\u00e9r\u00e9 de l'annonce\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t<div class=\"elementor-field-subgroup\"><span class=\"elementor-field-option\"><input type=\"checkbox\" value=\"Envoi diff\u00e9r\u00e9 de l&#039;annonce\" id=\"form-field-EnvoiUlterieur-0\" name=\"form_fields[EnvoiUlterieur]\"> <label for=\"form-field-EnvoiUlterieur-0\">Envoi diff\u00e9r\u00e9 de l'annonce<\/label><\/span><\/div>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidEnvoiUlterieur\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\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-4a59cf88 EnvoiUlterieurTexte elementor-widget elementor-widget-text-editor\" data-id=\"4a59cf88\" data-element_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 style=\"text-align: center;\">Envoyer l\u2019annonce jusqu\u2019\u00e0 8 jours apr\u00e8s paiement<br>\nUn lien vous sera adress\u00e9 par <span style=\"color: #ffffff;\"><a style=\"color: #ffffff;\" href=\"mailto:contact@via-agency.media\">contact@via-agency.media<\/a><\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-17d3ad0c e-con-full ReserverContainer e-flex e-con e-child\" data-id=\"17d3ad0c\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-177c9b71 elementor-button-align-center elementor-widget__width-auto HideFormButton ReserverBouton elementor-widget elementor-widget-form\" data-id=\"177c9b71\" data-element_type=\"widget\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_Envoi_Ulterieur\" aria-label=\"Formulaire_Envoi_Ulterieur\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249680\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"177c9b71\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-checkbox elementor-field-group elementor-column elementor-field-group-ReserverEspacePublicitaire elementor-col-100 elementor-sm-100\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-ReserverEspacePublicitaire\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tR\u00e9server cet espace publicitaire\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t<div class=\"elementor-field-subgroup\"><span class=\"elementor-field-option\"><input type=\"checkbox\" value=\"R\u00e9server cet espace publicitaire\" id=\"form-field-ReserverEspacePublicitaire-0\" name=\"form_fields[ReserverEspacePublicitaire]\"> <label for=\"form-field-ReserverEspacePublicitaire-0\">R\u00e9server cet espace publicitaire<\/label><\/span><\/div>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidEnvoiUlterieur\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-5bafe1f3 e-con-full AdUploadedTitle DeplaceAnnonce elementor-hidden-tablet elementor-hidden-mobile elementor-hidden-desktop e-flex e-con e-child\" data-id=\"5bafe1f3\" data-element_type=\"container\" id=\"DeplaceAnnonceId\">\n\t\t<div class=\"elementor-element elementor-element-432cc2a1 e-con-full DeplaceAnnonceSubContainer e-flex e-con e-child\" data-id=\"432cc2a1\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-446e8565 elementor-hidden-tablet elementor-hidden-mobile EspaceReserve elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"446e8565\" data-element_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>Espace r\u00e9serv\u00e9<br \/>Annonce transmise<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-60df49d0 elementor-hidden-tablet elementor-hidden-mobile DeplaceAnnonceText elementor-widget elementor-widget-text-editor\" data-id=\"60df49d0\" data-element_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\tSi vous souhaitez un autre emplacement, vous pouvez d\u00e9placer cette annonce\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-62ef38f0 e-con-full e-flex e-con e-child\" data-id=\"62ef38f0\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f4f51cb elementor-hidden-tablet elementor-hidden-mobile PositionEspacePublicitaireDeplacer elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"f4f51cb\" data-element_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>Position<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f214306 elementor-hidden-tablet elementor-hidden-mobile RefEspacePublicitaire elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"f214306\" data-element_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>R\u00e9f\u00e9rence<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1c5a5ed5 e-con-full AdUploadedOverlay elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile e-flex e-con e-child\" data-id=\"1c5a5ed5\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-4740d3e8 e-con-full OverlayHeader e-flex e-con e-child\" data-id=\"4740d3e8\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e964c6b elementor-hidden-tablet elementor-hidden-mobile OverlayRefEspace elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"e964c6b\" data-element_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>R\u00e9f\u00e9rence<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-30eb836c OverlayCroixReset elementor-widget elementor-widget-image\" data-id=\"30eb836c\" data-element_type=\"widget\" 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\t<a href=\"#\">\n\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-transparent.png\" title=\"\" alt=\"\" loading=\"lazy\" \/>\t\t\t\t\t\t\t\t<\/a>\n\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<\/div>\n\t\t<div class=\"elementor-element elementor-element-342c88b1 e-con-full OverlayPreviewZone e-flex e-con e-child\" data-id=\"342c88b1\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3c7e790f OverlayDeplaceTexte elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"3c7e790f\" data-element_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>Si vous souhaitez un autre emplacement, vous pouvez d\u00e9placer cette annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-51f00578 elementor-button-align-center elementor-widget__width-auto HideFormButton OverlayReserverForm elementor-widget elementor-widget-form\" data-id=\"51f00578\" data-element_type=\"widget\" id=\"Formulaire_Reserver_Overlay\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_Envoi_Ulterieur\" aria-label=\"Formulaire_Envoi_Ulterieur\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249680\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"51f00578\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-checkbox elementor-field-group elementor-column elementor-field-group-ReserverEspacePublicitaire elementor-col-100 elementor-sm-100\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-ReserverEspacePublicitaire\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tR\u00e9server cet espace publicitaire\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t<div class=\"elementor-field-subgroup\"><span class=\"elementor-field-option\"><input type=\"checkbox\" value=\"R\u00e9server cet espace publicitaire\" id=\"form-field-ReserverEspacePublicitaire-0\" name=\"form_fields[ReserverEspacePublicitaire]\"> <label for=\"form-field-ReserverEspacePublicitaire-0\">R\u00e9server cet espace publicitaire<\/label><\/span><\/div>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidEnvoiUlterieur\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-186a8e9c e-con-full e-flex e-con e-child\" data-id=\"186a8e9c\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5193306d elementor-grid-3 elementor-grid-tablet-2 elementor-grid-mobile-3 elementor-widget elementor-widget-loop-grid\" data-id=\"5193306d\" data-element_type=\"widget\" data-settings=\"{&quot;template_id&quot;:&quot;114614&quot;,&quot;columns&quot;:3,&quot;columns_tablet&quot;:2,&quot;columns_mobile&quot;:3,&quot;_skin&quot;:&quot;post&quot;,&quot;edit_handle_selector&quot;:&quot;[data-elementor-type=\\&quot;loop-item\\&quot;]&quot;,&quot;row_gap&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;row_gap_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;row_gap_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]}}\" data-widget_type=\"loop-grid.post\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-loop-container elementor-grid\" role=\"list\">\n\t\t<style id=\"loop-dynamic-114614\">.e-loop-item-32630 .elementor-element.elementor-element-bae3280::before, .e-loop-item-32630 .elementor-element.elementor-element-bae3280 > .elementor-background-video-container::before, .e-loop-item-32630 .elementor-element.elementor-element-bae3280 > .e-con-inner > .elementor-background-video-container::before, .e-loop-item-32630 .elementor-element.elementor-element-bae3280 > .elementor-background-slideshow::before, .e-loop-item-32630 .elementor-element.elementor-element-bae3280 > .e-con-inner > .elementor-background-slideshow::before, .e-loop-item-32630 .elementor-element.elementor-element-bae3280 > .elementor-motion-effects-container > .elementor-motion-effects-layer::before{background-image:url(\"https:\/\/togo-en.yearbook-media.com\/wp-content\/uploads\/2024\/02\/beautiful-alternative-energy-plant-with-solar-panels-e1719511128506.jpg\");}@media(max-width:1000px){.e-loop-item-32630 .elementor-element.elementor-element-bae3280::before, .e-loop-item-32630 .elementor-element.elementor-element-bae3280 > .elementor-background-video-container::before, .e-loop-item-32630 .elementor-element.elementor-element-bae3280 > .e-con-inner > .elementor-background-video-container::before, .e-loop-item-32630 .elementor-element.elementor-element-bae3280 > .elementor-background-slideshow::before, .e-loop-item-32630 .elementor-element.elementor-element-bae3280 > .e-con-inner > .elementor-background-slideshow::before, .e-loop-item-32630 .elementor-element.elementor-element-bae3280 > .elementor-motion-effects-container > .elementor-motion-effects-layer::before{background-image:url(\"https:\/\/togo-en.yearbook-media.com\/wp-content\/uploads\/2024\/02\/beautiful-alternative-energy-plant-with-solar-panels-e1719511128506.jpg\");}}<\/style><style id=\"loop-114614\">.elementor-114614 .elementor-element.elementor-element-d2b4376{--display:flex;--flex-direction:column;--container-widget-width:100%;--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114614 .elementor-element.elementor-element-bae3280{--display:flex;--min-height:300px;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--justify-content:flex-start;--align-items:flex-start;--overlay-opacity:1;--overlay-mix-blend-mode:darken;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114614 .elementor-element.elementor-element-bae3280::before, .elementor-114614 .elementor-element.elementor-element-bae3280 > .elementor-background-video-container::before, .elementor-114614 .elementor-element.elementor-element-bae3280 > .e-con-inner > .elementor-background-video-container::before, .elementor-114614 .elementor-element.elementor-element-bae3280 > .elementor-background-slideshow::before, .elementor-114614 .elementor-element.elementor-element-bae3280 > .e-con-inner > .elementor-background-slideshow::before, .elementor-114614 .elementor-element.elementor-element-bae3280 > .elementor-motion-effects-container > .elementor-motion-effects-layer::before{background-color:#FFFFFF;--background-overlay:'';background-position:center center;background-repeat:no-repeat;background-size:cover;}.elementor-114614 .elementor-element.elementor-element-bae3280::before{filter:brightness( 73% ) contrast( 100% ) saturate( 100% ) blur( 0px ) hue-rotate( 0deg );}.elementor-114614 .elementor-element.elementor-element-bae3280.e-con{--align-self:flex-start;}.elementor-widget-theme-post-title .elementor-heading-title{font-family:var( --e-global-typography-primary-font-family ), Sans-serif;font-weight:var( --e-global-typography-primary-font-weight );color:var( --e-global-color-primary );}.elementor-114614 .elementor-element.elementor-element-75eb4b4 > .elementor-widget-container{margin:60px 0px -5px 20px;padding:0px 020px 0px 0px;}.elementor-114614 .elementor-element.elementor-element-75eb4b4 .elementor-heading-title{font-family:\"Roboto\", Sans-serif;font-size:16px;font-weight:600;color:#FFFFFF;}.elementor-widget-theme-post-excerpt .elementor-widget-container{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );color:var( --e-global-color-text );}.elementor-114614 .elementor-element.elementor-element-f28c507 > .elementor-widget-container{margin:0px 0px -10px 20px;padding:0px 20px 0px 0px;}.elementor-114614 .elementor-element.elementor-element-f28c507 .elementor-widget-container{font-family:\"Roboto\", Sans-serif;font-size:12px;font-weight:400;line-height:1.3em;color:#FFFFFF;}.elementor-114614 .elementor-element.elementor-element-15d0e12{--display:flex;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-widget-text-editor{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );color:var( --e-global-color-text );}.elementor-widget-text-editor.elementor-drop-cap-view-stacked .elementor-drop-cap{background-color:var( --e-global-color-primary );}.elementor-widget-text-editor.elementor-drop-cap-view-framed .elementor-drop-cap, .elementor-widget-text-editor.elementor-drop-cap-view-default .elementor-drop-cap{color:var( --e-global-color-primary );border-color:var( --e-global-color-primary );}.elementor-114614 .elementor-element.elementor-element-b9200eb > .elementor-widget-container{margin:0px 0px 0px 20px;padding:0px 20px 0px 0px;}.elementor-114614 .elementor-element.elementor-element-b9200eb{font-family:\"Roboto\", Sans-serif;font-size:12px;font-weight:600;color:#FFFFFF;}@media(max-width:1001px) and (min-width:1001px){.elementor-114614 .elementor-element.elementor-element-bae3280{--width:100%;}}@media(max-width:1001px){.elementor-114614 .elementor-element.elementor-element-d2b4376{--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114614 .elementor-element.elementor-element-bae3280{--min-height:280px;--border-radius:0px 0px 0px 0px;}.elementor-114614 .elementor-element.elementor-element-75eb4b4 > .elementor-widget-container{margin:30px 0px -5px 20px;}.elementor-114614 .elementor-element.elementor-element-75eb4b4 .elementor-heading-title{font-size:14px;}.elementor-114614 .elementor-element.elementor-element-f28c507 > .elementor-widget-container{margin:0px 0px 0px 20px;}.elementor-114614 .elementor-element.elementor-element-f28c507 .elementor-widget-container{font-size:11px;}.elementor-114614 .elementor-element.elementor-element-15d0e12{--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114614 .elementor-element.elementor-element-b9200eb > .elementor-widget-container{margin:0px 0px 0px 20px;padding:0px 0px 0px 0px;}.elementor-114614 .elementor-element.elementor-element-b9200eb{font-size:11px;}}@media(max-width:1000px){.elementor-114614 .elementor-element.elementor-element-d2b4376{--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114614 .elementor-element.elementor-element-bae3280{--width:100%;--min-height:200px;--border-radius:0px 0px 0px 0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-114614 .elementor-element.elementor-element-75eb4b4 > .elementor-widget-container{margin:40px 0px 0px 10px;padding:0px 10px 0px 0px;}.elementor-114614 .elementor-element.elementor-element-75eb4b4{text-align:left;}.elementor-114614 .elementor-element.elementor-element-75eb4b4 .elementor-heading-title{font-size:15px;}.elementor-114614 .elementor-element.elementor-element-f28c507 > .elementor-widget-container{margin:0px 0px 0px 10px;padding:0px 10px 0px 0px;}.elementor-114614 .elementor-element.elementor-element-15d0e12{--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-114614 .elementor-element.elementor-element-b9200eb > .elementor-widget-container{margin:0px 0px 0px 10px;padding:0px 8px 0px 0px;}.elementor-114614 .elementor-element.elementor-element-b9200eb{font-size:12px;}}<\/style>\t\t<div data-elementor-type=\"loop-item\" data-elementor-id=\"114614\" class=\"elementor elementor-114614 e-loop-item e-loop-item-32630 post-32630 post type-post status-publish format-standard has-post-thumbnail hentry category-electricite category-togo category-togo-energie generate-columns tablet-grid-50 mobile-grid-100 grid-parent grid-20\" data-elementor-post-type=\"elementor_library\" data-custom-edit-handle=\"1\">\n\t\t\t<div class=\"elementor-element elementor-element-d2b4376 e-flex e-con-boxed e-con e-parent\" data-id=\"d2b4376\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-bae3280 e-con-full e-flex e-con e-child\" data-id=\"bae3280\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-75eb4b4 elementor-widget elementor-widget-theme-post-title elementor-page-title elementor-widget-heading\" data-id=\"75eb4b4\" data-element_type=\"widget\" data-widget_type=\"theme-post-title.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h5 class=\"elementor-heading-title elementor-size-default\"><a href=\"https:\/\/togo-en.yearbook-media.com\/fr\/togo-electricite-lelectricite-une-activite-strategique\/\">Togo &#8211; Electricit\u00e9 <br>&#8211; L\u2019\u00e9lectricit\u00e9, une activit\u00e9 strat\u00e9gique<\/a><\/h5>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f28c507 elementor-hidden-mobile VignetteSecteurExtraitPublication elementor-widget elementor-widget-theme-post-excerpt\" data-id=\"f28c507\" data-element_type=\"widget\" data-widget_type=\"theme-post-excerpt.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<p>Pour passer d\u2019un taux d\u2019\u00e9lectrification de 58% \u00e0 un acc\u00e8s universel \u00e0 une \u00e9nergie propre et fiable \u00e0 l\u2019horizon 2030, le gouvernement togolais multiplie les initiatives. Au niveau national, selon ...\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<a class=\"elementor-element elementor-element-15d0e12 e-con-full e-flex e-con e-child\" data-id=\"15d0e12\" data-element_type=\"container\" href=\"https:\/\/togo-en.yearbook-media.com\/fr\/togo-electricite-lelectricite-une-activite-strategique\/\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b9200eb elementor-widget elementor-widget-text-editor\" data-id=\"b9200eb\" data-element_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>Lire la suite \u00bb<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\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\t\t<\/div>\n\t\t\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-721e8f8e ToBeHidden e-con-full e-flex e-con e-child\" data-id=\"721e8f8e\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-6b0080ed e-con-full droppable e-flex e-con e-child\" data-id=\"6b0080ed\" data-element_type=\"container\" id=\"Ele4A\">\n\t\t\t\t<div class=\"elementor-element elementor-element-14e794a5 elementor-widget__width-inherit elementor-widget elementor-widget-text-editor\" data-id=\"14e794a5\" data-element_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>\t\t<div data-elementor-type=\"page\" data-elementor-id=\"83347\" class=\"elementor elementor-83347\" data-elementor-post-type=\"elementor_library\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6442de91 e-con-full OrdiMobileConteneurClass e-flex e-con e-child\" data-id=\"6442de91\" data-element_type=\"container\" id=\"testIdTest\">\n\t\t\t\t<div class=\"elementor-element elementor-element-57de103 elementor-widget elementor-widget-text-editor\" data-id=\"57de103\" data-element_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><style>.elementor-249681 .elementor-element.elementor-element-6da64a60{--display:flex;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--justify-content:space-around;--align-items:center;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:50px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-6da64a60.e-con{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-45f807e0{--display:flex;--min-height:0px;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:-100px;--margin-bottom:62px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:3;}.elementor-249681 .elementor-element.elementor-element-45f807e0.e-con{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-61dcced4{--display:flex;--margin-top:0px;--margin-bottom:-11px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-6c65b106{--display:flex;--margin-top:0px;--margin-bottom:-30px;--margin-left:-25px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-eb74aa8{--display:flex;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-eb74aa8:not(.elementor-motion-effects-element-type-background), .elementor-249681 .elementor-element.elementor-element-eb74aa8 > .elementor-motion-effects-container > .elementor-motion-effects-layer{background-color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-1c762c45{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--flex-wrap:nowrap;--margin-top:-3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-5be6a53a{--display:flex;--align-items:flex-start;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-5be6a53a.e-con{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-75917e71{--display:flex;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-widget-image .widget-image-caption{color:var( --e-global-color-text );font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-249681 .elementor-element.elementor-element-6be76773 > .elementor-widget-container{margin:38px 5px -38px -40px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-6be76773.elementor-element{--align-self:flex-start;}.elementor-249681 .elementor-element.elementor-element-6be76773{text-align:right;}.elementor-249681 .elementor-element.elementor-element-6be76773 img{width:17px;}.elementor-249681 .elementor-element.elementor-element-5ad25a69{--display:flex;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-5ad25a69.e-con{--align-self:flex-end;}.elementor-249681 .elementor-element.elementor-element-52dec736 > .elementor-widget-container{margin:45px -18px -55px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-52dec736{z-index:101;text-align:right;}.elementor-249681 .elementor-element.elementor-element-469b1a7c{--display:flex;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:-25px;--margin-bottom:90px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-469b1a7c:not(.elementor-motion-effects-element-type-background), .elementor-249681 .elementor-element.elementor-element-469b1a7c > .elementor-motion-effects-container > .elementor-motion-effects-layer{background-color:#9FC5F3;}.elementor-249681 .elementor-element.elementor-element-3f5f9124{--display:flex;--min-height:30px;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:center;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:1px;--margin-bottom:-6px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:99;}.elementor-249681 .elementor-element.elementor-element-3f5f9124.e-con{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-48a37689{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:flex-start;--margin-top:3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-widget-text-editor{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );color:var( --e-global-color-text );}.elementor-widget-text-editor.elementor-drop-cap-view-stacked .elementor-drop-cap{background-color:var( --e-global-color-primary );}.elementor-widget-text-editor.elementor-drop-cap-view-framed .elementor-drop-cap, .elementor-widget-text-editor.elementor-drop-cap-view-default .elementor-drop-cap{color:var( --e-global-color-primary );border-color:var( --e-global-color-primary );}.elementor-249681 .elementor-element.elementor-element-4b68287 > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249681 .elementor-element.elementor-element-4b68287.elementor-element{--align-self:flex-start;}.elementor-249681 .elementor-element.elementor-element-4b68287{text-align:start;font-family:\"Roboto\", Sans-serif;font-size:12px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-79a46db6{--display:flex;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-47d25f98 > .elementor-widget-container{margin:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-47d25f98{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:18px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-3aa42503{--display:flex;--flex-direction:row;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:flex-end;--align-items:flex-end;--margin-top:4px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-12d5dc39 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-12d5dc39.elementor-element{--align-self:flex-start;}.elementor-249681 .elementor-element.elementor-element-12d5dc39{text-align:end;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-21535e15{--display:flex;--justify-content:flex-start;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--flex-wrap:wrap;--margin-top:-2px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-21535e15.e-con{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-de420c1{--display:flex;--min-height:30px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-2f60f3f > .elementor-widget-container{margin:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-2f60f3f.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-2f60f3f{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:500;line-height:1.1em;color:#FB5E2A;}.elementor-249681 .elementor-element.elementor-element-6b485447 > .elementor-widget-container{margin:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-6b485447.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-6b485447{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-78e1d9f5{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:center;--gap:010px 9px;--row-gap:010px;--column-gap:9px;--flex-wrap:wrap;--margin-top:-14px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:100;}.elementor-249681 .elementor-element.elementor-element-78e1d9f5.e-con{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-cf3602e{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-7a1bb33 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-7a1bb33.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-7a1bb33{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-6bf72a5{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-1a57dd9 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-1a57dd9.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-1a57dd9{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-34d8bbba{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-32bd35c6 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-32bd35c6.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-32bd35c6{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-5a9252c3{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-8722042 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-8722042.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-8722042{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-19ecc2b3{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-6071d405 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-6071d405.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-6071d405{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-3617569c{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-4b013e71 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-4b013e71.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-4b013e71{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-7450a6f8{--display:flex;--min-height:20px;--justify-content:center;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:4px 4px 4px 4px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-30970f89 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-30970f89.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-30970f89{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:500;line-height:1.1em;color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-6aac67a6{--display:flex;--margin-top:-46px;--margin-bottom:-20px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:2;}.elementor-249681 .elementor-element.elementor-element-40d299c{width:100%;max-width:100%;}.elementor-249681 .elementor-element.elementor-element-40d299c.elementor-element{--align-self:flex-end;}.elementor-249681 .elementor-element.elementor-element-1fd15d20{width:100%;max-width:100%;}.elementor-249681 .elementor-element.elementor-element-1fd15d20.elementor-element{--align-self:flex-end;}.elementor-249681 .elementor-element.elementor-element-54e4e530{--display:flex;--justify-content:center;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-531f3cb1{width:100%;max-width:100%;font-family:\"Roboto\", Sans-serif;font-size:10px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249681 .elementor-element.elementor-element-531f3cb1 > .elementor-widget-container{margin:-37px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-531f3cb1.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-3a352c3f > .elementor-widget-container{margin:7px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-3a352c3f.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-3a352c3f{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:15px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249681 .elementor-element.elementor-element-7abb0aba > .elementor-widget-container{margin:7px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-7abb0aba.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-7abb0aba{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:15px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249681 .elementor-element.elementor-element-68e2b2ca > .elementor-widget-container{margin:-110px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-68e2b2ca.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-68e2b2ca{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:18px;font-weight:600;line-height:1.1em;color:#FB5E2A;}.elementor-249681 .elementor-element.elementor-element-8d50d33{--display:flex;--margin-top:-85px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-8d50d33.e-con{--align-self:center;}.elementor-widget-form .elementor-field-group > label, .elementor-widget-form .elementor-field-subgroup label{color:var( --e-global-color-text );}.elementor-widget-form .elementor-field-group > label{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .elementor-field-type-html{color:var( --e-global-color-text );font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .elementor-field-group .elementor-field{color:var( --e-global-color-text );}.elementor-widget-form .elementor-field-group .elementor-field, .elementor-widget-form .elementor-field-subgroup label{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .elementor-button{font-family:var( --e-global-typography-accent-font-family ), Sans-serif;font-weight:var( --e-global-typography-accent-font-weight );}.elementor-widget-form .e-form__buttons__wrapper__button-next{background-color:var( --e-global-color-accent );}.elementor-widget-form .elementor-button[type=\"submit\"]{background-color:var( --e-global-color-accent );}.elementor-widget-form .e-form__buttons__wrapper__button-previous{background-color:var( --e-global-color-accent );}.elementor-widget-form .elementor-message{font-family:var( --e-global-typography-text-font-family ), Sans-serif;font-weight:var( --e-global-typography-text-font-weight );}.elementor-widget-form .e-form__indicators__indicator, .elementor-widget-form .e-form__indicators__indicator__label{font-family:var( --e-global-typography-accent-font-family ), Sans-serif;font-weight:var( --e-global-typography-accent-font-weight );}.elementor-widget-form{--e-form-steps-indicator-inactive-primary-color:var( --e-global-color-text );--e-form-steps-indicator-active-primary-color:var( --e-global-color-accent );--e-form-steps-indicator-completed-primary-color:var( --e-global-color-accent );--e-form-steps-indicator-progress-color:var( --e-global-color-accent );--e-form-steps-indicator-progress-background-color:var( --e-global-color-text );--e-form-steps-indicator-progress-meter-color:var( --e-global-color-text );}.elementor-widget-form .e-form__indicators__indicator__progress__meter{font-family:var( --e-global-typography-accent-font-family ), Sans-serif;font-weight:var( --e-global-typography-accent-font-weight );}.elementor-249681 .elementor-element.elementor-element-6ae6ef83{width:var( --container-widget-width, 75% );max-width:75%;--container-widget-width:75%;--container-widget-flex-grow:0;z-index:120;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group{padding-right:calc( 10px\/2 );padding-left:calc( 10px\/2 );margin-bottom:6px;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-form-fields-wrapper{margin-left:calc( -10px\/2 );margin-right:calc( -10px\/2 );margin-bottom:-6px;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group > label, .elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{color:#7B88A3;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-type-html{padding-bottom:0px;color:#7A7A7A;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field{color:#484848;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field, .elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:01px 01px 01px 01px;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:01px 01px 01px 01px;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-message.elementor-message-success{color:#00FF2700;}.elementor-249681 .elementor-element.elementor-element-66fd4d36{--display:flex;--min-height:58px;--gap:0px 0px;--row-gap:0px;--column-gap:0px;border-style:solid;--border-style:solid;border-width:1px 1px 1px 1px;--border-top-width:1px;--border-right-width:1px;--border-bottom-width:1px;--border-left-width:1px;border-color:#FFFFFF;--border-color:#FFFFFF;--border-radius:8px 8px 8px 8px;--margin-top:12px;--margin-bottom:10px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:151;}.elementor-249681 .elementor-element.elementor-element-66fd4d36.e-con{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4{width:auto;max-width:auto;z-index:120;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 > .elementor-widget-container{margin:2px 0px 2px 1px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group{padding-right:calc( 0px\/2 );padding-left:calc( 0px\/2 );margin-bottom:0px;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-form-fields-wrapper{margin-left:calc( -0px\/2 );margin-right:calc( -0px\/2 );margin-bottom:-0px;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group > label, .elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-type-html{padding-bottom:0px;color:#FFFFFF;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field{color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field, .elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:14px;font-weight:600;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-message.elementor-message-success{color:#00FF2700;}.elementor-249681 .elementor-element.elementor-element-4a59cf88 > .elementor-widget-container{margin:-3px 0px -24px 0px;}.elementor-249681 .elementor-element.elementor-element-4a59cf88.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-4a59cf88{text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.2em;color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-17d3ad0c{--display:flex;--gap:0px 0px;--row-gap:0px;--column-gap:0px;border-style:none;--border-style:none;--border-radius:8px 8px 8px 8px;--margin-top:-4px;--margin-bottom:05px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:151;}.elementor-249681 .elementor-element.elementor-element-17d3ad0c.e-con{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-177c9b71{width:auto;max-width:auto;z-index:5;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249681 .elementor-element.elementor-element-177c9b71 > .elementor-widget-container{margin:2px 0px 2px 1px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-177c9b71.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-group{padding-right:calc( 0px\/2 );padding-left:calc( 0px\/2 );margin-bottom:0px;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-form-fields-wrapper{margin-left:calc( -0px\/2 );margin-right:calc( -0px\/2 );margin-bottom:-0px;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-group > label, .elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{color:#000000;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:400;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-type-html{padding-bottom:0px;color:#FFFFFF;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field{color:#000000;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field, .elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:16px;font-weight:600;line-height:1.1em;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-message.elementor-message-success{color:#00FF2700;}.elementor-249681 .elementor-element.elementor-element-5bafe1f3{--display:flex;--min-height:0px;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--gap:0px 0px;--row-gap:0px;--column-gap:0px;--overlay-opacity:1;--margin-top:230px;--margin-bottom:-220px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:10;}.elementor-249681 .elementor-element.elementor-element-5bafe1f3::before, .elementor-249681 .elementor-element.elementor-element-5bafe1f3 > .elementor-background-video-container::before, .elementor-249681 .elementor-element.elementor-element-5bafe1f3 > .e-con-inner > .elementor-background-video-container::before, .elementor-249681 .elementor-element.elementor-element-5bafe1f3 > .elementor-background-slideshow::before, .elementor-249681 .elementor-element.elementor-element-5bafe1f3 > .e-con-inner > .elementor-background-slideshow::before, .elementor-249681 .elementor-element.elementor-element-5bafe1f3 > .elementor-motion-effects-container > .elementor-motion-effects-layer::before{--background-overlay:'';background-size:cover;}.elementor-249681 .elementor-element.elementor-element-5bafe1f3.e-con{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-432cc2a1{--display:flex;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-446e8565 > .elementor-widget-container{margin:0px 3px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-446e8565.elementor-element{--align-self:flex-end;}.elementor-249681 .elementor-element.elementor-element-446e8565{z-index:5;text-align:center;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249681 .elementor-element.elementor-element-60df49d0 > .elementor-widget-container{margin:35px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-60df49d0.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-60df49d0{z-index:5;text-align:center;font-family:\"Roboto\", Sans-serif;font-size:15px;font-weight:500;line-height:1.1em;color:#6185C0;}.elementor-249681 .elementor-element.elementor-element-62ef38f0{--display:flex;--flex-direction:row;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:space-between;--align-items:flex-start;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:-287px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-f4f51cb > .elementor-widget-container{margin:0px 3px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-f4f51cb.elementor-element{--align-self:flex-end;}.elementor-249681 .elementor-element.elementor-element-f4f51cb{z-index:5;text-align:left;font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249681 .elementor-element.elementor-element-f214306 > .elementor-widget-container{margin:0px 0px 0px 3px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-f214306.elementor-element{--align-self:flex-end;}.elementor-249681 .elementor-element.elementor-element-f214306{z-index:5;text-align:start;font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249681 .elementor-element.elementor-element-1c5a5ed5{--display:flex;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--justify-content:flex-start;--align-items:center;--gap:0px 0px;--row-gap:0px;--column-gap:0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-1c5a5ed5.e-con{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-4740d3e8{--display:flex;--flex-direction:row;--container-widget-width:initial;--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:space-between;--margin-top:5px;--margin-bottom:5px;--margin-left:010px;--margin-right:10px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-e964c6b > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-e964c6b.elementor-element{--align-self:flex-end;}.elementor-249681 .elementor-element.elementor-element-e964c6b{z-index:5;text-align:left;font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:600;line-height:1.1em;color:#213864;}.elementor-249681 .elementor-element.elementor-element-30eb836c > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-30eb836c{z-index:101;text-align:right;}.elementor-249681 .elementor-element.elementor-element-342c88b1{--display:flex;--min-height:180px;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--justify-content:center;--align-items:center;--overflow:hidden;border-style:solid;--border-style:solid;border-width:4px 4px 4px 4px;--border-top-width:4px;--border-right-width:4px;--border-bottom-width:4px;--border-left-width:4px;border-color:#00FF19;--border-color:#00FF19;--border-radius:0px 0px 0px 0px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-342c88b1:not(.elementor-motion-effects-element-type-background), .elementor-249681 .elementor-element.elementor-element-342c88b1 > .elementor-motion-effects-container > .elementor-motion-effects-layer{background-color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-3c7e790f > .elementor-widget-container{padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-3c7e790f{font-family:\"Roboto\", Sans-serif;font-weight:500;color:#6185C0;}.elementor-249681 .elementor-element.elementor-element-51f00578{width:auto;max-width:auto;z-index:5;--e-form-steps-indicators-spacing:20px;--e-form-steps-indicator-padding:30px;--e-form-steps-indicator-inactive-secondary-color:#ffffff;--e-form-steps-indicator-active-secondary-color:#ffffff;--e-form-steps-divider-width:1px;--e-form-steps-divider-gap:10px;}.elementor-249681 .elementor-element.elementor-element-51f00578 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-51f00578.elementor-element{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-group{padding-right:calc( 0px\/2 );padding-left:calc( 0px\/2 );margin-bottom:0px;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-form-fields-wrapper{margin-left:calc( -0px\/2 );margin-right:calc( -0px\/2 );margin-bottom:-0px;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-group.recaptcha_v3-bottomleft, .elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-group.recaptcha_v3-bottomright{margin-bottom:0;}body.rtl .elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-labels-inline .elementor-field-group > label{padding-left:0px;}body:not(.rtl) .elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-labels-inline .elementor-field-group > label{padding-right:0px;}body .elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-labels-above .elementor-field-group > label{padding-bottom:0px;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-group > label, .elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{color:#000000;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-group > label{font-family:\"Roboto\", Sans-serif;font-size:17px;font-weight:400;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-type-html{padding-bottom:0px;color:#FFFFFF;font-family:\"Roboto\", Sans-serif;font-weight:400;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field{color:#213864;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field, .elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{font-family:\"Roboto\", Sans-serif;font-size:15.5px;font-weight:600;line-height:1.1em;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field:not(.elementor-select-wrapper){background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-select-wrapper select{background-color:#FFFFFF;border-color:#E8ECF1;border-width:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-select-wrapper::before{color:#E8ECF1;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-button{font-family:\"Roboto\", Sans-serif;font-size:1px;font-weight:100;border-radius:6px 6px 6px 6px;}.elementor-249681 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-next{background-color:#10274200;color:#FFFFFF00;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"]{background-color:#10274200;color:#FFFFFF00;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"] svg *{fill:#FFFFFF00;}.elementor-249681 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-previous{color:#ffffff;}.elementor-249681 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-next:hover{color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"]:hover{color:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-button[type=\"submit\"]:hover svg *{fill:#FFFFFF;}.elementor-249681 .elementor-element.elementor-element-51f00578 .e-form__buttons__wrapper__button-previous:hover{color:#ffffff;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-message{font-family:\"Roboto\", Sans-serif;font-size:13px;font-weight:400;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-message.elementor-message-success{color:#00FF2700;}@media(max-width:1001px){.elementor-249681 .elementor-element.elementor-element-6ae6ef83{z-index:11;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field, .elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{font-size:10px;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-button{font-size:12px;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4{z-index:11;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field, .elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{font-size:10px;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-button{font-size:12px;}.elementor-249681 .elementor-element.elementor-element-177c9b71{z-index:11;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field, .elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{font-size:10px;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-button{font-size:12px;}.elementor-249681 .elementor-element.elementor-element-51f00578{z-index:11;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field, .elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{font-size:10px;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-button{font-size:12px;}}@media(min-width:1001px){.elementor-249681 .elementor-element.elementor-element-6da64a60{--width:500px;}.elementor-249681 .elementor-element.elementor-element-45f807e0{--width:100%;}.elementor-249681 .elementor-element.elementor-element-6c65b106{--width:500px;}.elementor-249681 .elementor-element.elementor-element-75917e71{--width:10px;}.elementor-249681 .elementor-element.elementor-element-5ad25a69{--width:100%;}.elementor-249681 .elementor-element.elementor-element-469b1a7c{--width:500px;}.elementor-249681 .elementor-element.elementor-element-48a37689{--width:22%;}.elementor-249681 .elementor-element.elementor-element-79a46db6{--width:50%;}.elementor-249681 .elementor-element.elementor-element-3aa42503{--width:22%;}.elementor-249681 .elementor-element.elementor-element-78e1d9f5{--width:100%;}.elementor-249681 .elementor-element.elementor-element-cf3602e{--width:103px;}.elementor-249681 .elementor-element.elementor-element-6bf72a5{--width:103px;}.elementor-249681 .elementor-element.elementor-element-34d8bbba{--width:103px;}.elementor-249681 .elementor-element.elementor-element-5a9252c3{--width:103px;}.elementor-249681 .elementor-element.elementor-element-19ecc2b3{--width:103px;}.elementor-249681 .elementor-element.elementor-element-3617569c{--width:103px;}.elementor-249681 .elementor-element.elementor-element-7450a6f8{--width:103px;}.elementor-249681 .elementor-element.elementor-element-8d50d33{--width:100%;}.elementor-249681 .elementor-element.elementor-element-66fd4d36{--width:390px;}.elementor-249681 .elementor-element.elementor-element-17d3ad0c{--width:100%;}.elementor-249681 .elementor-element.elementor-element-5bafe1f3{--width:150%;}.elementor-249681 .elementor-element.elementor-element-62ef38f0{--width:95%;}.elementor-249681 .elementor-element.elementor-element-1c5a5ed5{--width:100%;}.elementor-249681 .elementor-element.elementor-element-4740d3e8{--width:100%;}}@media(max-width:1000px){.elementor-249681 .elementor-element.elementor-element-6da64a60{--width:390px;--margin-top:105px;--margin-bottom:-75px;--margin-left:0px;--margin-right:0px;}.elementor-249681 .elementor-element.elementor-element-45f807e0{--min-height:150px;--flex-direction:column;--container-widget-width:100%;--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--margin-top:-47px;--margin-bottom:-32px;--margin-left:0px;--margin-right:0px;--z-index:3;}.elementor-249681 .elementor-element.elementor-element-61dcced4{--width:25%;}.elementor-249681 .elementor-element.elementor-element-6c65b106{--width:100%;--flex-direction:row;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:100%;--container-widget-flex-grow:1;--container-widget-align-self:stretch;--flex-wrap-mobile:wrap;--justify-content:center;--align-items:center;--flex-wrap:nowrap;--margin-top:3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249681 .elementor-element.elementor-element-6c65b106.e-con{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-eb74aa8{--width:75%;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--align-items:center;}.elementor-249681 .elementor-element.elementor-element-eb74aa8.e-con{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-1c762c45{--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249681 .elementor-element.elementor-element-6be76773 > .elementor-widget-container{margin:-3px 40px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-5ad25a69{--width:100%;--justify-content:flex-end;--align-items:flex-end;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-52dec736 > .elementor-widget-container{margin:40px 55px -30px 0px;}.elementor-249681 .elementor-element.elementor-element-52dec736{z-index:100;}.elementor-249681 .elementor-element.elementor-element-469b1a7c{--width:78%;--align-items:center;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--flex-wrap:nowrap;--margin-top:-103px;--margin-bottom:-7px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-469b1a7c.e-con{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-3f5f9124{--justify-content:center;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249681 .elementor-element.elementor-element-48a37689{--width:25%;--margin-top:2px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-4b68287 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-4b68287{font-size:8px;}.elementor-249681 .elementor-element.elementor-element-79a46db6{--width:46%;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-47d25f98 > .elementor-widget-container{margin:0px -20px 0px -20px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-47d25f98{font-size:12px;}.elementor-249681 .elementor-element.elementor-element-3aa42503{--width:25%;--margin-top:4px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-12d5dc39 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-12d5dc39{font-size:7px;}.elementor-249681 .elementor-element.elementor-element-21535e15{--margin-top:-15px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249681 .elementor-element.elementor-element-de420c1{--min-height:15px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-2f60f3f{width:100%;max-width:100%;font-size:10px;}.elementor-249681 .elementor-element.elementor-element-2f60f3f > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-6b485447{width:100%;max-width:100%;font-size:10px;}.elementor-249681 .elementor-element.elementor-element-6b485447 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-78e1d9f5{--width:100%;--gap:6px 4px;--row-gap:6px;--column-gap:4px;--flex-wrap:wrap;--margin-top:-12px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249681 .elementor-element.elementor-element-cf3602e{--width:61px;--min-height:15px;}.elementor-249681 .elementor-element.elementor-element-7a1bb33{font-size:9px;}.elementor-249681 .elementor-element.elementor-element-6bf72a5{--width:61px;--min-height:15px;}.elementor-249681 .elementor-element.elementor-element-1a57dd9{font-size:9px;}.elementor-249681 .elementor-element.elementor-element-34d8bbba{--width:61px;--min-height:15px;}.elementor-249681 .elementor-element.elementor-element-32bd35c6{font-size:9px;}.elementor-249681 .elementor-element.elementor-element-5a9252c3{--width:61px;--min-height:15px;}.elementor-249681 .elementor-element.elementor-element-8722042{font-size:9px;}.elementor-249681 .elementor-element.elementor-element-19ecc2b3{--width:61px;--min-height:15px;}.elementor-249681 .elementor-element.elementor-element-6071d405{font-size:9px;}.elementor-249681 .elementor-element.elementor-element-3617569c{--width:61px;--min-height:15px;}.elementor-249681 .elementor-element.elementor-element-4b013e71{font-size:9px;}.elementor-249681 .elementor-element.elementor-element-7450a6f8{--width:61px;--min-height:15px;}.elementor-249681 .elementor-element.elementor-element-30970f89{font-size:9px;}.elementor-249681 .elementor-element.elementor-element-6aac67a6{--width:96%;--min-height:250px;--margin-top:-56px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-40d299c > .elementor-widget-container{margin:5px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-1fd15d20 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-54e4e530{--margin-top:3px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249681 .elementor-element.elementor-element-54e4e530.e-con{--order:-99999 \/* order start hack *\/;}.elementor-249681 .elementor-element.elementor-element-531f3cb1 > .elementor-widget-container{margin:-30px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-3a352c3f > .elementor-widget-container{margin:-181px 0px 1px 0px;}.elementor-249681 .elementor-element.elementor-element-3a352c3f{text-align:center;font-size:10px;line-height:1.2em;}.elementor-249681 .elementor-element.elementor-element-7abb0aba > .elementor-widget-container{margin:-180px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-7abb0aba{text-align:center;font-size:14px;line-height:1.2em;}.elementor-249681 .elementor-element.elementor-element-68e2b2ca > .elementor-widget-container{margin:-110px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-68e2b2ca{font-size:10px;}.elementor-249681 .elementor-element.elementor-element-8d50d33{--width:184px;--margin-top:-156px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249681 .elementor-element.elementor-element-8d50d33.e-con{--align-self:center;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83{width:var( --container-widget-width, 100% );max-width:100%;--container-widget-width:100%;--container-widget-flex-grow:0;z-index:120;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group > label{font-size:12px;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-group .elementor-field, .elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-field-subgroup label{font-size:8px;}.elementor-249681 .elementor-element.elementor-element-6ae6ef83 .elementor-button{font-size:10.5px;}.elementor-249681 .elementor-element.elementor-element-66fd4d36{--width:85%;--min-height:42px;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--align-items:center;--margin-top:10px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:151;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 > .elementor-widget-container{margin:2px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4{z-index:120;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group > label{font-size:12px;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-type-html{font-size:12px;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-group .elementor-field, .elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-field-subgroup label{font-size:10px;}.elementor-249681 .elementor-element.elementor-element-4ea8e2b4 .elementor-button{font-size:10.5px;}.elementor-249681 .elementor-element.elementor-element-4a59cf88 > .elementor-widget-container{margin:2px 0px -10px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-4a59cf88{font-size:7.5px;}.elementor-249681 .elementor-element.elementor-element-17d3ad0c{--width:85%;--min-height:42px;--flex-direction:column;--container-widget-width:calc( ( 1 - var( --container-widget-flex-grow ) ) * 100% );--container-widget-height:initial;--container-widget-flex-grow:0;--container-widget-align-self:initial;--flex-wrap-mobile:wrap;--align-items:center;--margin-top:2px;--margin-bottom:-20px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;--z-index:251;}.elementor-249681 .elementor-element.elementor-element-177c9b71 > .elementor-widget-container{margin:2px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-177c9b71{z-index:120;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-group > label{font-size:12px;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-type-html{font-size:12px;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-group .elementor-field, .elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-field-subgroup label{font-size:12px;}.elementor-249681 .elementor-element.elementor-element-177c9b71 .elementor-button{font-size:10.5px;}.elementor-249681 .elementor-element.elementor-element-5bafe1f3{--min-height:150px;--margin-top:-149px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;}.elementor-249681 .elementor-element.elementor-element-446e8565 > .elementor-widget-container{margin:-133px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-446e8565.elementor-element{--align-self:flex-start;}.elementor-249681 .elementor-element.elementor-element-446e8565{text-align:left;font-size:10px;}.elementor-249681 .elementor-element.elementor-element-f4f51cb > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249681 .elementor-element.elementor-element-f4f51cb.elementor-element{--align-self:flex-start;}.elementor-249681 .elementor-element.elementor-element-f4f51cb{text-align:center;font-size:10px;}.elementor-249681 .elementor-element.elementor-element-f214306 > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249681 .elementor-element.elementor-element-f214306.elementor-element{--align-self:flex-start;}.elementor-249681 .elementor-element.elementor-element-f214306{text-align:center;font-size:10px;}.elementor-249681 .elementor-element.elementor-element-1c5a5ed5{--width:390px;--margin-top:0px;--margin-bottom:0px;--margin-left:0px;--margin-right:0px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-e964c6b > .elementor-widget-container{margin:0px 0px 0px 10px;}.elementor-249681 .elementor-element.elementor-element-e964c6b.elementor-element{--align-self:flex-start;}.elementor-249681 .elementor-element.elementor-element-e964c6b{text-align:center;font-size:10px;}.elementor-249681 .elementor-element.elementor-element-30eb836c > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-30eb836c{z-index:100;}.elementor-249681 .elementor-element.elementor-element-342c88b1{--min-height:112px;--margin-top:5px;--margin-bottom:5px;--margin-left:5px;--margin-right:5px;--padding-top:0px;--padding-bottom:0px;--padding-left:0px;--padding-right:0px;}.elementor-249681 .elementor-element.elementor-element-3c7e790f{text-align:center;font-size:15px;}.elementor-249681 .elementor-element.elementor-element-51f00578 > .elementor-widget-container{margin:0px 0px 0px 0px;padding:0px 0px 0px 0px;}.elementor-249681 .elementor-element.elementor-element-51f00578{z-index:120;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-group > label{font-size:12px;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-type-html{font-size:12px;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-group .elementor-field, .elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-field-subgroup label{font-size:12px;}.elementor-249681 .elementor-element.elementor-element-51f00578 .elementor-button{font-size:10.5px;}}<\/style>\t\t<div data-elementor-type=\"loop-item\" data-elementor-id=\"249681\" class=\"elementor elementor-249681 elementor-bc-flex-widget e-loop-item e-loop-item-32630 post-32630 post type-post status-publish format-standard has-post-thumbnail hentry category-electricite category-togo category-togo-energie generate-columns tablet-grid-50 mobile-grid-100 grid-parent grid-20\" data-elementor-post-type=\"elementor_library\" data-custom-edit-handle=\"1\">\n\t\t\t<div class=\"elementor-element elementor-element-6da64a60 e-con-full OrdiMobileConteneurClass e-flex e-con e-child\" data-id=\"6da64a60\" data-element_type=\"container\" id=\"testIdTest\">\n\t\t<div class=\"elementor-element elementor-element-45f807e0 e-con-full UploadFileConteneur AdUploadedTitle elementor-hidden-tablet elementor-hidden-mobile elementor-hidden-desktop e-flex e-con e-child\" data-id=\"45f807e0\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-61dcced4 e-con-full e-flex e-con e-child\" data-id=\"61dcced4\" data-element_type=\"container\">\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-6c65b106 e-con-full e-flex e-con e-child\" data-id=\"6c65b106\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-eb74aa8 e-con-full e-flex e-con e-child\" data-id=\"eb74aa8\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1c762c45 e-con-full e-flex e-con e-child\" data-id=\"1c762c45\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-5be6a53a e-con-full e-flex e-con e-child\" data-id=\"5be6a53a\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-75917e71 e-con-full e-flex e-con e-child\" data-id=\"75917e71\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6be76773 AnnonceDragIcone elementor-widget elementor-widget-image\" data-id=\"6be76773\" data-element_type=\"widget\" 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 decoding=\"async\" src=\"https:\/\/via-agency.media\/wp-content\/uploads\/2025\/05\/arrow-drag-64-bleu.png\" title=\"\" alt=\"\" loading=\"lazy\" \/>\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<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-5ad25a69 e-con-full CroixResetAnnonceContainer e-flex e-con e-child\" data-id=\"5ad25a69\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-52dec736 elementor-widget elementor-widget-image\" data-id=\"52dec736\" data-element_type=\"widget\" id=\"CroixResetAnnonce\" 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\t<a href=\"#\">\n\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-transparent.png\" title=\"\" alt=\"\" loading=\"lazy\" \/>\t\t\t\t\t\t\t\t<\/a>\n\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<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-469b1a7c e-con-full UploadFileConteneur e-flex e-con e-child\" data-id=\"469b1a7c\" data-element_type=\"container\" id=\"UploadFileConteneur\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t<div class=\"elementor-element elementor-element-3f5f9124 e-con-full ChoisirEspacePublicitaireDisponibiliteConteneur e-flex e-con e-child\" data-id=\"3f5f9124\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-48a37689 e-con-full e-flex e-con e-child\" data-id=\"48a37689\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4b68287 PositionEspacePublicitaire elementor-widget elementor-widget-text-editor\" data-id=\"4b68287\" data-element_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\tPosition\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-79a46db6 e-con-full e-flex e-con e-child\" data-id=\"79a46db6\" data-element_type=\"container\" id=\"ChoixEspacePublicitaireTitre\">\n\t\t\t\t<div class=\"elementor-element elementor-element-47d25f98 elementor-widget elementor-widget-text-editor\" data-id=\"47d25f98\" data-element_type=\"widget\" id=\"ChoixEspacePublicitaireTexte\" 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\tChoix d&rsquo;espace publicitaire\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-3aa42503 e-con-full e-flex e-con e-child\" data-id=\"3aa42503\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-12d5dc39 ReferenceEspacePublicitaire elementor-widget elementor-widget-text-editor\" data-id=\"12d5dc39\" data-element_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>R\u00e9f\u00e9rence<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-21535e15 e-con-full EspPubFormatMainContainer e-flex e-con e-child\" data-id=\"21535e15\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-de420c1 e-con-full e-flex e-con e-child\" data-id=\"de420c1\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2f60f3f elementor-widget-mobile__width-inherit SelectionFormatTitre elementor-widget elementor-widget-text-editor\" data-id=\"2f60f3f\" data-element_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 style=\"text-align: center;\">Merci de s\u00e9lectionner un format d&rsquo;annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6b485447 elementor-widget-mobile__width-inherit elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile SelectionFormatTitreBlancOLD elementor-widget elementor-widget-text-editor\" data-id=\"6b485447\" data-element_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 style=\"text-align: center;\">Vous pouvez changer de format d&rsquo;annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-78e1d9f5 e-con-full EspPubFormatListe e-flex e-con e-child\" data-id=\"78e1d9f5\" data-element_type=\"container\">\n\t\t<a class=\"elementor-element elementor-element-cf3602e e-con-full EspPubFormatContainer FormatIdCreation e-flex e-con e-child\" data-id=\"cf3602e\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-7a1bb33 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"7a1bb33\" data-element_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\tCr\u00e9ation\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-6bf72a5 e-con-full EspPubFormatContainer FormatIdPopUp e-flex e-con e-child\" data-id=\"6bf72a5\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-1a57dd9 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"1a57dd9\" data-element_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\tPop-up\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-34d8bbba e-con-full EspPubFormatContainer FormatIdBanniere e-flex e-con e-child\" data-id=\"34d8bbba\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-32bd35c6 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"32bd35c6\" data-element_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\tBanni\u00e8re\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-5a9252c3 e-con-full EspPubFormatContainer FormatIdVideo e-flex e-con e-child\" data-id=\"5a9252c3\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8722042 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"8722042\" data-element_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\tVid\u00e9o\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-19ecc2b3 e-con-full EspPubFormatContainer FormatIdCommunique e-flex e-con e-child\" data-id=\"19ecc2b3\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6071d405 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"6071d405\" data-element_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\tCommuniqu\u00e9\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-3617569c e-con-full EspPubFormatContainer FormatIdInterview e-flex e-con e-child\" data-id=\"3617569c\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4b013e71 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"4b013e71\" data-element_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\tInterview\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-7450a6f8 e-con-full EspPubFormatContainer FormatIdParrainage e-flex e-con e-child\" data-id=\"7450a6f8\" data-element_type=\"container\" href=\"#\">\n\t\t\t\t<div class=\"elementor-element elementor-element-30970f89 EspPubFormat elementor-widget elementor-widget-text-editor\" data-id=\"30970f89\" data-element_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\tParrainage\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/a>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-6aac67a6 e-con-full HTMLUploadfileConteneur e-flex e-con e-child\" data-id=\"6aac67a6\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-40d299c elementor-widget__width-inherit HTMLUploadfileClass elementor-widget elementor-widget-html\" data-id=\"40d299c\" data-element_type=\"widget\" id=\"HTMLUploadfile\" 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=\"en\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <meta name=\"google\" content=\"notranslate\">\r\n    \r\n    <script data-jetpack-boost=\"ignore\" src=\"https:\/\/code.jquery.com\/jquery-3.6.0.min.js\"><\/script>\r\n    <script data-jetpack-boost=\"ignore\" src=\"https:\/\/code.jquery.com\/ui\/1.12.1\/jquery-ui.min.js\"><\/script>\r\n\r\n<script data-jetpack-boost=\"ignore\">\r\n\/\/ Lazy loading des biblioth\u00e8ques - charg\u00e9es uniquement au besoin\r\nwindow.VIALibraries = {\r\n    mammothLoaded: false,\r\n    pdfLoaded: false,\r\n    \r\n    loadMammoth: function(callback) {\r\n        if (this.mammothLoaded) { callback(); return; }\r\n        var script = document.createElement('script');\r\n        script.src = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/mammoth\/1.4.0\/mammoth.browser.min.js';\r\n        script.onload = function() { \r\n            window.VIALibraries.mammothLoaded = true; \r\n            callback(); \r\n        };\r\n        document.head.appendChild(script);\r\n    },\r\n    \r\n    loadPdfJs: function(callback) {\r\n        if (this.pdfLoaded) { callback(); return; }\r\n        var script = document.createElement('script');\r\n        script.src = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.11.174\/pdf.min.js';\r\n        script.onload = function() {\r\n            window.VIALibraries.pdfLoaded = true;\r\n            pdfjsLib.GlobalWorkerOptions.workerSrc = '\/\/cdn.jsdelivr.net\/npm\/pdfjs-dist@latest\/build\/pdf.worker.min.js';\r\n            callback();\r\n        };\r\n        document.head.appendChild(script);\r\n    }\r\n};\r\n<\/script>\r\n\r\n<\/head>\r\n<body>\r\n    <div id=\"PopUpMessageAchattest\" class=\"draggable\" draggable=\"true\" style=\"justify-content: center; align-items: flex-start;\">\r\n        <div id=\"drop_file_zone_achat\" class=\"drop_file_zone_achat_class\" ondrop=\"uploadFile_achat(event)\" ondragover=\"return false\">\r\n        <div id=\"drag_upload_file_achat\">\r\n            <p><input class=\"button-2_achat\" type=\"button\" value=\"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\" onclick=\"fileExplorer_achat(event);\" \/><\/p>\r\n                <input type=\"file\" id=\"selectfile_achat\" \/>\r\n        <\/div>\r\n        <\/div>\r\n        <div class=\"img-content\"><\/div>\r\n    <\/div>\r\n<\/body>\r\n<\/html>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1fd15d20 elementor-widget__width-inherit HTMLUploadfileClass elementor-widget elementor-widget-html\" data-id=\"1fd15d20\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<script data-jetpack-boost=\"ignore\">\r\nif (!window._espPubScriptLoaded) {\r\nwindow._espPubScriptLoaded = true;\r\n\/**\r\n * Configuration centralis\u00e9e\r\n *\/\r\nconst CONFIG = {\r\n    iframeId: 'yearbook-iframe',\r\n    ajaxUrl: 'https:\/\/via-agency.media\/wp-admin\/admin-ajax.php',\r\n    apercuUrl: 'https:\/\/rdc.yearbook-media.com\/apercu',\r\n    \r\n    allowedExtensions: {\r\n        video: ['mp4', 'mov', 'wmv', 'avi', 'flv', 'f4v', 'swf', 'mkv', 'webm', 'mpeg'],\r\n        image: ['jpg', 'jpeg', 'png', 'gif', 'tif', 'svg', 'webp'],\r\n        document: ['doc', 'docx', 'ppt', 'pptx', 'pdf']\r\n    },\r\n    \r\n    mimeTypes: {\r\n        docx: 'application\/vnd.openxmlformats-officedocument.wordprocessingml.document',\r\n        pdf: 'application\/pdf'\r\n    },\r\n    \r\n    dragScroll: {\r\n        threshold: 150,\r\n        maxSpeed: 65,\r\n        throttleDelay: 50\r\n    },\r\n    \r\n    breakpoints: {\r\n        mobile: 1000\r\n    },\r\n    \r\n    keywords: [\r\n        { normal: \"parrainage\", display: \"Parrainage\" },\r\n        { normal: \"communique\", display: \"Communiqu\u00e9\" },\r\n        { normal: \"interview\", display: \"Interview\" }\r\n    ]\r\n};\r\n\r\n\/**\r\n * \u2705 v1.19.1 : Module de positionnement dans l'iframe\r\n * \r\n * PROBL\u00c8ME : L'iframe ne scrolle pas en desktop \u2014 c'est le parent (#PageWebTitrePage) qui scrolle.\r\n * L'iframe est scal\u00e9e \u00e0 0.85 \u2192 les coordonn\u00e9es iframe \u2260 coordonn\u00e9es parent.\r\n * position:fixed dans l'iframe = relatif au CONTENU TOTAL, pas au viewport visible.\r\n * \r\n * SOLUTION : Le parent calcule visibleTopIframe (la position iframe du haut du viewport)\r\n * et l'envoie dans le message 'PageWebTitrePage-scroll'. L'iframe n'a qu'\u00e0 l'utiliser.\r\n * \r\n * Pour scroller, l'iframe envoie 'scrollToIframeY' au parent qui fait la conversion.\r\n *\/\r\nconst ScrollHelper = {\r\n    _visibleTopIframe: 0,\r\n    _iframeScale: 0.85,\r\n\r\n    init() {\r\n        \/\/ \u00c9couter les donn\u00e9es de scroll envoy\u00e9es par le parent\r\n        window.addEventListener('message', (event) => {\r\n            var msg = event.data;\r\n            if (msg && msg.action === 'PageWebTitrePage-scroll') {\r\n                if (typeof msg.visibleTopIframe === 'number') {\r\n                    this._visibleTopIframe = msg.visibleTopIframe;\r\n                }\r\n                if (typeof msg.iframeScale === 'number') {\r\n                    this._iframeScale = msg.iframeScale;\r\n                }\r\n            }\r\n        });\r\n        console.log('\u2705 ScrollHelper initialis\u00e9');\r\n    },\r\n\r\n    \/**\r\n     * Position Y dans le document iframe correspondant au haut du viewport visible\r\n     *\/\r\n    getVisibleTop() {\r\n        if (window === window.top) {\r\n            return window.scrollY || 0;\r\n        }\r\n        return this._visibleTopIframe;\r\n    },\r\n\r\n    \/**\r\n     * Demande au parent de scroller pour positionner `element` \u00e0 `offsetFromTop` px du viewport\r\n     *\/\r\n    scrollElementTo(element, offsetFromTop) {\r\n        if (!element) return;\r\n\r\n        \/\/ getBoundingClientRect().top dans une iframe sans scroll = position absolue Y\r\n        var elementAbsY = element.getBoundingClientRect().top;\r\n\r\n        if (window === window.top) {\r\n            window.scrollTo({ top: elementAbsY - offsetFromTop + (window.scrollY || 0), behavior: 'smooth' });\r\n            return;\r\n        }\r\n\r\n        \/\/ Envoyer au parent \u2014 le parent fait la conversion scale\r\n        window.parent.postMessage({\r\n            type: 'scrollToIframeY',\r\n            iframeId: CONFIG.iframeId,\r\n            iframeY: elementAbsY,\r\n            offsetFromTop: offsetFromTop\r\n        }, '*');\r\n        console.log('\ud83d\udcdc scrollToIframeY:', { iframeY: Math.round(elementAbsY), offsetFromTop });\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'\u00e9tat (SessionStorage)\r\n *\/\r\nconst StateManager = {\r\n    init() {\r\n        if (sessionStorage.getItem(\"AchatEspaceCall\") === 'No') {\r\n            sessionStorage.clear();\r\n        }\r\n        \r\n        this.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        this.set('dragstart_Rank_Emplacement_Page_Web', 'No');\r\n        this.set('dragstart_Commande_Emplacement_Page_Web', 'No');\r\n        \r\n        \/\/ \u2705 v2.1.1 : Popup \u2192 ne jamais pr\u00e9remplir le format\r\n        if (this.get('PopUpChoice') === 'Yes') {\r\n            this.set('Formatchoisi', 'No');\r\n            this.set('FormatSelect', '');\r\n            this.set('Commande_Format_Transmis', '');\r\n        }\r\n    },\r\n    \r\n    get(key) {\r\n        return sessionStorage.getItem(key);\r\n    },\r\n    \r\n    set(key, value) {\r\n        sessionStorage.setItem(key, value);\r\n    },\r\n    \r\n    getMultiple(keys) {\r\n        return keys.reduce((acc, key) => {\r\n            acc[key] = this.get(key);\r\n            return acc;\r\n        }, {});\r\n    },\r\n    \r\n    setMultiple(obj) {\r\n        Object.entries(obj).forEach(([key, value]) => {\r\n            this.set(key, value);\r\n        });\r\n    },\r\n    \r\n    buildEmplacementReference(rank) {\r\n        const codeSite = this.get('codeSite');\r\n        const codePage = this.get('codePage');\r\n        return `${codeSite}${codePage}L${rank.substring(3)}`;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion des fichiers\r\n *\/\r\nconst FileManager = {\r\n    getExtension(filename) {\r\n        console.log('filename:', filename);\r\n        const parts = filename.split('.');\r\n        return parts.length > 1 ? parts.pop().toLowerCase() : '';\r\n    },\r\n    \r\n    isAllowedExtension(extension) {\r\n        return Object.values(CONFIG.allowedExtensions)\r\n            .flat()\r\n            .includes(extension);\r\n    },\r\n    \r\n    getFileType(extension) {\r\n        for (const [type, extensions] of Object.entries(CONFIG.allowedExtensions)) {\r\n            if (extensions.includes(extension)) {\r\n                return type;\r\n            }\r\n        }\r\n        return null;\r\n    },\r\n    \r\n    async urlToFile(url, filename) {\r\n        console.log(\"Fetching from URL:\", url);\r\n        \r\n        const mimeType = filename.includes('.docx') \r\n            ? CONFIG.mimeTypes.docx \r\n            : filename.includes('.pdf') \r\n            ? CONFIG.mimeTypes.pdf \r\n            : null;\r\n        \r\n        try {\r\n            const response = await fetch(url);\r\n            \r\n            if (!response.ok) {\r\n                throw new Error(`Network response was not ok: ${response.status} ${response.statusText}`);\r\n            }\r\n            \r\n            const blob = await response.blob();\r\n            return new File([blob], filename, { type: mimeType });\r\n        } catch (error) {\r\n            console.error(\"Error in urlToFile:\", error);\r\n            alert(\"Erreur lors du chargement du fichier. Veuillez r\u00e9essayer.\");\r\n            throw error;\r\n        }\r\n    },\r\n    \r\n    createObjectUrl(file) {\r\n        \/\/ R\u00e9voquer l'ancien URL si existant\r\n        const oldUrl = StateManager.get('objectUrl');\r\n        if (oldUrl && oldUrl.startsWith('blob:')) {\r\n            URL.revokeObjectURL(oldUrl);\r\n            console.log('\ud83d\uddd1\ufe0f Old Object URL revoked');\r\n        }\r\n        \r\n        const url = URL.createObjectURL(file);\r\n        StateManager.set('objectUrl', url);\r\n        return url;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion du Drag & Drop\r\n *\/\r\nconst DragDropManager = {\r\n    state: {\r\n        isFileBeingDragged: false,\r\n        draggedFile: null,\r\n        dragInProgress: false,\r\n        throttleTimeout: null\r\n    },\r\n    \r\n    init() {\r\n        this.attachEventListeners();\r\n    },\r\n    \r\n    attachEventListeners() {\r\n        window.addEventListener('dragstart', (e) => this.handleDragStart(e), true);\r\n        jQuery(document).on('dragover', (e) => this.handleDragOver(e));\r\n        jQuery(document).on('dragleave drop', (e) => this.handleDragEnd(e));\r\n        jQuery(\"#drop_file_zone_achat\").on(\"dragover\", (e) => this.handleDropZoneDragOver(e));\r\n        jQuery(\".draggable\").on(\"dragend\", (e) => this.handleDraggableEnd(e));\r\n    },\r\n    \r\n    handleDragStart(e) {\r\n        console.log('Window-level dragstart', e);\r\n        this.state.dragInProgress = true;\r\n    \r\n        const $target = $(e.target);\r\n        const droppableParent = $target.closest('.droppable');\r\n        const parentId = droppableParent.length ? droppableParent.attr('id') : null;\r\n        \r\n        StateManager.set('dragstart_Rank_Emplacement_Page_Web', parentId);\r\n        console.log('dragstart_Rank_Emplacement_Page_Web', parentId);\r\n        \r\n        \/\/ \u2705 CALCULER IMM\u00c9DIATEMENT dragstart_Commande_Emplacement_Page_Web\r\n        if (parentId) {\r\n            const dragstartRef = StateManager.buildEmplacementReference(parentId);\r\n            StateManager.set('dragstart_Commande_Emplacement_Page_Web', dragstartRef);\r\n            console.log('dragstart_Commande_Emplacement_Page_Web', dragstartRef);\r\n            \/\/ \u2705 v2.4.5 : Capturer l'\u00e9tat checkbox R\u00e9server au moment du dragstart\r\n            \/\/ Si l'utilisateur a explicitement d\u00e9coch\u00e9, forcer \u00e0 No m\u00eame si DOM est coch\u00e9\r\n            var $_dragCb = $('#' + parentId).find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]');\r\n            var _dragCbChecked = $_dragCb.prop('checked') === true;\r\n            var _expliciteDecocheDrag = StateManager.get('_reserverDecoche_' + parentId) === 'Yes';\r\n            var _reserverDrag = _dragCbChecked && !_expliciteDecocheDrag;\r\n            StateManager.set('dragstart_ReserverChecked', _reserverDrag ? 'Yes' : 'No');\r\n            \/\/ R\u00e9initialiser le flag apr\u00e8s lecture\r\n            StateManager.set('_reserverDecoche_' + parentId, 'No');\r\n            console.log('[dragstart] ReserverChecked dom:', _dragCbChecked, '| d\u00e9coch\u00e9 explicitement:', _expliciteDecocheDrag, '| final:', _reserverDrag);\r\n        }\r\n    \r\n        const dataTransfer = e.dataTransfer || e.originalEvent?.dataTransfer;\r\n        const files = dataTransfer?.files || null;\r\n        \r\n        const imgSrc = $target.closest('.draggable').find('img').attr('src');\r\n        const videoSrc = $target.closest('.draggable').find('video').attr('src') || \r\n                        $target.closest('.draggable').find('video source').attr('src');\r\n        const mediaSrc = imgSrc || videoSrc;\r\n    \r\n        console.log('dragstart target:', e.target);\r\n        console.log('files:', files);\r\n        console.log('mediaSrc:', mediaSrc);\r\n    \r\n        if (!mediaSrc && (!files || files.length === 0)) {\r\n            console.log('No media source or files found, preventing drag');\r\n            e.preventDefault();\r\n            this.state.dragInProgress = false;\r\n            return false;\r\n        }\r\n    \r\n        if (mediaSrc) {\r\n            StateManager.set('objectUrl', mediaSrc);\r\n        }\r\n    \r\n        StateManager.set('Commande_Format_Transmis', '');\r\n        \r\n        if ($target.closest('.droppable').find('.doc-preview-container:visible').length > 0) {\r\n            StateManager.set('Commande_Format_Transmis', 'R\u00e9dactionnel');\r\n            StateManager.set('FullPathAdFile', \r\n                $target.closest('.droppable').find('.doc-preview-FullPathAdFile').text());\r\n        }\r\n    \r\n        if (files && files.length > 0) {\r\n            this.state.isFileBeingDragged = true;\r\n            this.state.draggedFile = files[0];\r\n        }\r\n        \r\n        \/\/ \u2705 TOUJOURS marquer comme \"Moved\" quand on drag depuis un espace existant\r\n        if (parentId && mediaSrc) {\r\n            StateManager.set('FirstUploadFileorMoved', 'Moved');\r\n            console.log('\u2705 Drag depuis espace existant - Moved');\r\n        }\r\n    \r\n        console.log('Drag Started', {\r\n            file: this.state.draggedFile,\r\n            mediaSrc: mediaSrc,\r\n            dragstartRef: StateManager.get('dragstart_Commande_Emplacement_Page_Web')\r\n        });\r\n    },\r\n    \r\n    handleDragOver(e) {\r\n        e.preventDefault();\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            this.handleIframeDragScroll(e);\r\n        } else {\r\n            this.handleDirectPageScroll(e);\r\n        }\r\n    },\r\n    \r\n    handleIframeDragScroll(e) {\r\n        if (!this.state.throttleTimeout) {\r\n            this.state.throttleTimeout = setTimeout(() => {\r\n                MessageManager.sendToParent('dragScroll', { clientY: e.clientY });\r\n                this.state.throttleTimeout = null;\r\n            }, CONFIG.dragScroll.throttleDelay);\r\n        }\r\n    },\r\n    \r\n    handleDirectPageScroll(e) {\r\n        const { threshold, maxSpeed } = CONFIG.dragScroll;\r\n        const windowHeight = window.innerHeight;\r\n        \r\n        if (e.clientY < threshold) {\r\n            const speed = Math.max(1, maxSpeed * (1 - e.clientY \/ threshold));\r\n            window.scrollBy(0, -speed);\r\n        } else if (e.clientY > windowHeight - threshold) {\r\n            const speed = Math.max(1, maxSpeed * (1 - (windowHeight - e.clientY) \/ threshold));\r\n            window.scrollBy(0, speed);\r\n        }\r\n    },\r\n    \r\n    handleDragEnd(e) {\r\n        e.preventDefault();\r\n        MessageManager.sendToParent('dragEnd', {});\r\n        console.log('dragleave drop');\r\n    },\r\n    \r\n    handleDropZoneDragOver(e) {\r\n        e.preventDefault();\r\n        console.log(\"FirstUploadFileorMoved:\", StateManager.get('FirstUploadFileorMoved'));\r\n    },\r\n    \r\n    handleDraggableEnd(e) {\r\n        e.preventDefault();\r\n        this.resetState();\r\n        console.log('dragend');\r\n    },\r\n    \r\n    resetState() {\r\n        this.state.isFileBeingDragged = false;\r\n        this.state.draggedFile = null;\r\n        this.state.dragInProgress = false;\r\n    },\r\n    \r\n    clearDataTransferFiles(e) {\r\n        e.dataTransfer = new DataTransfer();\r\n        console.log('DataTransfer files cleared');\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'interface utilisateur\r\n *\/\r\nconst UIManager = {\r\n    isMobile() {\r\n        return window.outerWidth < CONFIG.breakpoints.mobile;\r\n    },\r\n    \r\n    isDesktop() {\r\n        const userAgent = navigator.userAgent;\r\n        const isWindows = userAgent.indexOf('Windows') > -1;\r\n        const isMac = userAgent.indexOf('Macintosh') > -1;\r\n        const isLinux = userAgent.indexOf('Linux') > -1 && userAgent.indexOf('Android') === -1;\r\n        return isWindows || isMac || isLinux;\r\n    },\r\n    \r\n    initMobileUI() {\r\n        $(document).ready(() => {\r\n            $('label[for=\"form-field-LienAnnonce\"]').each(function() {\r\n                $(this).text('Renseigner le lien hypertexte de l\\'annonce');\r\n            });\r\n            \r\n            $('input[name=\"form_fields[LienAnnonce]\"]').each(function() {\r\n                $(this).attr('placeholder', 'Renseigner le lien hypertexte de l\\'annonce');\r\n            });\r\n        });\r\n        \r\n        jQuery('.MsgDatesText').hide();\r\n        this.attachMobileEventListeners();\r\n    },\r\n    \r\n    attachMobileEventListeners() {\r\n        jQuery('.TransmettreFichierAnnonceContainer').on('click', (e) => {\r\n            this.handleMobileSpaceSelection(e);\r\n        });\r\n        \r\n        jQuery('[id=\"form-field-selected_currency_Mobile\"]').off('change').on('change', (e) => {\r\n            this.handleMobileCurrencyChange(e);\r\n        });\r\n    },\r\n    \r\n    handleMobileSpaceSelection(e) {\r\n        e.preventDefault();\r\n        jQuery('#IndisponibilitesMsg').hide();\r\n        \r\n        jQuery('input[name=\"form_fields[SelectEspacePublicitaireMobile]\"]').prop('checked', false);\r\n        jQuery(e.currentTarget).find('input[name=\"form_fields[SelectEspacePublicitaireMobile]\"]').prop('checked', true);\r\n        \r\n        StateManager.set(\"PageWebDisplayed\", 'Yes');\r\n        \r\n        jQuery('.FormSelectDevisesMobile').hide();\r\n        jQuery(e.target).closest('.EspacePublicitaireMobile').find('.FormSelectDevisesMobile').show();\r\n        \r\n        const $droppable = jQuery(e.currentTarget).closest('.droppable');\r\n        const rankId = $droppable.attr('id');\r\n        \r\n        StateManager.set('Rank_Emplacement_Page_Web', rankId);\r\n        StateManager.set('Commande_Emplacement_Page_Web', \r\n            StateManager.buildEmplacementReference(rankId));\r\n        \r\n        this.updateEmplacementDisplay();\r\n        this.handleAvailabilityDisplay(e);\r\n        this.displayUploadedAdIfExists(e);\r\n        this.updateTariffDisplay(e);\r\n    },\r\n    \r\n    updateEmplacementDisplay() {\r\n        const emplacement = StateManager.get('Commande_Emplacement_Page_Web');\r\n        jQuery('#EmplacementAnnonceDataStep3').html(emplacement).css({'color': '#56BE50'});\r\n        console.log(\"Emplacement:\", emplacement);\r\n    },\r\n    \r\n    handleAvailabilityDisplay(e) {\r\n        const $espace = jQuery(e.target).closest('.EspacePublicitaireMobile');\r\n        const dispoText = $espace.find('.ChoisirEspacePublicitaireDisponibilite').text();\r\n        \r\n        if (dispoText.length > 46) {\r\n            const espacePublicitaireDispoFrom = dispoText.slice(-10);\r\n            console.log(\"espacePublicitaireDispoFrom:\", espacePublicitaireDispoFrom);\r\n            console.log(\"Date de debut:\", StateManager.get(\"Debut_de_campagne\"));\r\n        } else {\r\n            jQuery('#form-field-DebutCampagne').val(StateManager.get(\"Debut_de_campagne\"));\r\n        }\r\n    },\r\n    \r\n    displayUploadedAdIfExists(e) {\r\n        if (StateManager.get(\"FileReceived\") === 'Yes') {\r\n            jQuery('.VisualisationAnnonceMobile').hide();\r\n            \r\n            const espaceId = StateManager.get('espaceChoisi');\r\n            const $espace = document.querySelector(`[id=\"${espaceId}\"]`);\r\n            \r\n            jQuery($espace).find('.MessageAnnonceMobileTexte')\r\n                .html('Merci de choisir des dates de campagne<br>afin d\\'obtenir le tarif de cet espace publicitaire');\r\n            jQuery($espace).find('.VisualisationAnnonceMobile').show();\r\n        \r\n            const img = document.createElement('img');\r\n            img.src = StateManager.get('objectUrl');\r\n            img.style.width = 'auto';\r\n            img.style.height = 'auto';\r\n            img.style.maxWidth = '100%';\r\n            img.style.maxHeight = '200px';\r\n            \r\n            jQuery('.VisualisationAnnonceMobile').empty();\r\n            jQuery($espace).find('.VisualisationAnnonceMobile').append(img);\r\n        }\r\n    },\r\n    \r\n    updateTariffDisplay(e) {\r\n        jQuery('.TariftobedisplayedMobile').html('-');\r\n        const newTarif = StateManager.get('NewTarifformatted');\r\n        \r\n        if (newTarif && newTarif !== '-') {\r\n            jQuery(e.target).closest('.EspacePublicitaireMobile')\r\n                .find('.TariftobedisplayedMobile')\r\n                .html(newTarif);\r\n        }\r\n    },\r\n    \r\n    handleMobileCurrencyChange(e) {\r\n        event.preventDefault();\r\n        StateManager.setMultiple({\r\n            \"SelectionCatalogueOuAchat\": 'Catalogue',\r\n            \"selected_currency\": jQuery(e.currentTarget).val()\r\n        });\r\n        \r\n        jQuery('#form-field-selected_currency_2').val(StateManager.get(\"selected_currency\"));\r\n        console.log(\"selected currency:\", StateManager.get(\"selected_currency\"));\r\n        \r\n        setTimeout(() => {\r\n            jQuery(e.target).closest('.EspacePublicitaireMobile')\r\n                .find('.TariftobedisplayedMobile')\r\n                .html(StateManager.get(\"NewTarifformatted\"));\r\n        }, 500);\r\n    },\r\n    \r\n    initDesktopUI() {\r\n        StateManager.setMultiple({\r\n            \"FileReceived\": \"No\",\r\n            \"AdDisplayed\": \"No\"\r\n        });\r\n        jQuery('.MsgAdNotDisplayed').hide();\r\n    },\r\n    \r\n    showUploadProgress($dropZone) {\r\n        \/\/ Cacher les \u00e9l\u00e9ments\r\n        $dropZone.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed, span.ClassHdpCdp, .ClassRefEsp, .HideFormButton, .EspPubFormatMainContainer, .TexteMobileAnnonce')\r\n            .hide();\r\n        \r\n        \/\/ Afficher et styler le message de progression\r\n        var _uplMsg = 'Loading in progress <span class=\"dot-container\"><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><\/span>';\r\n        $dropZone.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed')\r\n            .show()\r\n            .html(_uplMsg)\r\n            .css({\r\n                'color': '#00ff19',\r\n                'background-color': 'white',\r\n                'padding': '12px 20px',\r\n                'border-radius': '6px',\r\n                'font-weight': '700',\r\n                'font-size': '18px',\r\n                'line-height': '1.4',\r\n                'display': 'inline-block',\r\n                'margin': '10px auto',\r\n                'text-align': 'center'\r\n            });\r\n        \r\n        \/\/ Cacher les autres \u00e9l\u00e9ments\r\n        $dropZone.closest('.droppable')\r\n            .find('.UploadIci, .EnvoiUlterieurTexte, .EnvoiUlterieurContainer')\r\n            .hide();\r\n            \r\n        $dropZone.closest('.droppable')\r\n            .find('.UploadFileConteneur')\r\n            .css({\r\n                'background-color': 'transparent'\r\n            });\r\n    },\r\n    \r\n    showFormatError($dropZone, message = 'Format de fichier incompatible') {\r\n        \/\/ \u2705 v2.4.6 : M\u00eame rendu overlay que le bloc jpeg \u2014 position absolute sur $dropZone\r\n        var _errId = 'fmt-error-msg-' + Date.now();\r\n        $dropZone.css('position', 'relative');\r\n        var _errHtml = '<div id=\"' + _errId + '\" style=\"'\r\n            + 'position:absolute;top:50px;left:50%;transform:translateX(-50%);width:auto;white-space:nowrap;'\r\n            + 'background:#fff;color:#FB5E2A;font-weight:700;font-size:13px;'\r\n            + 'text-align:center;padding:8px 10px;border-radius:6px;'\r\n            + 'border:2px solid #FB5E2A;box-sizing:border-box;'\r\n            + 'z-index:99999;line-height:1.4;'\r\n            + '\">' + message + '<\/div>';\r\n        $dropZone.append(_errHtml);\r\n        setTimeout(function() { jQuery('#' + _errId).remove(); }, 4000);\r\n    },\r\n    \r\n    updateAfterSuccessfulUpload($dropZone) {\r\n        jQuery('#errorMessageMobileText').hide();\r\n        \r\n        $dropZone.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed, span.ClassHdpCdp, .ClassRefEsp, .HideFormButton, .EspPubFormatMainContainer, .EnvoiUlterieurContainer')\r\n            .hide();\r\n        \r\n        \/\/ \u2705 Pas de margin-top:150px si d\u00e9p\u00f4t depuis miniature kit (d\u00e9j\u00e0 positionn\u00e9)\r\n        if (!window._dropFromMiniature) {\r\n            $dropZone.closest('.OrdiMobileConteneurClass')\r\n                .css({'margin-top': '150px', 'margin-bottom': '0px'});\r\n        }\r\n    },\r\n    \r\n    finalizeAdDisplay($dropZone) {\r\n        StateManager.setMultiple({\r\n            \"FileReceived\": \"Yes\",\r\n            \"PageWebDisplayed\": \"Yes\"\r\n        });\r\n        \r\n        jQuery('#MsgChoixPageWeb, #MsgInsererAnnonceConteneur').hide();\r\n        jQuery('#ChoixEspacePublicitaire')\r\n            .html('L\\'annonce est plac\u00e9e dans un espace publicitaire')\r\n            .show()\r\n            .css({'color': '#56BE50'});\r\n        \r\n        jQuery('#MsgPlacerAnnoncePosition').hide();\r\n        jQuery('#FonctionMenu4').show();\r\n        jQuery('.AnnonceData').html(\"Transmis\").css({'color': '#56BE50'});\r\n        \r\n        jQuery('#ProcederPaiementConteneur').hide();\r\n        jQuery('#ProcederPaiementTitreIconeUp').hide();\r\n        jQuery('#ProcederPaiementTitreIconeDown').show();\r\n        \r\n        jQuery('#message').remove();\r\n        \r\n        this.styleUploadedAd($dropZone);\r\n        this.adjustLayoutAfterUpload($dropZone);\r\n        \r\n        \/\/ \u2705 Mettre \u00e0 jour l'\u00e9tat de la checkbox \"R\u00e9server\" apr\u00e8s upload\r\n        FormatUIManager.updateReserverCheckboxState($dropZone.closest('.droppable'));\r\n    },\r\n    \r\n    styleUploadedAd($dropZone) {\r\n        const $container = $dropZone.closest('.OrdiMobileConteneurClass');\r\n        const $droppable = $dropZone.closest('.droppable');\r\n        \r\n        \/\/ \u2705 v1.19.5 : V\u00e9rifier si c'est une restauration via flag d\u00e9di\u00e9\r\n        const isRestoration = StateManager.get('_isAdRestoration') === 'Yes';\r\n        \r\n        $container\r\n            .find('.PositionReference, .TexteMobile, .EnvoiUlterieurContainer')\r\n            .hide();\r\n        \r\n        $container\r\n            .find('.AdUploadedTitle, .DimensionsMaximales')\r\n            .show();\r\n        \r\n        \/\/ \u2705 Bug 2 fix : montrer le conteneur parent + la croix (CroixResetAnnonceContainer cach\u00e9 par reset)\r\n        $droppable.find('.CroixResetAnnonceContainer').show();\r\n        $droppable.find('#CroixResetAnnonce').show();\r\n        \r\n        \/\/ \u2705 v2.2 : Marquer le droppable comme occup\u00e9 pour qu'Entete le skip\r\n        $droppable.attr('data-via-ad-loaded', 'true');\r\n        \r\n        \/\/ \u2705 v2.0.11 : AdUploadedTitle ne doit pas bloquer le touch sur doc-preview-readmore (mobile)\r\n        $container.find('.AdUploadedTitle').css('pointer-events', 'none');\r\n        \r\n        \/\/ \u2705 #CroixResetAnnonce au-dessus de tous les conteneurs superpos\u00e9s\r\n        $container.find('#CroixResetAnnonce').css({\r\n            'position': 'relative',\r\n            'z-index': '9999'\r\n        });\r\n        \r\n        \/\/ \u2705 Desktop : les conteneurs superpos\u00e9s bloquent la croix \u2014 les rendre transparents aux clics\r\n        if (!UIManager.isMobile()) {\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css('pointer-events', 'none');\r\n            \/\/ R\u00e9activer les \u00e9l\u00e9ments interactifs\r\n            $container.find('#CroixResetAnnonce').css('pointer-events', 'auto');\r\n            $dropZone.closest('#PopUpMessageAchattest').css('pointer-events', 'auto'); \/\/ drag annonce\r\n        }\r\n        \r\n        \/\/ \u2705 v2.4.3 : Sur mobile, masquer titre et logo drag quand annonce d\u00e9pos\u00e9e dans Ele0A\r\n        if (UIManager.isMobile()) {\r\n            if ($droppable.attr('id') === 'Ele0A') {\r\n                $droppable.find('#ChoixEspacePublicitaireTexte').hide();\r\n                $droppable.find('#Ele0ADragHandle').hide();\r\n                \/\/ \u2705 v2.4.12 : UploadFileConteneur a pointer-events:none \u2192 forcer auto sur la croix\r\n                $droppable.find('.CroixResetAnnonceContainer')[0] && $droppable.find('.CroixResetAnnonceContainer')[0].style.setProperty('pointer-events', 'auto', 'important');\r\n                $droppable.find('#CroixResetAnnonce')[0] && $droppable.find('#CroixResetAnnonce')[0].style.setProperty('pointer-events', 'auto', 'important');\r\n            }\r\n        }\r\n        \r\n        jQuery(\".HTMLUploadfileConteneur\").css({\r\n            'border': 'none',\r\n            'background-color': 'transparent'\r\n        });\r\n        \r\n        \/\/ \u2705 v2.4.12 : Retirer le liser\u00e9 envoi diff\u00e9r\u00e9 (#UploadFileConteneur) si pr\u00e9sent\r\n        \/\/ (le d\u00e9p\u00f4t d'une annonce cr\u00e9e son propre liser\u00e9 sur .HTMLUploadfileConteneur)\r\n        var $_ufcEd = $dropZone.closest('.droppable').find('#UploadFileConteneur');\r\n        if ($_ufcEd[0]) {\r\n            $_ufcEd[0].style.removeProperty('box-shadow');\r\n            $_ufcEd[0].style.removeProperty('box-sizing');\r\n            if (UIManager.isMobile()) {\r\n                $_ufcEd[0].style.removeProperty('transform');\r\n                $_ufcEd[0].style.removeProperty('transform-origin');\r\n            }\r\n        }\r\n        \r\n        $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n            'box-shadow': 'inset 0 0 0 2px #00FF19',  \/\/ \u2705 v2.4.5 : inset \u2192 jamais clipp\u00e9 par overflow:hidden\r\n            'background-color': 'white',\r\n            'box-sizing': 'border-box',\r\n            'overflow': 'hidden'\r\n        });\r\n        \r\n        \/\/ \u2705 v2.0.9 : Fix mobile \u2014 r\u00e9duire le scale pour que le liser\u00e9 vert soit visible\r\n        \/\/ \u2705 Pas de scale si annonce d\u00e9pos\u00e9e depuis la miniature kit (d\u00e9j\u00e0 aux bonnes dimensions)\r\n        \/\/ \u2705 v2.4.9 : Pas de scale si AchatEspaceCall=Yes (drop depuis miniature dans iframe)\r\n        \/\/ \u2705 data-kit-drop : marqueur DOM pos\u00e9 par kitAdCreated, r\u00e9siste \u00e0 l'async\r\n        var _fromKitDrop = $droppable[0] ? $droppable[0].getAttribute('data-kit-drop') === 'true' : false;\r\n        if (_fromKitDrop) { window._dropFromMiniature = true; } \/\/ sync le flag window\r\n        var _fromMiniature = window._dropFromMiniature || _fromKitDrop;\r\n        var _fromAchat = StateManager.get('AchatEspaceCall') === 'Yes';\r\n        if (UIManager.isMobile() && !_fromMiniature && !_fromAchat) {\r\n            $dropZone.closest('.UploadFileConteneur').css({\r\n                'transform': 'scale(1.35)',\r\n                'transform-origin': 'top center'\r\n            });\r\n            \/\/ \u2705 v2.4.11 : Corps de page mobile \u2014 le .ToBeHidden clippe le scale(1.35) c\u00f4t\u00e9 droit\r\n            \/\/ \u2192 overflow:visible pour que le liser\u00e9 vert soit visible sur les 4 c\u00f4t\u00e9s\r\n            $dropZone.closest('.ToBeHidden').css('overflow', 'visible');\r\n        }\r\n        \r\n        \/\/ \u2705 v2.2 : Sur restauration, Entete a d\u00e9j\u00e0 positionn\u00e9 le droppable correctement\r\n        \/\/ et est emp\u00each\u00e9 de le retoucher (data-via-ad-loaded). On ne touche pas aux marges.\r\n        \/\/ Sur premier upload, on applique les marges normalement.\r\n        \/\/ \u2705 Pas de marges si d\u00e9p\u00f4t depuis miniature kit (dimensions naturelles conserv\u00e9es)\r\n        if (!isRestoration && !_fromMiniature) {\r\n            if ($container.data('orig-mb') === undefined) {\r\n                $container.data('orig-mb', parseInt($container.css('margin-bottom')) || 0);\r\n            }\r\n            if ($droppable.data('orig-mt') === undefined) {\r\n                $droppable.data('orig-mt', parseInt($droppable.css('margin-top')) || 0);\r\n            }\r\n            var _isDocPreview = $dropZone.find('.doc-preview-container').length > 0;\r\n            var _marginAdd = _isDocPreview ? 60 : 130;\r\n            var _marginReduce = _isDocPreview ? 60 : 130;\r\n            $container.css({\r\n                'margin-bottom': ($container.data('orig-mb') + _marginAdd) + 'px'\r\n            });\r\n            $droppable.css({\r\n                'margin-top': ($droppable.data('orig-mt') - _marginReduce + 75) + 'px'\r\n            });\r\n        } else {\r\n            \/\/ \u2705 Sur restauration, ajouter 50px en dessous pour \u00e9viter que le contenu soit trop coll\u00e9\r\n            var _curMb = parseInt($container.css('margin-bottom')) || 0;\r\n            $container.css('margin-bottom', (_curMb + 50) + 'px');\r\n        }\r\n        \r\n        \/\/ \u2705 Masquer .PositionEspacePublicitaireContainer et l'ancien .ReserverContainer\r\n        $droppable.find('.PositionEspacePublicitaireContainer').hide();\r\n        $droppable.find('.ReserverContainer').hide();\r\n        \r\n        \/\/ \u2705 Supprimer tout ancien bouton dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ \u2705 v2.1.2 : Cr\u00e9er le bouton R\u00e9server m\u00eame lors d'une restauration\r\n        if (isRestoration) {\r\n            console.log('\ud83d\udd04 Restauration d\u00e9tect\u00e9e - affichage bouton R\u00e9server + DeplaceAnnonce');\r\n            $droppable.find('.DeplaceAnnonce').show();\r\n            \/\/ S'assurer que FileReceived est d\u00e9fini pour la validation\r\n            StateManager.set('FileReceived', 'Yes');\r\n            \/\/ Cocher automatiquement SEULEMENT si c'est une restauration de commande r\u00e9serv\u00e9e (pas pendingAd)\r\n            var _isPendingAdRestore = sessionStorage.getItem('_pendingAdRestoration') === 'Yes';\r\n            if (!_isPendingAdRestore) {\r\n                var _isReservedRestore = sessionStorage.getItem('_isReservedRestoration') === 'Yes';\r\n                setTimeout(function() {\r\n                    var $checkbox = $droppable.find('.reserver-dynamic-checkbox');\r\n                    if ($checkbox.length && _isReservedRestore) {\r\n                        $checkbox.prop('checked', true);\r\n                        $droppable.find('.reserver-dynamic-label').text('Espace publicitaire r\u00e9serv\u00e9').css('color', 'rgb(62, 170, 19)');\r\n                        console.log('\u2705 R\u00e9server coch\u00e9 automatiquement (restauration commande r\u00e9serv\u00e9e)');\r\n                    }\r\n                    sessionStorage.removeItem('_isReservedRestoration');\r\n                    StateManager.set('_isAdRestoration', 'No');\r\n                    \/\/ \u2705 v2.4.7 : updateReserverCheckboxState APR\u00c8S avoir coch\u00e9 la checkbox\r\n                    \/\/ (l'appel synchrone ligne 614 intervient avant le cocher \u2192 label incorrect)\r\n                    if (typeof FormatUIManager !== 'undefined') {\r\n                        FormatUIManager.updateReserverCheckboxState($droppable);\r\n                    }\r\n                }, 150);\r\n            } else {\r\n                \/\/ pendingAd : ne pas cocher, ne pas envoyer au parent\r\n                console.log('\u2705 pendingAd restaur\u00e9 \u2014 R\u00e9server NON coch\u00e9');\r\n                sessionStorage.removeItem('_pendingAdRestoration');\r\n                StateManager.set('_isAdRestoration', 'No');\r\n            }\r\n        }\r\n        \r\n        \/\/ \u2705 Supprimer tout bouton R\u00e9server existant avant insertion (\u00e9vite doublons sur restauration)\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ \u2705 Cr\u00e9er le bouton \"R\u00e9server\" dynamique avec id unique pour \u00e9viter conflit label\/for Elementor\r\n        const _rankId = $droppable.attr('id') || ('drop_' + Date.now());\r\n        const _cbId = 'reserver-cb-' + _rankId;\r\n        const reserverHTML = `\r\n            <div class=\"reserver-dynamic-container\">\r\n                <span class=\"reserver-dynamic-option\">\r\n                    <input type=\"checkbox\" id=\"${_cbId}\" value=\"R\u00e9server cet espace publicitaire\" \r\n                           class=\"reserver-dynamic-checkbox\"\r\n                           name=\"form_fields[ReserverEspacePublicitaire]\">\r\n                    <span class=\"reserver-dynamic-label\">R\u00e9server cet espace publicitaire<\/span>\r\n                <\/span>\r\n            <\/div>\r\n        `;\r\n        \r\n        \/\/ \u2705 Ins\u00e9rer juste avant .DeplaceAnnonceText (position stable)\r\n        const $anchor = $droppable.find('.DeplaceAnnonceText');\r\n        if ($anchor.length) {\r\n            $anchor.before(reserverHTML);\r\n            $anchor.prev('.reserver-dynamic-container').css('margin-bottom', '-40px');\r\n            if (!UIManager.isMobile()) {\r\n                $anchor.prev('.reserver-dynamic-container').find('.reserver-dynamic-label').css({'font-size': '20px', 'font-weight': '700'});\r\n            }\r\n        } else {\r\n            $droppable.after(reserverHTML);\r\n            const $btn = $droppable.next('.reserver-dynamic-container');\r\n            $btn.css('margin-top', UIManager.isMobile() ? '-10px' : '-140px');\r\n        }\r\n        \r\n        console.log('\u2705 Bouton \"R\u00e9server\" dynamique cr\u00e9\u00e9');\r\n    },\r\n    \r\n    adjustLayoutAfterUpload($dropZone) {\r\n        console.log('\ud83d\udcf1 adjustLayoutAfterUpload \u2014 isMobile():', this.isMobile(), 'outerWidth:', window.outerWidth);\r\n        if (this.isMobile()) {\r\n            this.adjustMobileLayout($dropZone);\r\n            \r\n            \/\/ Repositionner le bouton R\u00e9server APR\u00c8S les ajustements de layout\r\n            setTimeout(() => {\r\n                const $droppable = $dropZone.closest('.droppable');\r\n                const $btn = $droppable.find('.reserver-dynamic-container').add($droppable.next('.reserver-dynamic-container')).first();\r\n                const $lisere = $droppable.find('.HTMLUploadfileConteneur');\r\n                if ($btn.length && $lisere.length) {\r\n                    const lisereBottom = $lisere[0].getBoundingClientRect().bottom;\r\n                    const btnTop = $btn[0].getBoundingClientRect().top;\r\n                    const offset = lisereBottom - btnTop - 48;\r\n                    \r\n                    \/\/ 15px suppl\u00e9mentaires pour homepage et articles\r\n                    let extraOffset = 0;\r\n                    const isHomepage = window.location.pathname === \"\/\" || window.location.pathname === \"\/en\/\";\r\n                    const isSectorPage = $('body').hasClass('page');\r\n                    if (isHomepage) {\r\n                        extraOffset = 13;\r\n                    }\r\n                    if (!isSectorPage) {\r\n                        extraOffset = 15;\r\n                    }\r\n                    \r\n                    \/\/ \u2705 v2.0.9 : +4px pour documents (communiqu\u00e9\/interview\/PDF) avec pr\u00e9sentation HTML\r\n                    if ($droppable.find('.doc-preview-container:visible').length > 0) {\r\n                        extraOffset += 4;\r\n                    }\r\n                    \r\n                    $btn.css({\r\n                        'margin-top': (offset + extraOffset + 20) + 'px',\r\n                        'margin-bottom': (-(offset + extraOffset) - 100) + 'px'\r\n                    });\r\n                    console.log('\ud83d\udcd0 Repositionnement mobile R\u00e9server:', { lisereBottom, btnTop, offset });\r\n                }\r\n            }, 50);\r\n        } else {\r\n            this.adjustDesktopLayout($dropZone);\r\n        }\r\n    },\r\n    \r\n    adjustMobileLayout($dropZone) {\r\n        console.log('\ud83d\udcf1 adjustMobileLayout START');\r\n        console.log('\ud83d\udcf1 AchatEspaceCall:', StateManager.get(\"AchatEspaceCall\"));\r\n        console.log('\ud83d\udcf1 PageAjoutModifAnnonce:', StateManager.get(\"PageAjoutModifAnnonce\"));\r\n        console.log('\ud83d\udcf1 window===window.top:', window === window.top);\r\n        console.log('\ud83d\udcf1 pathname:', location.pathname);\r\n        \r\n        const $droppable = $dropZone.closest('.droppable');\r\n        \r\n        \/\/ \u2705 v2.4.3 : Masquer les textes position\/label\/r\u00e9f\u00e9rence (comme sur desktop)\r\n        $droppable\r\n            .find('.PositionEspacePublicitaire, .ReferenceEspacePublicitaire, .ChoisirEspacePublicitaireDisponibiliteConteneur')\r\n            .hide();\r\n        \r\n        \/\/ \u2705 v2.6 : Renseigner .PositionEspacePublicitaire sur mobile (manquait vs desktop)\r\n        (function() {\r\n            var _rankPosMob = StateManager.get('Rank_Emplacement_Page_Web') || $droppable.attr('id') || '';\r\n            var _posLibMob = PreviewRenderer._getPositionLibelle(_rankPosMob);\r\n            if (_posLibMob) {\r\n                $droppable\r\n                    .find('.PositionEspacePublicitaire')\r\n                    .text(_posLibMob)\r\n                    .each(function() {\r\n                        this.style.setProperty('display', 'block', 'important');\r\n                    });\r\n            }\r\n        })();\r\n        \r\n        \/\/ \u2705 Scop\u00e9 au $dropZone courant (\u00e9vite d'affecter les autres espaces pub)\r\n        $dropZone.closest('.droppable').find('#CroixResetAnnonce').css({'zoom': '75%'});\r\n\r\n        \/\/ \u2705 v2.4.3 : Remonter la croix reset sur mobile (override margin-top Elementor)\r\n        \/\/ \u2705 v2.4.5 : Poser aussi margin-right ici (Entete.txt ne l'atteint pas pour Ele0A)\r\n        var _croixContainer = $dropZone.closest('.OrdiMobileConteneurClass').find('.CroixResetAnnonceContainer')[0];\r\n        if (_croixContainer) {\r\n            var _isEle0ACroix = ($dropZone.closest('.droppable').attr('id') === 'Ele0A');\r\n            var _mtCroix = StateManager.get(\"PageAjoutModifAnnonce\") === 'Yes' ? '-88px' : '24px';\r\n            \/\/ Ele0A : +40px vers le bas, +15px vers la gauche (margin-right) par rapport \u00e0 Ele1A\r\n            \/\/ Ele0A : margin-top identique aux autres espaces (pas de d\u00e9calage suppl\u00e9mentaire)\r\n            _croixContainer.style.setProperty('margin-top', _mtCroix, 'important');\r\n            _croixContainer.style.setProperty('margin-right', _isEle0ACroix ? '17px' : '12px', 'important');\r\n        }\r\n        \r\n        var _isMiniatureAdj = window._dropFromMiniature;\r\n        window._dropFromMiniature = false;\r\n\r\n        if (_isMiniatureAdj && window.outerWidth <= 1000) {\r\n            \/\/ \u2705 Miniature doc-preview MOBILE : ajuster HTMLUploadfileConteneur \u00e0 la hauteur du contenu\r\n            \/\/ et neutraliser tous les margins Elementor qui d\u00e9calent le $dropZone hors du parent\r\n            var _isDocPreviewMob = $dropZone.find('.doc-preview-container').length > 0;\r\n            var _docH = _isDocPreviewMob ? 144 : 115;\r\n            $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n                'height':     _docH + 'px',\r\n                'min-height': _docH + 'px',\r\n                'max-height': _docH + 'px',\r\n                'margin-top': '-55px',\r\n                'margin-bottom': '0px',\r\n                'overflow': 'hidden'\r\n            });\r\n            $dropZone.css({'margin-top': '0px', 'margin-bottom': '0px', 'top': '0px', 'height': (_docH - 6) + 'px'});\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css({'margin-top': '65px', 'margin-bottom': '-10px'});\r\n            \/\/ \u2705 v2.4.9 : Doc-preview \u2014 overflow:visible pour que le liser\u00e9 du haut ne soit pas clipp\u00e9\r\n            if (_isDocPreviewMob) {\r\n                $dropZone.closest('.OrdiMobileConteneurClass').css('overflow', 'visible');\r\n                $dropZone.closest('.OrdiMobileConteneurClass').parent().css('overflow', 'visible');\r\n            }\r\n            \/\/ \u2705 v2.4.9 : Ele0A popup mobile \u2014 neutraliser translateY(-32px) pos\u00e9 par Entete sur EnvoiUlterieurTexte\r\n            var _isEle0AMob = ($dropZone.closest('.droppable').attr('id') === 'Ele0A');\r\n            if (_isEle0AMob) {\r\n                var $_euTxt = $dropZone.closest('.droppable').find('.EnvoiUlterieurTexte');\r\n                if ($_euTxt[0]) {\r\n                    $_euTxt[0].style.setProperty('transform', 'translateY(0px)', 'important');\r\n                    $_euTxt[0].style.setProperty('margin-top', '0px', 'important');\r\n                }\r\n            }\r\n            \/\/ \u2705 v2.4.12 : AchatEspaceCall=Yes \u2192 override margins (m\u00eame correction que pour upload direct)\r\n            if (StateManager.get('AchatEspaceCall') === 'Yes') {\r\n                $dropZone.css({'margin-top': '0px', 'margin-bottom': '0px', 'top': '0px'});\r\n                var _docHAchatMini = _isDocPreviewMob ? 150 : 112;\r\n                $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n                    'margin-top': '70px',\r\n                    'margin-bottom': '35px',\r\n                    'min-height': _docHAchatMini + 'px',\r\n                    'height': _isDocPreviewMob ? _docHAchatMini + 'px' : '',\r\n                    'max-height': _isDocPreviewMob ? _docHAchatMini + 'px' : ''\r\n                });\r\n                console.log('\ud83d\udcf1 [miniature] AchatEspaceCall=Yes OVERRIDE: mt=70px | docPreview:', _isDocPreviewMob);\r\n            }\r\n            return;\r\n        }\r\n        \/\/ \u2705 v2.4.10 : Miniature DESKTOP \u2192 layout normal appliqu\u00e9 ci-dessous\r\n        if (_isMiniatureAdj) {\r\n            \/\/ Pas de overflow:hidden \u2014 le liser\u00e9 box-shadow inset doit rester visible\r\n        }\r\n\r\n        $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n            'min-height': '112px',\r\n            'margin-top': '-85px',\r\n            \/\/ \u2705 v2.4.10 : Miniature desktop \u2014 pas de margin-bottom excessif qui fait grandir le droppable\r\n            'margin-bottom': _isMiniatureAdj ? '0px' : '20px' \/\/ \u2705 v2.6 : 195px \u2192 59px \u2192 20px (\u00f73) espace sous checkbox R\u00e9server\r\n        });\r\n        console.log('\ud83d\udcf1 HTMLUploadfileConteneur margins set: mt=-85px mb=20px, el found:', $dropZone.closest('.HTMLUploadfileConteneur').length);\r\n        \r\n        $dropZone.css({\r\n            'margin-top': '-50px',\r\n            'margin-bottom': '-140px'\r\n        });\r\n        \r\n        $dropZone.closest('.OrdiMobileConteneurClass').css({\r\n            'margin-top': '65px',\r\n            'margin-bottom': '-10px'\r\n        });\r\n        console.log('\ud83d\udcf1 OrdiMobile margins set: mt=65px mb=-10px');\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            \/\/ \u2705 v2.4.12 : Reset $dropZone margins (les -50px\/-140px tirent le contenu vers le haut dans l'iframe)\r\n            \/\/ Pour doc-preview (Communiqu\u00e9\/Interview), la hauteur est plus grande \u2192 ajuster min-height\r\n            var _isDocPreviewAchat = $dropZone.find('.doc-preview-container').length > 0;\r\n            var _docHAchat = _isDocPreviewAchat ? 150 : 112;\r\n            $dropZone.css({'margin-top': '0px', 'margin-bottom': '0px', 'top': '0px'});\r\n            $dropZone.closest('.HTMLUploadfileConteneur').css({\r\n                \/\/ \u2705 v2.4.13 : Miniature desktop \u2192 +40px suppl\u00e9mentaires pour compenser le d\u00e9calage\r\n                'margin-top': _isMiniatureAdj ? '110px' : '70px',\r\n                'margin-bottom': '35px',\r\n                'min-height': _docHAchat + 'px',\r\n                'height': _isDocPreviewAchat ? _docHAchat + 'px' : '',\r\n                'max-height': _isDocPreviewAchat ? _docHAchat + 'px' : ''\r\n            });\r\n            console.log('\ud83d\udcf1 AchatEspaceCall=Yes OVERRIDE: mt=' + (_isMiniatureAdj ? '110px' : '70px') + ' | docPreview:', _isDocPreviewAchat, '| h:', _docHAchat);\r\n        }\r\n        \r\n        if (location.pathname === '\/annonce' || location.pathname === '\/annonce\/') {\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css({'margin-top': '70px'});\r\n        }\r\n        \r\n        if (window === window.top) {\r\n            console.log('\ud83d\udcf1 window===window.top OVERRIDE droppable margins');\r\n            $dropZone.closest('.droppable').css({\r\n                'margin-top': '-100px',\r\n                'margin-bottom': '-100px'\r\n            });\r\n            $dropZone.closest('#UploadFileConteneur').css({'width': '80%'});\r\n        }        \r\n    },\r\n    \r\n    adjustDesktopLayout($dropZone) {\r\n        const emplacement = StateManager.get('Commande_Emplacement_Page_Web');\r\n        const $droppable = $dropZone.closest('.droppable');\r\n        \/\/ \u2705 v2.4.13 : Lire et resetter _dropFromMiniature ici aussi (desktop)\r\n        var _fromMiniatureDesktop = window._dropFromMiniature || ($droppable[0] ? $droppable[0].getAttribute('data-kit-drop') === 'true' : false);\r\n        window._dropFromMiniature = false;\r\n        \/\/ \u2705 Nettoyer data-kit-drop apr\u00e8s lecture\r\n        if ($droppable[0]) { $droppable[0].removeAttribute('data-kit-drop'); }\r\n        \r\n        \/\/ \u2705 Masquer les textes enfants (position, label, r\u00e9f\u00e9rence) sans toucher au conteneur\r\n        $droppable\r\n            .find('.PositionEspacePublicitaire, .ReferenceEspacePublicitaire, .ChoisirEspacePublicitaireDisponibiliteConteneur > div > .elementor-widget-text-editor')\r\n            .hide();\r\n        \r\n        \/\/ \u2705 +15px sur .droppable \u2014 sauf si drop depuis miniature (dimensions naturelles)\r\n        if (!_fromMiniatureDesktop) {\r\n            const currentMt = parseInt($droppable.css('margin-top')) || 0;\r\n            $droppable.css('margin-top', (currentMt + 15) + 'px');\r\n        } else {\r\n            \/\/ \u2705 v2.4.13 : Drop depuis miniature Kit \u2014 d\u00e9caler de 30px vers le bas\r\n            const currentMt = parseInt($droppable.css('margin-top')) || 0;\r\n            \/\/ \u2705 Homepage : -20px (annonce trop basse sur r\u00e9gie) \u2014 autres pages : +70px\r\n            var _mtOffsetMini = (window.location.pathname === '\/' || window.location.pathname === '\/en\/' || window.location.pathname === '\/fr\/') ? -20 : 70;\r\n            $droppable.css('margin-top', (currentMt + _mtOffsetMini) + 'px');\r\n        }\r\n        \r\n        $dropZone.closest('.OrdiMobileConteneurClass')\r\n            .find('.RefEspacePublicitaire')\r\n            .html(emplacement)\r\n            .attr('id', 'RefEspacePublicitaire')\r\n            .each(function() {\r\n                \/\/ \u2705 Forcer aussi le parent .DeplaceAnnonce visible (display:none !important inline)\r\n                var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                this.style.setProperty('display', 'block', 'important');\r\n            });\r\n        \/\/ \u2705 v2.4.5 : Renseigner et afficher .PositionEspacePublicitaire\r\n        (function() {\r\n            var _rankPos = StateManager.get('Rank_Emplacement_Page_Web') || $droppable.attr('id') || '';\r\n            var _posLib = PreviewRenderer._getPositionLibelle(_rankPos);\r\n            if (_posLib) {\r\n                $dropZone.closest('.OrdiMobileConteneurClass')\r\n                    .find('.PositionEspacePublicitaireDeplacer')\r\n                    .text(_posLib)\r\n                    .each(function() {\r\n                        var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                        if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                        this.style.setProperty('display', 'block', 'important');\r\n                    });\r\n            }\r\n        })();\r\n        \r\n        if (window.location.pathname === \"\/\" || window.location.pathname === \"\/en\/\") {\r\n            \/\/ \u2705 v2.4.10 : top selon contexte \u2014 espaces hors .remainingContent d\u00e9calent de 60px, ceux dedans de 20px\r\n            var _inRemainingContent = $dropZone.closest('.remainingContent').length > 0;\r\n            var _topOffsetHP = _inRemainingContent ? '20px' : '100px';\r\n            $dropZone.closest('.ToBeHidden')\r\n                .css('top', _topOffsetHP)\r\n                .css('min-height', '300px');\r\n            \/\/ NB : pas de overflow:hidden ici \u2014 le liser\u00e9 vert (box-shadow inset sur HTMLUploadfileConteneur)\r\n            \/\/ doit rester visible sur les 4 c\u00f4t\u00e9s\r\n        }\r\n        \r\n        \/\/ \u2705 Toutes pages desktop : rendre le parent du droppable non-clippant\r\n        \/\/ Le bouton R\u00e9server est ins\u00e9r\u00e9 apr\u00e8s .droppable avec margin-top n\u00e9gatif \u2014\r\n        \/\/ overflow:hidden sur le parent Elementor le masque sinon.\r\n        $droppable.parent().css('overflow', 'visible');\r\n        \r\n        if (location.pathname === '\/annonce' || location.pathname === '\/annonce\/') {\r\n            $dropZone.closest('.OrdiMobileConteneurClass').css({'margin-top': '0px'});\r\n        }\r\n    }\r\n};\r\n\r\n\/**\r\n * \u2705 Module de gestion des formats et du titre .SelectionFormatTitre\r\n *\/\r\nconst FormatUIManager = {\r\n    \r\n    \/**\r\n     * V\u00e9rifie si un format est s\u00e9lectionn\u00e9 dans un espace publicitaire\r\n     * V\u00e9rifie le background-color OU le sessionStorage (format venant de l'accord\u00e9on)\r\n     *\/\r\n    hasSelectedFormat($element) {\r\n        const $droppable = $element.closest('.droppable');\r\n        const isEle0A = $droppable.attr('id') === 'Ele0A';\r\n        if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n            if (isEle0A) {\r\n                \/\/ \u2705 v2.3.4 : Ele0A popup \u2014 vrai seulement si un format sous-jacent (hors FormatIdPopUp) est s\u00e9lectionn\u00e9\r\n                var _hasDomFmt = $droppable.find('.EspPubFormatContainer').not('.FormatIdPopUp').toArray().some(el => {\r\n                    return $(el).css('background-color') === 'rgb(255, 255, 255)';\r\n                });\r\n                if (_hasDomFmt) return true;\r\n                \/\/ \u2705 v2.4.5 : Fallback sessionStorage \u2014 DOM pas encore mis \u00e0 jour (timing MutationObserver)\r\n                return !!sessionStorage.getItem('FormatSelect');\r\n            }\r\n            \/\/ Autres espaces en mode popup \u2192 toujours vrai\r\n            return true;\r\n        }\r\n        const hasWhiteBg = $droppable.find('.EspPubFormatContainer').toArray().some(el => {\r\n            return $(el).css('background-color') === 'rgb(255, 255, 255)';\r\n        });\r\n        if (hasWhiteBg) return true;\r\n        \/\/ \u2705 v1.16.0 : Fallback sessionStorage Formatchoisi\r\n        if (sessionStorage.getItem('Formatchoisi') === 'Yes') return true;\r\n        \/\/ \u2705 v2.4.5 : Fallback FormatSelect \u2014 cas du chargement initial avec format d\u00e9j\u00e0 s\u00e9lectionn\u00e9\r\n        \/\/ (Formatchoisi peut \u00eatre remis \u00e0 No au chargement, mais FormatSelect persiste)\r\n        if (sessionStorage.getItem('FormatSelect')) return true;\r\n        \/\/ \u2705 v2.4.9 : Fallback _FormatSelectApplied \u2014 survit au clear de yearbook-media.js init\r\n        return !!sessionStorage.getItem('_FormatSelectApplied');\r\n    },\r\n    \r\n    \/**\r\n     * Met \u00e0 jour la couleur du titre .SelectionFormatTitre\r\n     * Blanc si un format est s\u00e9lectionn\u00e9, rouge #FB5E2A sinon\r\n     *\/\r\n    updateTitleColor($droppable) {\r\n        \/\/ \u2705 v2.4.5 : Ele0A \u2014 ne jamais afficher SelectionFormatTitre\r\n        if (sessionStorage.getItem('PopUpChoice') === 'Yes' && $droppable.attr('id') === 'Ele0A') {\r\n            $droppable.find('.SelectionFormatTitre').hide();\r\n            $droppable.find('.SelectionFormatTitreBlanc').show();\r\n            return;\r\n        }\r\n\r\n        if (this.hasSelectedFormat($droppable)) {\r\n            $droppable.find('.SelectionFormatTitre').hide();\r\n            $droppable.find('.SelectionFormatTitreBlanc').show();\r\n            console.log('\u2705 SelectionFormatTitreBlanc affich\u00e9 (format s\u00e9lectionn\u00e9)');\r\n        } else {\r\n            $droppable.find('.SelectionFormatTitre').show();\r\n            $droppable.find('.SelectionFormatTitreBlanc').hide();\r\n            console.log('\u26a0\ufe0f SelectionFormatTitre affich\u00e9 (aucun format s\u00e9lectionn\u00e9)');\r\n        }\r\n    },\r\n    \r\n    \/**\r\n     * Flash visuel sur le titre pour indiquer qu'un format est requis\r\n     *\/\r\n    flashTitle($element) {\r\n        const $droppable = $element.closest('.droppable');\r\n        const $titre = $droppable.find('.SelectionFormatTitre');\r\n        if (!$titre.length) return;\r\n        \r\n        \/\/ Flash rouge rapide 3 fois\r\n        let count = 0;\r\n        const originalColor = $titre.css('color');\r\n        \r\n        const flash = setInterval(() => {\r\n            $titre.css('color', count % 2 === 0 ? '#FF0000' : '#FB5E2A');\r\n            count++;\r\n            if (count >= 6) {\r\n                clearInterval(flash);\r\n                $titre.css('color', '#FB5E2A');\r\n            }\r\n        }, 250);\r\n        \r\n        console.log('\u26a0\ufe0f Flash titre format - action bloqu\u00e9e (aucun format s\u00e9lectionn\u00e9)');\r\n    },\r\n    \r\n    \/**\r\n     * Met \u00e0 jour l'\u00e9tat de la checkbox \"R\u00e9server cet espace publicitaire\"\r\n     * La checkbox est activable si : format s\u00e9lectionn\u00e9 ET (fichier d\u00e9pos\u00e9 OU envoi diff\u00e9r\u00e9)\r\n     *\/\r\n    updateReserverCheckboxState($droppable) {\r\n        \/\/ \u2705 Chercher le label : dynamique ou Elementor statique\r\n        let $label = null;\r\n        let $container = null;\r\n        \r\n        \/\/ 1. Bouton dynamique dans le droppable\r\n        $container = $droppable.find('.reserver-dynamic-container');\r\n        if (!$container.length) {\r\n            $container = $droppable.next('.reserver-dynamic-container');\r\n        }\r\n        if (!$container.length) {\r\n            \/\/ Mobile : checkbox attach\u00e9e au body avec data-droppable-id\r\n            $container = $('body > .reserver-dynamic-container[data-droppable-id=\"' + $droppable.attr('id') + '\"]');\r\n        }\r\n        if (!$container.length) {\r\n            $container = $('body > .reserver-dynamic-container');\r\n        }\r\n        \r\n        if ($container.length) {\r\n            $label = $container.find('.reserver-dynamic-label');\r\n            $container.find('.reserver-dynamic-option, .elementor-field-option').css('opacity', '1');\r\n        }\r\n        \r\n        \/\/ 2. Bouton Elementor statique - chercher dans le droppable puis globalement\r\n        let $reserverStatique = $droppable.find('.elementor-field-group-ReserverEspacePublicitaire label');\r\n        if (!$reserverStatique.length) {\r\n            $reserverStatique = $droppable.find('label[for^=\"form-field-ReserverEspacePublicitaire\"]');\r\n        }\r\n        if (!$reserverStatique.length) {\r\n            \/\/ Fallback global : le formulaire peut \u00eatre en dehors du droppable\r\n            $reserverStatique = $('.elementor-field-group-ReserverEspacePublicitaire .elementor-field-option label');\r\n        }\r\n        \r\n        const hasFormat = this.hasSelectedFormat($droppable);\r\n        const hasFile = StateManager.get('FileReceived') === 'Yes';\r\n        const hasEnvoiDiffere = $droppable.find('input[name*=\"EnvoiUlterieur\"]:checked').length > 0;\r\n        \r\n        const canReserve = hasFormat && (hasFile || hasEnvoiDiffere);\r\n        \r\n        \/\/ \u2705 Si la checkbox R\u00e9server est coch\u00e9e \u2192 label vert \"Espace publicitaire r\u00e9serv\u00e9\"\r\n        const isChecked = $droppable.find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').prop('checked') ||\r\n                          ($container.length && $container.find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').prop('checked'));\r\n        \/\/ \u2705 v2.4.7 : Signal de restauration r\u00e9serv\u00e9e \u2014 checkbox pas encore coch\u00e9e (setTimeout 150ms)\r\n        \/\/             mais on sait d\u00e9j\u00e0 que l'espace est r\u00e9serv\u00e9 \u2192 traiter comme coch\u00e9\r\n        const _isReservedRestoration = sessionStorage.getItem('_isReservedRestoration') === 'Yes';\r\n        const isCheckedOrReservedRestore = isChecked || _isReservedRestoration;\r\n        \r\n        if ($label && $label.length) {\r\n            if (isCheckedOrReservedRestore) {\r\n                $label.text('Espace publicitaire r\u00e9serv\u00e9').css('color', 'rgb(62, 170, 19)');\r\n            } else {\r\n                $label.text('R\u00e9server cet espace publicitaire').css('color', canReserve ? '#FB5E2A' : '');\r\n            }\r\n        }\r\n        if ($reserverStatique.length) {\r\n            if (isCheckedOrReservedRestore) {\r\n                $reserverStatique.attr('style', 'color: rgb(62, 170, 19) !important;');\r\n            } else if (canReserve) {\r\n                $reserverStatique.attr('style', 'color: #FB5E2A !important;');\r\n            } else {\r\n                $reserverStatique.removeAttr('style');\r\n            }\r\n        }\r\n        \r\n        console.log('\ud83d\udd04 updateReserverCheckboxState:', { hasFormat, hasFile, hasEnvoiDiffere, canReserve, dynamicLabel: !!($label && $label.length), staticLabel: $reserverStatique.length });\r\n    },\r\n    \r\n    \/**\r\n     * Initialise les listeners pour le changement de format et la checkbox R\u00e9server\r\n     *\/\r\n    init() {\r\n        \/\/ \u2705 \u00c9couter les clics sur les conteneurs de format et leurs parents\r\n        jQuery(document).on('click', '.EspPubFormatContainer, .EspPubFormatListe, .EspPubFormatMainContainer', (e) => {\r\n            const $droppable = jQuery(e.target).closest('.droppable');\r\n            if (!$droppable.length) return;\r\n            \r\n            \/\/ Multiples d\u00e9lais pour couvrir les traitements asynchrones\r\n            [50, 200, 500].forEach(delay => {\r\n                setTimeout(() => {\r\n                    this.updateTitleColor($droppable);\r\n                    this.updateReserverCheckboxState($droppable);\r\n                }, delay);\r\n            });\r\n\r\n            \/\/ \u2705 v2.2.0 : Si un format (non Cr\u00e9ation) est cliqu\u00e9, notifier le parent pour mettre \u00e0 jour le Kit\r\n            const $btn = jQuery(e.target).closest('.EspPubFormatContainer');\r\n            if ($btn.length && !$btn.hasClass('FormatIdCreation') && !$btn.hasClass('FormatIdPopUp')) {\r\n                \/\/ \u2705 v2.3.4 : FormatIdPopUp g\u00e9r\u00e9 par clickFormatFromIframe (Entete.txt) \u2014 ne pas doubler\r\n                var classes = $btn.attr('class') || '';\r\n                var match = classes.match(\/FormatId(\\w+)\/);\r\n                if (match && match[1]) {\r\n                    var _rankEP = $droppable.attr('id') || '';\r\n                    setTimeout(function() {\r\n                        MessageManager.sendToParent('formatChangedInIframe', { formatSelect: match[1], rank: _rankEP });\r\n                        console.log('\ud83d\udd04 formatChangedInIframe envoy\u00e9:', match[1], '| rank:', _rankEP);\r\n                    }, 100);\r\n                }\r\n            }\r\n        });\r\n        \r\n        \/\/ \u2705 MutationObserver sur les conteneurs de format pour d\u00e9tecter les changements de style\r\n        setTimeout(() => {\r\n            this.observeFormatChanges();\r\n            \r\n            \/\/ Initialiser les couleurs des titres au chargement\r\n            jQuery('.droppable').each((i, el) => {\r\n                this.updateTitleColor(jQuery(el));\r\n            });\r\n            \r\n            \/\/ \u2705 v2.3.4 : Popup \u2192 restaurer FormatIdPopUp + format sous-jacent (sans \u00e9craser applyFormatState)\r\n            if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n                jQuery('.FormatIdPopUp').css({'background-color': '#ffffff'});\r\n                jQuery('.FormatIdPopUp').find('.EspPubFormat').css({'color': '#37D900'});\r\n                \/\/ Restaurer aussi le format sous-jacent dans Ele0A\r\n                var _fmtSS = sessionStorage.getItem('FormatSelect') || '';\r\n                if (_fmtSS) {\r\n                    var _fmtSSNorm = _fmtSS.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                    jQuery('#Ele0A').find('.EspPubFormatContainer').not('.FormatIdCreation').each(function() {\r\n                        var _cls = this.className.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                        if (_cls.includes(_fmtSSNorm)) {\r\n                            jQuery(this).css({'background-color': '#ffffff'});\r\n                            jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                        }\r\n                    });\r\n                }\r\n                jQuery('.droppable').each((i, el) => {\r\n                    this.updateTitleColor(jQuery(el));\r\n                });\r\n            }\r\n        }, 500);\r\n        \r\n        \/\/ \u2705 v1.16.0 : Re-v\u00e9rifier apr\u00e8s un d\u00e9lai plus long (format venant de l'accord\u00e9on via postMessage)\r\n        [1500, 3000].forEach(delay => {\r\n            setTimeout(() => {\r\n                \/\/ \u2705 v2.3.4 : Popup \u2192 restaurer FormatIdPopUp + format sous-jacent\r\n                if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n                    jQuery('.FormatIdPopUp').css({'background-color': '#ffffff'});\r\n                    jQuery('.FormatIdPopUp').find('.EspPubFormat').css({'color': '#37D900'});\r\n                    var _fmtSSR = sessionStorage.getItem('FormatSelect') || '';\r\n                    if (_fmtSSR) {\r\n                        var _fmtSSRNorm = _fmtSSR.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                        jQuery('#Ele0A').find('.EspPubFormatContainer').not('.FormatIdCreation').each(function() {\r\n                            var _cls = this.className.normalize('NFD').replace(\/[\u0300-\u036f]\/g, '').toLowerCase();\r\n                            if (_cls.includes(_fmtSSRNorm)) {\r\n                                jQuery(this).css({'background-color': '#ffffff'});\r\n                                jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                            }\r\n                        });\r\n                    }\r\n                    jQuery('.droppable').each((i, el) => {\r\n                        this.updateTitleColor(jQuery(el));\r\n                    });\r\n                    return;\r\n                }\r\n                if (sessionStorage.getItem('Formatchoisi') === 'Yes') {\r\n                    jQuery('.droppable').each((i, el) => {\r\n                        this.updateTitleColor(jQuery(el));\r\n                    });\r\n                }\r\n            }, delay);\r\n        });\r\n    },\r\n    \r\n    \/**\r\n     * Attache un MutationObserver sur chaque .EspPubFormatContainer\r\n     * pour d\u00e9tecter tout changement de style (background-color) \r\n     * quel que soit le script qui le d\u00e9clenche\r\n     *\/\r\n    observeFormatChanges() {\r\n        \/\/ \u2705 Guard global anti-boucle \u2014 un seul verrou pour tous les observers\r\n        window._formatObserverLocked = false;\r\n        \r\n        jQuery('.EspPubFormatContainer').each((i, el) => {\r\n            const observer = new MutationObserver(() => {\r\n                if (window._formatObserverLocked) return;\r\n                window._formatObserverLocked = true;\r\n                \/\/ \u2705 v2.4.12 : Debounce 150ms \u2014 applyFormatState manipule plusieurs containers\r\n                \/\/ en s\u00e9quence rapide, le MutationObserver peut firer sur un \u00e9tat interm\u00e9diaire\r\n                clearTimeout(window._formatObserverTimer);\r\n                window._formatObserverTimer = setTimeout(() => {\r\n                    const $droppable = jQuery(el).closest('.droppable');\r\n                    this.updateTitleColor($droppable);\r\n                    this.updateReserverCheckboxState($droppable);\r\n                    window._formatObserverLocked = false;\r\n                }, 150);\r\n            });\r\n            observer.observe(el, { \r\n                attributes: true, \r\n                attributeFilter: ['style', 'class'] \r\n            });\r\n        });\r\n        console.log('\u2705 MutationObserver attach\u00e9 aux conteneurs de format');\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de communication avec la page parente\r\n *\/\r\nconst MessageManager = {\r\n    sendToParent(type, data = {}) {\r\n        try {\r\n            window.parent.postMessage({\r\n                type: type,\r\n                iframeId: CONFIG.iframeId,\r\n                data: data\r\n            }, '*');\r\n        } catch (error) {\r\n            console.error('Error sending message to parent:', error);\r\n            window.parent.postMessage({\r\n                type: 'error',\r\n                error: error.message,\r\n                iframeId: CONFIG.iframeId\r\n            }, '*');\r\n        }\r\n    },\r\n    \r\n    sendDataToParent(data) {\r\n        this.sendToParent('dataFromIframeEspacePub', data);\r\n    },\r\n    \r\n    sendDelAdToParent(data) {\r\n        this.sendToParent('dataDelAd', data);\r\n    },\r\n    \r\n    prepareUploadData() {\r\n        const keys = [\r\n            'AddNewRefInVosCampagnes',\r\n            'FirstUploadFileorMoved',\r\n            'LoadedPageUrl',\r\n            'codePage',\r\n            'Rank_Emplacement_Page_Web',\r\n            'Commande_Emplacement_Page_Web',\r\n            'dragstart_Commande_Emplacement_Page_Web',\r\n            'dragstart_Rank_Emplacement_Page_Web',  \r\n            'FullPathAdFile',\r\n            'Upload_File_Name',\r\n            'FileReceived',\r\n            'PageWebDisplayed',\r\n            'Commande_Format_Transmis',\r\n            'EspPubLienAnnonce',\r\n            'EnvoiUlterieur',\r\n            'Formatchoisi'\r\n        ];\r\n        \r\n        const data = StateManager.getMultiple(keys);\r\n        \r\n        \/\/ \u2705 v2.3.4 : Popup (Ele0A) \u2014 lire le format sous-jacent depuis le DOM\r\n        \/\/ StateManager contient 'PopUp' (virtuel), mais le vrai format est visuellement s\u00e9lectionn\u00e9 dans #Ele0A\r\n        if (data.Rank_Emplacement_Page_Web === 'Ele0A' || sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n            var _ele0AFormatDOM = '';\r\n            jQuery('#Ele0A').find('.EspPubFormatContainer').not('.FormatIdPopUp').each(function() {\r\n                if (jQuery(this).css('background-color') === 'rgb(255, 255, 255)') {\r\n                    var _cls = this.className || '';\r\n                    var _match = _cls.match(\/FormatId(\\S+)\/);\r\n                    if (_match) { _ele0AFormatDOM = _match[1]; return false; }\r\n                }\r\n            });\r\n            if (_ele0AFormatDOM) {\r\n                data.Commande_Format_Transmis = _ele0AFormatDOM;\r\n            }\r\n        }\r\n        \r\n        console.log('\ud83d\udce4 prepareUploadData:', {\r\n            FirstUploadFileorMoved: data.FirstUploadFileorMoved,\r\n            dragstart_Commande_Emplacement_Page_Web: data.dragstart_Commande_Emplacement_Page_Web,\r\n            Commande_Emplacement_Page_Web: data.Commande_Emplacement_Page_Web\r\n        });\r\n    \r\n        return data;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de rendu des aper\u00e7us de fichiers\r\n *\/\r\nconst PreviewRenderer = {\r\n    _getPositionLibelle(rankId) {\r\n        if (!rankId) return '';\r\n        var match = rankId.match(\/Ele(\\d+)[A-Z]\/);\r\n        if (!match) return '';\r\n        var rang = parseInt(match[1]);\r\n        if (rang === 0) return 'Pop-up';\r\n        if (rang === 1 || rang === 2) return 'Haut de page';\r\n        return 'Corps de page';\r\n    },\r\n    renderVideo(objectUrl, fileName, $dropZone) {\r\n        const videoElement = jQuery('<video controls autoplay muted>').attr({\r\n            'src': objectUrl,\r\n            'width': 'auto',\r\n            'height': 'auto',\r\n            'id': fileName\r\n        }).css({\r\n            'max-width': '100%',\r\n            'max-height': '100%'\r\n        });\r\n        \r\n        if (UIManager.isDesktop()) {\r\n            $dropZone.empty().append(videoElement.clone());\r\n            jQuery('#ApercuMobile').css({\r\n                'display': 'flex',\r\n                'justify-content': 'center',\r\n                'align-items': 'center'\r\n            }).append(videoElement);\r\n        } else {\r\n            const img = document.createElement('img');\r\n            img.src = objectUrl;\r\n            img.style.width = 'auto';\r\n            img.style.height = 'auto';\r\n            img.style.maxWidth = 'calc(100% - 4px)';  \/\/ \u2705 v2.4.5 : 2px retrait inset box-shadow\r\n            img.style.maxHeight = '115px';\r\n            \r\n            const container = $dropZone[0];\r\n            while (container.firstChild) {\r\n                container.removeChild(container.firstChild);\r\n            }\r\n            container.appendChild(img);\r\n        }\r\n        \r\n        StateManager.setMultiple({\r\n            'Commande_Format': 'Vid\u00e9o',\r\n            'Commande_Format_Transmis': 'Vid\u00e9o',\r\n            'videoSrc': objectUrl,\r\n            'FormatAnnonceSelection': 'Yes',\r\n            'PositionAnnonceSelection': 'Yes'\r\n        });\r\n        \r\n        jQuery('#FormatDataStep3').html('Vid\u00e9o').css({'color': '#56BE50'});\r\n        jQuery('#TarifDataStep3').css({'color': '#96894D'});\r\n    },\r\n    \r\n    renderImage(objectUrl, $dropZone) {\r\n        const maxHeight = UIManager.isMobile() ? 105 : $dropZone.closest('.HTMLUploadfileConteneur').height();\r\n    \r\n        $dropZone.css({\r\n            'display': 'flex',\r\n            'justify-content': 'center',\r\n            'align-items': 'center',\r\n            'width': '100%',\r\n            'height': maxHeight + 'px',\r\n            'overflow': 'hidden',\r\n            'position': UIManager.isMobile() ? 'relative' : '',\r\n            'top': UIManager.isMobile() ? '45px' : '',\r\n            'padding': UIManager.isMobile() ? '0 2px' : ''  \/\/ \u2705 v2.4.5 : 2px retrait inset box-shadow mobile\r\n        });\r\n    \r\n        \/\/ \u2705 v1.19.2 : Image charg\u00e9e en arri\u00e8re-plan, remplace le message d'attente au onload\r\n        \/\/ \u2705 v2.4.5 : max-width calc(100%-4px) sur mobile pour ne pas recouvrir le box-shadow inset 2px\r\n        var _mxw = UIManager.isMobile() ? 'calc(100% - 4px)' : '100%';\r\n        var img = new Image();\r\n        img.style.cssText = 'max-width:' + _mxw + '; max-height:' + maxHeight + 'px; width:auto; height:auto; object-fit:contain;';\r\n        img.onload = function() {\r\n            $dropZone.empty().append(img);\r\n        };\r\n        img.onerror = function() {\r\n            $dropZone.html('<img decoding=\"async\" src=\"' + objectUrl + '\" style=\"max-width:' + _mxw + '; max-height:' + maxHeight + 'px; width:auto; height:auto; object-fit:contain;\">');\r\n        };\r\n        img.src = objectUrl;\r\n    \r\n        StateManager.setMultiple({\r\n            'Commande_Format_Transmis': 'Image',\r\n            'FormatAnnonceSelection': 'Yes',\r\n            'PositionAnnonceSelection': 'Yes'\r\n        });\r\n    \r\n        console.log('Image ajout\u00e9e avec succ\u00e8s');\r\n    },\r\n    \r\n    async renderWord(fileObj, $dropZone) {\r\n        return new Promise((resolve, reject) => {\r\n            const reader = new FileReader();\r\n            \r\n            reader.onload = async (e) => {\r\n                try {\r\n                    const arrayBuffer = e.target.result;\r\n                    const result = await mammoth.convertToHtml({arrayBuffer: arrayBuffer});\r\n                    \r\n                    const htmlContent = result.value;\r\n                    const tempContainer = document.createElement('div');\r\n                    tempContainer.innerHTML = htmlContent;\r\n                    \r\n                    const textContent = tempContainer.textContent || \"\";\r\n                    const normalizedText = this.normalizeText(textContent);\r\n                    const firstImage = tempContainer.querySelector('img');\r\n                    \r\n                    const titleText = this.findDocumentTitle(normalizedText);\r\n                    \r\n                    if (firstImage) {\r\n                        this.renderDocumentPreview(\r\n                            $dropZone,\r\n                            firstImage.src,\r\n                            titleText,\r\n                            textContent,\r\n                            htmlContent\r\n                        );\r\n                    } else {\r\n                        \/\/ \u2705 v1.19.0 : Accepter les documents sans image\r\n                        this.renderDocumentPreview(\r\n                            $dropZone,\r\n                            null,\r\n                            titleText,\r\n                            textContent,\r\n                            htmlContent\r\n                        );\r\n                        console.log('\u2139\ufe0f Document Word sans image \u2014 aper\u00e7u texte seul');\r\n                    }\r\n                    resolve();\r\n                } catch (error) {\r\n                    $dropZone.html(`<p style=\"color: #FB5E2A; font-weight: 600; font-family: Roboto, Arial, sans-serif; font-size: 12px; text-align: center; padding: 15px;\">Erreur lors de la lecture du document<\/p>`);\r\n                    reject(error);\r\n                }\r\n            };\r\n            \r\n            reader.readAsArrayBuffer(fileObj);\r\n        });\r\n        \r\n        this.finalizeRedactionnelUpload();\r\n    },\r\n    \r\n    renderDocumentPreview($dropZone, imageSrc, title, text, htmlContent = null) {\r\n        \/\/ \u2705 v1.19.0 : Deux layouts \u2014 avec image ou texte seul\r\n        let previewHtml;\r\n\r\n        if (imageSrc) {\r\n            \/\/ Layout avec miniature image\r\n            previewHtml = `\r\n                <div class=\"doc-preview-container\">\r\n                    <div class=\"doc-preview-thumbnail\">\r\n                        <img decoding=\"async\" src=\"${imageSrc}\" alt=\"Document image\">\r\n                    <\/div>\r\n                    <div class=\"doc-preview-info\">\r\n                        <div class=\"doc-preview-title\" id=\"AdTitle\">${title}<\/div>\r\n                        <div class=\"doc-preview-description\" id=\"AdText\">${this.getTextPreview(text, 13)}<\/div>\r\n                        <div class=\"doc-preview-readmore\" id=\"AdLirelasuite\">Ouvrir et visualiser<\/div>\r\n                        <div class=\"doc-preview-FullPathAdFile\" id=\"AdFullPathAdFile\">${StateManager.get(\"FullPathAdFile\")}<\/div>\r\n                    <\/div>\r\n                <\/div>\r\n            `;\r\n        } else {\r\n            \/\/ Layout texte seul (sans image)\r\n            previewHtml = `\r\n                <div class=\"doc-preview-container doc-preview-noimage\">\r\n                    <div class=\"doc-preview-icon\">\r\n                        <svg width=\"36\" height=\"36\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#213864\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n                            <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"\/><polyline points=\"14 2 14 8 20 8\"\/><line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"\/><line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"\/><polyline points=\"10 9 9 9 8 9\"\/>\r\n                        <\/svg>\r\n                    <\/div>\r\n                    <div class=\"doc-preview-info doc-preview-info-full\">\r\n                        <div class=\"doc-preview-title\" id=\"AdTitle\">${title}<\/div>\r\n                        <div class=\"doc-preview-description\" id=\"AdText\">${this.getTextPreview(text, 25)}<\/div>\r\n                        <div class=\"doc-preview-readmore\" id=\"AdLirelasuite\">Ouvrir et visualiser<\/div>\r\n                        <div class=\"doc-preview-FullPathAdFile\" id=\"AdFullPathAdFile\">${StateManager.get(\"FullPathAdFile\")}<\/div>\r\n                    <\/div>\r\n                <\/div>\r\n            `;\r\n        }\r\n        \r\n        $dropZone.html(previewHtml + this.getPreviewStyles());\r\n        \r\n        if (htmlContent) {\r\n            this.attachWordPreviewHandler($dropZone, title, htmlContent);\r\n        }\r\n    },\r\n    \r\n    attachWordPreviewHandler($dropZone, titleText, htmlContent) {\r\n        var $droppable = $dropZone.closest('.droppable');\r\n\r\n        \/\/ \u2705 Adapter le libell\u00e9 selon le type de document\r\n        var isInterview = (titleText || '').toLowerCase().indexOf('interview') !== -1;\r\n        var formatLabel = isInterview ? 'l\\'interview' : 'le communiqu\u00e9';\r\n        $droppable.find('.doc-preview-readmore').text('Ouvrir et visualiser ' + formatLabel);\r\n\r\n        \/\/ \u2705 v2.0.11 : D\u00e9l\u00e9gation d'\u00e9v\u00e9nement \u2014 plus robuste sur mobile (survit aux manipulations DOM)\r\n        $droppable.off('click.docpreview').on('click.docpreview', '.doc-preview-readmore', (event) => {\r\n            event.preventDefault();\r\n            event.stopPropagation();\r\n            \r\n            if (htmlContent) {\r\n                var popupTitle = isInterview ? 'Interview' : 'Communiqu\u00e9';\r\n                PDFHandler.showInlineDocPopup($dropZone, {\r\n                    formatTitle: popupTitle,\r\n                    htmlContent: htmlContent\r\n                });\r\n            } else {\r\n                console.warn('Le document est encore en cours de traitement.');\r\n            }\r\n        });\r\n    },\r\n    \r\n    normalizeText(text) {\r\n        return text\r\n            .toLowerCase()\r\n            .normalize(\"NFD\")\r\n            .replace(\/[\\u0300-\\u036f]\/g, \"\");\r\n    },\r\n    \r\n    findDocumentTitle(normalizedText) {\r\n        const foundKeyword = CONFIG.keywords.find(keyword => \r\n            normalizedText.includes(keyword.normal)\r\n        );\r\n        if (foundKeyword) return foundKeyword.display;\r\n        \r\n        \/\/ \u2705 v1.19.1 : Fallback \u2014 utiliser le format s\u00e9lectionn\u00e9 (FormatSelect)\r\n        var formatSelect = (sessionStorage.getItem('FormatSelect') || '').toLowerCase();\r\n        if (formatSelect.indexOf('interview') !== -1) return 'Interview';\r\n        if (formatSelect.indexOf('communiq') !== -1) return 'Communiqu\u00e9';\r\n        \r\n        return \"Document\";\r\n    },\r\n    \r\n    getTextPreview(text, maxWords) {\r\n        const words = text.split(' ');\r\n        if (words.length > maxWords) {\r\n            return words.slice(0, maxWords).join(' ') + ' ...';\r\n        }\r\n        return text;\r\n    },\r\n    \r\n    getPreviewStyles() {\r\n        return `\r\n            <style>\r\n                @import url('https:\/\/fonts.googleapis.com\/css2?family=Roboto:wght@400;600&display=swap');\r\n                \r\n                .doc-preview-container {\r\n                    margin: 0px 0;\r\n                    display: flex;\r\n                    width: 100%;\r\n                    max-height: 140px;\r\n                    overflow: hidden;\r\n                    box-sizing: border-box;  \/* \u2705 v2.4.5 *\/\r\n                    background: white;\r\n                    background-color: #f8f8f8;\r\n                }\r\n                .doc-preview-thumbnail {\r\n                    width: 50%; \r\n                    height: 130px;\r\n                    overflow: hidden;\r\n                    display: flex;\r\n                    align-items: center;\r\n                    justify-content: center;\r\n                    margin-top: 0px;\r\n                }\r\n                .doc-preview-thumbnail img {\r\n                    max-width: 75%;\r\n                    max-height: 75%;\r\n                    object-position: center;\r\n                    object-fit: fill;\r\n                }\r\n                .doc-preview-info {\r\n                    width: 50%;\r\n                    height: 130px; \r\n                    flex: 1;\r\n                    padding: 10px;\r\n                    display: flex;\r\n                    flex-direction: column; \r\n                }\r\n                .doc-preview-title {\r\n                    font-family: 'Roboto', sans-serif;\r\n                    color: #213864;\r\n                    font-size: 14px;\r\n                    font-weight: 600;\r\n                    text-align: left;\r\n                    margin-bottom: 5px;\r\n                }\r\n                .doc-preview-description {\r\n                    font-family: 'Roboto', sans-serif;\r\n                    color: #213864;\r\n                    font-size: 11px;\r\n                    font-weight: 400;\r\n                    text-align: left;\r\n                    overflow: hidden;\r\n                    margin-bottom: 5px;\r\n                    flex: 1;\r\n                }\r\n                .doc-preview-readmore {\r\n                    font-family: 'Roboto', sans-serif;\r\n                    color: #958848;\r\n                    font-size: 13px;\r\n                    font-weight: 600;\r\n                    text-align: left;\r\n                    cursor: pointer;\r\n                    padding: 4px 0;\r\n                    -webkit-tap-highlight-color: rgba(149,136,72,0.2);\r\n                }\r\n                @media (max-width: 999px) {\r\n                    .doc-preview-readmore { font-size: 12px; }\r\n                    \/* \u2705 Laisser 3px tout autour pour que le liser\u00e9 vert (box-shadow\/outline sur parent) soit visible *\/\r\n                    .doc-preview-container {\r\n                        width: calc(100% - 16px) !important;\r\n                        max-height: 109px !important;\r\n                        margin: 3px !important;\r\n                        margin-top: 23px !important;\r\n                        box-sizing: border-box !important;\r\n                    }\r\n                }\r\n                .doc-preview-FullPathAdFile {\r\n                    display: none;\r\n                }\r\n                \/* \u2705 v1.19.0 : Layout sans image *\/\r\n                .doc-preview-noimage {\r\n                    flex-direction: row;\r\n                    align-items: flex-start;\r\n                    gap: 10px;\r\n                    padding: 8px 10px;\r\n                }\r\n                .doc-preview-icon {\r\n                    flex-shrink: 0;\r\n                    display: flex;\r\n                    align-items: center;\r\n                    justify-content: center;\r\n                    width: 44px;\r\n                    height: 44px;\r\n                    background: #eef2f7;\r\n                    border-radius: 6px;\r\n                    margin-top: 4px;\r\n                }\r\n                .doc-preview-info-full {\r\n                    width: 100%;\r\n                    height: auto;\r\n                    max-height: 130px;\r\n                }\r\n                .doc-preview-noimage .doc-preview-description {\r\n                    font-size: 11px;\r\n                    line-height: 1.35;\r\n                    max-height: 60px;\r\n                    overflow: hidden;\r\n                }\r\n            <\/style>\r\n        `;\r\n    },\r\n    \r\n    finalizeRedactionnelUpload() {\r\n        \/\/ \u2705 v1.19.5 : D\u00e9terminer le format r\u00e9dactionnel correct\r\n        \/\/ Si le format s\u00e9lectionn\u00e9 est \"Interview\", on garde \"Interview\"\r\n        \/\/ Sinon on met \"Communiqu\u00e9\" par d\u00e9faut (au lieu de \"R\u00e9dactionnel\" qui n'est pas un format tarifaire valide)\r\n        var formatSelect = sessionStorage.getItem('FormatSelect') || '';\r\n        var formatTransmis = 'Communiqu\u00e9'; \/\/ Par d\u00e9faut\r\n        \r\n        if (formatSelect.toLowerCase().indexOf('interview') !== -1) {\r\n            formatTransmis = 'Interview';\r\n        } else if (formatSelect.toLowerCase().indexOf('communiq') !== -1) {\r\n            formatTransmis = 'Communiqu\u00e9';\r\n        }\r\n        \r\n        StateManager.set('Commande_Format_Transmis', formatTransmis);\r\n        console.log('\u2705 Format r\u00e9dactionnel d\u00e9termin\u00e9:', formatTransmis, '(FormatSelect:', formatSelect, ')');\r\n        \r\n        if (StateManager.get(\"TarifDirectSelectionne\") === 'Yes') {\r\n            const formatText = jQuery('#FormatDataStep3').text();\r\n            if (formatText !== 'Vid\u00e9o' && formatText !== 'Banni\u00e8re') {\r\n                jQuery('#form-field-RedactionnelSelection')\r\n                    .val(formatText)\r\n                    .css({'color': '#56BE50'});\r\n            }\r\n        }\r\n        \r\n        RedactionnelDepose();\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'upload\r\n *\/\r\nconst UploadManager = {\r\n    isRunning: false,\r\n    \r\n    \/\/ \u2705 Reset manuel espace publicitaire\r\n    resetEspaceManuel: function($droppable) {\r\n        console.log('\ud83d\udd27 Reset manuel espace publicitaire');\r\n        \r\n        var $dropZone = $droppable.find('#drop_file_zone_achat');\r\n        var $uploadContainer = $droppable.find('.HTMLUploadfileConteneur');\r\n        var $container = $droppable.find('.OrdiMobileConteneurClass');\r\n        \r\n        \/\/ 1. Vider la zone de drop et restaurer le HTML par d\u00e9faut\r\n        $dropZone.empty().html(\r\n            '<div id=\"drag_upload_file_achat\">' +\r\n                '<p class=\"UploadIci\" style=\"color: #FB5E2A; font-weight: 600;\">Ici glisser \u2013 d\u00e9poser ou<br>t\u00e9l\u00e9charger une annonce<\/p>' +\r\n            '<\/div>'\r\n        );\r\n        \r\n        \/\/ 2. Afficher les \u00e9l\u00e9ments cach\u00e9s lors de l'upload\r\n        $droppable.find('.UploadIci').show();\r\n        $droppable.find('.EnvoiUlterieurTexte').show();\r\n        $droppable.find('.EnvoiUlterieurContainer').show();\r\n        $droppable.find('.EspPubFormatMainContainer').show();\r\n        $droppable.find('.EspPubFormatListe').show();\r\n        $droppable.find('.ChoisirEspacePublicitaireClass').show();\r\n        $droppable.find('.GlisserDeposerConteneur').show();\r\n        $droppable.find('.OUClass').show();\r\n        $droppable.find('.TexteMobileAnnonce').show();\r\n        $droppable.find('.PositionReference').show();\r\n        $droppable.find('.ClassHdpCdp').show();\r\n        $droppable.find('.ClassRefEsp').show();\r\n        \r\n        \/\/ 3. Cacher les \u00e9l\u00e9ments d'annonce upload\u00e9e\r\n        $droppable.find('.AdUploadedTitle').hide();\r\n        $droppable.find('#CroixResetAnnonce').hide();\r\n        $droppable.find('.CroixResetAnnonceContainer').hide();\r\n        $droppable.find('.DeplaceAnnonce').hide();\r\n        $droppable.find('.RefEspacePublicitaire').hide();\r\n        $droppable.find('.AdDroppedTextNotDisplayed').hide();\r\n        \r\n        \/\/ 4. Reset des styles\r\n        $uploadContainer.css({\r\n            'border': 'none',\r\n            'background-color': '',\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'min-height': ''\r\n        });\r\n        \r\n        $container.css({\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'top': '',\r\n            'height': ''\r\n        });\r\n        \r\n        \/\/ \u2705 Reset des positionnements desktop appliqu\u00e9s par adjustDesktopLayout\r\n        $droppable.closest('.ToBeHidden').css({'top': '', 'min-height': ''});\r\n        $droppable.parent().css('overflow', '');\r\n        \/\/ \u2705 v2.0.11 : Cleanup event namespace docpreview\r\n        $droppable.off('click.docpreview');\r\n        \r\n        \/\/ 5. Reset des formats s\u00e9lectionn\u00e9s\r\n        $droppable.find('.EspPubFormatContainer').css({\r\n            'background-color': '',\r\n            'border': ''\r\n        });\r\n        \r\n        \/\/ 6. Supprimer le bouton \"R\u00e9server\" dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ 7. Restaurer .PositionEspacePublicitaireContainer et .ReserverContainer\r\n        $droppable.find('.PositionEspacePublicitaireContainer').show();\r\n        $droppable.find('.ReserverContainer').hide();\r\n        \r\n        console.log('\u2705 Reset manuel termin\u00e9');\r\n    },\r\n    \r\n    async handleFileUpload(fileObj, $dropZone) {\r\n        console.log('fileObj:', fileObj);\r\n        \r\n        \/\/ \u2705 v2.4.6 : Contr\u00f4les d'extension EN PREMIER \u2014 avant tout affichage\r\n        const extension = FileManager.getExtension(fileObj.name);\r\n        StateManager.set('FileExtension', extension);\r\n        console.log('FileExtension:', extension);\r\n        \r\n        \/\/ \u2705 v2.6 : jpg\/jpeg accept\u00e9s sur desktop et mobile\r\n        \r\n        if (!FileManager.isAllowedExtension(extension)) {\r\n            UIManager.showFormatError($dropZone);\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 v1.19.5 : Afficher le message d'attente seulement si le format est valide\r\n        var _waitMsg = 'Loading in progress <span class=\"dot-container\"><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><\/span>';\r\n        $dropZone.html('<div class=\"ad-loading-msg\" style=\"color:#00ff19; background:white; padding:12px 20px; border-radius:6px; font-weight:700; text-align:center; font-size:18px; line-height:1.4;\">' + _waitMsg + '<\/div>');\r\n        \r\n        this.prepareUIForUpload($dropZone);\r\n        \r\n        const formData = new FormData();\r\n        formData.append('file', fileObj);\r\n        formData.append('action', 'upload_annonce_file_v3');\r\n        \r\n        UIManager.showUploadProgress($dropZone);\r\n        \r\n        try {\r\n            const response = await this.sendUploadRequest(formData);\r\n            await this.handleUploadResponse(response, fileObj, $dropZone, extension);\r\n        } catch (error) {\r\n            console.error('Upload error:', error);\r\n        }\r\n    },\r\n    \r\n    prepareUIForUpload($dropZone) {\r\n        if (!UIManager.isMobile()) {\r\n            jQuery('.ChoisirEspacePublicitaireClass').show();\r\n            jQuery('.ChoisirEspacePublicitaire2ndLigne').show();\r\n            jQuery('.GlisserDeposerConteneur').show();\r\n            jQuery('.OUClass').show();\r\n            \/\/ \u2705 Cibler uniquement le droppable courant \u2014 ne pas r\u00e9afficher sur les espaces d\u00e9j\u00e0 upload\u00e9s\r\n            $dropZone.closest('.droppable').find('.UploadIci').show();\r\n        }\r\n        \r\n        if (StateManager.get(\"PopUpChoice\") === 'Yes') {\r\n            \/\/ \u2705 Ne masquer DeplaceAnnonce QUE sur Ele0A \u2014 pas sur Ele1A qui a deja une annonce chargee\r\n            $dropZone.closest('.OrdiMobileConteneurClass').find('.DeplaceAnnonce').each(function() {\r\n                var _d = jQuery(this).closest('.droppable')[0];\r\n                if (_d && _d.getAttribute('data-via-ad-loaded') === 'true') { return; }\r\n                jQuery(this).hide();\r\n            });\r\n            $('.AnnonceDragIcone').show().find('img').attr('alt', '');\r\n        } else {\r\n            $('.AnnonceDragIcone').hide();\r\n        }\r\n        \r\n        if (StateManager.get(\"Commande_Page\") === 'Home Page') {\r\n            jQuery('#HPTarifConteneur').css({'background-color': '#B5FFB1'});\r\n        }\r\n        \r\n        jQuery('.ChoisirEspacePublicitaireClass').css({'color': '#ffffff'});\r\n        jQuery('.InterfaceTitreDore').not('#PageWebTitreDore')\r\n            .html(\"Merci de choisir les \u00e9l\u00e9ments de votre campagne publicitaire\");\r\n        jQuery('#ProcessCommande').show();\r\n    },\r\n    \r\n    sendUploadRequest(formData) {\r\n        \/\/ \u2705 v2.6 : dataType 'text' pour eviter parsererror si texte parasite apres le JSON\r\n        return jQuery.ajax({\r\n            url: CONFIG.ajaxUrl,\r\n            type: 'POST',\r\n            data: formData,\r\n            cache: false,\r\n            contentType: false,\r\n            processData: false,\r\n            dataType: 'text'\r\n        }).then(function(text) {\r\n            \/\/ Extraire le JSON meme si du texte parasite suit\r\n            var _json = null;\r\n            try {\r\n                var _match = text.match(\/(\\{[\\s\\S]*?\\})(?:[^{]|$)\/);\r\n                _json = JSON.parse(_match ? _match[1] : text);\r\n            } catch(_e) {\r\n                return jQuery.Deferred().reject({ responseText: text }).promise();\r\n            }\r\n            \/\/ Normaliser le format vers {success, data} attendu par handleUploadResponse\r\n            if (_json.status === 'success') {\r\n                var _fp = _json.file_path || '';\r\n                var _baseUrl = CONFIG.ajaxUrl.replace('\/wp-admin\/admin-ajax.php', '\/wp-content\/');\r\n                return {\r\n                    success: true,\r\n                    data: {\r\n                        file_url:  _baseUrl + _fp,\r\n                        file_name: _fp.replace(\/^.*\\\/\/, ''),\r\n                        file_path: _fp\r\n                    }\r\n                };\r\n            }\r\n            \/\/ Format WordPress standard {success, data} - retourner tel quel\r\n            return _json;\r\n        });\r\n    },\r\n    \r\n    async handleUploadResponse(response, fileObj, $dropZone, extension) {\r\n        console.log('\u2705 R\u00e9ponse re\u00e7ue');\r\n        \r\n        if (response.responseJSON) {\r\n            response = response.responseJSON;\r\n        }\r\n        \r\n        console.log('\u2705 Response pars\u00e9e:', response);\r\n        \r\n        if (!response.success || !response.data) {\r\n            \/\/ \u2705 v2.1.2 : Si c'est une restauration (_isAdRestoration = 'Yes'),\r\n            \/\/ le fichier existe d\u00e9j\u00e0 sur le serveur \u2192 afficher l'image depuis le fileObj local\r\n            if (StateManager.get('_isAdRestoration') === 'Yes' && fileObj) {\r\n                console.log('\ud83d\udd04 Restauration: upload \u00e9chou\u00e9 (fichier existant) \u2192 rendu local');\r\n                \r\n                FileManager.createObjectUrl(fileObj);\r\n                StateManager.set('FileReceived', 'Yes');\r\n                \r\n                \/\/ \u2705 v2.1.2 : Restaurer l'\u00e9tat EnvoiUlterieur depuis le sessionStorage parent\r\n                var _restoredEnvoi = sessionStorage.getItem('_restoredEnvoiUlterieur');\r\n                if (_restoredEnvoi === 'true') {\r\n                    StateManager.set('EnvoiUlterieur', 'true');\r\n                    StateManager.set('FileReceived', 'No');\r\n                    StateManager.set('FullPathAdFile', '');\r\n                    console.log('\ud83d\udce4 Restauration EnvoiUlterieur = true');\r\n                }\r\n                \r\n                var _objUrl = StateManager.get('objectUrl');\r\n                var _fileType = FileManager.getFileType(extension);\r\n                \r\n                StateManager.set('FormatReconnu', 'No');\r\n                \r\n                switch (_fileType) {\r\n                    case 'video':\r\n                        PreviewRenderer.renderVideo(_objUrl, fileObj.name, $dropZone);\r\n                        StateManager.set('FormatReconnu', 'Yes');\r\n                        break;\r\n                    case 'image':\r\n                        PreviewRenderer.renderImage(_objUrl, $dropZone);\r\n                        StateManager.set('FormatReconnu', 'Yes');\r\n                        break;\r\n                    case 'document':\r\n                        \/\/ \u2705 v2.1.2 : Documents Word\/PDF aussi en restauration\r\n                        await this.handleDocumentUpload(extension, fileObj, $dropZone);\r\n                        break;\r\n                }\r\n                \r\n                UIManager.updateAfterSuccessfulUpload($dropZone);\r\n                \r\n                if (StateManager.get('FormatReconnu') === 'Yes') {\r\n                    this.finalizeUpload($dropZone);\r\n                    $('#MsgSelectEspace').hide();\r\n                }\r\n                \r\n                FormatUIManager.updateReserverCheckboxState($dropZone.closest('.droppable'));\r\n                console.log('\u2705 Restauration visuelle termin\u00e9e (upload bypass)');\r\n                StateManager.set('_isAdRestoration', 'No');\r\n            }\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 SAUVEGARDER les infos de d\u00e9placement AVANT updateStateAfterUpload\r\n        const isMoved = StateManager.get('FirstUploadFileorMoved') === 'Moved';\r\n        const dragstartRankId = StateManager.get('dragstart_Rank_Emplacement_Page_Web');\r\n        const currentRankId = StateManager.get('Rank_Emplacement_Page_Web');\r\n        const shouldResetOldSpace = isMoved && dragstartRankId && dragstartRankId !== currentRankId;\r\n        \r\n        console.log('\ud83d\udd0d D\u00e9placement?', { isMoved, dragstartRankId, currentRankId, shouldResetOldSpace });\r\n        \r\n        this.updateStateAfterUploadWithoutReset(response, fileObj);\r\n        \r\n        const fileType = FileManager.getFileType(extension);\r\n        \r\n        StateManager.set('FormatReconnu', 'No');\r\n        \r\n        \/\/ \u2705 v1.19.2 : Message d'attente IMM\u00c9DIAT avant le rendu de l'annonce\r\n        var _waitMsg = 'Loading in progress <span class=\"dot-container\"><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><span class=\"dot\">.<\/span><\/span>';\r\n        $dropZone.html('<div class=\"ad-loading-msg\" style=\"color:#00ff19; background:white; padding:12px 20px; border-radius:6px; font-weight:700; text-align:center; font-size:18px; line-height:1.4;\">' + _waitMsg + '<\/div>');\r\n        \r\n        switch (fileType) {\r\n            case 'video':\r\n                PreviewRenderer.renderVideo(StateManager.get('objectUrl'), fileObj.name, $dropZone);\r\n                StateManager.set('FormatReconnu', 'Yes');\r\n                break;\r\n                \r\n            case 'image':\r\n                PreviewRenderer.renderImage(StateManager.get('objectUrl'), $dropZone);\r\n                StateManager.set('FormatReconnu', 'Yes');\r\n                break;\r\n                \r\n            case 'document':\r\n                await this.handleDocumentUpload(extension, fileObj, $dropZone);\r\n                break;\r\n        }\r\n        \r\n        UIManager.updateAfterSuccessfulUpload($dropZone);\r\n        \r\n        if (StateManager.get('FormatReconnu') === 'Yes') {\r\n            this.finalizeUpload($dropZone);\r\n            $('#MsgSelectEspace').hide();\r\n        }\r\n        \r\n        \/\/ \u2705 RESET L'ANCIEN ESPACE ICI - APR\u00c8S avoir affich\u00e9 la nouvelle image\r\n        \/\/ \u2705 v2.4.5 : Toujours initialiser \u00e0 false avant le bloc (\u00e9vite la valeur r\u00e9siduelle)\r\n        var _sourceWasReserved = false;\r\n        StateManager.set('_sourceWasReserved', 'No');\r\n        \r\n        if (shouldResetOldSpace) {\r\n            console.log('\ud83d\udd04 Reset ancien espace:', dragstartRankId);\r\n            \r\n            var $oldDroppable = $('#' + dragstartRankId);\r\n            \r\n            if ($oldDroppable.length) {\r\n                var $container = $oldDroppable.find('.OrdiMobileConteneurClass').first();\r\n                \r\n                \/\/ \u2705 v2.4.5 : Utiliser l'\u00e9tat captur\u00e9 au dragstart (fiable vs re-check async)\r\n                if ($container.length) {\r\n                    _sourceWasReserved = StateManager.get('dragstart_ReserverChecked') === 'Yes';\r\n                    console.log('[d\u00e9placement] ReserverChecked au dragstart:', _sourceWasReserved, '| rank:', dragstartRankId);\r\n                    StateManager.set('_sourceWasReserved', _sourceWasReserved ? 'Yes' : 'No');\r\n                    RestoreadSpaceTemplateLocal($container[0]);\r\n                }\r\n            }\r\n        }\r\n        StateManager.set(\"EnvoiUlterieur\", 'false');\r\n        \r\n        \/\/ \u2705 v1.19.1 : Positionner l'espace \u00e0 10px du haut du viewport apr\u00e8s upload\r\n        setTimeout(function() {\r\n            var el = $dropZone.closest('.droppable').find('.HTMLUploadfileConteneur')[0]\r\n                     || $dropZone.closest('.droppable')[0];\r\n            if (el) {\r\n                ScrollHelper.scrollElementTo(el, 10);\r\n            }\r\n        }, 400);\r\n        \r\n        \/\/ \u2705 NE PLUS envoyer automatiquement - c'est la checkbox \"R\u00e9server\" qui d\u00e9clenche\r\n        \/\/ On met \u00e0 jour l'\u00e9tat de la checkbox pour qu'elle devienne activable\r\n        FormatUIManager.updateReserverCheckboxState($dropZone.closest('.droppable'));\r\n        \r\n        \/\/ \u2705 v2.4.5 : Si l'espace source \u00e9tait r\u00e9serv\u00e9, cocher la checkbox de l'espace cible\r\n        if (StateManager.get('_sourceWasReserved') === 'Yes') {\r\n            var $targetCb = $dropZone.closest('.droppable').find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]');\r\n            if ($targetCb.length && !$targetCb.prop('checked')) {\r\n                $targetCb.prop('checked', true).trigger('change');\r\n                console.log('\u2705 [d\u00e9placement] Checkbox R\u00e9server coch\u00e9e sur espace cible');\r\n            }\r\n            StateManager.set('_sourceWasReserved', 'No');\r\n        }\r\n        \r\n        console.log('\ud83d\udccb Upload termin\u00e9 - en attente de validation via checkbox \"R\u00e9server\"');\r\n    },\r\n    \r\n    updateStateAfterUploadWithoutReset(response, fileObj) {\r\n        StateManager.setMultiple({\r\n            \"PageWhithADType\": StateManager.get('SelectedPageType'),\r\n            \"PageWhithADSecteur\": StateManager.get('SelectedPageSecteur')\r\n        });\r\n        \r\n        $('#BackPageWebWithADCroix').hide();\r\n        jQuery('#ApercuMobile').empty().css({\r\n            'display': 'flex',\r\n            'justify-content': 'center',\r\n            'align-items': 'center'\r\n        });\r\n        \r\n        const firstUploadOrMoved = StateManager.get('FirstUploadFileorMoved');\r\n        \r\n        if (firstUploadOrMoved === 'FirstUpload') {\r\n            StateManager.setMultiple({\r\n                \"FullPathAdFile\": response.data.file_url,\r\n                \"fileObj\": fileObj,\r\n                \"Upload_File_Name\": fileObj.name\r\n            });\r\n            \r\n            FileManager.createObjectUrl(fileObj);\r\n            \r\n            console.log('\ud83d\udcc1 Fichier upload\u00e9:', {\r\n                fullUrl: response.data.file_url,\r\n                fileName: response.data.file_name,\r\n                filePath: response.data.file_path\r\n            });\r\n        }\r\n    },\r\n    \r\n    updateStateAfterUpload(response, fileObj) {\r\n        StateManager.setMultiple({\r\n            \"PageWhithADType\": StateManager.get('SelectedPageType'),\r\n            \"PageWhithADSecteur\": StateManager.get('SelectedPageSecteur')\r\n        });\r\n        \r\n        $('#BackPageWebWithADCroix').hide();\r\n        jQuery('#ApercuMobile').empty().css({\r\n            'display': 'flex',\r\n            'justify-content': 'center',\r\n            'align-items': 'center'\r\n        });\r\n        \r\n        const firstUploadOrMoved = StateManager.get('FirstUploadFileorMoved');\r\n        console.log('\ud83d\udd0d FirstUploadFileorMoved:', firstUploadOrMoved);\r\n        \r\n        if (firstUploadOrMoved === 'FirstUpload') {\r\n            StateManager.setMultiple({\r\n                \"FullPathAdFile\": response.data.file_url,\r\n                \"fileObj\": fileObj,\r\n                \"Upload_File_Name\": fileObj.name\r\n            });\r\n            \r\n            FileManager.createObjectUrl(fileObj);\r\n            \r\n            console.log('\ud83d\udcc1 Fichier upload\u00e9:', {\r\n                fullUrl: response.data.file_url,\r\n                fileName: response.data.file_name,\r\n                filePath: response.data.file_path\r\n            });\r\n        } else if (firstUploadOrMoved === 'Moved') {\r\n            const dragstartRankId = StateManager.get('dragstart_Rank_Emplacement_Page_Web');\r\n            const currentRankId = StateManager.get('Rank_Emplacement_Page_Web');\r\n            \r\n            console.log('\ud83d\udd04 D\u00c9PLACEMENT D\u00c9TECT\u00c9');\r\n            console.log('   Ancien espace (dragstart):', dragstartRankId);\r\n            console.log('   Nouvel espace (current):', currentRankId);\r\n            \r\n            if (dragstartRankId && dragstartRankId !== currentRankId) {\r\n                const $oldDroppable = $('#' + dragstartRankId);\r\n                \r\n                console.log('   $oldDroppable trouv\u00e9:', $oldDroppable.length > 0);\r\n                \r\n                if ($oldDroppable.length) {\r\n                    const $container = $oldDroppable.find('.OrdiMobileConteneurClass');\r\n                    \r\n                    console.log('   $container trouv\u00e9:', $container.length > 0);\r\n                    \r\n                    if ($container.length) {\r\n                        console.log('\ud83d\udd27 Appel RestoreadSpaceTemplate sur:', $container[0]);\r\n                        \r\n                        if (typeof window.RestoreadSpaceTemplate === 'function') {\r\n                            window.RestoreadSpaceTemplate($container[0]);\r\n                            console.log('\u2705 RestoreadSpaceTemplate ex\u00e9cut\u00e9');\r\n                        }\r\n                    } else {\r\n                        console.warn('\u26a0\ufe0f .OrdiMobileConteneurClass non trouv\u00e9 dans', dragstartRankId);\r\n                    }\r\n                }\r\n            } else {\r\n                console.log('\u23ed\ufe0f M\u00eame espace ou dragstartRankId invalide, pas de reset');\r\n            }\r\n        }\r\n    },\r\n        \r\n    async handleDocumentUpload(extension, fileObj, $dropZone) {\r\n        StateManager.set('FormatReconnu', 'Yes');\r\n        \r\n        \/\/ \u2705 Cacher le File r\u00e9dactionnel pour r\u00e9utilisation lors des d\u00e9placements (\u00e9vite CORS)\r\n        window._lastRedactionnelFile = fileObj;\r\n        \r\n        if (extension === 'doc' || extension === 'docx') {\r\n            await new Promise(resolve => window.VIALibraries.loadMammoth(resolve));\r\n            await PreviewRenderer.renderWord(fileObj, $dropZone);\r\n        } else if (extension === 'ppt' || extension === 'pptx') {\r\n            this.renderPowerPoint($dropZone);\r\n            PreviewRenderer.finalizeRedactionnelUpload();\r\n        } else if (extension === 'pdf') {\r\n            await new Promise(resolve => window.VIALibraries.loadPdfJs(resolve));\r\n            await PDFHandler.renderPDF(fileObj, $dropZone);\r\n            PreviewRenderer.finalizeRedactionnelUpload();\r\n        }\r\n    },\r\n    \r\n    renderPowerPoint($dropZone) {\r\n        const img = jQuery('<img \/>', {\r\n            src: '\/wp-content\/uploads\/2024\/06\/microsoft-powerpoint.png',\r\n            css: {\r\n                'width': 'auto',\r\n                'height': 'auto',\r\n                'margin-bottom': '20px',\r\n                'max-width': '150px',\r\n                'max-height': '160px'\r\n            }\r\n        });\r\n        $dropZone.empty().append(img.clone());\r\n        jQuery('#ApercuMobile').append(img);\r\n    },\r\n    \r\n    finalizeUpload($dropZone) {\r\n        \/\/ \u2705 Reset sendDataToParentFlag : nouvel upload = pas encore r\u00e9serv\u00e9\r\n        StateManager.set('sendDataToParentFlag', 'No');\r\n        \r\n        StateManager.setMultiple({\r\n            \"PageAnnonceSelection\": 'Yes',\r\n            \"FormatReconnu\": 'Yes'\r\n        });\r\n        \r\n        jQuery('#MsgChoixPageWeb, #MsgInsererAnnonceConteneur').hide();\r\n        \r\n        if (StateManager.get(\"Commande_Format\") === 'R\u00e9dactionnel') {\r\n            StateManager.set('Commande_Format', '\u00e0 choisir');\r\n            RedactionnelDepose();\r\n        }\r\n        \r\n        if (StateManager.get(\"Commande_Page\") === ' ') {\r\n            jQuery('#HPTarifConteneur').css({'background-color': '#BCFFAD'});\r\n            jQuery('#EmplacementDataStep3').html(\"Home Page\");\r\n            StateManager.setMultiple({\r\n                \"Commande_Page\": 'Home Page',\r\n                \"PageAnnonceSelection\": 'Yes'\r\n            });\r\n        }\r\n        \r\n        $('#PageWeb').css('zoom', '70%');\r\n        $('#PageWebTitreDore').css({'font-size': '14px'});\r\n        \r\n        if (!UIManager.isMobile()) {\r\n            $('#PageWebTitreDore').css({'color': '#213864'});\r\n        }\r\n        \r\n        StateManager.set(\"Page_Web_with_AD_URL\", StateManager.get(\"Page_Web_URL\"));\r\n        \r\n        UIManager.finalizeAdDisplay($dropZone);\r\n        \r\n        \/\/ \u2705 Notifier le parent de l'annonce d\u00e9pos\u00e9e non r\u00e9serv\u00e9e \u2014 pour restauration au retour sur la page\r\n        var _fileRcv = StateManager.get('FileReceived');\r\n        var _isRestoring = StateManager.get('_isAdRestoration') === 'Yes';\r\n        console.log('\ud83d\udfe1 [finalizeUpload] FileReceived:', _fileRcv, '| _isAdRestoration:', _isRestoring);\r\n        if (_fileRcv === 'Yes' && !_isRestoring) {\r\n            var _pendingRank = StateManager.get('Rank_Emplacement_Page_Web') || $dropZone.closest('.droppable').attr('id') || '';\r\n            console.log('\ud83d\udfe1 [finalizeUpload] pendingRank:', _pendingRank, '| FullPathAdFile:', StateManager.get('FullPathAdFile'));\r\n            if (_pendingRank) {\r\n                console.log('\ud83d\udce4 [finalizeUpload] annonceDeposeeSansReservation \u2192 parent rank:', _pendingRank);\r\n                \/\/ \u2705 D\u00e9terminer le vrai format commercial selon le type de fichier d\u00e9pos\u00e9 + format s\u00e9lectionn\u00e9\r\n                var _formatSelect = sessionStorage.getItem('FormatSelect') || StateManager.get('Commande_Format_Transmis') || '';\r\n                var _uploadedExt = (StateManager.get('Upload_File_Name') || '').split('.').pop().toLowerCase();\r\n                var _fileKind = CONFIG.allowedExtensions.video.indexOf(_uploadedExt) !== -1 ? 'video'\r\n                              : CONFIG.allowedExtensions.image.indexOf(_uploadedExt) !== -1 ? 'image'\r\n                              : CONFIG.allowedExtensions.document.indexOf(_uploadedExt) !== -1 ? 'document'\r\n                              : '';\r\n                var _formatPending;\r\n                if (_fileKind === 'video') {\r\n                    \/\/ Vid\u00e9o \u2192 toujours Vid\u00e9o\r\n                    _formatPending = 'Vid\u00e9o';\r\n                } else if (_fileKind === 'image') {\r\n                    \/\/ Image \u2192 Banni\u00e8re ou Parrainage si s\u00e9lectionn\u00e9, sinon Banni\u00e8re par d\u00e9faut\r\n                    var _imgFormats = ['Banni\u00e8re', 'Banniere', 'Parrainage'];\r\n                    _formatPending = (_imgFormats.indexOf(_formatSelect) !== -1) ? _formatSelect : 'Banni\u00e8re';\r\n                } else if (_fileKind === 'document') {\r\n                    \/\/ Document \u2192 Communiqu\u00e9 ou Interview si s\u00e9lectionn\u00e9, sinon Communiqu\u00e9 par d\u00e9faut\r\n                    var _docFormats = ['Communiqu\u00e9', 'Communique', 'Interview'];\r\n                    _formatPending = (_docFormats.indexOf(_formatSelect) !== -1) ? _formatSelect : 'Communiqu\u00e9';\r\n                } else {\r\n                    \/\/ Fallback\r\n                    _formatPending = _formatSelect || StateManager.get('Commande_Format_Transmis') || '';\r\n                }\r\n                \/\/ \u2705 v2.4.9 : Si le format d\u00e9duit diff\u00e8re du format s\u00e9lectionn\u00e9 \u2192 mettre \u00e0 jour vignette + sessionStorage\r\n                if (_formatPending && _formatPending !== _formatSelect) {\r\n                    StateManager.set('FormatSelect', _formatPending);\r\n                    StateManager.set('Commande_Format_Transmis', _formatPending);\r\n                    StateManager.set('Formatchoisi', 'Yes');\r\n                    \/\/ Mettre \u00e0 jour visuellement la vignette dans le droppable courant\r\n                    var _fmtNorm = _formatPending.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    var $_drp = $dropZone.closest('.droppable');\r\n                    $_drp.find('.EspPubFormatContainer').each(function() {\r\n                        var _cls = this.className.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                        if (_cls.includes(_fmtNorm)) {\r\n                            jQuery(this).css({'background-color': '#ffffff'});\r\n                            jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                        } else if (!jQuery(this).hasClass('FormatIdPopUp')) {\r\n                            jQuery(this).css({'background-color': ''});\r\n                            jQuery(this).find('.EspPubFormat').css({'color': ''});\r\n                        }\r\n                    });\r\n                    \/\/ Mettre \u00e0 jour aussi le bandeau parent via postMessage\r\n                    MessageManager.sendToParent('formatChangedInIframe', { formatSelect: _formatPending, rank: _pendingRank });\r\n                    console.log('\ud83d\udd04 [finalizeUpload] Format corrig\u00e9:', _formatSelect, '\u2192', _formatPending);\r\n                }\r\n                var _firstUploadOrMoved = StateManager.get('FirstUploadFileorMoved');\r\n                var _isMoved = _firstUploadOrMoved === 'Moved';\r\n                var _oldRankMoved = _isMoved ? (StateManager.get('dragstart_Rank_Emplacement_Page_Web') || '') : '';\r\n                MessageManager.sendToParent('annonceDeposeeSansReservation', {\r\n                    Rank_Emplacement_Page_Web: _pendingRank,\r\n                    FullPathAdFile: StateManager.get('FullPathAdFile') || '',\r\n                    Upload_File_Name: StateManager.get('Upload_File_Name') || '',\r\n                    LoadedPageUrl: window.location.href,\r\n                    FileReceived: 'Yes',\r\n                    \/\/ \u2705 Lire EnvoiUlterieur depuis la checkbox du droppable courant (pas le StateManager global)\r\n                    \/\/ StateManager.get('EnvoiUlterieur') est global \u2192 peut valoir 'true' si un autre espace a sa checkbox coch\u00e9e\r\n                    EnvoiUlterieur: ($dropZone.closest('.droppable').find('input[name*=\"EnvoiUlterieur\"]').prop('checked') ? 'true' : 'false'),\r\n                    Commande_Format_Transmis: _formatPending,\r\n                    codeSite: StateManager.get('codeSite') || '',\r\n                    codePage: StateManager.get('codePage') || '',\r\n                    Commande_Emplacement_Page_Web: StateManager.buildEmplacementReference(_pendingRank),\r\n                    isMoved: _isMoved,\r\n                    oldRank: _oldRankMoved\r\n                });\r\n            }\r\n        }\r\n    },\r\n    \r\n    activateSendDataToParent($dropZone) {\r\n        if (StateManager.get(\"sendDataToParentFlag\") !== 'Yes') {\r\n            return;\r\n        }\r\n        \r\n        if (StateManager.get(\"FirstUploadFileorMoved\") === 'Moved') {\r\n            const dragstartRef = StateManager.buildEmplacementReference(\r\n                StateManager.get(\"dragstart_Rank_Emplacement_Page_Web\")\r\n            );\r\n            StateManager.set('dragstart_Commande_Emplacement_Page_Web', dragstartRef);\r\n        }\r\n        \r\n        console.log('Esp Pub Ref FirstUploadFileorMoved:', StateManager.get(\"FirstUploadFileorMoved\"));\r\n        console.log('Esp Pub dragstart_Commande:', StateManager.get(\"dragstart_Commande_Emplacement_Page_Web\"));\r\n        \r\n        if (StateManager.get(\"PageAjoutModifAnnonce\") === 'Yes') {\r\n            this.handlePageModification($dropZone);\r\n        } else {\r\n            this.handleNormalUpload();\r\n        }\r\n        \r\n        StateManager.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        setTimeout(() => {\r\n            StateManager.set(\"AddNewRefInVosCampagnes\", 'Yes');\r\n        }, 4000);\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            StateManager.set('Commande_Format_Transmis', '');\r\n        }\r\n    },\r\n    \r\n    handlePageModification($dropZone) {\r\n        $('#CroixResetAnnonce, .DeplaceAnnonce').hide();\r\n        $('.PageAjoutModifAnnonceCroixResetAnnonce').show();\r\n        \r\n        const emplacementRef = $dropZone.closest('.CampagnesTemplateClass')\r\n            .find('.ReferenceEspace').text();\r\n        \r\n        console.log('Commande_Emplacement_Page_Web:', emplacementRef);\r\n        \r\n        jQuery.ajax({\r\n            type: \"POST\",\r\n            url: CONFIG.ajaxUrl,\r\n            data: {\r\n                action: 'via_update_fichier_annonce',\r\n                commande_ref_url: StateManager.get(\"commande_ref_url\"),\r\n                emplacement_page_web: emplacementRef,\r\n                chemin_fichier: StateManager.get(\"FullPathAdFile\")\r\n            },\r\n            xhrFields: { withCredentials: true },\r\n            success: (response) => {\r\n                if (response.success) {\r\n                    console.log('\u2705 Fichier annonce mis \u00e0 jour:', response.data.message);\r\n                    location.reload();\r\n                } else {\r\n                    console.error('\u274c Erreur:', response.data.message);\r\n                }\r\n            },\r\n            error: (xhr, status, error) => {\r\n                console.error('\u274c Erreur AJAX:', error);\r\n            }\r\n        });\r\n    },\r\n    \r\n    handleNormalUpload() {\r\n        if (StateManager.get(\"EnvoiUlterieur\") === 'true') {\r\n            StateManager.setMultiple({\r\n                \"FullPathAdFile\": '',\r\n                \"Upload_File_Name\": ''\r\n            });\r\n        }\r\n        \r\n        StateManager.set(\"LoadedPageUrl\", window.location.href);\r\n        \r\n        console.log('EnvoiUlterieur:', StateManager.get(\"EnvoiUlterieur\"));\r\n        console.log('LoadedPageUrl:', StateManager.get(\"LoadedPageUrl\"));\r\n        console.log('FileReceived:', StateManager.get(\"FileReceived\"));\r\n        \r\n        const data = MessageManager.prepareUploadData();\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            MessageManager.sendDataToParent(data);\r\n        } else {\r\n            const formatChoisi = StateManager.get(\"Formatchoisi\") === 'Yes';\r\n            const fichierDepose = StateManager.get(\"FileReceived\") === 'Yes';\r\n            const envoiDiffere = StateManager.get(\"EnvoiUlterieur\") === 'true';\r\n            \r\n            console.log('\ud83d\udd0d handleNormalUpload - Conditions:', { formatChoisi, fichierDepose, envoiDiffere });\r\n            \r\n            if (formatChoisi && (fichierDepose || envoiDiffere)) {\r\n                if (typeof window.handleEspacePubData === 'function') {\r\n                    window.handleEspacePubData(data);\r\n                } else {\r\n                    console.warn('\u26a0\ufe0f handleEspacePubData non disponible, fallback direct');\r\n                    if (typeof window.executeWithProcessLoaded === 'function') {\r\n                        window.executeWithProcessLoaded(function() {\r\n                            jQuery('#PopupProcessCommandeContainer').show();\r\n                        });\r\n                    } else {\r\n                        jQuery('#PopupProcessCommandeContainer').show();\r\n                    }\r\n                }\r\n            } else if (formatChoisi) {\r\n                console.log('\ud83d\udcdd Mise \u00e0 jour format uniquement');\r\n                \r\n                const borderStyle = {'box-shadow': 'inset 0 0 0 2px #00FF19', 'box-sizing': 'border-box'};  \/\/ \u2705 v2.4.5\r\n                \r\n                jQuery(\".FormatClassique, .FormatPopup\").css({'border': 'none'});\r\n                \r\n                jQuery('.FormatClassique, .FormatPopup').each(function() {\r\n                    \/\/ \u2705 v2.1.1 : NFD normalize both sides\r\n                    var _cn = this.className.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    var _cf = (data.Commande_Format_Transmis || '').normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    if (_cn.includes(_cf) && _cf) {\r\n                        jQuery(this).css(borderStyle);\r\n                    }\r\n                });\r\n            }\r\n        }\r\n        \r\n        StateManager.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        setTimeout(() => {\r\n            StateManager.set(\"AddNewRefInVosCampagnes\", 'Yes');\r\n        }, 4000);\r\n        \r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            StateManager.set('Commande_Format_Transmis', '');\r\n        }\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion des fichiers PDF (s\u00e9par\u00e9 pour \u00e9viter la complexit\u00e9)\r\n *\/\r\nconst PDFHandler = {\r\n    pdfData: null,\r\n    pdfDataForViewer: null,\r\n    \r\n    async renderPDF(fileObj, $dropZone) {\r\n        return new Promise((resolve, reject) => {\r\n            const reader = new FileReader();\r\n            \r\n            reader.onload = async (e) => {\r\n                try {\r\n                    const arrayBuffer = e.target.result;\r\n                    this.pdfData = new Uint8Array(arrayBuffer);\r\n                    this.pdfDataForViewer = arrayBuffer;\r\n                    \r\n                    console.log(\"Initial PDF load, size:\", this.pdfData.byteLength);\r\n                    \r\n                    const pdfjsLib = window['pdfjs-dist\/build\/pdf'];\r\n                    pdfjsLib.GlobalWorkerOptions.workerSrc = \r\n                        '\/\/cdn.jsdelivr.net\/npm\/pdfjs-dist@latest\/build\/pdf.worker.min.js';\r\n                    \r\n                    const pdf = await pdfjsLib.getDocument({ data: new Uint8Array(this.pdfData) }).promise;\r\n                    const page = await pdf.getPage(1);\r\n                    \r\n                    const { titleText, pageText } = await this.extractTextFromPage(page);\r\n                    const imageData = await this.extractImageFromPage(page, pdfjsLib);\r\n                    \r\n                    if (imageData) {\r\n                        PreviewRenderer.renderDocumentPreview(\r\n                            $dropZone,\r\n                            imageData.dataUrl,\r\n                            titleText,\r\n                            pageText\r\n                        );\r\n                    } else {\r\n                        \/\/ \u2705 v1.19.0 : Accepter les PDF sans image\r\n                        PreviewRenderer.renderDocumentPreview(\r\n                            $dropZone,\r\n                            null,\r\n                            titleText,\r\n                            pageText\r\n                        );\r\n                        console.log('\u2139\ufe0f PDF sans image \u2014 aper\u00e7u texte seul');\r\n                    }\r\n                    \r\n                    this.attachPDFPreviewHandler($dropZone, titleText);\r\n                    resolve();\r\n                } catch (error) {\r\n                    console.error('Error extracting from PDF:', error);\r\n                    \/\/ \u2705 v1.19.0 : Message d'erreur en fran\u00e7ais\r\n                    $dropZone.html(`\r\n                        <div style=\"padding: 15px; background-color: #f8f8f8; border-radius: 4px; text-align: center;\">\r\n                            <p style=\"color: #FB5E2A; font-weight: 600; font-family: Roboto, Arial, sans-serif; font-size: 12px;\">\r\n                                Erreur lors de la lecture du document\r\n                            <\/p>\r\n                        <\/div>\r\n                    `);\r\n                    reject(error);\r\n                }\r\n            };\r\n            \r\n            reader.readAsArrayBuffer(fileObj);\r\n        });\r\n    },\r\n    \r\n    async extractTextFromPage(page) {\r\n        const textContent = await page.getTextContent();\r\n        \r\n        let text = '';\r\n        let lastX = -1;\r\n        let lastY = -1;\r\n        \r\n        for (const item of textContent.items) {\r\n            if (lastY !== -1 && (Math.abs(lastY - item.transform[5]) > 5)) {\r\n                text += '\\n';\r\n            } else if (lastX !== -1 && (item.transform[4] - lastX > 10)) {\r\n                text += ' ';\r\n            }\r\n            \r\n            text += item.str;\r\n            \r\n            lastX = item.transform[4] + (item.width || 0);\r\n            lastY = item.transform[5];\r\n        }\r\n        \r\n        text = text\r\n            .replace(\/(\\w) (\\w)\/g, (match, p1, p2) => {\r\n                if (\/[\u00e9\u00e8\u00ea\u00eb\u00e0\u00e2\u00e4\u00f4\u00f6\u00fb\u00fc\u00ef\u00ee\u00e7]\/i.test(p2)) {\r\n                    return p1 + p2;\r\n                }\r\n                return match;\r\n            })\r\n            .replace(\/ ([.,;:!?])\/g, '$1');\r\n        \r\n        const normalizedText = PreviewRenderer.normalizeText(text);\r\n        const titleText = PreviewRenderer.findDocumentTitle(normalizedText);\r\n        \r\n        return { titleText, pageText: text };\r\n    },\r\n    \r\n    async extractImageFromPage(page, pdfjsLib) {\r\n        const opList = await page.getOperatorList();\r\n        const imageInfo = [];\r\n        let currentTransform = null;\r\n        \r\n        for (let i = 0; i < opList.fnArray.length; i++) {\r\n            const operator = opList.fnArray[i];\r\n            const args = opList.argsArray[i];\r\n            \r\n            if (operator === pdfjsLib.OPS.transform) {\r\n                currentTransform = args;\r\n            } else if (operator === pdfjsLib.OPS.paintImageXObject) {\r\n                const imageName = args[0];\r\n                \r\n                if (!imageInfo.some(info => info.name === imageName)) {\r\n                    const position = currentTransform ? {\r\n                        x: currentTransform[4] || 0,\r\n                        y: currentTransform[5] || 0\r\n                    } : { x: 0, y: 0 };\r\n                    \r\n                    imageInfo.push({ name: imageName, position: position });\r\n                }\r\n            }\r\n        }\r\n        \r\n        if (imageInfo.length === 0) {\r\n            return null;\r\n        }\r\n        \r\n        imageInfo.sort((a, b) => b.position.y - a.position.y);\r\n        \r\n        const targetImageName = imageInfo[0].name;\r\n        const imageObj = page.objs.get(targetImageName);\r\n        \r\n        if (!imageObj) {\r\n            const img = await page.objs.get(targetImageName, true);\r\n            return this.processImageObject(img);\r\n        }\r\n        \r\n        return this.processImageObject(imageObj);\r\n    },\r\n    \r\n    processImageObject(imageObj) {\r\n        if (!imageObj) {\r\n            throw new Error('Image object is null');\r\n        }\r\n        \r\n        if (imageObj.bitmap instanceof ImageBitmap) {\r\n            const width = imageObj.bitmap.width || imageObj.width || imageObj.w;\r\n            const height = imageObj.bitmap.height || imageObj.height || imageObj.h;\r\n            \r\n            const canvas = document.createElement('canvas');\r\n            canvas.width = width;\r\n            canvas.height = height;\r\n            const ctx = canvas.getContext('2d');\r\n            \r\n            ctx.drawImage(imageObj.bitmap, 0, 0);\r\n            \r\n            return {\r\n                canvas: canvas,\r\n                width: width,\r\n                height: height,\r\n                dataUrl: canvas.toDataURL('image\/jpeg', 0.92)\r\n            };\r\n        }\r\n        \r\n        const width = imageObj.width || imageObj.w;\r\n        const height = imageObj.height || imageObj.h;\r\n        \r\n        if (!width || !height) {\r\n            throw new Error('Could not determine image dimensions');\r\n        }\r\n        \r\n        let imgData = imageObj.data || imageObj.bitmap;\r\n        \r\n        if (!imgData) {\r\n            throw new Error('No valid image data found');\r\n        }\r\n        \r\n        const canvas = document.createElement('canvas');\r\n        canvas.width = width;\r\n        canvas.height = height;\r\n        const ctx = canvas.getContext('2d');\r\n        \r\n        ctx.fillStyle = 'white';\r\n        ctx.fillRect(0, 0, width, height);\r\n        \r\n        const imageData = ctx.createImageData(width, height);\r\n        \r\n        this.fillImageData(imageData, imgData, imageObj.kind, width, height);\r\n        \r\n        ctx.putImageData(imageData, 0, 0);\r\n        \r\n        return {\r\n            canvas: canvas,\r\n            width: width,\r\n            height: height,\r\n            dataUrl: canvas.toDataURL('image\/jpeg', 0.92)\r\n        };\r\n    },\r\n    \r\n    fillImageData(imageData, imgData, kind, width, height) {\r\n        if (kind === 'GRAY') {\r\n            for (let i = 0, j = 0; i < imgData.length; i++, j += 4) {\r\n                const value = imgData[i];\r\n                imageData.data[j] = value;\r\n                imageData.data[j + 1] = value;\r\n                imageData.data[j + 2] = value;\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else if (kind === 'CMYK') {\r\n            for (let i = 0, j = 0; i < imgData.length; i += 4, j += 4) {\r\n                const c = imgData[i] \/ 255;\r\n                const m = imgData[i + 1] \/ 255;\r\n                const y = imgData[i + 2] \/ 255;\r\n                const k = imgData[i + 3] \/ 255;\r\n                \r\n                imageData.data[j] = 255 * (1 - c) * (1 - k);\r\n                imageData.data[j + 1] = 255 * (1 - m) * (1 - k);\r\n                imageData.data[j + 2] = 255 * (1 - y) * (1 - k);\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else if (kind === 'RGB24') {\r\n            for (let i = 0, j = 0; i < imgData.length; i += 3, j += 4) {\r\n                imageData.data[j] = imgData[i];\r\n                imageData.data[j + 1] = imgData[i + 1];\r\n                imageData.data[j + 2] = imgData[i + 2];\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else if (imgData.length === width * height * 3) {\r\n            for (let i = 0, j = 0; i < imgData.length; i += 3, j += 4) {\r\n                imageData.data[j] = imgData[i];\r\n                imageData.data[j + 1] = imgData[i + 1];\r\n                imageData.data[j + 2] = imgData[i + 2];\r\n                imageData.data[j + 3] = 255;\r\n            }\r\n        } else {\r\n            const tempArray = new Uint8ClampedArray(imgData.length);\r\n            for (let i = 0; i < imgData.length; i++) {\r\n                tempArray[i] = imgData[i];\r\n            }\r\n            \r\n            if (tempArray.length === imageData.data.length \/ 4 * 3) {\r\n                for (let i = 0, j = 0; i < tempArray.length; i += 3, j += 4) {\r\n                    imageData.data[j] = tempArray[i];\r\n                    imageData.data[j + 1] = tempArray[i + 1];\r\n                    imageData.data[j + 2] = tempArray[i + 2];\r\n                    imageData.data[j + 3] = 255;\r\n                }\r\n            } else if (tempArray.length === imageData.data.length) {\r\n                imageData.data.set(tempArray);\r\n            } else {\r\n                console.warn('Unknown image format - creating placeholder');\r\n                for (let i = 0; i < imageData.data.length; i += 4) {\r\n                    const x = (i\/4) % width;\r\n                    const y = Math.floor((i\/4) \/ width);\r\n                    imageData.data[i] = x % 256;\r\n                    imageData.data[i + 1] = y % 256;\r\n                    imageData.data[i + 2] = 100;\r\n                    imageData.data[i + 3] = 255;\r\n                }\r\n            }\r\n        }\r\n    },\r\n    \r\n    attachPDFPreviewHandler($dropZone, titleText) {\r\n        var $droppable = $dropZone.closest('.droppable');\r\n        var self = this;\r\n\r\n        \/\/ \u2705 Adapter le libell\u00e9 selon le format (communiqu\u00e9 \/ interview)\r\n        var kitFormat = $droppable.data('kitFormatSelect') || '';\r\n        var isInterview = (kitFormat || titleText || '').toLowerCase().indexOf('interview') !== -1;\r\n        var formatLabel = isInterview ? 'l\\'interview' : 'le communiqu\u00e9';\r\n        $droppable.find('.doc-preview-readmore').text('Ouvrir et visualiser ' + formatLabel);\r\n\r\n        \/\/ \u2705 v2.0.11 : D\u00e9l\u00e9gation d'\u00e9v\u00e9nement \u2014 plus robuste sur mobile\r\n        $droppable.off('click.docpreview').on('click.docpreview', '.doc-preview-readmore', (event) => {\r\n            event.preventDefault();\r\n            event.stopPropagation();\r\n            var popupTitle = isInterview ? 'Interview' : 'Communiqu\u00e9';\r\n\r\n            \/\/ \u2705 Priorit\u00e9 1 : pdfImageDataURL dispo (Kit)\r\n            var kitPdfImage = $droppable.data('kitPdfImageDataURL');\r\n            if (kitPdfImage) {\r\n                PDFHandler.showInlineDocPopup($dropZone, {\r\n                    formatTitle: popupTitle,\r\n                    pdfDataURL: kitPdfImage\r\n                });\r\n                return;\r\n            }\r\n\r\n            \/\/ \u2705 Priorit\u00e9 2 : PDF upload\u00e9 manuellement \u2192 popup inline aussi\r\n            if (self.pdfDataForViewer && self.pdfDataForViewer.byteLength > 0) {\r\n                PDFHandler.showInlineDocPopup($dropZone, {\r\n                    formatTitle: popupTitle,\r\n                    pdfArrayBuffer: self.pdfDataForViewer\r\n                });\r\n                return;\r\n            }\r\n\r\n            console.error('PDF data is not available');\r\n        });\r\n    },\r\n\r\n    \/\/ \u2705 v1.19.1 : Popup inline document \u2014 position:absolute + ScrollHelper.getVisibleTop()\r\n    \/\/ Le parent envoie visibleTopIframe dans le message scroll \u2192 positionnement fiable.\r\n    showInlineDocPopup($dropZone, options) {\r\n        var existing = document.getElementById('via-pdf-inline-popup');\r\n        if (existing) existing.remove();\r\n\r\n        var $droppable = $dropZone.closest('.droppable');\r\n        var droppableW = $droppable.outerWidth() || 300;\r\n        var popupW = Math.round(droppableW * 1.15);\r\n        \/\/ \u2705 v2.0.11 : Contraindre la largeur au viewport sur mobile (\u00e9vite troncature gauche\/droite)\r\n        var viewportW = document.documentElement.clientWidth || window.innerWidth;\r\n        if (UIManager.isMobile()) {\r\n            popupW = Math.min(popupW, viewportW - 8);\r\n        }\r\n        var popupH = Math.round(popupW * 2.5 * 0.51);\r\n\r\n        \/\/ \u2500\u2500 Position visible r\u00e9elle \u2500\u2500\r\n        var visibleTop = ScrollHelper.getVisibleTop();\r\n        var popupTop = Math.round(visibleTop + 284);\r\n\r\n        \/\/ \u2500\u2500 Popup position:absolute (positionn\u00e9 dans le document iframe) \u2500\u2500\r\n        var popup = document.createElement('div');\r\n        popup.id = 'via-pdf-inline-popup';\r\n        popup.style.cssText =\r\n            'position:absolute;z-index:99999;top:' + popupTop + 'px;' +\r\n            'width:' + popupW + 'px;height:' + popupH + 'px;' +\r\n            'background:#fff;border-radius:8px 8px 0 0;padding:0;' +\r\n            'box-shadow:0 8px 32px rgba(0,0,0,0.35);display:flex;flex-direction:column;' +\r\n            'min-width:200px;min-height:150px;touch-action:none;';\r\n\r\n        \/\/ Centrer horizontalement sur le droppable (coordonn\u00e9es absolues)\r\n        var droppableRect = $droppable[0].getBoundingClientRect();\r\n        var scrollX = window.scrollX || 0;\r\n        var initLeft = Math.round(droppableRect.left + scrollX + (droppableRect.width - popupW) \/ 2);\r\n        initLeft = Math.max(4, initLeft);\r\n        \/\/ \u2705 v2.0.11 : Contraindre \u00e0 droite aussi sur mobile\r\n        if (UIManager.isMobile()) {\r\n            initLeft = Math.min(initLeft, viewportW - popupW - 4);\r\n            initLeft = Math.max(4, initLeft);\r\n        }\r\n        popup.style.left = initLeft + 'px';\r\n\r\n        \/\/ \u2500\u2500 Header \u2500\u2500\r\n        var header = document.createElement('div');\r\n        header.style.cssText =\r\n            'display:flex;align-items:center;justify-content:center;position:relative;' +\r\n            'padding:10px 14px;background:#f0f0f0;color:#494949;flex-shrink:0;' +\r\n            'cursor:grab;user-select:none;border-radius:8px 8px 0 0;';\r\n        var titleEl = document.createElement('span');\r\n        titleEl.style.cssText = 'font-family:Roboto,Arial,sans-serif;font-size:15px;font-weight:600;';\r\n        titleEl.textContent = options.formatTitle || 'Document';\r\n        header.appendChild(titleEl);\r\n\r\n        var closeBtn = document.createElement('button');\r\n        closeBtn.textContent = '\u00d7';\r\n        closeBtn.style.cssText =\r\n            'position:absolute;right:10px;top:50%;transform:translateY(-50%);' +\r\n            'background:transparent;border:none;color:#494949;font-size:20px;' +\r\n            'cursor:pointer;line-height:1;padding:0 4px;';\r\n        closeBtn.addEventListener('click', cleanup);\r\n        header.appendChild(closeBtn);\r\n        popup.appendChild(header);\r\n\r\n        \/\/ \u2500\u2500 Zone scrollable \u2014 pleine largeur \u2500\u2500\r\n        var scrollZone = document.createElement('div');\r\n        scrollZone.style.cssText =\r\n            'flex:1;overflow-y:auto;overflow-x:hidden;padding:0;margin:0;touch-action:pan-y;';\r\n        popup.appendChild(scrollZone);\r\n\r\n        var loader = document.createElement('div');\r\n        loader.style.cssText =\r\n            'text-align:center;padding:30px;font-family:Roboto,Arial,sans-serif;font-size:12px;color:#666;';\r\n        loader.textContent = 'Chargement du document\u2026';\r\n        scrollZone.appendChild(loader);\r\n\r\n        \/\/ \u2500\u2500 8 poign\u00e9es de redimensionnement \u2500\u2500\r\n        var handles = [\r\n            { cursor:'nw-resize', pos:'top:-4px;left:-4px;',       dx:-1, dy:-1 },\r\n            { cursor:'n-resize',  pos:'top:-4px;left:50%;',        dx:0,  dy:-1 },\r\n            { cursor:'ne-resize', pos:'top:-4px;right:-4px;',      dx:1,  dy:-1 },\r\n            { cursor:'w-resize',  pos:'top:50%;left:-4px;',        dx:-1, dy:0  },\r\n            { cursor:'e-resize',  pos:'top:50%;right:-4px;',       dx:1,  dy:0  },\r\n            { cursor:'sw-resize', pos:'bottom:-4px;left:-4px;',    dx:-1, dy:1  },\r\n            { cursor:'s-resize',  pos:'bottom:-4px;left:50%;',     dx:0,  dy:1  },\r\n            { cursor:'se-resize', pos:'bottom:-4px;right:-4px;',   dx:1,  dy:1  }\r\n        ];\r\n        handles.forEach(function(h) {\r\n            var handle = document.createElement('div');\r\n            var isCorner = (h.dx !== 0 && h.dy !== 0);\r\n            handle.style.cssText =\r\n                'position:absolute;touch-action:none;' + h.pos +\r\n                'width:' + (isCorner ? '12px' : (h.dy === 0 ? '8px' : '30px')) + ';' +\r\n                'height:' + (isCorner ? '12px' : (h.dy === 0 ? '30px' : '8px')) + ';' +\r\n                'cursor:' + h.cursor + ';z-index:10;';\r\n            (function(hInfo) {\r\n                handle.addEventListener('pointerdown', function(e) {\r\n                    e.preventDefault(); e.stopPropagation();\r\n                    handle.setPointerCapture(e.pointerId);\r\n                    var startX = e.clientX, startY = e.clientY;\r\n                    var rect0 = popup.getBoundingClientRect();\r\n                    var sY = window.scrollY || 0, sX = window.scrollX || 0;\r\n                    var startW = rect0.width, startH = rect0.height;\r\n                    var startL = rect0.left + sX, startT = rect0.top + sY;\r\n                    function onResize(ev) {\r\n                        ev.preventDefault();\r\n                        var ddx = ev.clientX - startX, ddy = ev.clientY - startY;\r\n                        var newW = startW, newH = startH, newL = startL, newT = startT;\r\n                        if (hInfo.dx === 1)  newW = Math.max(200, startW + ddx);\r\n                        if (hInfo.dx === -1) { newW = Math.max(200, startW - ddx); newL = startL + ddx; }\r\n                        if (hInfo.dy === 1)  newH = Math.max(150, startH + ddy);\r\n                        if (hInfo.dy === -1) { newH = Math.max(150, startH - ddy); newT = startT + ddy; }\r\n                        popup.style.width  = newW + 'px';\r\n                        popup.style.height = newH + 'px';\r\n                        popup.style.left   = newL + 'px';\r\n                        popup.style.top    = newT + 'px';\r\n                    }\r\n                    function onResizeEnd(ev) {\r\n                        handle.releasePointerCapture(ev.pointerId);\r\n                        handle.removeEventListener('pointermove', onResize);\r\n                        handle.removeEventListener('pointerup', onResizeEnd);\r\n                    }\r\n                    handle.addEventListener('pointermove', onResize);\r\n                    handle.addEventListener('pointerup', onResizeEnd);\r\n                });\r\n            })(h);\r\n            popup.appendChild(handle);\r\n        });\r\n\r\n        \/\/ \u2500\u2500 Drag via header \u2500\u2500\r\n        header.style.touchAction = 'none';\r\n        header.addEventListener('pointerdown', function(e) {\r\n            if (e.target === closeBtn) return;\r\n            e.preventDefault();\r\n            header.setPointerCapture(e.pointerId);\r\n            var mx = e.clientX, my = e.clientY;\r\n            var popupRect = popup.getBoundingClientRect();\r\n            var scrollY = window.scrollY || 0;\r\n            var scrollX = window.scrollX || 0;\r\n            var curLeft = popupRect.left + scrollX;\r\n            var curTop  = popupRect.top  + scrollY;\r\n            header.style.cursor = 'grabbing';\r\n            function onMove(ev) {\r\n                ev.preventDefault();\r\n                var dx = ev.clientX - mx;\r\n                var dy = ev.clientY - my;\r\n                curLeft += dx;\r\n                curTop  += dy;\r\n                popup.style.left = curLeft + 'px';\r\n                popup.style.top  = curTop  + 'px';\r\n                mx = ev.clientX;\r\n                my = ev.clientY;\r\n            }\r\n            function onUp(ev) {\r\n                header.releasePointerCapture(ev.pointerId);\r\n                header.style.cursor = 'grab';\r\n                header.removeEventListener('pointermove', onMove);\r\n                header.removeEventListener('pointerup', onUp);\r\n            }\r\n            header.addEventListener('pointermove', onMove);\r\n            header.addEventListener('pointerup', onUp);\r\n        });\r\n\r\n        \/\/ \u2500\u2500 Cleanup \u2500\u2500\r\n        function cleanup() {\r\n            popup.remove();\r\n            document.removeEventListener('keydown', escHandler);\r\n        }\r\n        var escHandler = function(e) { if (e.key === 'Escape') cleanup(); };\r\n        document.addEventListener('keydown', escHandler);\r\n\r\n        document.body.appendChild(popup);\r\n\r\n        \/\/ \u2500\u2500 Rendre le contenu \u2500\u2500\r\n        if (options.pdfDataURL)          this.renderPdfInPopup(scrollZone, options.pdfDataURL, popupW, 'dataurl');\r\n        else if (options.pdfArrayBuffer) this.renderPdfInPopup(scrollZone, options.pdfArrayBuffer, popupW, 'arraybuffer');\r\n        else if (options.htmlContent)    this.renderHtmlInPopup(scrollZone, options.htmlContent);\r\n    },\r\n\r\n    \/\/ Alias pour compatibilit\u00e9\r\n    showInlinePdfPopup($dropZone, pdfImageDataURL, formatTitle) {\r\n        this.showInlineDocPopup($dropZone, { formatTitle: formatTitle, pdfDataURL: pdfImageDataURL });\r\n    },\r\n\r\n    \/\/ \u2705 Rendu PDF dans popup (dataurl ou arraybuffer) \u2014 avec crop des marges blanches\r\n    async renderPdfInPopup(container, pdfData, popupWidth, mode) {\r\n        try {\r\n            var u8;\r\n            if (mode === 'dataurl') {\r\n                var b64 = pdfData.split(',')[1];\r\n                var bstr = atob(b64);\r\n                u8 = new Uint8Array(bstr.length);\r\n                for (var i = 0; i < bstr.length; i++) { u8[i] = bstr.charCodeAt(i); }\r\n            } else {\r\n                u8 = new Uint8Array(pdfData);\r\n            }\r\n\r\n            var pdfjsLib = window['pdfjs-dist\/build\/pdf'];\r\n            if (!pdfjsLib) {\r\n                container.innerHTML = '<div style=\"padding:20px;text-align:center;color:#c00;\">pdf.js non charg\u00e9<\/div>';\r\n                return;\r\n            }\r\n            pdfjsLib.GlobalWorkerOptions.workerSrc =\r\n                '\/\/cdn.jsdelivr.net\/npm\/pdfjs-dist@latest\/build\/pdf.worker.min.js';\r\n\r\n            var pdf = await pdfjsLib.getDocument({ data: u8 }).promise;\r\n            console.log('\ud83d\udcc4 PDF popup :', pdf.numPages, 'pages');\r\n            container.innerHTML = '';\r\n\r\n            var firstPage = await pdf.getPage(1);\r\n            var vpNative = firstPage.getViewport({ scale: 1 });\r\n            var scale = popupWidth \/ vpNative.width;\r\n\r\n            \/\/ \u2705 R\u00e9f\u00e9rence au popup pour ajuster sa hauteur apr\u00e8s rendu\r\n            var _popup = container.closest('#via-pdf-inline-popup');\r\n            var _headerH = _popup ? (_popup.querySelector('div[style*=\"grab\"]') || {offsetHeight: 44}).offsetHeight : 44;\r\n\r\n            \/\/ \u2705 D\u00e9tecte les marges blanches haut\/bas d'un canvas rendu et retourne {top, bottom}\r\n            function detectWhiteMargins(canvas) {\r\n                var ctx = canvas.getContext('2d');\r\n                var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;\r\n                var W = canvas.width, H = canvas.height;\r\n                var topRow = 0, bottomRow = H - 1;\r\n                \/\/ Chercher la premi\u00e8re ligne non-blanche (tol\u00e9rance 252 pour les artefacts anti-aliasing)\r\n                outer: for (var y = 0; y < H; y++) {\r\n                    for (var x = 0; x < W; x++) {\r\n                        var i = (y * W + x) * 4;\r\n                        if (data[i] < 252 || data[i+1] < 252 || data[i+2] < 252) { topRow = y; break outer; }\r\n                    }\r\n                }\r\n                outer2: for (var y2 = H - 1; y2 >= topRow; y2--) {\r\n                    for (var x2 = 0; x2 < W; x2++) {\r\n                        var i2 = (y2 * W + x2) * 4;\r\n                        if (data[i2] < 252 || data[i2+1] < 252 || data[i2+2] < 252) { bottomRow = y2; break outer2; }\r\n                    }\r\n                }\r\n                return { top: topRow, bottom: bottomRow };\r\n            }\r\n\r\n            for (var pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\r\n                var page = await pdf.getPage(pageNum);\r\n                var vp = page.getViewport({ scale: scale });\r\n                \/\/ Rendre dans un canvas temporaire\r\n                var tmpCanvas = document.createElement('canvas');\r\n                tmpCanvas.width = vp.width;\r\n                tmpCanvas.height = vp.height;\r\n                await page.render({ canvasContext: tmpCanvas.getContext('2d'), viewport: vp }).promise;\r\n\r\n                \/\/ \u2705 Crop marges blanches\r\n                var margins = detectWhiteMargins(tmpCanvas);\r\n                var cropTop = Math.max(0, margins.top - 4);\r\n                var cropBottom = Math.min(tmpCanvas.height - 1, margins.bottom + 4);\r\n                var croppedH = cropBottom - cropTop + 1;\r\n\r\n                \/\/ Canvas final crop\u00e9\r\n                var canvas = document.createElement('canvas');\r\n                canvas.width = tmpCanvas.width;\r\n                canvas.height = croppedH;\r\n                canvas.getContext('2d').drawImage(tmpCanvas, 0, cropTop, tmpCanvas.width, croppedH, 0, 0, tmpCanvas.width, croppedH);\r\n                canvas.style.cssText = 'display:block;width:100%;height:auto;margin:0;padding:0;';\r\n                container.appendChild(canvas);\r\n                console.log('\ud83d\udcc4 Page', pageNum, '- crop:', cropTop, '\u2192', cropBottom, '(', Math.round(cropTop\/vp.height*100), '% top trimmed)');\r\n            }\r\n\r\n            \/\/ \u2705 Ajuster la hauteur du popup \u00e0 la hauteur r\u00e9elle du contenu rendu\r\n            \/\/ (popup \u00e9tait calcul\u00e9 sur popupW*2.5*0.51 qui peut \u00eatre trop grand ou trop petit)\r\n            if (_popup) {\r\n                var _totalH = 0;\r\n                container.querySelectorAll('canvas').forEach(function(c) { _totalH += c.height * (popupWidth \/ c.width); });\r\n                var _viewportH = window.innerHeight || document.documentElement.clientHeight || 600;\r\n                var _maxPopupH = Math.round(_viewportH * 0.88);\r\n                var _idealH = Math.min(_totalH + _headerH + 8, _maxPopupH);\r\n                _popup.style.height = _idealH + 'px';\r\n                console.log('\ud83d\udcd0 Popup redimensionn\u00e9:', Math.round(_idealH), 'px (contenu:', Math.round(_totalH), ')');\r\n            }\r\n        } catch (err) {\r\n            console.error('\u274c Erreur rendu PDF popup:', err);\r\n            container.innerHTML =\r\n                '<div style=\"padding:20px;text-align:center;color:#c00;font-size:12px;\">Erreur lors du chargement du document<\/div>';\r\n        }\r\n    },\r\n\r\n    \/\/ \u2705 Rendu HTML (Word) dans popup \u2014 avec CSS complet pour mammoth\r\n    renderHtmlInPopup(container, htmlContent) {\r\n        container.innerHTML = '';\r\n        \/\/ \u2705 Nettoyer les <p> vides en d\u00e9but\/fin produits par mammoth (marges parasites)\r\n        htmlContent = htmlContent\r\n            .replace(\/^(\\s*<p[^>]*>\\s*(<br\\s*\\\/?>\\s*)*<\\\/p>\\s*)+\/i, '')\r\n            .replace(\/(\\s*<p[^>]*>\\s*(<br\\s*\\\/?>\\s*)*<\\\/p>\\s*)+$\/i, '');\r\n        \/\/ \u2500\u2500 Styles pour le HTML g\u00e9n\u00e9r\u00e9 par mammoth (titres, paragraphes, listes, images) \u2500\u2500\r\n        var style = document.createElement('style');\r\n        style.textContent = [\r\n            '.via-html-popup-body { padding:20px 24px; background:#fff; color:#222; font-family:Georgia,\"Times New Roman\",serif; font-size:15px; line-height:1.7; }',\r\n            '.via-html-popup-body h1 { font-size:22px; font-weight:700; margin:0 0 12px; line-height:1.3; }',\r\n            '.via-html-popup-body h2 { font-size:18px; font-weight:700; margin:18px 0 8px; line-height:1.3; }',\r\n            '.via-html-popup-body h3 { font-size:15px; font-weight:700; margin:14px 0 6px; }',\r\n            '.via-html-popup-body p  { margin:0 0 10px; }',\r\n            '.via-html-popup-body p:first-child { margin-top:0; }',\r\n            '.via-html-popup-body strong, .via-html-popup-body b { font-weight:700; }',\r\n            '.via-html-popup-body em, .via-html-popup-body i { font-style:italic; }',\r\n            '.via-html-popup-body ul, .via-html-popup-body ol { margin:6px 0 10px 22px; padding:0; }',\r\n            '.via-html-popup-body li { margin-bottom:4px; }',\r\n            '.via-html-popup-body img { max-width:100%; height:auto; display:block; margin:10px auto; border-radius:4px; }',\r\n            '.via-html-popup-body table { width:100%; border-collapse:collapse; margin:10px 0; font-size:13px; }',\r\n            '.via-html-popup-body td, .via-html-popup-body th { border:1px solid #ddd; padding:6px 8px; vertical-align:top; }',\r\n            '.via-html-popup-body th { background:#f0f4f8; font-weight:700; }',\r\n            '.via-html-popup-body a { color:#225da9; text-decoration:underline; }'\r\n        ].join('');\r\n        container.appendChild(style);\r\n        var wrapper = document.createElement('div');\r\n        wrapper.className = 'via-html-popup-body';\r\n        wrapper.innerHTML = htmlContent;\r\n        container.appendChild(wrapper);\r\n    },\r\n    \r\n    async renderPDFInWindow(childWindow, container) {\r\n        container.innerHTML = '';\r\n        \r\n        const script = childWindow.document.createElement('script');\r\n        script.src = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.4.120\/pdf.min.js';\r\n        childWindow.document.head.appendChild(script);\r\n        \r\n        script.onload = async () => {\r\n            const pdfjsLib = childWindow.pdfjsLib;\r\n            const viewerContainer = childWindow.document.createElement('div');\r\n            viewerContainer.style.width = '100%';\r\n            viewerContainer.style.backgroundColor = 'white';\r\n            viewerContainer.style.position = 'relative';\r\n            container.appendChild(viewerContainer);\r\n            \r\n            const loadingTask = pdfjsLib.getDocument({data: window.pdfDataToTransfer});\r\n            const pdf = await loadingTask.promise;\r\n            \r\n            const firstPage = await pdf.getPage(1);\r\n            const viewport = firstPage.getViewport({scale: 1.5});\r\n            const pageHeight = viewport.height;\r\n            \r\n            const spacing = -15;\r\n            const totalHeight = (pageHeight * pdf.numPages) + (spacing * (pdf.numPages - 1));\r\n            viewerContainer.style.height = `${totalHeight}px`;\r\n            \r\n            for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\r\n                const page = await pdf.getPage(pageNum);\r\n                const canvas = childWindow.document.createElement('canvas');\r\n                const context = canvas.getContext('2d');\r\n                \r\n                canvas.width = viewport.width;\r\n                canvas.height = viewport.height;\r\n                \r\n                canvas.style.position = 'absolute';\r\n                canvas.style.left = '50%';\r\n                canvas.style.transform = 'translateX(-50%)';\r\n                canvas.style.top = `${(pageNum - 1) * (pageHeight + spacing)}px`;\r\n                \r\n                await page.render({\r\n                    canvasContext: context,\r\n                    viewport: viewport\r\n                }).promise;\r\n                \r\n                viewerContainer.appendChild(canvas);\r\n            }\r\n        };\r\n    },\r\n    \r\n    arrayBufferToBase64(buffer) {\r\n        let binary = '';\r\n        const bytes = new Uint8Array(buffer);\r\n        const len = bytes.byteLength;\r\n        for (let i = 0; i < len; i++) {\r\n            binary += String.fromCharCode(bytes[i]);\r\n        }\r\n        return window.btoa(binary);\r\n    },\r\n    \r\n    base64ToArrayBuffer(base64) {\r\n        const binaryString = window.atob(base64);\r\n        const len = binaryString.length;\r\n        const bytes = new Uint8Array(len);\r\n        for (let i = 0; i < len; i++) {\r\n            bytes[i] = binaryString.charCodeAt(i);\r\n        }\r\n        return bytes.buffer;\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion des \u00e9v\u00e9nements de drop et d'upload\r\n *\/\r\nconst DropHandler = {\r\n    async handleDrop(e) {\r\n        e.preventDefault();\r\n        \r\n        const $currentTarget = this.findDropTarget(e);\r\n        \r\n        if (!$currentTarget) {\r\n            console.log('No valid drop target found');\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 V\u00c9RIFIER SI C'EST UN D\u00c9PLACEMENT (pas besoin de v\u00e9rifier le format)\r\n        const isMoved = StateManager.get('FirstUploadFileorMoved') === 'Moved';\r\n        const dragstartRef = StateManager.get('dragstart_Commande_Emplacement_Page_Web');\r\n        let hasDragstartRef = false;\r\n        \r\n        if (dragstartRef) {\r\n            if (dragstartRef !== 'No') {\r\n                hasDragstartRef = true;\r\n            }\r\n        }\r\n        \r\n        let isDeplacementAnnonce = false;\r\n        if (isMoved) {\r\n            if (hasDragstartRef) {\r\n                isDeplacementAnnonce = true;\r\n            }\r\n        }\r\n        \r\n        if (isDeplacementAnnonce) {\r\n            console.log('\ud83d\udd04 D\u00e9placement d\u00e9tect\u00e9 - contr\u00f4le format ignor\u00e9');\r\n        } else {\r\n            \/\/ \u2705 CONTR\u00d4LE FORMAT SEULEMENT POUR NOUVEAU D\u00c9P\u00d4T\r\n            \/\/ Utilise FormatUIManager au lieu de showFormatWarning\r\n            if (StateManager.get('Formatchoisi') === 'No') {\r\n                FormatUIManager.flashTitle($currentTarget);\r\n                return;\r\n            }\r\n            \r\n            if (!FormatUIManager.hasSelectedFormat($currentTarget)) {\r\n                FormatUIManager.flashTitle($currentTarget);\r\n                return;\r\n            }\r\n        }\r\n    \r\n        console.log(\"Drop at:\", $currentTarget);\r\n        \r\n        this.updateEmplacementState($currentTarget);\r\n        \r\n        const shouldProcess = this.shouldProcessDrop(e, $currentTarget);\r\n        \r\n        if (shouldProcess) {\r\n            await this.processFileDrop(e, $currentTarget);\r\n        } else {\r\n            this.processVideoDrop($currentTarget);\r\n        }\r\n        \r\n        DragDropManager.clearDataTransferFiles(e);\r\n    },\r\n    \r\n    findDropTarget(e) {\r\n        \/\/ \u2705 v2.4.3 : Si Ele0A est actif et le drop arrive sur Ele1A \u2192 rediriger vers Ele0A\r\n        if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n            var _ele0ADrop = document.querySelector('#Ele0A #drop_file_zone_achat');\r\n            if (_ele0ADrop) {\r\n                console.log('\ud83c\udfaf findDropTarget \u2014 PopUpChoice=Yes \u2192 cible forc\u00e9e: Ele0A');\r\n                return jQuery(_ele0ADrop);\r\n            }\r\n        }\r\n\r\n        let target = e.target.closest('#drop_file_zone_achat');\r\n        \r\n        if (!target) {\r\n            target = e.currentTarget.closest('#drop_file_zone_achat');\r\n            console.log('Drop target found 1');\r\n        }\r\n        \r\n        if (!target) {\r\n            target = jQuery(e.target).closest('#drop_file_zone_achat')[0];\r\n            console.log('Drop target found 2');\r\n        }\r\n        \r\n        return target ? jQuery(target) : null;\r\n    },\r\n    \r\n    updateEmplacementState($target) {\r\n        const espaceId = $target.closest('.droppable').attr('id');\r\n        \r\n        StateManager.set('Rank_Emplacement_Page_Web', espaceId);\r\n        StateManager.set('Commande_Emplacement_Page_Web',\r\n            StateManager.buildEmplacementReference(espaceId));\r\n        \r\n        UIManager.updateEmplacementDisplay();\r\n        \r\n        console.log(\"Rank_Emplacement_Page_Web:\", StateManager.get('Rank_Emplacement_Page_Web'));\r\n        console.log(\"Droppable at:\", StateManager.get('Commande_Emplacement_Page_Web'));\r\n    },\r\n    \r\n    shouldProcessDrop(e, $target) {\r\n        const hasFiles = e.dataTransfer.files.length > 0;\r\n        const isRedactionnel = StateManager.get('Commande_Format_Transmis') === 'R\u00e9dactionnel';\r\n        const isValidBackground = window.getComputedStyle(\r\n            $target.closest('#UploadFileConteneur')[0]\r\n        ).backgroundColor !== 'rgba(0, 0, 0, 0)';\r\n        \r\n        return (hasFiles || isRedactionnel) && isValidBackground;\r\n    },\r\n    \r\n    async processFileDrop(e, $target) {\r\n        jQuery('.MsgAdNotDisplayed').hide();\r\n        StateManager.setMultiple({\r\n            \"AdDisplayed\": 'Yes',\r\n            \/\/ \u2705 NE PLUS mettre sendDataToParentFlag ici - c'est la checkbox \"R\u00e9server\" qui le fera\r\n            \/\/ \"sendDataToParentFlag\": 'Yes'\r\n        });\r\n        \r\n        console.log('ajaxFileUpload_achat launched');\r\n        console.log(\"FirstUploadFileorMoved:\", StateManager.get('FirstUploadFileorMoved'));\r\n        \r\n        if (UIManager.isMobile()) {\r\n            $target = jQuery('#Ele1A').find('#drop_file_zone_achat');\r\n        }\r\n        \r\n        if (StateManager.get('Commande_Format_Transmis') === 'R\u00e9dactionnel') {\r\n            const fileURL = StateManager.get('FullPathAdFile');\r\n            const filename = fileURL.substring(fileURL.indexOf('_') + 1);\r\n            \r\n            try {\r\n                \/\/ \u2705 R\u00e9utiliser le File cach\u00e9 (\u00e9vite CORS cross-domain)\r\n                let file;\r\n                if (window._lastRedactionnelFile) {\r\n                    file = window._lastRedactionnelFile;\r\n                    console.log('\u267b\ufe0f R\u00e9utilisation du File cach\u00e9:', file.name, Math.round(file.size \/ 1024) + 'KB');\r\n                } else {\r\n                    file = await FileManager.urlToFile(fileURL, filename);\r\n                }\r\n                await UploadManager.handleFileUpload(file, $target);\r\n            } catch (error) {\r\n                console.error('Error:', error);\r\n            }\r\n        } else {\r\n            await UploadManager.handleFileUpload(e.dataTransfer.files[0], $target);\r\n        }\r\n    },\r\n    \r\n    processVideoDrop($target) {\r\n        const isValidBackground = window.getComputedStyle(\r\n            $target.closest('#UploadFileConteneur')[0]\r\n        ).backgroundColor !== 'rgba(0, 0, 0, 0)';\r\n        \r\n        if (!isValidBackground) {\r\n            jQuery('.MsgAdNotDisplayed').show();\r\n            StateManager.set(\"AdDisplayed\", 'No');\r\n            return;\r\n        }\r\n        \r\n        StateManager.set(\"AdDisplayed\", 'Yes');\r\n        \r\n        const objectUrl = StateManager.get('videoSrc');\r\n        const $previousDropZone = $('.drop_file_zone_achat_class').has(`video[src=\"${objectUrl}\"]`);\r\n        window.RestoreadSpaceTemplate($previousDropZone);\r\n        \r\n        const videoElement = jQuery('<video controls autoplay muted>').attr({\r\n            'src': objectUrl,\r\n            'max-width': '100%',\r\n            'max-height': '100%',\r\n            'draggable': 'true'\r\n        }).css({\r\n            'max-width': '100%',\r\n            'max-height': '100%'\r\n        });\r\n        \r\n        $target.empty().append(videoElement);\r\n        \r\n        $target.closest('#UploadFileConteneur').css({'background-color': '#FFFFFF00'});\r\n        \r\n        $target.closest('.OrdiMobileConteneurClass')\r\n            .find('.RefEspacePublicitaire')\r\n            .html('R\u00e9f\u00e9rence de l\\'espace : ' + StateManager.get('Commande_Emplacement_Page_Web'))\r\n            .attr('id', 'RefEspacePublicitaire')\r\n            .each(function() {\r\n                var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                this.style.setProperty('display', 'block', 'important');\r\n            });\r\n        \/\/ \u2705 v2.4.5 : Renseigner et afficher .PositionEspacePublicitaire\r\n        (function() {\r\n            var _rankPosV = StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            var _posLibV = PreviewRenderer._getPositionLibelle(_rankPosV);\r\n            if (_posLibV) {\r\n                $target.closest('.OrdiMobileConteneurClass')\r\n                    .find('.PositionEspacePublicitaireDeplacer')\r\n                    .text(_posLibV)\r\n                    .each(function() {\r\n                        var _parent = jQuery(this).closest('.DeplaceAnnonce')[0];\r\n                        if (_parent) { _parent.style.setProperty('display', 'flex', 'important'); }\r\n                        this.style.setProperty('display', 'block', 'important');\r\n                    });\r\n            }\r\n        })();\r\n        \r\n        $target.closest('.OrdiMobileConteneurClass').find('.AdUploadedTitle').show();\r\n        \r\n        $target.closest('.OrdiMobileConteneurClass')\r\n            .css({'top': '60px', 'margin-bottom': '80px'});\r\n        \r\n        $target.closest('.HTMLUploadfileConteneur')\r\n            .not('.AdUploadedTitle')\r\n            .css({\r\n                'top': '0px',\r\n                'margin-bottom': '0px',\r\n                'box-shadow': 'inset 0 0 0 2px #00FF19',  \/\/ \u2705 v2.4.5\r\n                'background-color': 'white'\r\n            });\r\n        \r\n        $target.closest('.droppable')\r\n            .find('.AdDroppedTextNotDisplayed, .ChoisirEspacePublicitaire2ndLigne, span.ClassHdpCdp, .ClassRefEsp, .HideFormButton, .EspPubFormatMainContainer, .EnvoiUlterieurContainer')\r\n            .hide();\r\n        \r\n        jQuery('#MsgElementsCommandeValides, #MessageOptionsacompleterConteneur').hide();\r\n        \r\n        StateManager.set(\"FirstUploadFileorMoved\", 'Moved');\r\n        \r\n        \/\/ \u2705 Mettre \u00e0 jour l'\u00e9tat de la checkbox R\u00e9server (au lieu d'envoyer automatiquement)\r\n        FormatUIManager.updateReserverCheckboxState($target.closest('.droppable'));\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion de l'explorateur de fichiers\r\n *\/\r\nconst FileExplorer = {\r\n    isRunning: false,\r\n\r\n    open(e) {\r\n        if (this.isRunning) {\r\n            return;\r\n        }\r\n        \r\n        const $element = jQuery(e.target).closest('.droppable');\r\n        \r\n        \/\/ \u2705 V\u00e9rifier si un format est s\u00e9lectionn\u00e9 (utilise FormatUIManager)\r\n        if (!FormatUIManager.hasSelectedFormat($element)) {\r\n            FormatUIManager.flashTitle($element);\r\n            return;\r\n        }\r\n        \r\n        this.isRunning = true;\r\n        \r\n        const rankId = $element.attr('id');\r\n        \r\n        StateManager.set('Rank_Emplacement_Page_Web', rankId);\r\n        StateManager.set('Commande_Emplacement_Page_Web',\r\n            StateManager.buildEmplacementReference(rankId));\r\n        \r\n        UIManager.updateEmplacementDisplay();\r\n        \r\n        console.log(\"Drop at:\", StateManager.get('Commande_Emplacement_Page_Web'));\r\n        \r\n        StateManager.set('FirstUploadFileorMoved', 'FirstUpload');\r\n        \r\n        const $currentTarget = jQuery(e.target).closest('#drop_file_zone_achat');\r\n        const $fileInput = jQuery('#selectfile_achat');\r\n        \r\n        console.log(\"currentTarget\", $currentTarget);\r\n        \r\n        $fileInput.off('change');\r\n        $fileInput.off('click');\r\n        \r\n        const onChange = (event) => {\r\n            this.isRunning = false;\r\n            $fileInput.off('change', onChange);\r\n            \r\n            \/\/ \u2705 NE PLUS mettre sendDataToParentFlag ici\r\n            \/\/ StateManager.set(\"sendDataToParentFlag\", 'Yes');\r\n            \r\n            if ($fileInput[0].files.length > 0) {\r\n                UploadManager.handleFileUpload($fileInput[0].files[0], $currentTarget);\r\n            }\r\n        };\r\n        \r\n        const onClick = () => {\r\n            $fileInput.off('click', onClick);\r\n            $fileInput.on('focus', function onFocus() {\r\n                setTimeout(() => {\r\n                    if (!$fileInput.val()) {\r\n                        FileExplorer.isRunning = false;\r\n                    }\r\n                }, 200);\r\n                $fileInput.off('focus', onFocus);\r\n            });\r\n        };\r\n        \r\n        $fileInput.on('change', onChange);\r\n        $fileInput.on('click', onClick);\r\n        \r\n        $fileInput.click();\r\n        \r\n        setTimeout(() => {\r\n            this.isRunning = false;\r\n        }, 300);\r\n    }\r\n};\r\n\r\n\/**\r\n * Module de gestion du reset d'annonce\r\n *\/\r\nconst AdResetHandler = {\r\n    handle(e) {\r\n        e.preventDefault();\r\n        console.log(\"CroixResetAnnonce click\");\r\n        \r\n        \/\/ Reset l'\u00e9tat EnvoiUlterieur\r\n        StateManager.set('EnvoiUlterieur', 'false');\r\n        \r\n        \/\/ \u2705 v1.19.6 : Reset FileReceived mais garder le format s\u00e9lectionn\u00e9\r\n        StateManager.set('FileReceived', 'No');\r\n        \r\n        const $element = jQuery(e.currentTarget);\r\n        const $droppable = $element.closest('.droppable');\r\n        const resetRef = StateManager.buildEmplacementReference($droppable.attr('id'));\r\n        \r\n        console.log(\"Reset_Commande_Emplacement_Page_Web:\", resetRef);\r\n        \r\n        \/\/ \u2705 Supprimer le bouton \"R\u00e9server\" dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        $droppable.find('.ReserverContainer').hide();\r\n        \r\n        var _rankForDel = $droppable.attr('id') || StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n        if (StateManager.get(\"AchatEspaceCall\") === 'Yes') {\r\n            MessageManager.sendDelAdToParent({\r\n                Commande_Emplacement_Page_Web: resetRef,\r\n                Rank_Emplacement_Page_Web: _rankForDel,\r\n                LoadedPageUrl: window.location.href\r\n            });\r\n        } else {\r\n            window.processdataDelAd({\r\n                Commande_Emplacement_Page_Web: resetRef,\r\n                Rank_Emplacement_Page_Web: _rankForDel,\r\n                LoadedPageUrl: window.location.href\r\n            });\r\n        }\r\n        \r\n        \/\/ \u2705 v1.16.0 : Appeler RestoreadSpaceTemplateLocal directement (accessible dans ce scope)\r\n        RestoreadSpaceTemplateLocal(e.currentTarget);\r\n        \r\n        window.FonctionCroixResetAnnonce(e.currentTarget);\r\n        \r\n        \/\/ \u2705 v2.1.1 : Sauf popup\r\n        var formatWasSelected = sessionStorage.getItem('FormatSelect') \r\n            || sessionStorage.getItem('Commande_Format_Transmis')\r\n            || $droppable.data('kitFormatSelect');\r\n        \r\n        if (sessionStorage.getItem('PopUpChoice') !== 'Yes' && (formatWasSelected || sessionStorage.getItem('Formatchoisi') === 'Yes')) {\r\n            sessionStorage.setItem('Formatchoisi', 'Yes');\r\n            console.log('\u2705 Formatchoisi forc\u00e9 \u00e0 Yes apr\u00e8s reset');\r\n        }\r\n        \r\n        \/\/ \u2705 v1.19.6 : Remettre \u00e0 jour le titre format et r\u00e9afficher la checkbox R\u00e9server\r\n        setTimeout(() => {\r\n            FormatUIManager.updateTitleColor($droppable);\r\n            FormatUIManager.updateReserverCheckboxState($droppable);\r\n            \r\n            \/\/ \u2705 R\u00e9afficher le .ReserverContainer statique\r\n            $droppable.find('.ReserverContainer').show();\r\n        }, 150);\r\n    }\r\n};\r\n\r\n\/**\r\n * \u2705 Template pour r\u00e9initialisation des espaces publicitaires (IFRAME)\r\n *\/\r\nvar adSpaceTemplatesLocal = {};\r\n\r\nfunction saveAdSpaceTemplateLocal() {\r\n    var saved = 0;\r\n    jQuery('.droppable').each(function() {\r\n        var droppableId = jQuery(this).attr('id');\r\n        if (!droppableId) return;\r\n        \r\n        \/\/ \u2705 Ne jamais sauvegarder Ele0A (clone temporaire popup, pas un template d'origine)\r\n        if (droppableId === 'Ele0A') return;\r\n        \r\n        \/\/ \u2705 Ne pas r\u00e9-\u00e9craser un template d\u00e9j\u00e0 sauvegard\u00e9\r\n        if (adSpaceTemplatesLocal[droppableId]) return;\r\n        \r\n        \/\/ \u2705 v2.3.4 : Ne pas sauvegarder si template d\u00e9j\u00e0 connu (\u00e9tat propre sauvegard\u00e9)\r\n        \/\/ Le guard hasAd est supprim\u00e9 \u2014 on veut capturer le template le plus t\u00f4t possible\r\n        \/\/ Si le template existe d\u00e9j\u00e0, on ne le r\u00e9\u00e9crase pas\r\n        \/\/ (le guard anti-\u00e9crasement if (adSpaceTemplatesLocal[droppableId]) return; suffit)\r\n        \r\n        var $content = jQuery(this).find('.OrdiMobileConteneurClass').first();\r\n        if ($content.length > 0) {\r\n            adSpaceTemplatesLocal[droppableId] = $content.clone(true, true);\r\n            saved++;\r\n        }\r\n    });\r\n    if (saved > 0) {\r\n        console.log('\u2705 Templates espaces pub sauvegard\u00e9s:', saved, 'espaces -', Object.keys(adSpaceTemplatesLocal));\r\n        return true;\r\n    }\r\n    return false;\r\n}\r\n\r\nfunction RestoreadSpaceTemplateLocal(element) {\r\n    console.log('\ud83d\udd04 RestoreadSpaceTemplateLocal', element);\r\n    \r\n    var $element = jQuery(element);\r\n    var $droppable = $element.closest('.droppable');\r\n    var droppableId = $droppable.attr('id');\r\n    \r\n    \/\/ \u2705 FIX Ele0A : pas de template sauvegard\u00e9 (clone temporaire popup)\r\n    \/\/ \u2192 pas de remplacement DOM, reset visuel direct sur le contenu existant\r\n    var _isEle0A = (droppableId === 'Ele0A');\r\n\r\n    \/\/ \u2705 v1.19.3 : Chercher le template sp\u00e9cifique \u00e0 CET espace (sauf Ele0A)\r\n    if (!_isEle0A) {\r\n        if (!droppableId || !adSpaceTemplatesLocal[droppableId]) {\r\n            if (!saveAdSpaceTemplateLocal()) {\r\n                console.error('\u274c Template non disponible');\r\n                return false;\r\n            }\r\n            if (!adSpaceTemplatesLocal[droppableId]) {\r\n                console.error('\u274c Template non trouv\u00e9 pour', droppableId);\r\n                return false;\r\n            }\r\n        }\r\n    }\r\n    \r\n    var adSpaceElement = $droppable.find('.OrdiMobileConteneurClass').first();\r\n    \r\n    if (!adSpaceElement || !adSpaceElement.length) {\r\n        console.error('\u274c OrdiMobileConteneurClass non trouv\u00e9');\r\n        return false;\r\n    }\r\n    \r\n    var newElement;\r\n    if (_isEle0A) {\r\n        \/\/ Ele0A : pas de clone \u2014 on remet en \u00e9tat le contenu existant directement\r\n        newElement = adSpaceElement;\r\n        console.log('\u2705 [Ele0A] reset visuel direct (pas de template clone)');\r\n        \/\/ \u2705 Vider le contenu du dropzone et restaurer le HTML par d\u00e9faut\r\n        \/\/ (le replaceWith n'ayant pas lieu, l'image d\u00e9pos\u00e9e et le fond blanc restent sinon)\r\n        var $dz0A = $droppable.find('#drop_file_zone_achat');\r\n        $dz0A.empty().html(\r\n            '<div id=\"drag_upload_file_achat\">' +\r\n                '<p class=\"UploadIci\" style=\"color:#FB5E2A;font-weight:600;\">Ici glisser \u2013 d\u00e9poser ou<br>t\u00e9l\u00e9charger une annonce<\/p>' +\r\n            '<\/div>'\r\n        );\r\n        \/\/ Restaurer le fond bleu #9FC5F3 et retirer les styles d'annonce upload\u00e9e\r\n        $droppable.find('#UploadFileConteneur').css({\r\n            'background-color': '#9FC5F3',\r\n            'border': '',\r\n            'box-sizing': ''\r\n        });\r\n        $droppable.find('.HTMLUploadfileConteneur').css({\r\n            'box-shadow': '',\r\n            'background-color': '',\r\n            'border': '',\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'min-height': '',\r\n            'overflow': '',\r\n            'height': '',\r\n            'max-height': ''\r\n        });\r\n        \/\/ Masquer la croix et le titre d'annonce upload\u00e9e\r\n        $droppable.find('.AdUploadedTitle, #CroixResetAnnonce, .CroixResetAnnonceContainer, .DeplaceAnnonce').hide();\r\n        $droppable.removeAttr('data-via-ad-loaded').removeAttr('data-from-miniature');\r\n        console.log('\u2705 [Ele0A] dropzone vid\u00e9 + fond restaur\u00e9');\r\n    } else {\r\n        \/\/ \u2705 v1.19.3 : Cloner le template SP\u00c9CIFIQUE \u00e0 cet espace (pas le premier)\r\n        newElement = adSpaceTemplatesLocal[droppableId].clone(true, true);\r\n        console.log('\u2705 Template utilis\u00e9 pour', droppableId);\r\n        adSpaceElement.replaceWith(newElement);\r\n        \/\/ \u2705 v2.4.12 : Effacer data-via-ad-loaded (sinon selectEspaceActif masque .ReserverContainer)\r\n        $droppable.removeAttr('data-via-ad-loaded').removeAttr('data-from-miniature');\r\n        if (window.outerWidth < 1000) {\r\n            newElement.css({'margin-top': '-25px', 'bottom': '0px'});\r\n        }\r\n    }\r\n    \r\n    \/\/ D\u00e9cocher la case Envoi diff\u00e9r\u00e9 si elle existe\r\n    newElement.find('input[name*=\"EnvoiUlterieur\"]').prop('checked', false);\r\n    \r\n    \/\/ \u2705 D\u00e9cocher la checkbox \"R\u00e9server\"\r\n    newElement.find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').prop('checked', false);\r\n    \r\n    \/\/ Reset l'\u00e9tat EnvoiUlterieur\r\n    StateManager.set('EnvoiUlterieur', 'false');\r\n    \r\n    \/\/ \u2705 v1.19.3 : R\u00e9initialiser TOUS les styles inline des conteneurs parents modifi\u00e9s pendant le d\u00e9p\u00f4t\r\n    if ($droppable.length) {\r\n        \/\/ \u2705 v2.0.9 : Restaurer les marges de l'algorithme de positionnement (sauvegard\u00e9es par styleUploadedAd)\r\n        var origMt = $droppable.data('orig-mt');\r\n        $droppable.css({\r\n            'margin-top': (origMt !== undefined) ? origMt + 'px' : '',\r\n            'margin-bottom': '',\r\n            'margin-left': '',\r\n            'margin-right': ''\r\n        });\r\n        \/\/ \u2705 v2.0.11 : Cleanup event namespace docpreview\r\n        $droppable.off('click.docpreview');\r\n        \r\n        \/\/ Reset .OrdiMobileConteneurClass margins\r\n        var $container = $droppable.find('.OrdiMobileConteneurClass');\r\n        var origMb = $container.data('orig-mb');\r\n        $container.css({\r\n            'margin-top': '',\r\n            'margin-bottom': (origMb !== undefined) ? origMb + 'px' : ''\r\n        });\r\n        \r\n        \/\/ Reset .HTMLUploadfileConteneur (set by styleUploadedAd: box-shadow inset, background-color:white)\r\n        $droppable.find('.HTMLUploadfileConteneur').css({\r\n            'border': '',\r\n            'box-shadow': '',\r\n            'outline': '',\r\n            'outline-offset': '',\r\n            'background-color': '',\r\n            'margin-top': '',\r\n            'margin-bottom': '',\r\n            'min-height': '',\r\n            'overflow': '',\r\n            'padding': '',\r\n            'position': ''\r\n        });\r\n        $droppable.find('.via-green-border-overlay').remove();\r\n        \r\n        \/\/ \u2705 Restaurer pointer-events sur OrdiMobileConteneurClass et ses enfants\r\n        $droppable.find('.OrdiMobileConteneurClass').css('pointer-events', '');\r\n        $droppable.find('#CroixResetAnnonce').css({'pointer-events': '', 'position': '', 'z-index': ''});\r\n        \/\/ \u2705 v2.4.5 : Reset margin-right Ele0A (pos\u00e9 par adjustMobileLayout)\r\n        var _croixContReset = $droppable.find('.CroixResetAnnonceContainer')[0];\r\n        if (_croixContReset) { _croixContReset.style.removeProperty('margin-right'); _croixContReset.style.removeProperty('margin-top'); }\r\n        $droppable.find('#PopUpMessageAchattest').css('pointer-events', '');\r\n        \r\n        \/\/ \u2705 v2.0.9 : Restaurer le scale(1.4) sur .UploadFileConteneur (r\u00e9duit \u00e0 scale(1) par styleUploadedAd sur mobile)\r\n        $droppable.find('.UploadFileConteneur').css({\r\n            'transform': '',\r\n            'transform-origin': ''\r\n        });\r\n        \r\n        \/\/ Reset #UploadFileConteneur - Restaurer le fond bleu #9FC5F3 + retirer liser\u00e9 envoi diff\u00e9r\u00e9\r\n        $droppable.find('#UploadFileConteneur').css({\r\n            'width': '',\r\n            'background-color': '#9FC5F3',\r\n            'border': '',\r\n            'box-sizing': ''\r\n        });\r\n        \r\n        \/\/ Reset .ToBeHidden (set by adjustDesktopLayout: top:105px, min-height:300px + overflow mobile)\r\n        $droppable.closest('.ToBeHidden').css({\r\n            'top': '',\r\n            'min-height': '',\r\n            'overflow': ''\r\n        });\r\n        \r\n        \/\/ Reset overflow sur le parent du droppable (set by adjustDesktopLayout)\r\n        $droppable.parent().css('overflow', '');\r\n        \r\n        \/\/ \u2705 v1.19.5 : Gestion device-specific pour les textes\r\n        var isDesktop = window.outerWidth >= 1000;\r\n        \r\n        if (isDesktop) {\r\n            \/\/ Desktop : cacher les textes mobiles, afficher UploadIci\r\n            $droppable.find('.TexteMobile').hide();\r\n            $droppable.find('.TexteMobileAnnonce').hide();\r\n            $droppable.find('.TexteMobileAjoutAnnonce').hide();\r\n            $droppable.find('.UploadIci').show();\r\n        } else {\r\n            \/\/ Mobile : afficher TexteMobileAnnonce\r\n            $droppable.find('.TexteMobileAnnonce').show();\r\n        }\r\n        \r\n        \/\/ R\u00e9-afficher les \u00e9l\u00e9ments masqu\u00e9s pendant l'upload\r\n        $droppable.find('.PositionEspacePublicitaireContainer').show();\r\n        $droppable.find('.ChoisirEspacePublicitaireDisponibiliteConteneur').show();\r\n        $droppable.find('.PositionEspacePublicitaire, .ReferenceEspacePublicitaire, .ChoisirEspacePublicitaireDisponibiliteConteneur > div > .elementor-widget-text-editor').show();\r\n        $droppable.find('.AdDroppedTextNotDisplayed').hide();\r\n        \/\/ \u2705 v2.4.5 : Ele0A + PopUpChoice=Yes \u2192 ne pas r\u00e9-afficher le titre si format d\u00e9j\u00e0 s\u00e9lectionn\u00e9\r\n        var _skipTitre = (sessionStorage.getItem('PopUpChoice') === 'Yes' && $droppable.attr('id') === 'Ele0A');\r\n        $droppable.find('.SelectionFormatTitreBlanc').hide();\r\n        if (!_skipTitre) {\r\n            $droppable.find('.SelectionFormatTitre').show();\r\n        }\r\n        $droppable.find('span.ClassHdpCdp, .ClassRefEsp').show();\r\n        $droppable.find('.EspPubFormatMainContainer').show();\r\n        $droppable.find('.EspPubFormatListe').show();\r\n        $droppable.find('.ChoisirEspacePublicitaireClass').show();\r\n        $droppable.find('.GlisserDeposerConteneur').show();\r\n        $droppable.find('.OUClass').show();\r\n        $droppable.find('.PositionReference').show();\r\n        $droppable.find('.ClassHdpCdp').show();\r\n        $droppable.find('.ClassRefEsp').show();\r\n        $droppable.find('.EnvoiUlterieurTexte').show();\r\n        $droppable.find('.EnvoiUlterieurContainer').show();\r\n        \r\n        \/\/ \u2705 v1.19.5 : R\u00e9afficher le .ReserverContainer (bouton Elementor statique)\r\n        $droppable.find('.ReserverContainer').show();\r\n        newElement.find('.ReserverContainer').show();\r\n        \r\n        \/\/ Masquer les \u00e9l\u00e9ments sp\u00e9cifiques \u00e0 l'annonce upload\u00e9e\r\n        $droppable.find('.AdUploadedTitle, #CroixResetAnnonce, .CroixResetAnnonceContainer, .DeplaceAnnonce').hide();\r\n        $droppable.find('#CroixResetAnnonce').css({'position': '', 'z-index': ''});\r\n        $droppable.find('.RefEspacePublicitaire').hide();\r\n        \r\n        \/\/ Supprimer le bouton \"R\u00e9server\" dynamique\r\n        $droppable.find('.reserver-dynamic-container').remove();\r\n        $droppable.next('.reserver-dynamic-container').remove();\r\n        \r\n        \/\/ \u2705 v1.19.6 : Restaurer le format s\u00e9lectionn\u00e9 visuellement\r\n        \/\/ Chercher le format dans plusieurs sources possibles\r\n        var formatSelect = sessionStorage.getItem('FormatSelect') \r\n            || sessionStorage.getItem('Commande_Format_Transmis')\r\n            || $droppable.data('kitFormatSelect')\r\n            || '';\r\n        \r\n        var formatchoisi = sessionStorage.getItem('Formatchoisi');\r\n        console.log('\ud83d\udcd0 Format \u00e0 restaurer:', formatSelect, '| Formatchoisi:', formatchoisi);\r\n        \r\n        \/\/ D'abord reset tous les formats visuellement (sur newElement ET $droppable)\r\n        var $allFormats = newElement.find('.EspPubFormatContainer').add($droppable.find('.EspPubFormatContainer'));\r\n        $allFormats.css({\r\n            'background-color': '',\r\n            'border': ''\r\n        });\r\n        newElement.find('.EspPubFormat').add($droppable.find('.EspPubFormat')).css({\r\n            'color': ''\r\n        });\r\n        \r\n        \/\/ Si un format \u00e9tait s\u00e9lectionn\u00e9 (via sessionStorage OU visuellement avant)\r\n        \/\/ \u2705 v2.1.1 : Sauf popup\r\n        if ((formatSelect || formatchoisi === 'Yes') && sessionStorage.getItem('PopUpChoice') !== 'Yes') {\r\n            var formatFound = false;\r\n            \r\n            if (formatSelect) {\r\n                \/\/ \u2705 v2.1.1 : Normaliser via NFD (plus fiable que les replace manuels)\r\n                var formatLower = formatSelect.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase().replace(\/ \/g, '');\r\n                \r\n                \/\/ Appliquer sur newElement ET $droppable pour \u00eatre s\u00fbr\r\n                var $allContainers = newElement.find('.EspPubFormatContainer').add($droppable.find('.EspPubFormatContainer'));\r\n                \r\n                $allContainers.each(function() {\r\n                    var className = this.className.normalize('NFD').replace(\/[\\u0300-\\u036f]\/g, '').toLowerCase();\r\n                    \r\n                    if (className.includes(formatLower)) {\r\n                        jQuery(this).css({'background-color': '#ffffff'});\r\n                        jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                        formatFound = true;\r\n                        \/\/ \u2705 v2.4.12 : M\u00e9moriser le format restaur\u00e9 (lu par selectEspaceActif pour re-surligner apr\u00e8s reset global)\r\n                        $droppable.attr('data-restored-format', formatSelect);\r\n                        console.log('\u2705 Format restaur\u00e9 visuellement:', formatSelect, '- classe:', this.className);\r\n                    }\r\n                });\r\n            }\r\n            \r\n            \/\/ \u2705 IMPORTANT : Pr\u00e9server Formatchoisi = Yes pour permettre l'upload\r\n            sessionStorage.setItem('Formatchoisi', 'Yes');\r\n            console.log('\u2705 Formatchoisi maintenu \u00e0 Yes');\r\n            \r\n            \/\/ Basculer les titres format (sur newElement ET $droppable)\r\n            newElement.find('.SelectionFormatTitre').hide();\r\n            newElement.find('.SelectionFormatTitreBlanc').show();\r\n            $droppable.find('.SelectionFormatTitre').hide();\r\n            $droppable.find('.SelectionFormatTitreBlanc').show();\r\n        }\r\n    }\r\n    \r\n    \/\/ \u2705 v1.19.2 : Relancer InitLoadedPage pour recalculer positions et tailles\r\n    setTimeout(function() {\r\n        if (typeof window.InitLoadedPage === 'function') {\r\n            window.InitLoadedPage();\r\n        }\r\n        \r\n        \/\/ \u2705 v1.19.6 : R\u00e9attacher les MutationObservers sur les formats\r\n        if (typeof FormatUIManager !== 'undefined' && FormatUIManager.observeFormatChanges) {\r\n            FormatUIManager.observeFormatChanges();\r\n        }\r\n    }, 100);\r\n    \r\n    console.log('\u2705 Espace publicitaire r\u00e9initialis\u00e9');\r\n    return true;\r\n}\r\n\r\n\/\/ \u2705 Exposer pour appel depuis yearbook-media.js (suppression popup mode=popup)\r\nwindow.RestoreadSpaceTemplateLocal = RestoreadSpaceTemplateLocal;\r\n\r\nwindow.verifierAffichageMsgSelectEspaceLocal = function() {\r\n    const formatChoisi = StateManager.get('Formatchoisi') === 'Yes';\r\n    const fileReceived = StateManager.get('FileReceived');\r\n    const envoiUlterieur = StateManager.get('EnvoiUlterieur');\r\n    \r\n    var dateDebut, dateFin, pays;\r\n    try {\r\n        dateDebut = window.parent.$('#form-field-DebutCampagne').val();\r\n        dateFin = window.parent.$('#form-field-FinCampagne').val();\r\n        pays = window.parent.$('#form-field-Nationalite_Societe').val();\r\n    } catch(e) {\r\n        jQuery('#MsgSelectEspace').hide();\r\n        return;\r\n    }\r\n    \r\n    if (!dateDebut || !dateFin || !pays || !formatChoisi) {\r\n        jQuery('#MsgSelectEspace').hide();\r\n        return;\r\n    }\r\n    \r\n    if (fileReceived !== 'Yes') {\r\n        if (envoiUlterieur !== 'true') {\r\n            jQuery('#MsgSelectEspace').show();\r\n        } else {\r\n            jQuery('#MsgSelectEspace').hide();\r\n        }\r\n    } else {\r\n        jQuery('#MsgSelectEspace').hide();\r\n    }\r\n};\r\n\r\n\/\/ Sauvegarder les templates au chargement (apr\u00e8s rendu complet Elementor)\r\njQuery(document).ready(function() {\r\n    \/\/ \u2705 v1.19.3 : D\u00e9lai augment\u00e9 + double sauvegarde pour garantir les bonnes dimensions\r\n    setTimeout(saveAdSpaceTemplateLocal, 3000);\r\n    setTimeout(saveAdSpaceTemplateLocal, 6000);\r\n    \/\/ \u2705 v2.3.4 : Sauvegarde imm\u00e9diate d\u00e8s que la page est pr\u00eate dans l'iframe\r\n    \/\/ (avant toute interaction utilisateur)\r\n    setTimeout(saveAdSpaceTemplateLocal, 100);\r\n    setTimeout(saveAdSpaceTemplateLocal, 500);\r\n});\r\n\r\n\/\/ \u2705 v2.3.4 : Forcer sauvegarde \u00e0 la r\u00e9ception de elementsRemoved (espaces visibles + vierges)\r\nwindow.addEventListener('message', function(e) {\r\n    if (e.data && e.data.type === 'elementsRemoved') {\r\n        \/\/ Les espaces sont vierges \u00e0 ce stade \u2192 sauvegarder imm\u00e9diatement\r\n        setTimeout(saveAdSpaceTemplateLocal, 50);\r\n        setTimeout(saveAdSpaceTemplateLocal, 300);\r\n    }\r\n});\r\n\r\n\/**\r\n * Fonction helper pour le d\u00e9p\u00f4t r\u00e9dactionnel\r\n *\/\r\nfunction RedactionnelDepose() {\r\n    jQuery('#Tariftobedisplayed').html('-');\r\n    jQuery('#TarifDataStep3').html('\u00e0 choisir').css({'color': '#FB5E2A'});\r\n    jQuery('#FormatDataStep3').html('\u00e0 choisir').css({'color': '#FB5E2A'});\r\n    jQuery('#ListePaysDirect, #ListeThemeDirect, .ListeArticles, #PageAfficheeMessage').hide();\r\n    StateManager.set(\"PositionAnnonceSelection\", 'Yes');\r\n}\r\n\r\n\/**\r\n * Exposition des fonctions globales n\u00e9cessaires\r\n *\/\r\nwindow.uploadFile_achat = (e) => DropHandler.handleDrop(e);\r\nwindow.fileExplorer_achat = (e) => FileExplorer.open(e);\r\nwindow.ajaxFileUpload_achat = (fileObj, dropZone) => UploadManager.handleFileUpload(fileObj, dropZone);\r\nwindow.ActivatesendDataToParent = (dropZone) => UploadManager.activateSendDataToParent(dropZone);\r\n\/\/ \u2705 v2.3.4 : Exposer FormatUIManager pour appel depuis Entete.txt (selectEspaceActif)\r\nwindow.FormatUIManagerRef = FormatUIManager;\r\n\r\n\/**\r\n * Initialisation de l'application\r\n *\/\r\njQuery(document).ready(() => {\r\n    StateManager.init();\r\n    ScrollHelper.init();\r\n    DragDropManager.init();\r\n    FormatUIManager.init();\r\n    \r\n    if (UIManager.isMobile()) {\r\n        UIManager.initMobileUI();\r\n    } else {\r\n        UIManager.initDesktopUI();\r\n    }\r\n    \r\n    jQuery(document).on('click', '#CroixResetAnnonce', (e) => AdResetHandler.handle(e));\r\n    \r\n    \/\/ \u2705 Clic sur le texte du label \u2192 toggle manuel de la checkbox du m\u00eame conteneur\r\n    jQuery(document).on('click', '.reserver-dynamic-label', function(e) {\r\n        e.preventDefault();\r\n        e.stopPropagation();\r\n        const $cb = $(this).closest('.reserver-dynamic-option, .reserver-dynamic-container').find('.reserver-dynamic-checkbox');\r\n        if ($cb.length) {\r\n            $cb.prop('checked', !$cb.prop('checked')).trigger('change');\r\n        }\r\n    });\r\n\r\n    \/\/ \u2705 CHECKBOX \"R\u00e9server cet espace publicitaire\" \u2014 VALIDATION ET ENVOI DES DONN\u00c9ES\r\n    \/\/ \u2705 v2.4.13 : iOS touchend\r\n    \/\/ \u2705 v2.4.13 : Mobile \u2014 \u00e9couter touchend sur input ET click\/touchend sur label\r\n    jQuery(document).on('touchend', 'input[name=\"form_fields[ReserverEspacePublicitaire]\"]', function() {\r\n        if (this._viaResTouch) { return; }\r\n        this._viaResTouch = true;\r\n        var _self = this;\r\n        setTimeout(function() { _self._viaResTouch = false; }, 500);\r\n        setTimeout(function() { jQuery(_self).trigger('change'); }, 100);\r\n    });\r\n    jQuery(document).on('touchend click', '.elementor-field-group-ReserverEspacePublicitaire label, .reserver-dynamic-label, .reserver-dynamic-option label', function(e) {\r\n        \/\/ Trouver l'input associ\u00e9\r\n        var $input = jQuery(this).closest('.elementor-field-option, .reserver-dynamic-option').find('input[name=\"form_fields[ReserverEspacePublicitaire]\"]');\r\n        if (!$input.length) { $input = jQuery(this).siblings('input[name=\"form_fields[ReserverEspacePublicitaire]\"]'); }\r\n        if (!$input.length) { $input = jQuery('input[name=\"form_fields[ReserverEspacePublicitaire]\"]').first(); }\r\n        if ($input.length) {\r\n            if (e.type === 'touchend') { e.preventDefault(); }\r\n            var _wasChecked = $input.prop('checked');\r\n            $input.prop('checked', !_wasChecked);\r\n            setTimeout(function() {\r\n                $input.trigger('change');\r\n            }, 50);\r\n        }\r\n    });\r\n    jQuery(document).on('change', 'input[name=\"form_fields[ReserverEspacePublicitaire]\"]', function(e) {\r\n        const $checkbox = $(this);\r\n        let $droppable = $checkbox.closest('.droppable');\r\n        if (!$droppable.length) {\r\n            $droppable = $checkbox.closest('.reserver-dynamic-container').prev('.droppable');\r\n        }\r\n        \/\/ \u2705 v2.4.13 : Fallback mobile \u2014 checkbox dans body > .reserver-dynamic-container[data-droppable-id]\r\n        if (!$droppable.length) {\r\n            const $dynContainer = $checkbox.closest('.reserver-dynamic-container');\r\n            const _droppableId = $dynContainer.attr('data-droppable-id') || '';\r\n            if (_droppableId) {\r\n                $droppable = $('#' + _droppableId);\r\n            }\r\n        }\r\n        \/\/ Dernier recours : utiliser le rank en sessionStorage\r\n        if (!$droppable.length) {\r\n            const _rankFallback = StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            if (_rankFallback) { $droppable = $('#' + _rankFallback); }\r\n        }\r\n        \r\n        \/\/ Si on d\u00e9coche\r\n        if (!$checkbox.is(':checked')) {\r\n            console.log('\u2610 Checkbox \"R\u00e9server\" d\u00e9coch\u00e9e');\r\n            \/\/ \u2705 Mettre \u00e0 jour le label\r\n            const $lbl = $checkbox.closest('.reserver-dynamic-option, .elementor-field-option').find('.reserver-dynamic-label, label').not('input');\r\n            $lbl.text('R\u00e9server cet espace publicitaire').css('color', '');\r\n            \/\/ \u2705 Notifier le parent pour d\u00e9-r\u00e9server l'item dans le r\u00e9cap\r\n            const _rankDecoche = $droppable.attr('id') || StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            const _emplacementDecoche = StateManager.buildEmplacementReference(_rankDecoche);\r\n            MessageManager.sendToParent('annulationReservation', {\r\n                Rank_Emplacement_Page_Web: _rankDecoche,\r\n                Commande_Emplacement_Page_Web: _emplacementDecoche,\r\n                LoadedPageUrl: window.location.href\r\n            });\r\n            \/\/ \u2705 v2.4.5 : M\u00e9moriser que ce rank a \u00e9t\u00e9 explicitement d\u00e9coch\u00e9\r\n            StateManager.set('_reserverDecoche_' + _rankDecoche, 'Yes');\r\n            console.log('\ud83d\udce4 annulationReservation envoy\u00e9 \u2192 parent | rank:', _rankDecoche, '| emplacement:', _emplacementDecoche);\r\n            return;\r\n        }\r\n        \r\n        \/\/ \u2705 V\u00e9rifier les conditions : format s\u00e9lectionn\u00e9 ET (fichier d\u00e9pos\u00e9 OU envoi diff\u00e9r\u00e9)\r\n        const hasFormat = FormatUIManager.hasSelectedFormat($droppable);\r\n        const hasFile = StateManager.get('FileReceived') === 'Yes';\r\n        const hasEnvoiDiffere = $droppable.find('input[name*=\"EnvoiUlterieur\"]:checked').length > 0;\r\n        \r\n        console.log('\ud83d\udd0d Checkbox \"R\u00e9server\" - Validation:', { hasFormat, hasFile, hasEnvoiDiffere });\r\n        \r\n        if (!hasFormat) {\r\n            \/\/ \u2705 Si un fichier est d\u00e9j\u00e0 d\u00e9pos\u00e9 \u2192 d\u00e9duire le format depuis l'extension (ne pas bloquer)\r\n            if (hasFile) {\r\n                const _uploadedName = StateManager.get('Upload_File_Name') || '';\r\n                const _ext = _uploadedName.split('.').pop().toLowerCase();\r\n                const _fileType = FileManager.getFileType(_ext);\r\n                let _deducedFormat = '';\r\n                if (_fileType === 'video') {\r\n                    _deducedFormat = sessionStorage.getItem('SiteLangue') === 'EN' ? 'Video' : 'Vid\u00e9o';\r\n                } else if (_fileType === 'image') {\r\n                    _deducedFormat = sessionStorage.getItem('SiteLangue') === 'EN' ? 'Banner' : 'Banni\u00e8re';\r\n                } else if (_fileType === 'document') {\r\n                    _deducedFormat = sessionStorage.getItem('SiteLangue') === 'EN' ? 'Press release' : 'Communiqu\u00e9';\r\n                }\r\n                if (_deducedFormat) {\r\n                    StateManager.set('Commande_Format_Transmis', _deducedFormat);\r\n                    StateManager.set('FormatSelect', _deducedFormat);\r\n                    StateManager.set('Formatchoisi', 'Yes');\r\n                    console.log('\u2705 Format d\u00e9duit depuis extension (' + _ext + '):', _deducedFormat);\r\n                    \/\/ Continuer vers l'envoi (pas de return false)\r\n                } else {\r\n                    e.preventDefault();\r\n                    $checkbox.prop('checked', false);\r\n                    FormatUIManager.flashTitle($droppable);\r\n                    console.log('\u274c R\u00e9servation bloqu\u00e9e : format non d\u00e9ductible depuis extension:', _ext);\r\n                    return false;\r\n                }\r\n            } else {\r\n                e.preventDefault();\r\n                $checkbox.prop('checked', false);\r\n                FormatUIManager.flashTitle($droppable);\r\n                console.log('\u274c R\u00e9servation bloqu\u00e9e : aucun format s\u00e9lectionn\u00e9');\r\n                return false;\r\n            }\r\n        }\r\n        \r\n        if (!hasFile && !hasEnvoiDiffere) {\r\n            e.preventDefault();\r\n            $checkbox.prop('checked', false);\r\n            console.log('\u274c R\u00e9servation bloqu\u00e9e : ni annonce d\u00e9pos\u00e9e ni envoi diff\u00e9r\u00e9');\r\n            return false;\r\n        }\r\n        \r\n        \/\/ \u2705 Conditions remplies \u2014 Pr\u00e9parer et envoyer les donn\u00e9es\r\n        console.log('\u2705 Checkbox \"R\u00e9server\" valid\u00e9e \u2014 envoi des donn\u00e9es');\r\n        \r\n        const rankId = $droppable.attr('id');\r\n        \r\n        StateManager.setMultiple({\r\n            \"sendDataToParentFlag\": \"Yes\",\r\n            \"Formatchoisi\": \"Yes\",\r\n            \"Rank_Emplacement_Page_Web\": rankId,\r\n            \"Commande_Emplacement_Page_Web\": StateManager.buildEmplacementReference(rankId),\r\n            \"LoadedPageUrl\": window.location.href,\r\n            \/\/ \u2705 v2.3.0 : Forcer avant l'envoi \u2014 le setTimeout(4000) dans activateSendDataToParent\r\n            \/\/ arrive trop tard sur le 1er clic \u2192 AddNewRefInVosCampagnes restait null\r\n            \"AddNewRefInVosCampagnes\": \"Yes\"\r\n        });\r\n        \r\n        \/\/ \u2705 D\u00e9clencher l'envoi des donn\u00e9es via activateSendDataToParent\r\n        const $dropZone = $droppable.find('#drop_file_zone_achat');\r\n        UploadManager.activateSendDataToParent($dropZone);\r\n    });\r\n    \r\n    \/\/ G\u00c9RER \"Envoi diff\u00e9r\u00e9\" \u2014 marquer l'\u00e9tat sans envoyer (c'est \"R\u00e9server\" qui envoie)\r\n    \/\/ \u2705 v2.4.13 : iOS touchend\r\n    jQuery(document).on('touchend', 'input[name*=\"EnvoiUlterieur\"]', function() {\r\n        if (this._viaTouch) { return; }\r\n        this._viaTouch = true;\r\n        var _self = this;\r\n        setTimeout(function() { _self._viaTouch = false; }, 500);\r\n        setTimeout(function() { jQuery(_self).trigger('change'); }, 100);\r\n    });\r\n    jQuery(document).on('change', 'input[name*=\"EnvoiUlterieur\"]', function(e) {\r\n        const $checkbox = $(this);\r\n        let $droppable = $checkbox.closest('.droppable');\r\n        \/\/ \u2705 v2.4.13 : Fallback mobile\r\n        if (!$droppable.length) {\r\n            const $dynContainer = $checkbox.closest('.reserver-dynamic-container');\r\n            const _droppableId = $dynContainer.attr('data-droppable-id') || '';\r\n            if (_droppableId) { $droppable = $('#' + _droppableId); }\r\n        }\r\n        if (!$droppable.length) {\r\n            const _rankFallback = StateManager.get('Rank_Emplacement_Page_Web') || '';\r\n            if (_rankFallback) { $droppable = $('#' + _rankFallback); }\r\n        }\r\n  \r\n        \/\/ Si on d\u00e9coche\r\n        if (!$checkbox.is(':checked')) {\r\n            StateManager.set('EnvoiUlterieur', 'false');\r\n            \r\n            if (typeof window.verifierAffichageMsgSelectEspaceLocal === 'function') {\r\n                window.verifierAffichageMsgSelectEspaceLocal();\r\n            }\r\n            \r\n            \/\/ Mettre \u00e0 jour l'\u00e9tat de la checkbox R\u00e9server\r\n            FormatUIManager.updateReserverCheckboxState($droppable);\r\n            return;\r\n        }\r\n        \r\n        \/\/ Si on coche, masquer le message\r\n        jQuery('#MsgSelectEspace').hide();\r\n    \r\n        \/\/ V\u00e9rifier si un format est s\u00e9lectionn\u00e9\r\n        const hasSelectedFormat = FormatUIManager.hasSelectedFormat($droppable);\r\n        \r\n        if (!hasSelectedFormat) {\r\n            e.preventDefault();\r\n            $checkbox.prop('checked', false);\r\n            FormatUIManager.flashTitle($droppable);\r\n            return false;\r\n        }\r\n        \r\n        \/\/ \u2705 FORMAT OK \u2014 Marquer l'\u00e9tat envoi diff\u00e9r\u00e9 (sans envoyer les donn\u00e9es)\r\n        const rankId = $droppable.attr('id');\r\n        \r\n        StateManager.setMultiple({\r\n            \"EnvoiUlterieur\": 'true',\r\n            \"Rank_Emplacement_Page_Web\": rankId,\r\n            \"Commande_Emplacement_Page_Web\": StateManager.buildEmplacementReference(rankId),\r\n            \"LoadedPageUrl\": window.location.href,\r\n            \"FileReceived\": \"No\",\r\n            \"FullPathAdFile\": '',\r\n            \"Upload_File_Name\": '',\r\n            \"Formatchoisi\": 'Yes'\r\n        });\r\n        \r\n        console.log('\ud83d\udcdd Envoi diff\u00e9r\u00e9 coch\u00e9 \u2014 en attente de validation via checkbox \"R\u00e9server\"');\r\n        \r\n        \/\/ \u2705 Mettre \u00e0 jour l'\u00e9tat de la checkbox R\u00e9server (maintenant activable)\r\n        FormatUIManager.updateReserverCheckboxState($droppable);\r\n    });\r\n\r\n    \/\/ \u2705 v2.2.0 : Bouton \"Cr\u00e9ation\" dans espace publicitaire \u2192 Kit Ad Creator dans le parent\r\n    jQuery(document).on('click', '.FormatIdCreation', function(e) {\r\n        e.preventDefault();\r\n        var $btn = jQuery(this);\r\n        var isActive = $btn.data('creationActive') === true;\r\n\r\n        if (isActive) {\r\n            \/\/ D\u00e9sactiver\r\n            $btn.data('creationActive', false);\r\n            $btn.find('.EspPubFormat').css({'color': '#ffffff'});\r\n            $btn.css({'background-color': 'transparent'});\r\n            MessageManager.sendToParent('closeAdCreatorFromIframe', {});\r\n            console.log('\ud83c\udfa8 Cr\u00e9ation iframe \u2192 toggle OFF, fermeture popup parent');\r\n        } else {\r\n            \/\/ Activer : texte vert sur fond blanc\r\n            $btn.data('creationActive', true);\r\n            $btn.find('.EspPubFormat').css({'color': '#37D900'});\r\n            $btn.css({'background-color': '#ffffff'});\r\n            var formatSelect = sessionStorage.getItem('FormatSelect') || '';\r\n            var formatTransmis = sessionStorage.getItem('Commande_Format_Transmis') || '';\r\n            \/\/ \u2705 v2.2.1 : Envoyer aussi Commande_Format_Transmis (format cliqu\u00e9 dans l'iframe, sans accent)\r\n            var _rankKit = $btn.closest('.droppable').attr('id') || sessionStorage.getItem('Rank_Emplacement_Page_Web') || '';\r\n            var _cSite = sessionStorage.getItem('codeSite') || '';\r\n            var _cPage = sessionStorage.getItem('codePage') || '';\r\n            var _sfxKit = _rankKit.replace('Ele', '');\r\n            var _emplKit = (_cSite && _cPage && _sfxKit) ? (_cSite + _cPage + 'L' + _sfxKit) : (sessionStorage.getItem('Commande_Emplacement_Page_Web') || '');\r\n            MessageManager.sendToParent('openAdCreatorFromIframe', { formatSelect: formatSelect, formatTransmis: formatTransmis, rankId: _rankKit, emplacement: _emplKit });\r\n            console.log('\ud83c\udfa8 Cr\u00e9ation iframe \u2192 toggle ON (FormatSelect:', formatSelect, '| Commande_Format_Transmis:', formatTransmis, ')');\r\n        }\r\n    });\r\n\r\n    \/\/ \u2705 v2.2.0 : Messages depuis le parent concernant le bouton Cr\u00e9ation\r\n    window.addEventListener('message', function(event) {\r\n        var msg = event.data;\r\n        if (!msg) return;\r\n\r\n        \/\/ \u2705 v2.2.1 : Fournir la position du titre R\u00e9server pour positionner la miniature\r\n        if (msg.type === 'getReserverLabelRect') {\r\n            var $label = jQuery('.reserver-dynamic-label').first();\r\n            if ($label.length) {\r\n                var r = $label[0].getBoundingClientRect();\r\n                var iframeScale = (window.outerWidth > 1000) ? 0.75 : 0.80; \/\/ \u2705 v2.4.12 : 0.85 \u2192 0.75 (scale r\u00e9el du parent)\r\n                event.source.postMessage({\r\n                    type: 'reserVeurLabelRectResult',\r\n                    \/\/ Retourner bottom en coordonn\u00e9es iframe internes (non scal\u00e9es)\r\n                    bottom: r.bottom,\r\n                    left: r.left,\r\n                    right: r.right,\r\n                    iframeScale: iframeScale\r\n                }, '*');\r\n            } else {\r\n                event.source.postMessage({ type: 'reserVeurLabelRectResult', bottom: null }, '*');\r\n            }\r\n        }\r\n\r\n        \/\/ Fermeture du popup \u2192 d\u00e9s\u00e9lectionner le bouton Cr\u00e9ation\r\n        if (msg.type === 'adCreatorClosedFromParent') {\r\n            jQuery('.FormatIdCreation').each(function() {\r\n                jQuery(this).data('creationActive', false);\r\n                jQuery(this).find('.EspPubFormat').css({'color': '#ffffff'});\r\n                jQuery(this).css({'background-color': 'transparent'});\r\n            });\r\n            console.log('\ud83c\udfa8 adCreatorClosedFromParent re\u00e7u \u2192 bouton Cr\u00e9ation d\u00e9s\u00e9lectionn\u00e9');\r\n        }\r\n\r\n        \/\/ Restaurer le style du bouton Cr\u00e9ation apr\u00e8s un reset de removeElements\r\n        if (msg.type === 'restoreCreationButton') {\r\n            jQuery('.FormatIdCreation').each(function() {\r\n                if (jQuery(this).data('creationActive') === true) {\r\n                    jQuery(this).find('.EspPubFormat').css({'color': '#37D900'});\r\n                    jQuery(this).css({'background-color': '#ffffff'});\r\n                }\r\n            });\r\n            console.log('\ud83c\udfa8 restoreCreationButton re\u00e7u \u2192 style Cr\u00e9ation restaur\u00e9');\r\n        }\r\n    });\r\n\r\n});\r\n\r\n\/\/ =========================================================================\r\n\/\/ \u2705 Listener kitAdCreated \u2014 annonce cr\u00e9\u00e9e par le Kit overlay (mode=kit)\r\n\/\/ Injecte directement dans l'espace pub identifi\u00e9 par rankId\r\nwindow.addEventListener('message', function(event) {\r\n    var msg = event.data;\r\n    if (!msg || msg.action !== 'kitAdCreated') return;\r\n\r\n    var _rankId = msg.rankId || '';\r\n    var _emplacement = msg.emplacement || '';\r\n    console.log('\ud83c\udfa8 [espace_pub] kitAdCreated re\u00e7u | rankId:', _rankId, '| emplacement:', _emplacement);\r\n\r\n    if (!_rankId) { console.warn('\u26a0\ufe0f [kitAdCreated] rankId manquant'); return; }\r\n\r\n    var $droppable = jQuery('#' + _rankId);\r\n    if (!$droppable.length) { console.warn('\u26a0\ufe0f [kitAdCreated] droppable non trouv\u00e9:', _rankId); return; }\r\n    var $dropZone = $droppable.find('.drop_file_zone_achat_class').first();\r\n    if (!$dropZone.length) { $dropZone = $droppable.find('#drop_file_zone_achat').first(); }\r\n    if (!$dropZone.length) { console.warn('\u26a0\ufe0f [kitAdCreated] dropZone non trouv\u00e9e dans', _rankId); return; }\r\n\r\n    var _dataURL = msg.fullResDataURL || msg.pdfDataURL || null;\r\n    var _filename = msg.filename || 'annonce.png';\r\n    var _isPDF = msg.isPDF || false;\r\n    if (!_dataURL) { console.warn('\u26a0\ufe0f [kitAdCreated] aucune donn\u00e9e image'); return; }\r\n\r\n    var _parts = _dataURL.split(',');\r\n    var _mime = (_parts[0].match(\/:(.*?);\/) || [])[1] || (_isPDF ? 'application\/pdf' : 'image\/png');\r\n    var _bStr = atob(_parts[1]);\r\n    var _bytes = new Uint8Array(_bStr.length);\r\n    for (var _i = 0; _i < _bStr.length; _i++) { _bytes[_i] = _bStr.charCodeAt(_i); }\r\n    var _blob = new Blob([_bytes], { type: _mime });\r\n    \/\/ \u2705 Ajouter extension si absente\r\n    var _MIME_EXT = {'image\/png':'.png','image\/jpeg':'.jpg','image\/jpg':'.jpg','image\/webp':'.webp','application\/pdf':'.pdf'};\r\n    if (_filename.indexOf('.') === -1) { _filename = _filename + (_MIME_EXT[_mime] || (_isPDF ? '.pdf' : '.png')); }\r\n    var _file = new File([_blob], _filename, { type: _mime });\r\n\r\n    \/\/ \u2705 Pr\u00e9parer StateManager\r\n    StateManager.set('Rank_Emplacement_Page_Web', _rankId);\r\n    StateManager.set('Commande_Emplacement_Page_Web', _emplacement);\r\n    StateManager.set('Formatchoisi', 'Yes');\r\n    \/\/ \u2705 Marquer le droppable directement en DOM \u2014 r\u00e9siste \u00e0 l'async, lu par styleUploadedAd\r\n    $droppable[0].setAttribute('data-kit-drop', 'true');\r\n    window._dropFromMiniature = true;\r\n\r\n    console.log('\u2705 [kitAdCreated] \u2192 UploadManager.handleFileUpload | rankId:', _rankId);\r\n    UploadManager.handleFileUpload(_file, $dropZone).then(function() {\r\n        console.log('\u2705 [kitAdCreated] handleFileUpload termin\u00e9');\r\n    }).catch(function(err) {\r\n        window._dropFromMiniature = false;\r\n        $droppable[0].removeAttribute('data-kit-drop');\r\n        console.error('\u274c [kitAdCreated] handleFileUpload erreur:', err);\r\n    });\r\n});\r\n\r\n\/\/ \u2705 v1.17.0 : Listener \"thumbnailDropped\" \u2014 d\u00e9p\u00f4t de l'annonce depuis la miniature\r\n\/\/ =========================================================================\r\n\/**\r\n * Re\u00e7oit le drop de l'image-annonce depuis la miniature dans la page parente.\r\n * Identifie l'espace publicitaire sous le curseur, s\u00e9lectionne cet espace,\r\n * et d\u00e9clenche le flux dataFromIframeEspacePub en mode \"envoi diff\u00e9r\u00e9\"\r\n * (l'utilisateur uploadera le vrai fichier depuis le formulaire de commande).\r\n *\r\n * Coordonn\u00e9es re\u00e7ues : viewport de l'iframe (clientX\/clientY relatifs \u00e0 l'iframe)\r\n *\/\r\nwindow.addEventListener('message', function(event) {\r\n    var msg = event.data;\r\n    if (!msg || msg.action !== 'thumbnailDropped') return;\r\n\r\n    console.log('\ud83d\udce8 thumbnailDropped re\u00e7u \u2014 coords iframe:', msg.xRel, msg.yRel);\r\n\r\n    \/\/ \u2705 v1.19.3 : Corriger les coordonn\u00e9es pour le facteur de scale de l'iframe\r\n    \/\/ \u2705 v2.4.10 : 0.75 = scale appliqu\u00e9 par le PARENT sur l'\u00e9l\u00e9ment iframe (et non 0.85 qui est le scale interne OrdiMobileConteneurClass)\r\n    \/\/ Les coords xRel\/yRel viennent de getBoundingClientRect() sur l'iframe scal\u00e9 \u00e0 0.75 dans le parent \u2192 diviser par 0.75\r\n    var iframeScale = (window.outerWidth > 1000) ? 0.75 : 0.80;\r\n    \/\/ \u2705 v2.4.3 : Si Entete a intercept\u00e9 et pos\u00e9 un redirect vers Ele0A, utiliser ces coords\r\n    var _redirect = window._thumbnailDropRedirect || null;\r\n    window._thumbnailDropRedirect = null;\r\n    \/\/ \u2705 v2.4.4 : Les coords de redirect viennent de getBoundingClientRect() dans l'iframe (espace logique)\r\n    \/\/            \u2192 ne pas re-diviser par iframeScale (d\u00e9j\u00e0 en coords iframe-logiques)\r\n    var xAdjusted = _redirect ? _redirect.xRel : (msg.xRel \/ iframeScale);\r\n    var yAdjusted = _redirect ? _redirect.yRel : (msg.yRel \/ iframeScale);\r\n    if (_redirect) { console.log('\ud83d\udd00 [thumbnailDropped] coords redirig\u00e9es vers Ele0A:', Math.round(xAdjusted), Math.round(yAdjusted)); }\r\n    else { console.log('\ud83d\udcd0 Coords ajust\u00e9es (scale', iframeScale, '):', Math.round(xAdjusted), Math.round(yAdjusted)); }\r\n\r\n    \/\/ 1. Identifier l'espace publicitaire le plus proche du point de drop\r\n    \/\/    \u2705 v1.18.1 : Recherche par distance \u2014 coords \u00e9ventuellement redirig\u00e9es par Entete.txt\r\n    var allDroppables = document.querySelectorAll('.droppable');\r\n    var droppableEl = null;\r\n    var closestDist = Infinity;\r\n\r\n    \/\/ \u2705 v2.4.4 : Guard rect Ele0A \u2014 si PopUpChoice=Yes ET curseur dans le rect d'Ele0A \u2192 forcer\r\n    \/\/            (Ele0A est un popup flottant : son centre peut \u00eatre loin du curseur \u2192 algo distance l'ignore)\r\n    \/\/            Ne force PAS si le drop est hors d'Ele0A \u2192 les autres espaces restent accessibles\r\n    if (sessionStorage.getItem('PopUpChoice') === 'Yes') {\r\n        var _ele0ACheck = document.getElementById('Ele0A');\r\n        if (_ele0ACheck) {\r\n            var _r0A = _ele0ACheck.getBoundingClientRect();\r\n            var _margin = 30;\r\n            var _inR0A = (xAdjusted >= _r0A.left - _margin);\r\n            if (_inR0A) { _inR0A = (xAdjusted <= _r0A.right + _margin); }\r\n            if (_inR0A) { _inR0A = (yAdjusted >= _r0A.top - _margin); }\r\n            if (_inR0A) { _inR0A = (yAdjusted <= _r0A.bottom + _margin); }\r\n            if (_inR0A) {\r\n                droppableEl = _ele0ACheck;\r\n                closestDist = 0;\r\n                console.log('\ud83c\udfaf [thumbnailDropped] Ele0A forc\u00e9 (curseur dans rect Ele0A +30px)');\r\n            }\r\n        }\r\n    }\r\n\r\n    if (!droppableEl) {\r\n        allDroppables.forEach(function(d) {\r\n            var r = d.getBoundingClientRect();\r\n            var dCenterX = r.left + r.width  \/ 2;\r\n            var dCenterY = r.top  + r.height \/ 2;\r\n            var dist = Math.abs(dCenterX - xAdjusted) + Math.abs(dCenterY - yAdjusted);\r\n            if (dist < closestDist) { closestDist = dist; droppableEl = d; }\r\n        });\r\n        \/\/ \u2705 v2.4.3 : Si Entete a d\u00e9tect\u00e9 un drop sur Ele0A \u2192 forcer directement\r\n        if (_redirect) { if (_redirect.forceEle0A) {\r\n            var _ele0AForced = document.getElementById('Ele0A');\r\n            if (_ele0AForced) { droppableEl = _ele0AForced; console.log('\ud83c\udfaf [thumbnailDropped] Ele0A forc\u00e9 (redirect Entete)'); }\r\n        } }\r\n    }\r\n\r\n    if (!droppableEl || closestDist > 800) {\r\n        console.warn('thumbnailDropped \u2014 aucun droppable proche (dist min:', closestDist, ')');\r\n        return;\r\n    }\r\n    console.log('\ud83d\udccd Droppable trouv\u00e9:', droppableEl.id, '(dist:', Math.round(closestDist), ')');\r\n\r\n    var $droppable = jQuery(droppableEl);\r\n    var rankId = $droppable.attr('id');\r\n    if (!rankId) { console.warn('thumbnailDropped \u2014 .droppable sans id'); return; }\r\n\r\n    var $dropZone = $droppable.find('#drop_file_zone_achat').first();\r\n    if (!$dropZone.length) { console.warn('thumbnailDropped \u2014 #drop_file_zone_achat introuvable dans', rankId); return; }\r\n\r\n    var emplacementRef = StateManager.buildEmplacementReference(rankId);\r\n    console.log('\u2705 thumbnailDropped \u2014 espace pub:', rankId, '\u2192', emplacementRef);\r\n\r\n    \/\/ 2. Pr\u00e9parer l'\u00e9tat SessionStorage (comme un vrai drop de fichier)\r\n    StateManager.setMultiple({\r\n        'Rank_Emplacement_Page_Web':     rankId,\r\n        'Commande_Emplacement_Page_Web': emplacementRef,\r\n        'FirstUploadFileorMoved':        'FirstUpload',\r\n        'Formatchoisi':                  'Yes',\r\n        'Commande_Format_Transmis':      'Image',\r\n        'EnvoiUlterieur':                'false',\r\n        'FileReceived':                  'No',\r\n        'AdDisplayed':                   'Yes'\r\n    });\r\n\r\n    UIManager.updateEmplacementDisplay();\r\n\r\n    \/\/ 3. Construire le File \u00e0 partir du PDF (communiqu\u00e9\/interview) ou de l'image PNG (autres formats)\r\n    \/\/    puis appeler handleFileUpload \u2192 m\u00eame flux qu'un vrai drag&drop : liser\u00e9 vert, aper\u00e7u, R\u00e9server\r\n    var dataURL, mime, ext;\r\n\r\n    \/\/ \u2705 Stocker le PDF image et le format sur le droppable pour le popup de visualisation inline\r\n    if (msg.pdfImageDataURL) {\r\n        $droppable.data('kitPdfImageDataURL', msg.pdfImageDataURL);\r\n        $droppable.data('kitFormatSelect', msg.FormatSelect || '');\r\n        console.log('\ud83d\udcce pdfImageDataURL stock\u00e9 sur', rankId, '| format:', msg.FormatSelect);\r\n    } else {\r\n        $droppable.removeData('kitPdfImageDataURL');\r\n        $droppable.removeData('kitFormatSelect');\r\n    }\r\n\r\n    if (msg.isPDF && msg.pdfDataURL) {\r\n        \/\/ \u2500\u2500 Format PDF (communiqu\u00e9 \/ interview) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        dataURL = msg.pdfDataURL;                         \/\/ \"data:application\/pdf;base64,\u2026\"\r\n        mime    = 'application\/pdf';\r\n        ext     = '.pdf';\r\n    } else if (msg.imageDataURL) {\r\n        \/\/ \u2500\u2500 Format image (banni\u00e8re \/ parrainage) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n        dataURL = msg.imageDataURL;\r\n        var mimeMatch = dataURL.match(\/^data:([^;]+);base64,\/);\r\n        mime    = mimeMatch ? mimeMatch[1] : 'image\/png';\r\n        ext     = mime === 'image\/jpeg' ? '.jpg' : '.png';\r\n    } else {\r\n        console.warn('thumbnailDropped \u2014 aucune donn\u00e9e image\/pdf disponible');\r\n        return;\r\n    }\r\n\r\n    var baseName = msg.filename ? msg.filename.replace(\/\\.[^.]+$\/, '') : 'annonce-kit';\r\n    var fileName = baseName + ext;\r\n\r\n    \/\/ dataURL \u2192 Uint8Array \u2192 Blob \u2192 File\r\n    var b64  = dataURL.split(',')[1];\r\n    var bstr = atob(b64);\r\n    var u8   = new Uint8Array(bstr.length);\r\n    for (var i = 0; i < bstr.length; i++) { u8[i] = bstr.charCodeAt(i); }\r\n    var blob    = new Blob([u8], { type: mime });\r\n    var fileObj = new File([blob], fileName, { type: mime });\r\n\r\n    console.log('thumbnailDropped \u2192 handleFileUpload:', fileName, Math.round(fileObj.size \/ 1024) + 'KB');\r\n\r\n    \/\/ \u2705 Cacher le File pour r\u00e9utilisation lors des d\u00e9placements (\u00e9vite CORS)\r\n    window._lastRedactionnelFile = fileObj;\r\n\r\n    \/\/ \u2705 v2.4.10 : Signaler \u00e0 adjustDesktopLayout que c'est un drop depuis la miniature\r\n    \/\/ \u2192 applique max-height sur HTMLUploadfileConteneur pour \u00e9viter le d\u00e9bordement vertical (homepage corps de page)\r\n    window._dropFromMiniature = true;\r\n    UploadManager.handleFileUpload(fileObj, $dropZone);\r\n\r\n    \/\/ \u2705 v1.19.1 : Positionner l'espace \u00e0 10px du haut du viewport (tous formats)\r\n    \/\/ \u2705 v2.4.13 : Skip si drop depuis miniature \u2014 selectEspaceActif g\u00e8re d\u00e9j\u00e0 le scroll\r\n    if (!window._dropFromMiniature) {\r\n        setTimeout(function() {\r\n            var el = $droppable.find('.HTMLUploadfileConteneur')[0] || $droppable[0];\r\n            if (el) {\r\n                ScrollHelper.scrollElementTo(el, 10);\r\n            }\r\n        }, 400);\r\n    }\r\n});\r\n\r\nconsole.log('This is a ' + (UIManager.isDesktop() ? 'desktop' : 'non-desktop') + ' device.');\r\n\r\n} \/\/ end _espPubScriptLoaded guard\r\n<\/script>\r\n\r\n<style>\r\n\/* Les styles CSS restent inchang\u00e9s *\/\r\n#drop_file_zone_achat {\r\n    background-color: #FFFFFF00;\r\n    color: #225DA9;\r\n    font-weight: 500;\r\n    text-align: center;\r\n    border: #999 0px dashed;\r\n    width: 100%;\r\n    height: 180px;\r\n    font-size: 11.5px;\r\n    display: flex;\r\n    justify-content: center; \r\n    align-items: center; \r\n    flex-wrap: wrap;\r\n}\r\n\r\n#drag_upload_file_achat {\r\n    margin: 0 auto;\r\n    width: 90%;\r\n    height: 60px;\r\n}\r\n\r\n#drag_upload_file_achat p {\r\n    text-align: center;\r\n}\r\n\r\n\/* \u2705 v1.16.0 : Liser\u00e9 noir fin autour du texte \"Ici glisser \u2013 d\u00e9poser\" *\/\r\n.GlisserDeposerConteneur .elementor-widget-container p {\r\n    border: 1px solid #000000;\r\n    border-radius: 4px;\r\n    padding: 4px 10px;\r\n    display: inline-block;\r\n}\r\n\r\n#selectfile_achat {\r\n    display: none;\r\n}\r\n\r\n.button-2_achat, .button-2_achat-after-reset {\r\n    background-color: #ffffff00!important;\r\n    border: 1px solid white!important;\r\n    border-radius: 8px;\r\n    color: #225DA9!important;\r\n    cursor: pointer;\r\n    display: inline-block;\r\n    font-size: 11px;\r\n    font-weight: 500;\r\n    list-style: none;\r\n    width: 390px;\r\n    height: 62px;\r\n    top: 0px!important; \r\n    margin-top: 0px!important; \r\n    padding-left: 5px!important;\r\n    padding-right: 5px!important;\r\n    margin-bottom: 70px!important;\r\n    margin: 0;\r\n    text-align: center;\r\n    transition: all 200ms;\r\n    vertical-align: baseline;\r\n    white-space: wrap!important;\r\n}\r\n\r\n@media only screen and (max-width: 1000px) {\r\n    .button-2_achat, .button-2_achat-after-reset {\r\n        width: 95%;\r\n        height: 50px;\r\n    }\r\n}\r\n\r\n.newMessageClass {\r\n    background-color: #FFFFFF00!important;\r\n    font-size: 13px; \r\n    font-weight: 600;\r\n    color: #56BE50;\r\n    height: 35px;\r\n    width: 550px; \r\n    position: relative;\r\n    z-index: 99;\r\n    top: 45px;\r\n    bottom: 0px;\r\n    right: 0px;\r\n    left: 0px;\r\n    display: flex;\r\n    justify-content: center;\r\n    align-items: center;\r\n    text-align: center;\r\n}\r\n\r\n.MessageClassFormatnonReconnuTitre {\r\n    background-color: #FFFFFF00!important;\r\n    font-size: 13px; \r\n    font-weight: 600;\r\n    color: #FB5E2A;\r\n    height: 35px;\r\n    width: 550px; \r\n    position: relative;\r\n    z-index: 99;\r\n    margin-top: -300px;\r\n    right: 0px;\r\n    text-align: center;\r\n    line-height: 15px;\r\n}\r\n\r\n.MessageClassFormatnonReconnu {\r\n    background-color: #FFFFFF00!important;\r\n    font-size: 13px; \r\n    font-weight: 600;\r\n    color: #ffffff;\r\n    height: 35px;\r\n    width: 550px; \r\n    position: relative;\r\n    z-index: 99;\r\n    margin-top: -280px;\r\n    right: 0px;\r\n    text-align: center;\r\n    line-height: 15px;\r\n}\r\n\r\n.newButtonClass {\r\n    font-size: 12px; \r\n    font-weight: 500;\r\n    background-color: #ffffff00;\r\n    color: #717171;\r\n    height: 10px;\r\n    width: 100%; \r\n    position: relative;\r\n    z-index: 99;\r\n    top: 45px;\r\n    bottom: 0px;\r\n    text-align: center;\r\n    right:  50px;\r\n    line-height: 10px;\r\n    border-radius: 3px;\r\n    border: 0px solid #E8ECF1;\r\n}\r\n\r\n.linkClass {\r\n    width: 15px; \r\n    height: 15px;\r\n    margin-top: -310px;\r\n    margin-bottom: -25px;\r\n    margin-right: -50px;\r\n    position: relative;\r\n    top: 0; \r\n    z-index: 99;\r\n    display: block;\r\n    background-image: url('https:\/\/rdc.via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-blanc.jpg');\r\n    background-size: cover;\r\n}\r\n\r\n.newButtonClassVideo {\r\n    font-size: 12px; \r\n    font-weight: 500;\r\n    background-color: #ffffff00;\r\n    color: #717171;\r\n    height: 10px;\r\n    width: 100%; \r\n    position: relative;\r\n    z-index: 99;\r\n    top: 0px;\r\n    bottom: 0px;\r\n    right: 10px;\r\n    text-align: center;\r\n    line-height: 10px;\r\n    border-radius: 3px;\r\n    border: 0px solid #E8ECF1;\r\n}\r\n\r\n.linkClassVideo {\r\n    width: 15px; \r\n    height: 15px;\r\n    margin-top: -438px;\r\n    margin-bottom: -25px;\r\n    margin-right: -15px;\r\n    position: relative;\r\n    top: 0; \r\n    z-index: 99;\r\n    display: block;\r\n    background-image: url('https:\/\/rdc.via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-blanc.jpg');\r\n    background-size: cover;\r\n}\r\n\r\n.FinCampagneMobileClass .elementor-button,\r\n.DebutCampagneMobileClass .elementor-button,\r\n.FormSelectDevisesMobile .elementor-button,\r\n.HideFormButton .elementor-button {\r\n    display: none !important;\r\n}\r\n\r\n#drag_upload_file_achat {\r\n    margin: 0;\r\n    padding: 0;\r\n    position: relative;\r\n}\r\n\r\n.dot-container {\r\n    display: inline-block;\r\n}\r\n\r\n.dot {\r\n    opacity: 0;\r\n    transition: opacity 0.3s ease;\r\n}\r\n\r\n@keyframes firstDot {\r\n    0%, 100% { opacity: 0; }\r\n    10%, 70% { opacity: 1; }\r\n    90% { opacity: 0; }\r\n}\r\n\r\n@keyframes secondDot {\r\n    0%, 20%, 100% { opacity: 0; }\r\n    30%, 70% { opacity: 1; }\r\n    90% { opacity: 0; }\r\n}\r\n\r\n@keyframes thirdDot {\r\n    0%, 40%, 100% { opacity: 0; }\r\n    50%, 70% { opacity: 1; }\r\n    90% { opacity: 0; }\r\n}\r\n\r\n.dot:nth-child(1) {\r\n    animation: firstDot 3s infinite;\r\n}\r\n\r\n.dot:nth-child(2) {\r\n    animation: secondDot 3s infinite;\r\n}\r\n\r\n.dot:nth-child(3) {\r\n    animation: thirdDot 3s infinite;\r\n}\r\n\r\n.droppable .elementor-field-type-checkbox .elementor-field-option {\r\n    display: flex;\r\n    flex-direction: row-reverse;\r\n    align-items: center;\r\n    gap: 8px;\r\n}\r\n\r\n.droppable .elementor-field-type-checkbox .elementor-field-option input[type=\"checkbox\"] {\r\n    width: 12px;\r\n    height: 12px;\r\n    min-width: 12px;\r\n    min-height: 12px;\r\n}\r\n\r\n\/* \u2705 Bouton \"R\u00e9server\" dynamique *\/\r\n.reserver-dynamic-container {\r\n    text-align: center;\r\n    margin-top: -7px;\r\n    margin-bottom: 15px;\r\n    padding: 5px 0;\r\n    transform: scale(1.4);\r\n    transform-origin: center top;\r\n    position: relative;\r\n    z-index: 200;\r\n}\r\n\r\n@media only screen and (min-width: 1001px) {\r\n    .reserver-dynamic-container {\r\n        transform: scale(1);\r\n        margin-top: -200px;\r\n        margin-bottom: 0;\r\n    }\r\n}\r\n\r\n.reserver-dynamic-option {\r\n    display: inline-flex;\r\n    flex-direction: row-reverse;\r\n    align-items: center;\r\n    gap: 8px;\r\n    cursor: pointer;\r\n    color: #213864;\r\n    background-color: #ffffff;\r\n    padding: 2px 4px;\r\n    border-radius: 6px;\r\n}\r\n\r\n.reserver-dynamic-checkbox {\r\n    width: 16px;\r\n    height: 16px;\r\n    min-width: 16px;\r\n    min-height: 16px;\r\n    cursor: pointer;\r\n    pointer-events: auto;\r\n}\r\n\r\n.reserver-dynamic-label {\r\n    cursor: pointer;\r\n    color: #213864;\r\n    font-size: 16px;\r\n    font-weight: 600;\r\n    user-select: none;\r\n}\r\n\r\n@media only screen and (max-width: 1000px) {\r\n    .reserver-dynamic-container {\r\n        transform: scale(0.98);\r\n        margin-bottom: 20px;\r\n        white-space: nowrap;\r\n        z-index: 300;\r\n        pointer-events: auto;\r\n    }\r\n    .reserver-dynamic-option {\r\n        padding-top: 0px;\r\n        padding-bottom: 0px;\r\n    }\r\n}\r\n\r\n\/* \u2705 v2.1.3 : DeplaceAnnonceText \/ DeplaceAnnonce \u2014 desktop uniquement *\/\r\n@media only screen and (min-width: 1001px) {\r\n    .DeplaceAnnonceText {\r\n        margin-top: -5px;\r\n        position: relative;\r\n        z-index: 201;\r\n    }\r\n    .DeplaceAnnonce {\r\n        margin-bottom: -150px;\r\n    }\r\n}\r\n<\/style>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-54e4e530 e-con-full MsgFormatIncorrectConteneur elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile e-flex e-con e-child\" data-id=\"54e4e530\" data-element_type=\"container\" id=\"NotusedAnymore\">\n\t\t\t\t<div class=\"elementor-element elementor-element-531f3cb1 MsgFormatIncorrect elementor-widget__width-inherit elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"531f3cb1\" data-element_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 style=\"text-align: center;\">Le format du fichier n&rsquo;est pas reconnu<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3a352c3f elementor-hidden-desktop TexteMobile TexteMobileAnnonce elementor-widget elementor-widget-text-editor\" data-id=\"3a352c3f\" data-element_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\tGlisser-d\u00e9poser ou cliquer ici<br>pour t\u00e9l\u00e9charger une annonce\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7abb0aba elementor-hidden-desktop TexteMobileAjoutAnnonce elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"7abb0aba\" data-element_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 style=\"text-align: center;\">Cliquer ici pour t\u00e9l\u00e9charger une annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-68e2b2ca UploadIci elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"68e2b2ca\" data-element_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>Ici glisser-d\u00e9poser ou t\u00e9l\u00e9charger une annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-8d50d33 e-con-full e-flex e-con e-child\" data-id=\"8d50d33\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6ae6ef83 elementor-button-align-center elementor-widget__width-initial HideFormButton EspPubLienAnnonce elementor-widget-mobile__width-initial elementor-widget elementor-widget-form\" data-id=\"6ae6ef83\" data-element_type=\"widget\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_URL_annonce\" aria-label=\"Formulaire_URL_annonce\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249681\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"6ae6ef83\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-text elementor-field-group elementor-column elementor-field-group-LienAnnonce elementor-col-100 elementor-sm-100 elementor-field-required\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-LienAnnonce\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tIci renseigner si n\u00e9cessaire le lien hypertexte de l\u2019annonce\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<input size=\"1\" type=\"text\" name=\"form_fields[LienAnnonce]\" id=\"form-field-LienAnnonce\" class=\"elementor-field elementor-size-xs  elementor-field-textual\" placeholder=\"Ici renseigner si n\u00e9cessaire le lien hypertexte de l\u2019annonce\" required=\"required\">\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidURLAnnonce\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-66fd4d36 e-con-full EnvoiUlterieurContainer e-flex e-con e-child\" data-id=\"66fd4d36\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4ea8e2b4 elementor-button-align-center elementor-widget__width-auto HideFormButton EnvoiUlterieur elementor-widget elementor-widget-form\" data-id=\"4ea8e2b4\" data-element_type=\"widget\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_Envoi_Ulterieur\" aria-label=\"Formulaire_Envoi_Ulterieur\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249681\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"4ea8e2b4\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-checkbox elementor-field-group elementor-column elementor-field-group-EnvoiUlterieur elementor-col-100 elementor-sm-100\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-EnvoiUlterieur\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tEnvoi diff\u00e9r\u00e9 de l'annonce\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t<div class=\"elementor-field-subgroup\"><span class=\"elementor-field-option\"><input type=\"checkbox\" value=\"Envoi diff\u00e9r\u00e9 de l&#039;annonce\" id=\"form-field-EnvoiUlterieur-0\" name=\"form_fields[EnvoiUlterieur]\"> <label for=\"form-field-EnvoiUlterieur-0\">Envoi diff\u00e9r\u00e9 de l'annonce<\/label><\/span><\/div>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidEnvoiUlterieur\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\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-4a59cf88 EnvoiUlterieurTexte elementor-widget elementor-widget-text-editor\" data-id=\"4a59cf88\" data-element_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 style=\"text-align: center;\">Envoyer l\u2019annonce jusqu\u2019\u00e0 8 jours apr\u00e8s paiement<br>\nUn lien vous sera adress\u00e9 par <span style=\"color: #ffffff;\"><a style=\"color: #ffffff;\" href=\"mailto:contact@via-agency.media\">contact@via-agency.media<\/a><\/span><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-17d3ad0c e-con-full ReserverContainer e-flex e-con e-child\" data-id=\"17d3ad0c\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-177c9b71 elementor-button-align-center elementor-widget__width-auto HideFormButton ReserverBouton elementor-widget elementor-widget-form\" data-id=\"177c9b71\" data-element_type=\"widget\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_Envoi_Ulterieur\" aria-label=\"Formulaire_Envoi_Ulterieur\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249681\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"177c9b71\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-checkbox elementor-field-group elementor-column elementor-field-group-ReserverEspacePublicitaire elementor-col-100 elementor-sm-100\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-ReserverEspacePublicitaire\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tR\u00e9server cet espace publicitaire\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t<div class=\"elementor-field-subgroup\"><span class=\"elementor-field-option\"><input type=\"checkbox\" value=\"R\u00e9server cet espace publicitaire\" id=\"form-field-ReserverEspacePublicitaire-0\" name=\"form_fields[ReserverEspacePublicitaire]\"> <label for=\"form-field-ReserverEspacePublicitaire-0\">R\u00e9server cet espace publicitaire<\/label><\/span><\/div>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidEnvoiUlterieur\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-5bafe1f3 e-con-full AdUploadedTitle DeplaceAnnonce elementor-hidden-tablet elementor-hidden-mobile elementor-hidden-desktop e-flex e-con e-child\" data-id=\"5bafe1f3\" data-element_type=\"container\" id=\"DeplaceAnnonceId\">\n\t\t<div class=\"elementor-element elementor-element-432cc2a1 e-con-full DeplaceAnnonceSubContainer e-flex e-con e-child\" data-id=\"432cc2a1\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-446e8565 elementor-hidden-tablet elementor-hidden-mobile EspaceReserve elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"446e8565\" data-element_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>Espace r\u00e9serv\u00e9<br \/>Annonce transmise<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-60df49d0 elementor-hidden-tablet elementor-hidden-mobile DeplaceAnnonceText elementor-widget elementor-widget-text-editor\" data-id=\"60df49d0\" data-element_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\tSi vous souhaitez un autre emplacement, vous pouvez d\u00e9placer cette annonce\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-62ef38f0 e-con-full e-flex e-con e-child\" data-id=\"62ef38f0\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f4f51cb elementor-hidden-tablet elementor-hidden-mobile PositionEspacePublicitaireDeplacer elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"f4f51cb\" data-element_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>Position<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f214306 elementor-hidden-tablet elementor-hidden-mobile RefEspacePublicitaire elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"f214306\" data-element_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>R\u00e9f\u00e9rence<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1c5a5ed5 e-con-full AdUploadedOverlay elementor-hidden-desktop elementor-hidden-tablet elementor-hidden-mobile e-flex e-con e-child\" data-id=\"1c5a5ed5\" data-element_type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-4740d3e8 e-con-full OverlayHeader e-flex e-con e-child\" data-id=\"4740d3e8\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e964c6b elementor-hidden-tablet elementor-hidden-mobile OverlayRefEspace elementor-hidden-desktop elementor-widget elementor-widget-text-editor\" data-id=\"e964c6b\" data-element_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>R\u00e9f\u00e9rence<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-30eb836c OverlayCroixReset elementor-widget elementor-widget-image\" data-id=\"30eb836c\" data-element_type=\"widget\" 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\t<a href=\"#\">\n\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/via-agency.media\/wp-content\/uploads\/2024\/06\/Croix-retour-HP-fond-transparent.png\" title=\"\" alt=\"\" loading=\"lazy\" \/>\t\t\t\t\t\t\t\t<\/a>\n\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<\/div>\n\t\t<div class=\"elementor-element elementor-element-342c88b1 e-con-full OverlayPreviewZone e-flex e-con e-child\" data-id=\"342c88b1\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3c7e790f OverlayDeplaceTexte elementor-hidden-tablet elementor-hidden-mobile elementor-widget elementor-widget-text-editor\" data-id=\"3c7e790f\" data-element_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>Si vous souhaitez un autre emplacement, vous pouvez d\u00e9placer cette annonce<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-51f00578 elementor-button-align-center elementor-widget__width-auto HideFormButton OverlayReserverForm elementor-widget elementor-widget-form\" data-id=\"51f00578\" data-element_type=\"widget\" id=\"Formulaire_Reserver_Overlay\" data-settings=\"{&quot;step_next_label&quot;:&quot;Suivant&quot;,&quot;step_previous_label&quot;:&quot;Pr\\u00e9c\\u00e9dent&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;step_icon_shape&quot;:&quot;none&quot;,&quot;button_width&quot;:&quot;100&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" id=\"Formulaire_Annonceur_donnees_notconnected2\" name=\"Formulaire_Envoi_Ulterieur\" aria-label=\"Formulaire_Envoi_Ulterieur\" action=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"249681\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"51f00578\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-checkbox elementor-field-group elementor-column elementor-field-group-ReserverEspacePublicitaire elementor-col-100 elementor-sm-100\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-ReserverEspacePublicitaire\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tR\u00e9server cet espace publicitaire\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t<div class=\"elementor-field-subgroup\"><span class=\"elementor-field-option\"><input type=\"checkbox\" value=\"R\u00e9server cet espace publicitaire\" id=\"form-field-ReserverEspacePublicitaire-0\" name=\"form_fields[ReserverEspacePublicitaire]\"> <label for=\"form-field-ReserverEspacePublicitaire-0\">R\u00e9server cet espace publicitaire<\/label><\/span><\/div>\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-xs\" type=\"submit\" id=\"ButtonValidEnvoiUlterieur\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\"> <\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<input type=\"hidden\" name=\"trp-form-language\" value=\"fr\"\/><\/form>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\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-1947443 e-flex e-con-boxed e-con e-parent\" data-id=\"1947443\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>",
        "protected": false
    },
    "excerpt": {
        "rendered": "",
        "protected": false
    },
    "author": 1,
    "featured_media": 0,
    "parent": 0,
    "menu_order": 0,
    "comment_status": "closed",
    "ping_status": "closed",
    "template": "",
    "meta": {
        "_acf_changed": false,
        "footnotes": ""
    },
    "class_list": [
        "post-113220",
        "page",
        "type-page",
        "status-publish",
        "hentry",
        "generate-columns",
        "tablet-grid-50",
        "mobile-grid-100",
        "grid-parent",
        "grid-20"
    ],
    "acf": [],
    "yoast_head": "<!-- This site is optimized with the Yoast SEO plugin v24.8.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Togo - Electricit\u00e9<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/togo-en.yearbook-media.com\/fr\/electricite\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Togo - Electricit\u00e9\" \/>\n<meta property=\"og:url\" content=\"https:\/\/togo-en.yearbook-media.com\/fr\/electricite\/\" \/>\n<meta property=\"og:site_name\" content=\"TOGO YEARBOOK RAPPORT ECONOMIQUE\" \/>\n<meta property=\"article:modified_time\" content=\"2025-04-29T10:02:10+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/togo-en.yearbook-media.com\/electricite\/\",\"url\":\"https:\/\/togo-en.yearbook-media.com\/electricite\/\",\"name\":\"Togo - Electricit\u00e9\",\"isPartOf\":{\"@id\":\"https:\/\/togo-en.yearbook-media.com\/#website\"},\"datePublished\":\"2024-11-27T09:38:27+00:00\",\"dateModified\":\"2025-04-29T10:02:10+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/togo-en.yearbook-media.com\/electricite\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/togo-en.yearbook-media.com\/electricite\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/togo-en.yearbook-media.com\/electricite\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/togo-en.yearbook-media.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Togo &#8211; Electricit\u00e9\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/togo-en.yearbook-media.com\/#website\",\"url\":\"https:\/\/togo-en.yearbook-media.com\/\",\"name\":\"TOGO YEARBOOK RAPPORT ECONOMIQUE\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/togo-en.yearbook-media.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->",
    "yoast_head_json": {
        "title": "Togo - Electricit\u00e9",
        "robots": {
            "index": "index",
            "follow": "follow",
            "max-snippet": "max-snippet:-1",
            "max-image-preview": "max-image-preview:large",
            "max-video-preview": "max-video-preview:-1"
        },
        "canonical": "https:\/\/togo-en.yearbook-media.com\/fr\/electricite\/",
        "og_locale": "fr_FR",
        "og_type": "article",
        "og_title": "Togo - Electricit\u00e9",
        "og_url": "https:\/\/togo-en.yearbook-media.com\/fr\/electricite\/",
        "og_site_name": "TOGO YEARBOOK RAPPORT ECONOMIQUE",
        "article_modified_time": "2025-04-29T10:02:10+00:00",
        "twitter_card": "summary_large_image",
        "schema": {
            "@context": "https:\/\/schema.org",
            "@graph": [
                {
                    "@type": "WebPage",
                    "@id": "https:\/\/togo-en.yearbook-media.com\/electricite\/",
                    "url": "https:\/\/togo-en.yearbook-media.com\/electricite\/",
                    "name": "Togo - Electricit\u00e9",
                    "isPartOf": {
                        "@id": "https:\/\/togo-en.yearbook-media.com\/#website"
                    },
                    "datePublished": "2024-11-27T09:38:27+00:00",
                    "dateModified": "2025-04-29T10:02:10+00:00",
                    "breadcrumb": {
                        "@id": "https:\/\/togo-en.yearbook-media.com\/electricite\/#breadcrumb"
                    },
                    "inLanguage": "fr-FR",
                    "potentialAction": [
                        {
                            "@type": "ReadAction",
                            "target": [
                                "https:\/\/togo-en.yearbook-media.com\/electricite\/"
                            ]
                        }
                    ]
                },
                {
                    "@type": "BreadcrumbList",
                    "@id": "https:\/\/togo-en.yearbook-media.com\/electricite\/#breadcrumb",
                    "itemListElement": [
                        {
                            "@type": "ListItem",
                            "position": 1,
                            "name": "Accueil",
                            "item": "https:\/\/togo-en.yearbook-media.com\/"
                        },
                        {
                            "@type": "ListItem",
                            "position": 2,
                            "name": "Togo &#8211; Electricit\u00e9"
                        }
                    ]
                },
                {
                    "@type": "WebSite",
                    "@id": "https:\/\/togo-en.yearbook-media.com\/#website",
                    "url": "https:\/\/togo-en.yearbook-media.com\/",
                    "name": "TOGO YEARBOOK RAPPORT ECONOMIQUE",
                    "description": "",
                    "potentialAction": [
                        {
                            "@type": "SearchAction",
                            "target": {
                                "@type": "EntryPoint",
                                "urlTemplate": "https:\/\/togo-en.yearbook-media.com\/?s={search_term_string}"
                            },
                            "query-input": {
                                "@type": "PropertyValueSpecification",
                                "valueRequired": true,
                                "valueName": "search_term_string"
                            }
                        }
                    ],
                    "inLanguage": "fr-FR"
                }
            ]
        }
    },
    "_links": {
        "self": [
            {
                "href": "https:\/\/togo-en.yearbook-media.com\/fr\/wp-json\/wp\/v2\/pages\/113220"
            }
        ],
        "collection": [
            {
                "href": "https:\/\/togo-en.yearbook-media.com\/fr\/wp-json\/wp\/v2\/pages"
            }
        ],
        "about": [
            {
                "href": "https:\/\/togo-en.yearbook-media.com\/fr\/wp-json\/wp\/v2\/types\/page"
            }
        ],
        "author": [
            {
                "embeddable": true,
                "href": "https:\/\/togo-en.yearbook-media.com\/fr\/wp-json\/wp\/v2\/users\/1"
            }
        ],
        "replies": [
            {
                "embeddable": true,
                "href": "https:\/\/togo-en.yearbook-media.com\/fr\/wp-json\/wp\/v2\/comments?post=113220"
            }
        ],
        "version-history": [
            {
                "count": 2,
                "href": "https:\/\/togo-en.yearbook-media.com\/fr\/wp-json\/wp\/v2\/pages\/113220\/revisions"
            }
        ],
        "predecessor-version": [
            {
                "id": 159708,
                "href": "https:\/\/togo-en.yearbook-media.com\/fr\/wp-json\/wp\/v2\/pages\/113220\/revisions\/159708"
            }
        ],
        "wp:attachment": [
            {
                "href": "https:\/\/togo-en.yearbook-media.com\/fr\/wp-json\/wp\/v2\/media?parent=113220"
            }
        ],
        "curies": [
            {
                "name": "wp",
                "href": "https:\/\/api.w.org\/{rel}",
                "templated": true
            }
        ]
    }
}