{"id":3566,"date":"2025-08-14T07:11:12","date_gmt":"2025-08-14T07:11:12","guid":{"rendered":"https:\/\/porvoonkodit.fi\/asunnon-hakijalle\/kohteet\/uudiskohteet\/"},"modified":"2026-09-01T13:17:18","modified_gmt":"2026-09-01T13:17:18","slug":"uudiskohteet","status":"publish","type":"page","link":"https:\/\/porvoonkodit.fi\/en\/asunnon-hakijalle\/kohteet\/uudiskohteet\/","title":{"rendered":"New Developments"},"content":{"rendered":"\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<section id=\"g-v1l9vvr\" class=\"section-g-v1l9vvr gutentor-module gutentor-container-cover wp-block-gutentor-m3 alignfull d-none\"><div class=\"grid-container\">\n<section id=\"g-mmom818\" class=\"section-g-mmom818 gutentor-module gutentor-container-cover wp-block-gutentor-m3\"><div class=\"grid-container\">\n<div id=\"section-g-39kx12j\" class=\"section-g-39kx12j gutentor-element gutentor-element-advanced-text wp-block-gutentor-e1\"><div class=\"gutentor-text-wrap\"><h2 class=\"gutentor-text\">Vaskenvalajankatu 8<\/h2><\/div><\/div>\n\n\n\n<div id=\"section-g-vttsj0s\" class=\"section-g-vttsj0s gutentor-element gutentor-element-advanced-text wp-block-gutentor-e1\"><div class=\"gutentor-text-wrap\"><p class=\"gutentor-text\"><strong>New accessible flats under construction in the centre of Porvoo<\/strong>.<br><br>Porvoon Kodit\u2019s upcoming new project, Vaskenvalajankatu 8, is located in a central spot at the intersection of Wittenberginkatu and Kev\u00e4tkummuntie, just a stone\u2019s throw from the centre and Tarmola\u2019s services, with excellent transport connections.<br><br>Vaskenvalajankatu comprises four residential buildings, totaling 122 reasonably priced rental flats. The property is expected to be completed in early 2026 and will be the largest project of Porvoon Kodit, as well as part of Porvoo\u2019s new, modern urban look.<br><br>Vaskenvalajankatu is a state-subsidized rental property, featuring 74 standard rental flats, 33 senior flats (Building B, intended for residents aged 55+), and 15 assisted living flats (Building C). Flat sizes range from 30 to 73.5 m\u00b2, with layouts from studios to four-room flats. The complex will also include building saunas and shared facilities. The yard area is planned to feature a playground as well as &nbsp;cosy recreational and passage areas with paving and plantings designed for natural asymmetry. A parking area will also be built on the Vaskenvalajankatu side of the property.<br><br>The buildings are designed to match energy efficiency class A. Living safety is enhanced by an automatic fire detection and extinguishing system, and comfort by water-circulating underfloor heating and central ventilation with cooling. All flats are accessible. In addition to geothermal heating, the property will be connected to the district heating network. There is a broadband cable TV system in the property. Balconies are glazed.<br><br>The property is completely smoke-free, meaning smoking is prohibited also in the yard area and on balconies. Pets are welcome.<br><br>The project is state-subsidized, which means that resident selection follows needs assessment and the applicable income and asset limits. In the senior flats (for residents aged 55+), only asset limits apply.<br><br><strong>Applications for available flats are now open!<\/strong><\/p><\/div><\/div>\n\n\n\n<div id=\"section-g-muz1x5l\" class=\"section-g-muz1x5l gutentor-element gutentor-element-button wp-block-gutentor-e2 gutentor-btn-full-mobile gutentor-btn-custom-desktop gutentor-btn-custom-tablet button-align-left-desktop button-align-left-tablet button-align-center-mobile\"><span class=\"gutentor-button-wrap\"><a class=\"gutentor-button gutentor-block-button gutentor-icon-hide\" href=\"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2025\/09\/Vaskenvalajankatu-8-Markkinointimateriaali-paivitetty-1.pdf\" target=\"_blank\" rel=\" noopener noreferrer\"><i class=\"gutentor-button-icon fas fa-book\"><\/i><span>See brochure<\/span><\/a><\/span><\/div>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div id=\"section-g-sslltmt\" class=\"section-g-sslltmt gutentor-element gutentor-element-button wp-block-gutentor-e2 gutentor-btn-full-mobile gutentor-btn-custom-desktop gutentor-btn-custom-tablet button-align-left-desktop button-align-left-tablet button-align-center-mobile\"><span class=\"gutentor-button-wrap\"><a class=\"gutentor-button gutentor-block-button gutentor-icon-hide\" href=\"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2025\/09\/Vaskenvalajankatu-8-hinnasto.pdf\" target=\"_blank\" rel=\" noopener noreferrer\"><i class=\"gutentor-button-icon fas fa-book\"><\/i><span>Rental apartments and prices<\/span><\/a><\/span><\/div>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div id=\"section-g-lks9ppo\" class=\"section-g-lks9ppo gutentor-element gutentor-element-button wp-block-gutentor-e2 gutentor-btn-full-mobile gutentor-btn-custom-desktop gutentor-btn-custom-tablet button-align-left-desktop button-align-left-tablet button-align-center-mobile\"><span class=\"gutentor-button-wrap\"><a class=\"gutentor-button gutentor-block-button gutentor-icon-hide\" href=\"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2025\/09\/Vaskenvalajankatu-8-rakennustapaselostus_markkinointi.pdf\" target=\"_blank\" rel=\" noopener noreferrer\"><i class=\"gutentor-button-icon fas fa-book\"><\/i><span>Construction method description<\/span><\/a><\/span><\/div>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div id=\"section-g-7llllls\" class=\"section-g-7llllls gutentor-element gutentor-element-button wp-block-gutentor-e2 gutentor-btn-full-mobile gutentor-btn-custom-desktop gutentor-btn-custom-tablet button-align-left-desktop button-align-left-tablet button-align-center-mobile\"><span class=\"gutentor-button-wrap\"><a class=\"gutentor-button gutentor-block-button gutentor-icon-hide\" href=\"https:\/\/app.kodia.fi\/public\/Porvoon-A-asunnot-Oy---Borg%C3%A5-A-bost%C3%A4der-Ab\/apply\/\" target=\"_blank\" rel=\" noopener noreferrer\"><i class=\"gutentor-button-icon fas fa-book\"><\/i><span>Apply for an apartment<\/span><\/a><\/span><\/div>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div id=\"section-g-amm6z6t\" class=\"section-g-amm6z6t gutentor-element gutentor-element-advanced-text wp-block-gutentor-e1\"><div class=\"gutentor-text-wrap\"><p class=\"gutentor-text\"><\/p><\/div><\/div>\n<\/div><\/section>\n<\/div><\/section>\n\n\n\n<section id=\"g-73q9r77\" class=\"section-g-73q9r77 gutentor-module gutentor-container-cover wp-block-gutentor-m3 alignfull\"><div class=\"grid-container\">\n<section id=\"g-5dyonry\" class=\"section-g-5dyonry gutentor-module gutentor-container-cover wp-block-gutentor-m3\"><div class=\"grid-container\">\n<div id=\"section-g-7hxxf5a\" class=\"section-g-7hxxf5a gutentor-element gutentor-element-advanced-text wp-block-gutentor-e1\"><div class=\"gutentor-text-wrap\"><h2 class=\"gutentor-text\">Opistokuja 1 \u2013 new rental homes close to services<\/h2><\/div><\/div>\n\n\n\n<div id=\"section-g-olowll8\" class=\"section-g-olowll8 gutentor-element gutentor-element-advanced-text wp-block-gutentor-e1\"><div class=\"gutentor-text-wrap\"><p class=\"gutentor-text\"><strong>In the spring of 2027, Porvoon Kodit&#8217;s new state-subsidised rental home project will be completed at Opistokuja in N\u00e4si. Spacious family apartments, communal spaces that make everyday life easier and a comfortable shared yard for the entire block will be built near the centre of Porvoo!<\/strong><br><br>At Opistokuja, you live close to everything! Schools, daycare centres, a grocery store, the Art Factory, and health and medical services can be found just around the corner. There will be a total of 38 homes, in two buildings, and there are options for many life situations \u2013 from compact two-room apartments to more spacious family apartments<br>Residents have access to common areas that make everyday life smoother, such as a house sauna with a comfortable club room, a spacious laundry room with a drying room, and shared remote work and multi-purpose spaces. Glazed balconies bring additional space and comfort to living all year round. The shared courtyard creates safety for children to play and space for life encounters. Electric car charging is possible in all parking spaces.<br><br><strong>The application period starts soon!<\/strong><\/p><\/div><\/div>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1682\" data-id=\"9811\" src=\"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/08\/Porvoon-Asunnot-Opistokuja-1-Julkisivun-havainnekuva-31.7.2026-scaled.jpg\" alt=\"\" class=\"wp-image-9811\" srcset=\"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/08\/Porvoon-Asunnot-Opistokuja-1-Julkisivun-havainnekuva-31.7.2026-scaled.jpg 2560w, https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/08\/Porvoon-Asunnot-Opistokuja-1-Julkisivun-havainnekuva-31.7.2026-300x197.jpg 300w, https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/08\/Porvoon-Asunnot-Opistokuja-1-Julkisivun-havainnekuva-31.7.2026-1024x673.jpg 1024w, https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/08\/Porvoon-Asunnot-Opistokuja-1-Julkisivun-havainnekuva-31.7.2026-768x505.jpg 768w, https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/08\/Porvoon-Asunnot-Opistokuja-1-Julkisivun-havainnekuva-31.7.2026-1536x1009.jpg 1536w, https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/08\/Porvoon-Asunnot-Opistokuja-1-Julkisivun-havainnekuva-31.7.2026-2048x1346.jpg 2048w\" sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1706\" data-id=\"9873\" src=\"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/09\/Porvoon-Asunnot-Opistokuja-1-Asunnon-B35-sisahavainnekuva-31.7.2026-1-scaled.jpg\" alt=\"\" class=\"wp-image-9873\" srcset=\"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/09\/Porvoon-Asunnot-Opistokuja-1-Asunnon-B35-sisahavainnekuva-31.7.2026-1-scaled.jpg 2560w, https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/09\/Porvoon-Asunnot-Opistokuja-1-Asunnon-B35-sisahavainnekuva-31.7.2026-1-300x200.jpg 300w, https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/09\/Porvoon-Asunnot-Opistokuja-1-Asunnon-B35-sisahavainnekuva-31.7.2026-1-1024x682.jpg 1024w, https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/09\/Porvoon-Asunnot-Opistokuja-1-Asunnon-B35-sisahavainnekuva-31.7.2026-1-768x512.jpg 768w, https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/09\/Porvoon-Asunnot-Opistokuja-1-Asunnon-B35-sisahavainnekuva-31.7.2026-1-1536x1024.jpg 1536w, https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/09\/Porvoon-Asunnot-Opistokuja-1-Asunnon-B35-sisahavainnekuva-31.7.2026-1-2048x1365.jpg 2048w\" sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" \/><\/figure>\n<\/figure>\n\n\n\n<section id=\"g-p1awzzs\" class=\"section-g-p1awzzs gutentor-module gutentor-container-cover wp-block-gutentor-m3\"><div class=\"grid-container\">\n<div id=\"section-g-a111071\" class=\"section-g-a111071 gutentor-element gutentor-element-advanced-text wp-block-gutentor-e1\"><div class=\"gutentor-text-wrap\"><p class=\"gutentor-text\"><strong><strong>Apartments<\/strong><\/strong><\/p><\/div><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A total of <strong>38<\/strong> apartments in two buildings (5 and 6 stories)<\/li>\n\n\n\n<li><strong>2 rooms + kitchenette:<\/strong> 11 apartments (43,5 m\u00b2 \u2013 48 m\u00b2)<\/li>\n\n\n\n<li><strong>3 rooms + kitchenette:<\/strong> 18 apartments (61 m\u00b2 \u2013 64 m\u00b2)<\/li>\n\n\n\n<li><strong>4 rooms + kitchenette:<\/strong> 9 apartments (80 m\u00b2 \u2013 80,5 m\u00b2)<\/li>\n<\/ul>\n<\/div><\/section>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Shared facilities, courtyard, and smooth everyday living<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The shared facilities include a building sauna next to the club room, a large laundry room and drying room, as well as plenty of storage for outdoor equipment. Glazed balconies add extra usable space well into autumn. In addition, both buildings have a small shared room that can be rented separately, for example for remote work. Residents of the block also have access to a shared courtyard.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Quality materials and well-designed kitchens<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Every home includes a separate cooker and built-in oven, a dishwasher, and an integrated microwave. The finishing touch is high-quality cabinet materials that stand up to use and look great.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The development is state-subsidized, which means resident selection follows needs-based criteria as well as the applicable income and asset limits.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Interested?<\/strong> Join our mailing list to get notified when the application period begins. We will also announce the start of the application period on this page.<\/p>\n\n\n<style>.efb.d-none{display:none!important;} #teststyleefb{display:none;} .efb-waiting-12 { position: relative; } .efb-waiting-12 * { pointer-events: none; opacity: 0.9; } .efb-waiting-12::after { content: \"\"; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 120px; height: 30px; background: url(\"data:image\/svg+xml,%3Csvg%20viewBox%3D%220%200%20120%2030%22%20height%3D%2215px%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20preserveAspectRatio%3D%22xMidYMid%20meet%22%3E%0A%09%09%09%09%09%09%09%3Ccircle%20cx%3D%2215%22%20cy%3D%2215%22%20r%3D%2215%22%20fill%3D%22%23abb8c3%22%3E%0A%09%09%09%09%09%09%09%09%3Canimate%20attributeName%3D%22r%22%20from%3D%2215%22%20to%3D%229%22%20begin%3D%220s%22%20dur%3D%221s%22%20values%3D%2215%3B9%3B15%22%20calcMode%3D%22linear%22%20repeatCount%3D%22indefinite%22%2F%3E%0A%09%09%09%09%09%09%09%3C%2Fcircle%3E%0A%09%09%09%09%09%09%09%3Ccircle%20cx%3D%2260%22%20cy%3D%2215%22%20r%3D%229%22%20fill%3D%22%23abb8c3%22%3E%0A%09%09%09%09%09%09%09%09%3Canimate%20attributeName%3D%22r%22%20from%3D%229%22%20to%3D%2215%22%20begin%3D%220.3s%22%20dur%3D%221s%22%20values%3D%229%3B15%3B9%22%20calcMode%3D%22linear%22%20repeatCount%3D%22indefinite%22%2F%3E%0A%09%09%09%09%09%09%09%3C%2Fcircle%3E%0A%09%09%09%09%09%09%09%3Ccircle%20cx%3D%22105%22%20cy%3D%2215%22%20r%3D%2215%22%20fill%3D%22%23abb8c3%22%3E%0A%09%09%09%09%09%09%09%09%3Canimate%20attributeName%3D%22r%22%20from%3D%2215%22%20to%3D%229%22%20begin%3D%220.6s%22%20dur%3D%221s%22%20values%3D%2215%3B9%3B15%22%20calcMode%3D%22linear%22%20repeatCount%3D%22indefinite%22%2F%3E%0A%09%09%09%09%09%09%09%3C%2Fcircle%3E%0A%09%09%09%09%09%09%3C%2Fsvg%3E\") no-repeat center center; background-size: contain; z-index: 9999; } .btn-colorDEfb-f66900 { background-color: #f66900 !important; }<\/style><div class=\"efb d-none\"><script>window.efb_loading_ui_12 = \"<svg viewBox=\\\"0 0 120 30\\\" height=\\\"15px\\\" xmlns=\\\"http:\\\/\\\/www.w3.org\\\/2000\\\/svg\\\" preserveAspectRatio=\\\"xMidYMid meet\\\">\\n\\t\\t\\t\\t\\t\\t\\t<circle cx=\\\"15\\\" cy=\\\"15\\\" r=\\\"15\\\" fill=\\\"#abb8c3\\\">\\n\\t\\t\\t\\t\\t\\t\\t\\t<animate attributeName=\\\"r\\\" from=\\\"15\\\" to=\\\"9\\\" begin=\\\"0s\\\" dur=\\\"1s\\\" values=\\\"15;9;15\\\" calcMode=\\\"linear\\\" repeatCount=\\\"indefinite\\\"\\\/>\\n\\t\\t\\t\\t\\t\\t\\t<\\\/circle>\\n\\t\\t\\t\\t\\t\\t\\t<circle cx=\\\"60\\\" cy=\\\"15\\\" r=\\\"9\\\" fill=\\\"#abb8c3\\\">\\n\\t\\t\\t\\t\\t\\t\\t\\t<animate attributeName=\\\"r\\\" from=\\\"9\\\" to=\\\"15\\\" begin=\\\"0.3s\\\" dur=\\\"1s\\\" values=\\\"9;15;9\\\" calcMode=\\\"linear\\\" repeatCount=\\\"indefinite\\\"\\\/>\\n\\t\\t\\t\\t\\t\\t\\t<\\\/circle>\\n\\t\\t\\t\\t\\t\\t\\t<circle cx=\\\"105\\\" cy=\\\"15\\\" r=\\\"15\\\" fill=\\\"#abb8c3\\\">\\n\\t\\t\\t\\t\\t\\t\\t\\t<animate attributeName=\\\"r\\\" from=\\\"15\\\" to=\\\"9\\\" begin=\\\"0.6s\\\" dur=\\\"1s\\\" values=\\\"15;9;15\\\" calcMode=\\\"linear\\\" repeatCount=\\\"indefinite\\\"\\\/>\\n\\t\\t\\t\\t\\t\\t\\t<\\\/circle>\\n\\t\\t\\t\\t\\t\\t<\\\/svg>\";<\/script><\/div><div class=\"efb d-none\"><script>\n\t(function() {\n\t\t\"use strict\";\nconst EFB_ERROR_PANEL = {\n\t\t\terrors: [],\n\t\t\terrorKeys: new Set(),\n\t\t\tvisibleErrorKeys: new Set(),\n\t\t\tisOpen: false,\n\t\t\tpanel: null,\n\t\t\tbadge: null,\n\t\t\tinlineTargetFormId: null,\n\t\t\tstorageKey: \"efb_error_panel_dismissed_v1\",\n\t\t\tdismissedKeys: new Set(),\nt: {\"title\":\"Error Monitor\",\"plugin\":\"Plugin\",\"theme\":\"Theme\",\"wpCore\":\"WordPress Core\",\"external\":\"External\",\"unknown\":\"Unknown\",\"notice\":\"Notice\",\"line\":\"Line\",\"file\":\"File\",\"dismiss\":\"Dismiss\",\"dismissAll\":\"Dismiss All\",\"dismissItem\":\"Dismiss %s\",\"noErrors\":\"No errors detected\",\"warning\":\"These errors may interfere with forms built using Easy Form Builder.\",\"adminOnly\":\"This panel is only visible to site administrators.\",\"easyformbuilder\":\"Easy Form Builder\",\"warningBadge\":\"Warning\",\"jqueryMissing\":\"jQuery Dependency Issue\",\"jqueryMessage\":\"jQuery is not properly loaded or available. AJAX and interactive form features may not work correctly.\"},\nloadDismissedKeys() {\n\t\t\t\ttry {\n\t\t\t\t\tconst raw = window.localStorage.getItem(this.storageKey);\n\t\t\t\t\tif (!raw) return;\n\t\t\t\t\tconst parsed = JSON.parse(raw);\n\t\t\t\t\tconst keys = Array.isArray(parsed) ? parsed : (Array.isArray(parsed.keys) ? parsed.keys : []);\n\t\t\t\t\tthis.dismissedKeys = new Set(keys.filter(Boolean));\n\t\t\t\t} catch(e) {\n\t\t\t\t\tthis.dismissedKeys = new Set();\n\t\t\t\t}\n\t\t\t},\nsaveDismissedKeys() {\n\t\t\t\ttry {\n\t\t\t\t\twindow.localStorage.setItem(this.storageKey, JSON.stringify({ keys: Array.from(this.dismissedKeys) }));\n\t\t\t\t} catch(e) {}\n\t\t\t},\nparseSource(source) {\n\t\t\t\tif (!source) return { type: \"unknown\", name: this.t.unknown, file: \"\", fullPath: \"\" };\nlet file = \"\";\n\t\t\t\tlet fullPath = \"\";\n\t\t\t\ttry {\n\t\t\t\t\tconst url = new URL(source);\n\t\t\t\t\tconst pathname = url.pathname;\n\t\t\t\t\tconst wpContentIdx = pathname.indexOf(\"\/wp-content\/\");\n\t\t\t\t\tif (wpContentIdx !== -1) {\n\t\t\t\t\t\tfullPath = pathname.substring(wpContentIdx + 1); \/\/ Remove leading slash\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfullPath = pathname.split(\"\/\").slice(-4).join(\"\/\");\n\t\t\t\t\t}\n\t\t\t\t\tfile = pathname.split(\"\/\").slice(-2).join(\"\/\");\n\t\t\t\t} catch(e) {\n\t\t\t\t\tconst wpContentIdx = source.indexOf(\"\/wp-content\/\");\n\t\t\t\t\tif (wpContentIdx !== -1) {\n\t\t\t\t\t\tfullPath = source.substring(wpContentIdx + 1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfullPath = source.split(\"\/\").slice(-4).join(\"\/\");\n\t\t\t\t\t}\n\t\t\t\t\tfile = source.split(\"\/\").slice(-2).join(\"\/\");\n\t\t\t\t}\nconst pluginMatch = source.match(\/wp-content\\\/plugins\\\/([^\\\/]+)\/);\n\t\t\t\tif (pluginMatch) {\n\t\t\t\t\tconst name = pluginMatch[1].replace(\/-\/g, \" \").replace(\/\\b\\w\/g, c => c.toUpperCase());\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: \"plugin\",\n\t\t\t\t\t\tslug: pluginMatch[1],\n\t\t\t\t\t\tname: name,\n\t\t\t\t\t\tfile: file,\n\t\t\t\t\t\tfullPath: fullPath,\n\t\t\t\t\t\tisEFB: pluginMatch[1].includes(\"easy-form\")\n\t\t\t\t\t};\n\t\t\t\t}\nconst themeMatch = source.match(\/wp-content\\\/themes\\\/([^\\\/]+)\/);\n\t\t\t\tif (themeMatch) {\n\t\t\t\t\tconst name = themeMatch[1].replace(\/-\/g, \" \").replace(\/\\b\\w\/g, c => c.toUpperCase());\n\t\t\t\t\treturn { type: \"theme\", slug: themeMatch[1], name: name, file: file, fullPath: fullPath, isEFB: false };\n\t\t\t\t}\nif (source.match(\/wp-(includes|admin)\/)) {\n\t\t\t\t\treturn { type: \"wpCore\", name: this.t.wpCore, file: file, fullPath: fullPath, isEFB: false };\n\t\t\t\t}\nif (source.startsWith(\"http\")) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst url = new URL(source);\n\t\t\t\t\t\tif (!source.includes(window.location.hostname)) {\n\t\t\t\t\t\t\treturn { type: \"external\", name: url.hostname, file: file, fullPath: source, isEFB: false };\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch(e) {}\n\t\t\t\t}\nreturn { type: \"unknown\", name: this.t.unknown, file: file, fullPath: fullPath || source, isEFB: false };\n\t\t\t},\ncreateUI() {\n\t\t\t\tthis.badge = document.createElement(\"div\");\n\t\t\t\tthis.badge.id = \"efb-error-badge\";\n\t\t\t\tthis.badge.innerHTML = `\n\t\t\t\t\t<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\">\n\t\t\t\t\t\t<path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"\/>\n\t\t\t\t\t\t<line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"\/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"\/>\n\t\t\t\t\t<\\\/svg>\n\t\t\t\t\t<span class=\"efb-error-label\">${this.t.warningBadge}<\\\/span>\n\t\t\t\t\t<svg class=\"efb-badge-chevron\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n\t\t\t\t\t\t<path fill-rule=\"evenodd\" d=\"M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708\"\/>\n\t\t\t\t\t<\\\/svg>\n\t\t\t\t\t<!-- <span class=\"efb-badge-tooltip\">${this.t.adminOnly}<\\\/span>-->\n\t\t\t\t`;\n\t\t\t\tconst isRtl = document.documentElement.dir === \"rtl\" || document.body.dir === \"rtl\" || getComputedStyle(document.documentElement).direction === \"rtl\";\n\t\t\t\tthis.isRtl = isRtl;\n\t\t\t\tthis.badge.style.cssText = `\n\t\t\t\t\tall: initial !important;\n\t\t\t\t\tposition: relative !important;\n\t\t\t\t\tz-index: auto !important;\n\t\t\t\t\tbackground: #dc3545 !important;\n\t\t\t\t\tcolor: #fff !important; padding: 12px 18px !important; border-radius: 50px !important;\n\t\t\t\t\tcursor: pointer !important; display: inline-flex !important; align-items: center !important; justify-content: center !important; gap: 10px !important;\n\t\t\t\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif !important;\n\t\t\t\t\tfont-size: 13px !important; font-weight: 600 !important;\n\t\t\t\t\tbox-shadow: 0 4px 15px rgba(220,53,69,0.4) !important;\n\t\t\t\t\topacity: 0 !important; pointer-events: none !important; visibility: hidden !important;\n\t\t\t\t\tdirection: ltr !important; box-sizing: border-box !important;\n\t\t\t\t\tline-height: normal !important; text-transform: none !important;\n\t\t\t\t\ttext-decoration: none !important; letter-spacing: normal !important;\n\t\t\t\t\tmargin: 0 !important; float: none !important; border: none !important;\n\t\t\t\t\tmin-height: 0 !important; max-height: none !important;\n\t\t\t\t\tmin-width: 0 !important; height: auto !important; width: auto !important;\n\t\t\t\t\toverflow: visible !important;\n\t\t\t\t`;\n\t\t\t\tthis.badge.setAttribute(\"role\", \"status\");\n\t\t\t\tthis.badge.setAttribute(\"aria-live\", \"polite\");\n\t\t\t\tthis.badge.onclick = () => this.togglePanel();\n\t\t\t\tdocument.body.appendChild(this.badge);\nthis.panel = document.createElement(\"div\");\n\t\t\t\tthis.panel.id = \"efb-error-panel\";\n\t\t\t\tthis.panel.innerHTML = `\n\t\t\t\t\t<div class=\"efb-panel-header\">\n\t\t\t\t\t\t<div class=\"efb-panel-title\">\n\t\t\t\t\t\t\t<span>${this.t.easyformbuilder} - ${this.t.title}<\\\/span>\n\t\t\t\t\t\t<\\\/div>\n\t\t\t\t\t\t<div class=\"efb-panel-actions\">\n\t\t\t\t\t\t\t<button class=\"efb-btn-clear\" onclick=\"EFB_ERROR_PANEL.dismissAll()\">${this.t.dismissAll}<\\\/button>\n\t\t\t\t\t\t\t<button class=\"efb-btn-close\" onclick=\"EFB_ERROR_PANEL.togglePanel()\">\u00d7<\\\/button>\n\t\t\t\t\t\t<\\\/div>\n\t\t\t\t\t<\\\/div>\n<div class=\"efb-panel-warning\">\n\t\t\t\t\t\t<span>${this.t.warning}<\\\/span>\n\t\t\t\t\t<\\\/div>\n\t\t\t\t\t<div class=\"efb-admin-notice\">\n\t\t\t\t\t\t<!-- <span>${this.t.adminOnly}<\\\/span> -->\n\t\t\t\t\t\t<span class=\"efb-admin-badge\">ADMIN<\\\/span>\n\t\t\t\t\t<\\\/div>\n\t\t\t\t\t<div class=\"efb-panel-body\" id=\"efb-error-list\">\n\t\t\t\t\t\t<div class=\"efb-no-errors\">\u2713 ${this.t.noErrors}<\\\/div>\n\t\t\t\t\t<\\\/div>\n\t\t\t\t\t<div class=\"efb-panel-footer\">\n\t\t\t\t\t\t<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n\t\t\t\t\t\t\t<path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"\/>\n\t\t\t\t\t\t<\\\/svg>\n\t\t\t\t\t\t<!-- <span>${this.t.adminOnly}<\\\/span> -->\n\t\t\t\t\t<\\\/div>\n\t\t\t\t`;\n\t\t\t\tthis.panel.style.cssText = `\n\t\t\t\t\tposition: fixed !important; top: 50% !important; left: 50% !important; transform: translate(-50%, -50%) scale(0.9) !important;\n\t\t\t\t\tz-index: 1000000 !important; width: 92% !important; max-width: 520px !important; max-height: 80vh !important;\n\t\t\t\t\tbackground: #fff !important; border-radius: 16px !important; box-shadow: 0 25px 80px rgba(0,0,0,0.4) !important;\n\t\t\t\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif !important;\n\t\t\t\t\tdisplay: none !important; opacity: 0 !important; transition: all 0.3s ease !important; overflow: hidden !important;\n\t\t\t\t`;\n\t\t\t\tdocument.body.appendChild(this.panel);\nthis.overlay = document.createElement(\"div\");\n\t\t\t\tthis.overlay.id = \"efb-error-overlay\";\n\t\t\t\tthis.overlay.style.cssText = `\n\t\t\t\t\tposition: fixed; top: 0; left: 0; right: 0; bottom: 0;\n\t\t\t\t\tbackground: rgba(0,0,0,0.6); z-index: 999998; backdrop-filter: blur(2px);\n\t\t\t\t\tdisplay: none; opacity: 0; transition: opacity 0.3s ease;\n\t\t\t\t`;\n\t\t\t\tthis.overlay.onclick = () => this.togglePanel();\n\t\t\t\tdocument.body.appendChild(this.overlay);\nconst style = document.createElement(\"style\");\n\t\t\t\tstyle.textContent = `\n\t\t\t\t\t@keyframes efb-badge-pulse {\n\t\t\t\t\t\t0% { transform: scale(1); opacity: 0.5; }\n\t\t\t\t\t\t100% { transform: scale(1.6); opacity: 0; }\n\t\t\t\t\t}\n\t\t\t\t\t@keyframes efb-count-pop {\n\t\t\t\t\t\t0% { transform: scale(1); }\n\t\t\t\t\t\t50% { transform: scale(1.3); }\n\t\t\t\t\t\t100% { transform: scale(1); }\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-badge:hover {\n\t\t\t\t\t\tbackground: #c82333 !important;\n\t\t\t\t\t\tbox-shadow: 0 6px 25px rgba(220,53,69,0.5) !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-badge svg,\n\t\t\t\t\t#efb-error-badge span:not(.efb-badge-tooltip) {\n\t\t\t\t\t\tall: initial !important;\n\t\t\t\t\t\tfont-family: inherit !important; color: inherit !important;\n\t\t\t\t\t\tline-height: normal !important; display: inline-block !important;\n\t\t\t\t\t\tbox-sizing: border-box !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-badge svg {\n\t\t\t\t\t\twidth: 18px !important; height: 18px !important;\n\t\t\t\t\t\tfill: none !important; stroke: currentColor !important; stroke-width: 2.5 !important;\n\t\t\t\t\t\tvertical-align: middle !important; flex-shrink: 0 !important;\n\t\t\t\t\t\toverflow: visible !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-badge .efb-error-label {\n\t\t\t\t\t\tfont-size: 13px !important; font-weight: 600 !important;\n\t\t\t\t\t\tcolor: #fff !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-badge .efb-badge-chevron {\n\t\t\t\t\t\twidth: 16px !important; height: 16px !important;\n\t\t\t\t\t\tcolor: #fff !important; opacity: 0.9 !important;\n\t\t\t\t\t\ttransition: transform 0.2s ease, opacity 0.2s ease !important;\n\t\t\t\t\t\tflex-shrink: 0 !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-badge:hover .efb-badge-chevron { opacity: 1 !important; transform: translateY(1px) !important; }\n\t\t\t\t\t#efb-error-badge.is-open .efb-badge-chevron { transform: rotate(180deg) !important; }\n\t\t\t\t\t#efb-error-badge::before,\n\t\t\t\t\t#efb-error-badge::after {\n\t\t\t\t\t\tcontent: \"\" !important; position: absolute !important; inset: -2px !important;\n\t\t\t\t\t\tborder-radius: 50px !important; z-index: -1 !important;\n\t\t\t\t\t\tborder: 1.5px solid rgba(220,53,69,0.4) !important;\n\t\t\t\t\t\tanimation: efb-badge-pulse 2.5s ease-out infinite !important;\n\t\t\t\t\t\tpointer-events: none !important; box-sizing: border-box !important;\n\t\t\t\t\t\tbackground: transparent !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-badge::after {\n\t\t\t\t\t\tanimation-delay: 1.25s !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-badge .efb-badge-tooltip {\n\t\t\t\t\t\tall: initial !important;\n\t\t\t\t\t\tdisplay: none !important;\n\t\t\t\t\t\tposition: absolute !important; top: 50% !important; ${isRtl ? \"right\" : \"left\"}: calc(100% + 12px) !important;\n\t\t\t\t\t\ttransform: translateY(-50%) translateX(${isRtl ? \"8px\" : \"-8px\"}) !important;\n\t\t\t\t\t\twhite-space: nowrap !important;\n\t\t\t\t\t\tbackground: linear-gradient(135deg, #890000, #000014) !important;\n\t\t\t\t\t\tcolor: #e2e8f0 !important; padding: 8px 14px !important; border-radius: 8px !important;\n\t\t\t\t\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif !important;\n\t\t\t\t\t\tfont-size: 12px !important; font-weight: 500 !important; letter-spacing: 0.2px !important;\n\t\t\t\t\t\tbox-shadow: 0 4px 15px rgba(0,0,0,0.3) !important;\n\t\t\t\t\t\topacity: 0 !important; pointer-events: none !important;\n\t\t\t\t\t\ttransition: opacity 0.25s ease, transform 0.25s ease !important;\n\t\t\t\t\t\tbox-sizing: border-box !important; line-height: normal !important;\n\t\t\t\t\t\tdisplay: none !important; z-index: 1000000 !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-badge .efb-badge-tooltip::before {\n\t\t\t\t\t\tcontent: \"\" !important; position: absolute !important; top: 50% !important; ${isRtl ? \"left\" : \"right\"}: 100% !important;\n\t\t\t\t\t\ttransform: translateY(-50%) !important;\n\t\t\t\t\t\tborder: 6px solid transparent !important;\n\t\t\t\t\t\tborder-${isRtl ? \"left\" : \"right\"}-color: #1e1e2e !important;\n\t\t\t\t\t\t${isRtl ? \"border-right: none\" : \"border-left: none\"} !important;\n\t\t\t\t\t\tdisplay: block !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-badge:hover .efb-badge-tooltip {\n\t\t\t\t\t\topacity: 1 !important; pointer-events: auto !important;\n\t\t\t\t\t\ttransform: translateY(-50%) translateX(0) !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel,\n\t\t\t\t\t#efb-error-panel *,\n\t\t\t\t\t#efb-error-panel *::before,\n\t\t\t\t\t#efb-error-panel *::after {\n\t\t\t\t\t\tall: revert !important;\n\t\t\t\t\t\tbox-sizing: border-box !important;\n\t\t\t\t\t\tmargin: 0 !important;\n\t\t\t\t\t\tpadding: 0 !important;\n\t\t\t\t\t\tborder: none !important;\n\t\t\t\t\t\tfloat: none !important;\n\t\t\t\t\t\tmin-height: 0 !important;\n\t\t\t\t\t\tmax-height: none !important;\n\t\t\t\t\t\tmin-width: 0 !important;\n\t\t\t\t\t\theight: auto !important;\n\t\t\t\t\t\twidth: auto !important;\n\t\t\t\t\t\tline-height: normal !important;\n\t\t\t\t\t\tletter-spacing: normal !important;\n\t\t\t\t\t\ttext-transform: none !important;\n\t\t\t\t\t\ttext-decoration: none !important;\n\t\t\t\t\t\ttext-indent: 0 !important;\n\t\t\t\t\t\ttext-align: start !important;\n\t\t\t\t\t\tvertical-align: baseline !important;\n\t\t\t\t\t\twhite-space: normal !important;\n\t\t\t\t\t\tword-spacing: normal !important;\n\t\t\t\t\t\tbackground: transparent !important;\n\t\t\t\t\t\tcolor: inherit !important;\n\t\t\t\t\t\tfont: inherit !important;\n\t\t\t\t\t\tlist-style: none !important;\n\t\t\t\t\t\toutline: none !important;\n\t\t\t\t\t\toverflow: visible !important;\n\t\t\t\t\t\tposition: static !important;\n\t\t\t\t\t\ttransform: none !important;\n\t\t\t\t\t\ttransition: none !important;\n\t\t\t\t\t\tanimation: none !important;\n\t\t\t\t\t\tvisibility: visible !important;\n\t\t\t\t\t\topacity: 1 !important;\n\t\t\t\t\t\tz-index: auto !important;\n\t\t\t\t\t\tdisplay: block !important;\n\t\t\t\t\t\tflex: none !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel {\n\t\t\t\t\t\tposition: fixed !important; top: 50% !important; left: 50% !important;\n\t\t\t\t\t\tz-index: 1000000 !important; width: 92% !important; max-width: 520px !important; max-height: 80vh !important;\n\t\t\t\t\t\tbackground: #fff !important; border-radius: 16px !important; box-shadow: 0 25px 80px rgba(0,0,0,0.4) !important;\n\t\t\t\t\t\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif !important;\n\t\t\t\t\t\toverflow: hidden !important; font-size: 14px !important; color: #333 !important;\n\t\t\t\t\t\tline-height: 1.5 !important;\n\t\t\t\t\t\tdirection: ${isRtl ? \"rtl\" : \"ltr\"} !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel svg {\n\t\t\t\t\t\tdisplay: inline-block !important; vertical-align: middle !important;\n\t\t\t\t\t\theight: auto !important; width: auto !important; overflow: visible !important;\n\t\t\t\t\t\tfill: none !important; stroke: currentColor !important; stroke-width: 2 !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel img {\n\t\t\t\t\t\tmax-width: 100% !important; height: auto !important; max-height: 150px !important;\n\t\t\t\t\t\tdisplay: inline-block !important; object-fit: contain !important; border: none !important;\n\t\t\t\t\t\tmargin: 0 !important; padding: 0 !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-panel-header {\n\t\t\t\t\t\tbackground: linear-gradient(135deg, #dc3545, #410404) !important;\n\t\t\t\t\t\tcolor: #fff !important; padding: 16px 20px !important;\n\t\t\t\t\t\tdisplay: flex !important; justify-content: space-between !important; align-items: center !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-panel-title { display: flex !important; align-items: center !important; gap: 10px !important; font-weight: 600 !important; font-size: 15px !important; color: #fff !important; }\n\t\t\t\t\t#efb-error-panel .efb-panel-title svg { color: #fff !important; }\n\t\t\t\t\t#efb-error-panel .efb-panel-actions { display: flex !important; gap: 8px !important; align-items: center !important; }\n\t\t\t\t\t#efb-error-panel .efb-btn-clear {\n\t\t\t\t\t\tbackground: rgba(255,255,255,0.2) !important; border: none !important; color: #fff !important;\n\t\t\t\t\t\tpadding: 6px 12px !important; border-radius: 6px !important; cursor: pointer !important; font-size: 12px !important;\n\t\t\t\t\t\ttransition: background 0.2s !important; display: inline-block !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-btn-clear:hover { background: rgba(255,255,255,0.3) !important; }\n\t\t\t\t\t#efb-error-panel .efb-btn-close {\n\t\t\t\t\t\tbackground: none !important; border: none !important; color: #fff !important; font-size: 26px !important;\n\t\t\t\t\t\tcursor: pointer !important; line-height: 1 !important; padding: 0 4px !important; opacity: 0.8 !important;\n\t\t\t\t\t\ttransition: opacity 0.2s !important; display: inline-block !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-btn-close:hover { opacity: 1 !important; }\n\t\t\t\t\t#efb-error-panel .efb-panel-warning {\n\t\t\t\t\t\tbackground: #fff8e6 !important; border-bottom: 1px solid #ffe0a0 !important;\n\t\t\t\t\t\tpadding: 12px 16px !important; display: flex !important; align-items: center !important; gap: 10px !important;\n\t\t\t\t\t\tcolor: #8a6d3b !important; font-size: 13px !important; line-height: 1.4 !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-panel-warning svg { flex-shrink: 0 !important; color: #f0ad4e !important; }\n\t\t\t\t\t#efb-error-panel .efb-admin-notice {\n\t\t\t\t\t\tbackground: linear-gradient(135deg, #e8f4fd 0%, #d1e9ff 100%) !important;\n\t\t\t\t\t\tborder-bottom: 1px solid #b8daff !important;\n\t\t\t\t\t\tpadding: 10px 16px !important; display: flex !important; align-items: center !important; gap: 10px !important;\n\t\t\t\t\t\tcolor: #004085 !important; font-size: 12px !important; line-height: 1.4 !important;\n\t\t\t\t\t\tposition: relative !important; overflow: hidden !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-admin-notice::before {\n\t\t\t\t\t\tcontent: \"\" !important; position: absolute !important; top: 0 !important; left: 0 !important; right: 0 !important; height: 2px !important;\n\t\t\t\t\t\tbackground: linear-gradient(90deg, #007bff, #00d4ff, #007bff) !important;\n\t\t\t\t\t\tbackground-size: 200% 100% !important;\n\t\t\t\t\t\tanimation: efb-admin-shine 2s linear infinite !important;\n\t\t\t\t\t\tdisplay: block !important; padding: 0 !important; margin: 0 !important;\n\t\t\t\t\t}\n\t\t\t\t\t@keyframes efb-admin-shine {\n\t\t\t\t\t\t0% { background-position: 200% 0; }\n\t\t\t\t\t\t100% { background-position: -200% 0; }\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-admin-notice svg { flex-shrink: 0 !important; color: #007bff !important; }\n\t\t\t\t\t#efb-error-panel .efb-admin-notice span:not(.efb-admin-badge) { flex: 1 !important; display: inline !important; }\n\t\t\t\t\t#efb-error-panel .efb-admin-badge {\n\t\t\t\t\t\tbackground: linear-gradient(135deg, #007bff, #0056b3) !important;\n\t\t\t\t\t\tcolor: #fff !important; font-size: 9px !important; font-weight: 700 !important;\n\t\t\t\t\t\tpadding: 4px 10px !important; border-radius: 20px !important;\n\t\t\t\t\t\ttext-transform: uppercase !important; letter-spacing: 1px !important;\n\t\t\t\t\t\tbox-shadow: 0 2px 8px rgba(0,123,255,0.3) !important;\n\t\t\t\t\t\tanimation: efb-badge-glow 2s ease-in-out infinite !important;\n\t\t\t\t\t\tdisplay: inline-block !important;\n\t\t\t\t\t}\n\t\t\t\t\t@keyframes efb-badge-glow {\n\t\t\t\t\t\t0%, 100% { box-shadow: 0 2px 8px rgba(0,123,255,0.3); }\n\t\t\t\t\t\t50% { box-shadow: 0 2px 15px rgba(0,123,255,0.6); }\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-panel-body { max-height: 45vh !important; overflow-y: auto !important; padding: 16px !important; }\n\t\t\t\t\t#efb-error-panel .efb-panel-footer {\n\t\t\t\t\t\tbackground: #f8f9fa !important; border-top: 1px solid #e9ecef !important;\n\t\t\t\t\t\tpadding: 10px 16px !important; display: flex !important; align-items: center !important; gap: 8px !important;\n\t\t\t\t\t\tcolor: #6c757d !important; font-size: 11px !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-panel-footer svg { opacity: 0.6 !important; color: #6c757d !important; }\n\t\t\t\t\t#efb-error-panel .efb-no-errors {\n\t\t\t\t\t\ttext-align: center !important; color: #28a745 !important; padding: 40px 20px !important;\n\t\t\t\t\t\tfont-size: 15px !important; font-weight: 500 !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-error-item {\n\t\t\t\t\t\tbackground: #f8f9fa !important; border-radius: 10px !important; padding: 14px !important;\n\t\t\t\t\t\tmargin-bottom: 12px !important; border-${isRtl ? \"right\" : \"left\"}: 4px solid #dc3545 !important;\n\t\t\t\t\t\ttransition: transform 0.2s, box-shadow 0.2s !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-error-item:hover { transform: translateX(${isRtl ? \"-2px\" : \"2px\"}) !important; box-shadow: 0 2px 8px rgba(0,0,0,0.08) !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-item:last-child { margin-bottom: 0 !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-item.is-efb { border-${isRtl ? \"right\" : \"left\"}-color: #ff4b93 !important; background: #fff5f8 !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-item.is-theme { border-${isRtl ? \"right\" : \"left\"}-color: #28a745 !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-item.is-core { border-${isRtl ? \"right\" : \"left\"}-color: #007bff !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-item.is-external { border-${isRtl ? \"right\" : \"left\"}-color: #6c757d !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-source {\n\t\t\t\t\t\tdisplay: flex !important; align-items: center !important; gap: 8px !important;\n\t\t\t\t\t\tfont-weight: 600 !important; font-size: 14px !important; margin-bottom: 8px !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-error-source-name { flex: 1 !important; min-width: 0 !important; display: inline-block !important; }\n\t\t\t\t\t#efb-error-panel .efb-btn-dismiss {\n\t\t\t\t\t\tbackground: #fff !important; border: 1px solid #dee2e6 !important; color: #495057 !important;\n\t\t\t\t\t\tpadding: 4px 9px !important; border-radius: 6px !important; cursor: pointer !important;\n\t\t\t\t\t\tfont-size: 11px !important; font-weight: 600 !important; line-height: 1.2 !important;\n\t\t\t\t\t\tmargin-${isRtl ? \"right\" : \"left\"}: auto !important; display: inline-block !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-btn-dismiss:hover {\n\t\t\t\t\t\tbackground: #f1f3f5 !important; color: #212529 !important; border-color: #ced4da !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-error-source .type-badge {\n\t\t\t\t\t\tfont-size: 9px !important; padding: 3px 8px !important; border-radius: 4px !important;\n\t\t\t\t\t\ttext-transform: uppercase !important; font-weight: 700 !important; letter-spacing: 0.5px !important;\n\t\t\t\t\t\tdisplay: inline-block !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-error-source .type-plugin { background: #fff3cd !important; color: #856404 !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-source .type-theme { background: #d4edda !important; color: #155724 !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-source .type-wpCore { background: #cce5ff !important; color: #004085 !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-source .type-external { background: #e2e3e5 !important; color: #383d41 !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-source .type-unknown { background: #f5c6cb !important; color: #721c24 !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-source .type-notice { background: #fff3cd !important; color: #664d03 !important; border: 1px solid #ffecb5 !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-msg { color: #333 !important; font-size: 13px !important; line-height: 1.5 !important; word-break: break-word !important; margin-bottom: 8px !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-msg a { color: #0d6efd !important; text-decoration: underline !important; font-weight: 600 !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-msg strong { font-weight: 700 !important; color: #1f2937 !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-msg img { max-width: 100% !important; height: auto !important; max-height: 14px !important; display: inline-block !important; object-fit: contain !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-file {\n\t\t\t\t\t\tbackground: #1e1e2e !important; padding: 8px 12px !important; border-radius: 6px !important;\n\t\t\t\t\t\tfont-family: \"SF Mono\", Monaco, Consolas, monospace !important;\n\t\t\t\t\t\tfont-size: 11px !important; color: #a6e3a1 !important; word-break: break-all !important;\n\t\t\t\t\t\tdisplay: flex !important; align-items: flex-start !important; gap: 8px !important;\n\t\t\t\t\t\tline-height: 1.5 !important; direction: ltr !important; text-align: left !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-error-file svg { flex-shrink: 0 !important; opacity: 0.7 !important; margin-top: 2px !important; color: #89b4fa !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-file .efb-full-path { color: #cdd6f4 !important; display: inline !important; }\n\t\t\t\t\t#efb-error-panel .efb-stack-trace {\n\t\t\t\t\t\tmargin-top: 10px !important; background: #1e1e2e !important; border-radius: 8px !important;\n\t\t\t\t\t\toverflow: hidden !important; border: 1px solid #313244 !important; direction: ltr !important; text-align: left !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-stack-title {\n\t\t\t\t\t\tbackground: #313244 !important; color: #cdd6f4 !important; padding: 8px 12px !important;\n\t\t\t\t\t\tfont-size: 11px !important; font-weight: 600 !important; display: flex !important; align-items: center !important; gap: 6px !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-stack-title svg { color: #89b4fa !important; }\n\t\t\t\t\t#efb-error-panel .efb-stack-items { padding: 8px 0 !important; }\n\t\t\t\t\t#efb-error-panel .efb-stack-item {\n\t\t\t\t\t\tdisplay: flex !important; align-items: flex-start !important; gap: 10px !important; padding: 6px 12px !important;\n\t\t\t\t\t\tfont-family: \"SF Mono\", Monaco, Consolas, monospace !important; font-size: 11px !important;\n\t\t\t\t\t\ttransition: background 0.15s !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-stack-item:hover { background: #313244 !important; }\n\t\t\t\t\t#efb-error-panel .efb-stack-item.is-efb { background: rgba(255,75,147,0.1) !important; }\n\t\t\t\t\t#efb-error-panel .efb-stack-item.is-efb:hover { background: rgba(255,75,147,0.2) !important; }\n\t\t\t\t\t#efb-error-panel .efb-stack-num {\n\t\t\t\t\t\tcolor: #6c7086 !important; min-width: 18px !important; text-align: ${isRtl ? \"left\" : \"right\"} !important;\n\t\t\t\t\t\tfont-size: 10px !important; padding-top: 2px !important; display: inline-block !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-stack-content { flex: 1 !important; min-width: 0 !important; }\n\t\t\t\t\t#efb-error-panel .efb-stack-func { color: #f9e2af !important; display: block !important; margin-bottom: 2px !important; }\n\t\t\t\t\t#efb-error-panel .efb-stack-loc { display: flex !important; flex-wrap: wrap !important; gap: 6px !important; align-items: center !important; height: auto !important; min-height: 0 !important; max-height: none !important; }\n\t\t\t\t\t#efb-error-panel .efb-stack-source {\n\t\t\t\t\t\tfont-size: 9px !important; padding: 2px 6px !important; border-radius: 3px !important;\n\t\t\t\t\t\ttext-transform: uppercase !important; font-weight: 600 !important; display: inline-block !important;\n\t\t\t\t\t}\n\t\t\t\t\t#efb-error-panel .efb-stack-source.plugin { background: #fff3cd !important; color: #856404 !important; }\n\t\t\t\t\t#efb-error-panel .efb-stack-source.theme { background: #d4edda !important; color: #155724 !important; }\n\t\t\t\t\t#efb-error-panel .efb-stack-source.wpCore { background: #cce5ff !important; color: #004085 !important; }\n\t\t\t\t\t#efb-error-panel .efb-stack-source.external { background: #e2e3e5 !important; color: #383d41 !important; }\n\t\t\t\t\t#efb-error-panel .efb-stack-source.unknown { background: #f5c6cb !important; color: #721c24 !important; }\n\t\t\t\t\t#efb-error-panel .efb-stack-path { color: #a6adc8 !important; word-break: break-all !important; display: inline !important; }\n\t\t\t\t\t#efb-error-panel .efb-error-meta { color: #6c757d !important; font-size: 11px !important; margin-top: 8px !important; }\n\t\t\t\t`;\n\t\t\t\tdocument.head.appendChild(style);\n\t\t\t},\ntogglePanel() {\n\t\t\t\tthis.isOpen = !this.isOpen;\n\t\t\t\tif (this.isOpen) {\n\t\t\t\t\tif (this.badge) this.badge.classList.add(\"is-open\");\n\t\t\t\t\tthis.panel.style.setProperty(\"display\", \"block\", \"important\");\n\t\t\t\t\tthis.overlay.style.display = \"block\";\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis.panel.style.setProperty(\"opacity\", \"1\", \"important\");\n\t\t\t\t\t\tthis.panel.style.setProperty(\"transform\", \"translate(-50%, -50%) scale(1)\", \"important\");\n\t\t\t\t\t\tthis.overlay.style.opacity = \"1\";\n\t\t\t\t\t}, 10);\n\t\t\t\t} else {\n\t\t\t\t\tif (this.badge) this.badge.classList.remove(\"is-open\");\n\t\t\t\t\tthis.panel.style.setProperty(\"opacity\", \"0\", \"important\");\n\t\t\t\t\tthis.panel.style.setProperty(\"transform\", \"translate(-50%, -50%) scale(0.9)\", \"important\");\n\t\t\t\t\tthis.overlay.style.opacity = \"0\";\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis.panel.style.setProperty(\"display\", \"none\", \"important\");\n\t\t\t\t\t\tthis.overlay.style.display = \"none\";\n\t\t\t\t\t}, 300);\n\t\t\t\t}\n\t\t\t},\ngetInlineTarget(formId) {\n\t\t\t\tconst id = formId !== null && formId !== undefined ? String(formId) : \"\";\n\t\t\t\tif (id !== \"\") {\n\t\t\t\t\treturn document.getElementById(\"efb-submit-error-badge-slot-\" + id)\n\t\t\t\t\t\t|| document.querySelector(\"#body_efb_\" + id + \" #efb-final-step\")\n\t\t\t\t\t\t|| document.querySelector(\"#body_efb_\" + id + \" .view-efb\");\n\t\t\t\t}\n\t\t\t\treturn document.querySelector(\".efb-submit-error-badge-slot\")\n\t\t\t\t\t|| document.querySelector(\".view-efb #efb-final-step\")\n\t\t\t\t\t|| document.querySelector(\".view-efb\");\n\t\t\t},\nshowInlineBadge(formId = null) {\n\t\t\t\tif (!this.badge) return;\n\t\t\t\tif (formId !== null && formId !== undefined) {\n\t\t\t\t\tthis.inlineTargetFormId = formId;\n\t\t\t\t}\n\t\t\t\tconst target = this.getInlineTarget(this.inlineTargetFormId);\n\t\t\t\tif (target && this.badge.parentNode !== target) {\n\t\t\t\t\ttarget.appendChild(this.badge);\n\t\t\t\t} else if (!this.badge.isConnected) {\n\t\t\t\t\tdocument.body.appendChild(this.badge);\n\t\t\t\t}\n\t\t\t\tthis.showBadge();\n\t\t\t},\nshowBadge() {\n\t\t\t\tif (!this.badge) return;\n\t\t\t\tthis.badge.style.setProperty(\"visibility\", \"visible\", \"important\");\n\t\t\t\tthis.badge.style.setProperty(\"opacity\", \"1\", \"important\");\n\t\t\t\tthis.badge.style.setProperty(\"pointer-events\", \"auto\", \"important\");\n\t\t\t},\nhideBadge() {\n\t\t\t\tif (!this.badge) return;\n\t\t\t\tthis.badge.style.setProperty(\"opacity\", \"0\", \"important\");\n\t\t\t\tthis.badge.style.setProperty(\"pointer-events\", \"none\", \"important\");\n\t\t\t\tthis.badge.style.setProperty(\"visibility\", \"hidden\", \"important\");\n\t\t\t},\nclearSubmissionBadge(formId = null) {\n\t\t\t\tthis.hideBadge();\n\t\t\t\tif (formId === null || formId === undefined || String(formId) === String(this.inlineTargetFormId)) {\n\t\t\t\t\tthis.inlineTargetFormId = null;\n\t\t\t\t\tthis.visibleErrorKeys.clear();\n\t\t\t\t}\n\t\t\t\tthis.closePanelIfOpen();\n\t\t\t},\nupdateCount() {},\naddError(errorData) {\n\t\t\t\terrorData = errorData || {};\n\t\t\t\tconst { message, source, lineno, stack = [], typeOverride = null, nameOverride = null, formatOptions = {}, showBadge = false, context = \"\", formId = null } = errorData;\n\t\t\t\tconst shouldShowBadge = showBadge === true || context === \"submissionAjax\";\n\t\t\t\tconst errorKey = (message || \"\") + \"|\" + (source || \"\") + \"|\" + (lineno || \"\");\n\t\t\t\tif (this.dismissedKeys.has(errorKey)) return;\n\t\t\t\tif (this.errorKeys.has(errorKey)) {\n\t\t\t\t\tif (shouldShowBadge) {\n\t\t\t\t\t\tthis.visibleErrorKeys.add(errorKey);\n\t\t\t\t\t\tthis.showInlineBadge(formId);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.errorKeys.add(errorKey);\nconst parsed = this.parseSource(source);\n\t\t\t\tif (typeOverride) { parsed.type = typeOverride; }\n\t\t\t\tif (nameOverride) { parsed.name = nameOverride; }\n\t\t\t\tconst time = new Date().toLocaleTimeString([], {hour: \"2-digit\", minute: \"2-digit\"});\nconst realSource = stack.length > 0 ? stack[0].parsed : parsed;\n\t\t\t\tconst realPath = stack.length > 0 ? stack[0].parsed.fullPath + \":\" + stack[0].line : (parsed.fullPath + (lineno ? \":\" + lineno : \"\"));\nthis.errors.push({ key: errorKey, message, source, lineno, parsed, stack, time, showBadge: shouldShowBadge });\nif (shouldShowBadge) {\n\t\t\t\t\tthis.visibleErrorKeys.add(errorKey);\n\t\t\t\t\tthis.showInlineBadge(formId);\n\t\t\t\t}\n\t\t\t\tthis.updateCount();\nif (context === \"submissionAjax\") return;\nconst list = document.getElementById(\"efb-error-list\");\n\t\t\t\tif (!list) return;\n\t\t\t\tconst noErrors = list.querySelector(\".efb-no-errors\");\n\t\t\t\tif (noErrors) noErrors.remove();\nconst typeClass = realSource.isEFB ? \"is-efb\" :\n\t\t\t\t\trealSource.type === \"theme\" ? \"is-theme\" :\n\t\t\t\t\trealSource.type === \"wpCore\" ? \"is-core\" :\n\t\t\t\t\trealSource.type === \"external\" ? \"is-external\" : \"\";\nlet stackHtml = \"\";\n\t\t\t\tif (stack.length > 0) {\n\t\t\t\t\tstackHtml = `<div class=\"efb-stack-trace\">\n\t\t\t\t\t\t<div class=\"efb-stack-title\">\n\t\t\t\t\t\t\t<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n\t\t\t\t\t\t\t\t<polyline points=\"4 17 10 11 4 5\"\/><line x1=\"12\" y1=\"19\" x2=\"20\" y2=\"19\"\/>\n\t\t\t\t\t\t\t<\\\/svg>\n\t\t\t\t\t\t\tStack Trace\n\t\t\t\t\t\t<\\\/div>\n\t\t\t\t\t\t<div class=\"efb-stack-items\">\n\t\t\t\t\t\t\t${stack.map((s, i) => `\n\t\t\t\t\t\t\t\t<div class=\"efb-stack-item ${s.parsed.isEFB ? \"is-efb\" : \"\"}\">\n\t\t\t\t\t\t\t\t\t<span class=\"efb-stack-num\">${i + 1}<\\\/span>\n\t\t\t\t\t\t\t\t\t<div class=\"efb-stack-content\">\n\t\t\t\t\t\t\t\t\t\t<span class=\"efb-stack-func\">${this.escapeHtml(s.func)}<\\\/span>\n\t\t\t\t\t\t\t\t\t\t<span class=\"efb-stack-loc\">\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"efb-stack-source ${s.parsed.type}\">${s.parsed.name}<\\\/span>\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"efb-stack-path\">${s.parsed.fullPath}:${s.line}<\\\/span>\n\t\t\t\t\t\t\t\t\t\t<\\\/span>\n\t\t\t\t\t\t\t\t\t<\\\/div>\n\t\t\t\t\t\t\t\t<\\\/div>\n\t\t\t\t\t\t\t`).join(\"\")}\n\t\t\t\t\t\t<\\\/div>\n\t\t\t\t\t<\\\/div>`;\n\t\t\t\t}\nconst item = document.createElement(\"div\");\n\t\t\t\titem.className = \"efb-error-item \" + typeClass;\n\t\t\t\tconst messageHtml = context === \"submissionAjax\" ? \"\" : `<div class=\"efb-error-msg\">${this.formatMessage(message, formatOptions)}<\\\/div>`;\n\t\t\t\titem.innerHTML = `\n\t\t\t\t\t<div class=\"efb-error-source\">\n\t\t\t\t\t\t<span class=\"type-badge type-${realSource.type}\">${this.t[realSource.type] || realSource.type}<\\\/span>\n\t\t\t\t\t\t<span class=\"efb-error-source-name\">${realSource.name}<\\\/span>\n\t\t\t\t\t\t<button type=\"button\" class=\"efb-btn-dismiss\" aria-label=\"${this.getDismissLabel(realSource.name)}\">${this.t.dismiss}<\\\/button>\n\t\t\t\t\t<\\\/div>\n\t\t\t\t\t${messageHtml}\n\t\t\t\t\t<div class=\"efb-error-file\">\n\t\t\t\t\t\t<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n\t\t\t\t\t\t\t<path d=\"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z\"\/>\n\t\t\t\t\t\t<\\\/svg>\n\t\t\t\t\t\t<span class=\"efb-full-path\">${realPath}<\\\/span>\n\t\t\t\t\t<\\\/div>\n\t\t\t\t\t${stackHtml}\n\t\t\t\t\t<div class=\"efb-error-meta\">${time}<\\\/div>\n\t\t\t\t`;\n\t\t\t\titem.dataset.errorKey = errorKey;\n\t\t\t\tconst dismissBtn = item.querySelector(\".efb-btn-dismiss\");\n\t\t\t\tif (dismissBtn) {\n\t\t\t\t\tdismissBtn.addEventListener(\"click\", () => this.dismissError(errorKey));\n\t\t\t\t}\n\t\t\t\tlist.insertBefore(item, list.firstChild);\n\t\t\t},\ngetDismissLabel(label) {\n\t\t\t\tconst template = this.t.dismissItem || \"Dismiss %s\";\n\t\t\t\treturn this.escapeHtml(template.replace(\"%s\", label || \"\"));\n\t\t\t},\nshowEmptyState() {\n\t\t\t\tconst list = document.getElementById(\"efb-error-list\");\n\t\t\t\tif (list) {\n\t\t\t\t\tlist.innerHTML = \"<div class=\\\"efb-no-errors\\\">\u00e2\u0153\u201c \" + this.t.noErrors + \"<\\\/div>\";\n\t\t\t\t}\n\t\t\t},\nclosePanelIfOpen() {\n\t\t\t\tif (this.isOpen) {\n\t\t\t\t\tthis.togglePanel();\n\t\t\t\t}\n\t\t\t},\ndismissAll() {\n\t\t\t\tthis.errors.forEach(error => {\n\t\t\t\t\tif (error.key) {\n\t\t\t\t\t\tthis.dismissedKeys.add(error.key);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tthis.saveDismissedKeys();\n\t\t\t\tthis.errors = [];\n\t\t\t\tthis.errorKeys.clear();\n\t\t\t\tthis.visibleErrorKeys.clear();\n\t\t\t\tthis.updateCount();\n\t\t\t\tconst list = document.getElementById(\"efb-error-list\");\n\t\t\t\tlist.innerHTML = \"<div class=\\\"efb-no-errors\\\">\u2713 \" + this.t.noErrors + \"<\\\/div>\";\n\t\t\t\tthis.hideBadge();\n\t\t\t\tthis.closePanelIfOpen();\n\t\t\t},\ndismissError(errorKey) {\n\t\t\t\tif (!errorKey) return;\n\t\t\t\tthis.dismissedKeys.add(errorKey);\n\t\t\t\tthis.saveDismissedKeys();\n\t\t\t\tthis.errors = this.errors.filter(error => error.key !== errorKey);\n\t\t\t\tthis.errorKeys.delete(errorKey);\n\t\t\t\tthis.visibleErrorKeys.delete(errorKey);\n\t\t\t\tconst list = document.getElementById(\"efb-error-list\");\n\t\t\t\tif (list) {\n\t\t\t\t\tArray.from(list.querySelectorAll(\".efb-error-item\")).forEach(item => {\n\t\t\t\t\t\tif (item.dataset.errorKey === errorKey) {\n\t\t\t\t\t\t\titem.remove();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthis.updateCount();\n\t\t\t\tif (this.errors.length === 0) {\n\t\t\t\t\tthis.showEmptyState();\n\t\t\t\t}\n\t\t\t\tif (this.visibleErrorKeys.size === 0) {\n\t\t\t\t\tthis.hideBadge();\n\t\t\t\t\tthis.closePanelIfOpen();\n\t\t\t\t}\n\t\t\t},\nclearErrors() {\n\t\t\t\tthis.dismissAll();\n\t\t\t},\nescapeHtml(text) {\n\t\t\t\tconst div = document.createElement(\"div\");\n\t\t\t\tdiv.textContent = text;\n\t\t\t\treturn div.innerHTML;\n\t\t\t},\nescapeRegExp(text) {\n\t\t\t\tconst backslash = String.fromCharCode(92);\n\t\t\t\tconst specials = backslash + \"^$.*+?()[]{}|\";\n\t\t\t\treturn String(text).split(\"\").map(ch => specials.indexOf(ch) !== -1 ? backslash + ch : ch).join(\"\");\n\t\t\t},\nformatMessage(message, options = {}) {\n\t\t\t\tlet html = this.escapeHtml(message).replace(\/\\n\/g, \"<br>\");\n\t\t\t\tconst boldTexts = Array.isArray(options.boldTexts) ? options.boldTexts : [];\n\t\t\t\tboldTexts.filter(Boolean).forEach(text => {\n\t\t\t\t\tconst safeText = this.escapeHtml(text);\n\t\t\t\t\thtml = html.replace(new RegExp(this.escapeRegExp(safeText), \"g\"), \"<strong>\" + safeText + \"<\\\/strong>\");\n\t\t\t\t});\nconst links = Array.isArray(options.links) ? options.links : [];\n\t\t\t\tlinks.filter(Boolean).forEach(link => {\n\t\t\t\t\tconst rawUrl = typeof link === \"string\" ? link : link.url;\n\t\t\t\t\tconst rawLabel = typeof link === \"string\" ? link : (link.label || link.url);\n\t\t\t\t\tif (!rawUrl) return;\n\t\t\t\t\tconst safeUrl = this.escapeHtml(rawUrl);\n\t\t\t\t\tconst safeLabel = this.escapeHtml(rawLabel || rawUrl);\n\t\t\t\t\thtml = html.replace(new RegExp(this.escapeRegExp(safeUrl), \"g\"), \"<a href=\\\"\" + safeUrl + \"\\\" target=\\\"_blank\\\" rel=\\\"noopener noreferrer\\\">\" + safeLabel + \"<\\\/a>\");\n\t\t\t\t});\nreturn html;\n\t\t\t},\nparseStack(stackString) {\n\t\t\t\tif (!stackString) return [];\n\t\t\t\tconst lines = stackString.split(\"\\n\");\n\t\t\t\tconst stack = [];\nfor (const line of lines) {\n\t\t\t\t\tconst match = line.match(\/at\\s+(.+?)\\s*\\(?(https?:\\\/\\\/[^)\\s]+):(\\d+):(\\d+)\\)?\/);\n\t\t\t\t\tif (match) {\n\t\t\t\t\t\tconst [, funcName, url, lineNo, colNo] = match;\n\t\t\t\t\t\tconst parsed = this.parseSource(url);\n\t\t\t\t\t\tstack.push({\n\t\t\t\t\t\t\tfunc: funcName.trim(),\n\t\t\t\t\t\t\turl: url,\n\t\t\t\t\t\t\tline: lineNo,\n\t\t\t\t\t\t\tcol: colNo,\n\t\t\t\t\t\t\tparsed: parsed\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn stack;\n\t\t\t},\ntest(message) {\n\t\t\t\tconst msg = message || \"\ud83e\uddea This is a TEST error message from EFB_ERROR_PANEL.test()\";\n\t\t\t\tconst err = new Error(msg);\n\t\t\t\tconst stack = this.parseStack(err.stack);\n\t\t\t\tthis.addError({\n\t\t\t\t\tmessage: msg,\n\t\t\t\t\tsource: window.location.href,\n\t\t\t\t\tlineno: null,\n\t\t\t\t\tstack: stack\n\t\t\t\t});\n\t\t\t\tconsole.info(\"%c[EFB Debug Panel]%c Test error added: \" + msg, \"color:#ff4b93;font-weight:bold\", \"color:inherit\");\n\t\t\t},\nlog(message, options = {}) {\n\t\t\t\tif (!message) { console.warn(\"[EFB Debug Panel] log() requires a message\"); return; }\nlet source = options.source || window.location.href;\n\t\t\t\tlet lineno = options.line || options.lineno || null;\n\t\t\t\tlet stack = [];\nif (Array.isArray(options.stack) && options.stack.length > 0) {\n\t\t\t\t\tstack = options.stack.map(s => {\n\t\t\t\t\t\tconst filePath = s.file || s.url || \"\";\n\t\t\t\t\t\tconst parsed = this.parseSource(filePath.startsWith(\"http\") ? filePath : window.location.origin + \"\/\" + filePath);\n\t\t\t\t\t\tparsed.fullPath = filePath;\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tfunc: s.func || s.function || \"anonymous\",\n\t\t\t\t\t\t\turl: filePath,\n\t\t\t\t\t\t\tline: String(s.line || \"?\"),\n\t\t\t\t\t\t\tcol: String(s.col || s.column || \"?\"),\n\t\t\t\t\t\t\tparsed: parsed\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t} else if (options.captureStack !== false) {\n\t\t\t\t\tconst err = new Error(\"__efb_log__\");\n\t\t\t\t\tstack = this.parseStack(err.stack);\n\t\t\t\t\tif (stack.length > 0 && stack[0].func.includes(\"log\")) {\n\t\t\t\t\t\tstack.shift();\n\t\t\t\t\t}\n\t\t\t\t}\nconst typeOverride = options.type || null;\n\t\t\t\tconst nameOverride = options.name || null;\n\t\t\t\tconst formatOptions = options.format || {};\n\t\t\t\tconst showBadge = options.showBadge === true;\n\t\t\t\tconst context = options.context || \"\";\n\t\t\t\tconst formId = options.formId || options.form_id || null;\n\t\t\t\tthis.addError({ message, source, lineno, stack, typeOverride, nameOverride, formatOptions, showBadge, context, formId });\n\t\t\t\tconsole.info(\"%c[EFB Debug Panel]%c Logged: \" + message, \"color:#ff4b93;font-weight:bold\", \"color:inherit\");\n\t\t\t},\ninit() {\n\t\t\t\tconst self = this;\n\t\t\t\tthis.loadDismissedKeys();\nif (document.readyState === \"loading\") {\n\t\t\t\t\tdocument.addEventListener(\"DOMContentLoaded\", () => self.createUI());\n\t\t\t\t} else {\n\t\t\t\t\tself.createUI();\n\t\t\t\t}\n\/\/ Check if jQuery is loaded and working properly\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (typeof jQuery === \"undefined\" || !jQuery || typeof jQuery.ajax !== \"function\") {\n\t\t\t\t\t\tself.addError({\n\t\t\t\t\t\t\tmessage: self.t.jqueryMessage,\n\t\t\t\t\t\t\tsource: \"window\",\n\t\t\t\t\t\t\tlineno: null,\n\t\t\t\t\t\t\ttypeOverride: \"jqueryMissing\",\n\t\t\t\t\t\t\tnameOverride: self.t.jqueryMissing\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t\/* WordPress deliberately runs jQuery in noConflict mode, so a missing\n\t\t\t\t\t * global `$` is normal and must not be reported as an application error. *\/\n\t\t\t\t}, 500);\nwindow.addEventListener(\"error\", function(event) {\n\t\t\t\t\tlet stack = [];\n\t\t\t\t\tif (event.error && event.error.stack) {\n\t\t\t\t\t\tstack = self.parseStack(event.error.stack);\n\t\t\t\t\t}\n\t\t\t\t\tself.addError({\n\t\t\t\t\t\tmessage: event.message,\n\t\t\t\t\t\tsource: event.filename,\n\t\t\t\t\t\tlineno: event.lineno,\n\t\t\t\t\t\tstack: stack\n\t\t\t\t\t});\n\t\t\t\t}, true);\nwindow.addEventListener(\"unhandledrejection\", function(event) {\n\t\t\t\t\tlet source = \"\";\n\t\t\t\t\tlet stack = [];\n\t\t\t\t\tlet message = event.reason instanceof Error ? event.reason.message : String(event.reason);\nif (event.reason && event.reason.stack) {\n\t\t\t\t\t\tconst match = event.reason.stack.match(\/https?:\\\/\\\/[^\\s]+\/);\n\t\t\t\t\t\tsource = match ? match[0] : \"\";\n\t\t\t\t\t\tstack = self.parseStack(event.reason.stack);\n\t\t\t\t\t}\nself.addError({ message, source, lineno: null, stack });\n\t\t\t\t});\n\t\t\t}\n\t\t};\nEFB_ERROR_PANEL.init();\n\t\twindow.EFB_ERROR_PANEL = EFB_ERROR_PANEL;\n\t})();<\/script><\/div>  <style>\n\t\t@font-face {  font-family: \"bootstrap-icons\";  src: url(\"https:\/\/porvoonkodit.fi\/wp-content\/plugins\/easy-form-builder\/includes\/admin\/assets\/css\/fonts\/bootstrap-icons.woff2?856008caa5eb66df68595e734e59580d\")\n\t   format(\"woff2\"),url(\"https:\/\/porvoonkodit.fi\/wp-content\/plugins\/easy-form-builder\/includes\/admin\/assets\/css\/fonts\/bootstrap-icons.woff?856008caa5eb66df68595e734e59580d\") format(\"woff\");}[class^=\"bi-\"]::before,[class*=\" bi-\"]::before {  display: inline-block;  font-family: bootstrap-icons !important;  font-style: normal;  font-weight: normal !important;  font-variant: normal;  text-transform: none;  line-height: 1;  vertical-align: -.125em;  -webkit-font-smoothing: antialiased;  -moz-osx-font-smoothing: grayscale;}\n\t    .bi-chevron-right::before {content:\"\\f285\";} .bi-chevron-left::before {content:\"\\f284\";} .bi-hand-thumbs-up::before {content:\"\\f407\";} .bi-check2-square::before {content:\"\\f271\";} .bi-clipboard-check::before {content:\"\\f28b\";} .bi-shield-lock-fill::before {content:\"\\f537\";} .bi-exclamation-triangle-fill::before {content:\"\\f33a\";} .bi-exclamation-diamond-fill::before {content:\"\\f334\";} .bi-hourglass-split::before {content:\"\\f41f\";} .bi-chat-square-text::before {content:\"\\f264\";} .bi-download::before {content:\"\\f30a\";} .bi-star-fill::before {content:\"\\f586\";} .bi-envelope::before {content:\"\\f32f\";} .bi-arrow-right::before {content:\"\\f138\";} .bi-arrow-left::before {content:\"\\f12f\";} .bi-upload::before {content:\"\\f603\";} .bi-x-lg::before {content:\"\\f659\";} .bi-file-earmark-richtext::before {content:\"\\f383\";} .bi-check-square::before {content:\"\\f26d\";} .bi-square::before {content:\"\\f584\";} .bi-chevron-down::before {content:\"\\f282\";} .bi-chevron-up::before {content:\"\\f286\";} .bi-check-lg::before {content:\"\\f633\";} .bi-crosshair::before {content:\"\\f769\";} .bi-search::before {content:\"\\f52a\";} .bi-trash::before {content:\"\\f5de\";} .bi-shield-check::before {content:\"\\f52f\";} .bi-paperclip::before {content:\"\\f4b3\";} .bi-type-bold::before {content:\"\\f5f0\";} .bi-type-italic::before {content:\"\\f5f4\";} .bi-type-underline::before {content:\"\\f5f6\";} .bi-eraser::before {content:\"\\f331\";} .bi-person::before {content:\"\\f4e1\";} .bi-reply::before {content:\"\\f520\";} .bi-hash::before {content:\"\\f40a\";} .bi-calendar3::before {content:\"\\f214\";} .bi-globe2::before {content:\"\\f3ef\";} .bi-credit-card::before {content:\"\\f2dc\";} .bi-calculator::before {content:\"\\f1e0\";} .bi-palette::before {content:\"\\f4b1\";} .bi-pen::before {content:\"\\f4c8\";} .bi-star::before {content:\"\\f588\";} .bi-x::before {content:\"\\f62a\";}\n\t\t\t<\/style> <div style=\"display:none;\"><i class='bi bi-chevron-right'><\/i><i class='bi bi-chevron-left'><\/i><i class='bi bi-hand-thumbs-up'><\/i><i class='bi bi-check2-square'><\/i><i class='bi bi-clipboard-check'><\/i><i class='bi bi-shield-lock-fill'><\/i><i class='bi bi-exclamation-triangle-fill'><\/i><i class='bi bi-exclamation-diamond-fill'><\/i><i class='bi bi-check2-square'><\/i><i class='bi bi-hourglass-split'><\/i><i class='bi bi-chat-square-text'><\/i><i class='bi bi-download'><\/i><i class='bi bi-star-fill'><\/i><i class='bi bi-hand-thumbs-up'><\/i><i class='bi bi-envelope'><\/i><i class='bi bi-arrow-right'><\/i><i class='bi bi-arrow-left'><\/i><i class='bi bi-upload'><\/i><i class='bi bi-x-lg'><\/i><i class='bi bi-file-earmark-richtext'><\/i><i class='bi bi-check-square'><\/i><i class='bi bi-square'><\/i><i class='bi bi-chevron-down'><\/i><i class='bi bi-chevron-up'><\/i><i class='bi bi-check-lg'><\/i><i class='bi bi-crosshair'><\/i><i class='bi bi-search'><\/i><i class='bi bi-trash'><\/i><i class='bi bi-shield-check'><\/i><i class='bi bi-chat-square-text'><\/i><i class='bi bi-paperclip'><\/i><i class='bi bi-type-bold'><\/i><i class='bi bi-type-italic'><\/i><i class='bi bi-type-underline'><\/i><i class='bi bi-eraser'><\/i><i class='bi bi-person'><\/i><i class='bi bi-reply'><\/i><i class='bi bi-hash'><\/i><i class='bi bi-calendar3'><\/i><i class='bi bi-globe2'><\/i><i class='bi bi-credit-card'><\/i><i class='bi bi-calculator'><\/i><i class='bi bi-palette'><\/i><i class='bi bi-pen'><\/i><i class='bi bi-star'><\/i><i class='bi bi-reply'><\/i><i class='bi bi-x'><\/i><\/div>  <div id=\"body_efb_12\" class=\"efb row pb-3 efb px-2 pre-efb body_efb efb-waiting-12 \" data-currentstep=\"1\" data-steps=\"1\" data-formid=\"12\"> <form id=\"efbform\" class=\"mx-0 px-0 efb\" data-formid=\"12\"> <div class=\"efb px-0 pt-2 pb-0 my-1 col-12 mb-2 view-efb\" id=\"view-efb\" data-formid=\"12\">   <div class=\"efb mt-1 px-2\"><fieldset data-step=\"step-1-efb\" id=\"step-1-efb\" class=\"efb my-2 mx-0 px-0 steps-efb efb row fieldset\" data-formid=\"12\"><div class=\"efb my-1 mx-0 text def   ttEfb row col-md-6 col-12 efbField \" data-step=\"0\" data-amount=\"3\" data-id=\"janf5eutd-id\" id=\"janf5eutd\" data-tag=\"text\"><label for=\"janf5eutd_\" class=\"efb mx-0 px-0 pt-2 pb-1 col-md-3 col-12 col-form-label text-labelEfb txt-center fs-6\" id=\"janf5eutd_labG\"><span id=\"janf5eutd_lab\" class=\"efb fs-6\">Name<\/span><span class=\"efb mx-1 text-danger\" id=\"janf5eutd_req\" role=\"none\">*<\/span><\/label> <div class=\"efb col-md-9 col-12 px-0 mx-0 ttEfb show\" id=\"janf5eutd-f\"> <small id=\"janf5eutd_-message\" class=\"efb py-1 fs-7 tx ttiptext px-2\" style=\"display:none\"> ! <\/small> <input type=\"text\" class=\"efb input-efb px-2 mb-0 emsFormBuilder_v w-100 form-control border-d h-l-efb efb-square text-labelEfb required efbField efb1 \" data-id=\"janf5eutd-el\" data-vid=\"janf5eutd\" data-formid=\"12\" data-css=\"janf5eutd\" id=\"janf5eutd_\" placeholder=\"Name\"  aria-required=\"true\" aria-label=\"Name\"  autocomplete=\"off\"    > <div class=\"efb efb-field-description\"><small id=\"janf5eutd-des\" class=\"efb form-text d-flex fs-7 col-sm-12 efb  mx-4 justify-content-start text-muted  \"><\/small><\/div><\/div><\/div><div class=\"efb my-1 mx-0 email def   ttEfb row col-md-6 col-12 efbField \" data-step=\"0\" data-amount=\"5\" data-id=\"82i3wedt1-id\" id=\"82i3wedt1\" data-tag=\"email\"><label for=\"82i3wedt1_\" class=\"efb mx-0 px-0 pt-2 pb-1 col-md-3 col-12 col-form-label text-labelEfb txt-center fs-6\" id=\"82i3wedt1_labG\"><span id=\"82i3wedt1_lab\" class=\"efb fs-6\">E-mail<\/span><span class=\"efb mx-1 text-danger\" id=\"82i3wedt1_req\" role=\"none\">*<\/span><\/label> <div class=\"efb col-md-9 col-12 px-0 mx-0 ttEfb show\" id=\"82i3wedt1-f\"> <small id=\"82i3wedt1_-message\" class=\"efb py-1 fs-7 tx ttiptext px-2\" style=\"display:none\"> ! <\/small> <input type=\"email\" class=\"efb input-efb px-2 mb-0 emsFormBuilder_v w-100 form-control border-d h-l-efb efb-square text-labelEfb required efbField efb1 \" data-id=\"82i3wedt1-el\" data-vid=\"82i3wedt1\" data-formid=\"12\" data-css=\"82i3wedt1\" id=\"82i3wedt1_\" placeholder=\"E-mail\"  aria-required=\"true\" aria-label=\"E-mail\"  autocomplete=\"email\"    > <div class=\"efb efb-field-description\"><small id=\"82i3wedt1-des\" class=\"efb form-text d-flex fs-7 col-sm-12 efb  mx-4 justify-content-start text-muted  \"><\/small><\/div><\/div><\/div>  <\/fieldset> <fieldset data-step='step-2-efb' class='efb my-5 steps-efb efb row d-none text-center' id='efb-final-step' data-formid='12'>  <h2 class=\"efb fs-3 text-center\">Please Wait <svg viewBox=\"0 0 120 30\" height=\"15px\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" preserveAspectRatio=\"xMidYMid meet\"> <circle cx=\"15\" cy=\"15\" r=\"15\" fill=\"#abb8c3\"> <animate attributeName=\"r\" from=\"15\" to=\"9\" begin=\"0s\" dur=\"1s\" values=\"15;9;15\" calcMode=\"linear\" repeatCount=\"indefinite\" \/> <\/circle> <circle cx=\"60\" cy=\"15\" r=\"9\" fill=\"#abb8c3\"> <animate attributeName=\"r\" from=\"9\" to=\"15\" begin=\"0.3s\" dur=\"1s\" values=\"9;15;9\" calcMode=\"linear\" repeatCount=\"indefinite\" \/> <\/circle> <circle cx=\"105\" cy=\"15\" r=\"15\" fill=\"#abb8c3\"> <animate attributeName=\"r\" from=\"15\" to=\"9\" begin=\"0.6s\" dur=\"1s\" values=\"15;9;15\" calcMode=\"linear\" repeatCount=\"indefinite\" \/> <\/circle> <\/svg><\/h2><p class=\"efb fs-5\"><p class=\"efb fs-5\">Submitting the form<\/p><\/p> <div step-2-efb><\/div> <\/fieldset><\/div> <\/div>  <div class=\"efb footer-test p-1\"><div class=\"efb d-flex justify-content-center d-block text-center efb mx-3\" id=\"f_btn_send_efb\" data-tag=\"buttonNav\" data-formid=\"12\"> <a id=\"btn_send_efb\" role=\"button\" class=\"efb text-decoration-none mx-0 btn p-2  btn-colorDEfb-f66900 efb-square h-d-efb  efb-btn-lg btn_send_efb\" data-formid=\"12\" data-currentstep=\"1\" onclick=\"btn_navigate_handle_efb('12' ,'subscribe' ,'btn_send_efb',this)\"><span id=\"button_group_button_single_text\" class=\"efb text-light\" >Submit<\/span><\/a> <\/div><\/div> <\/form>  <\/div>  <div id=\"alert_efb\" class=\"efb mx-5 alert_efb\" data-formid=\"12\"><\/div>  <div class=\"efb d-none\"><script> \/\/efbJs<\/script><\/div>\n\n\n\n<section id=\"g-c114467\" class=\"section-g-c114467 gutentor-module gutentor-container-cover wp-block-gutentor-m3 d-none\"><div class=\"grid-container\">\n<div id=\"section-g-eenk9rn\" class=\"section-g-eenk9rn gutentor-element gutentor-element-button wp-block-gutentor-e2 gutentor-btn-full-mobile gutentor-btn-custom-desktop gutentor-btn-custom-tablet button-align-left-desktop button-align-left-tablet button-align-center-mobile\"><span class=\"gutentor-button-wrap\"><a class=\"gutentor-button gutentor-block-button gutentor-icon-hide\" href=\"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2025\/09\/Vaskenvalajankatu-8-Markkinointimateriaali-paivitetty-1.pdf\" target=\"_blank\" rel=\" noopener noreferrer\"><i class=\"gutentor-button-icon fas fa-book\"><\/i><span>Katso esite<\/span><\/a><\/span><\/div>\n\n\n\n<div id=\"section-g-4r4heyn\" class=\"section-g-4r4heyn gutentor-element gutentor-element-button wp-block-gutentor-e2 gutentor-btn-full-mobile gutentor-btn-custom-desktop gutentor-btn-custom-tablet button-align-left-desktop button-align-left-tablet button-align-center-mobile\"><span class=\"gutentor-button-wrap\"><a class=\"gutentor-button gutentor-block-button gutentor-icon-hide\" href=\"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2025\/09\/Vaskenvalajankatu-8-hinnasto.pdf\" target=\"_blank\" rel=\" noopener noreferrer\"><i class=\"gutentor-button-icon fas fa-book\"><\/i><span>Kohteen vuokra-asunnot ja hinnat<\/span><\/a><\/span><\/div>\n\n\n\n<div id=\"section-g-1x1tzm8\" class=\"section-g-1x1tzm8 gutentor-element gutentor-element-button wp-block-gutentor-e2 gutentor-btn-full-mobile gutentor-btn-custom-desktop gutentor-btn-custom-tablet button-align-left-desktop button-align-left-tablet button-align-center-mobile\"><span class=\"gutentor-button-wrap\"><a class=\"gutentor-button gutentor-block-button gutentor-icon-hide\" href=\"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2025\/09\/Vaskenvalajankatu-8-rakennustapaselostus_markkinointi.pdf\" target=\"_blank\" rel=\" noopener noreferrer\"><i class=\"gutentor-button-icon fas fa-book\"><\/i><span>Rakennustapaseloste<\/span><\/a><\/span><\/div>\n\n\n\n<div id=\"section-g-giliexc\" class=\"section-g-giliexc gutentor-element gutentor-element-button wp-block-gutentor-e2 gutentor-btn-full-mobile gutentor-btn-custom-desktop gutentor-btn-custom-tablet button-align-left-desktop button-align-left-tablet button-align-center-mobile\"><span class=\"gutentor-button-wrap\"><a class=\"gutentor-button gutentor-block-button gutentor-icon-hide\" href=\"https:\/\/app.kodia.fi\/public\/Porvoon-A-asunnot-Oy---Borg%C3%A5-A-bost%C3%A4der-Ab\/apply\/\" target=\"_blank\" rel=\" noopener noreferrer\"><i class=\"gutentor-button-icon fas fa-book\"><\/i><span>Hae asuntoa<\/span><\/a><\/span><\/div>\n<\/div><\/section>\n<\/div><\/section>\n<\/div><\/section>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":3,"featured_media":0,"parent":3411,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-3566","page","type-page","status-publish"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>New Developments - Porvoon Kodit<\/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:\/\/porvoonkodit.fi\/en\/asunnon-hakijalle\/kohteet\/uudiskohteet\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"New Developments - Porvoon Kodit\" \/>\n<meta property=\"og:url\" content=\"https:\/\/porvoonkodit.fi\/en\/asunnon-hakijalle\/kohteet\/uudiskohteet\/\" \/>\n<meta property=\"og:site_name\" content=\"Porvoon Kodit\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/AyhtiotAbolagen\/\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-01T13:17:18+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/08\/Porvoon-Asunnot-Opistokuja-1-Julkisivun-havainnekuva-31.7.2026-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1682\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/porvoonkodit.fi\\\/en\\\/asunnon-hakijalle\\\/kohteet\\\/uudiskohteet\\\/\",\"url\":\"https:\\\/\\\/porvoonkodit.fi\\\/en\\\/asunnon-hakijalle\\\/kohteet\\\/uudiskohteet\\\/\",\"name\":\"New Developments - Porvoon Kodit\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/porvoonkodit.fi\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/porvoonkodit.fi\\\/en\\\/asunnon-hakijalle\\\/kohteet\\\/uudiskohteet\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/porvoonkodit.fi\\\/en\\\/asunnon-hakijalle\\\/kohteet\\\/uudiskohteet\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/porvoonkodit.fi\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/Porvoon-Asunnot-Opistokuja-1-Julkisivun-havainnekuva-31.7.2026-scaled.jpg\",\"datePublished\":\"2025-08-14T07:11:12+00:00\",\"dateModified\":\"2026-09-01T13:17:18+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/porvoonkodit.fi\\\/en\\\/asunnon-hakijalle\\\/kohteet\\\/uudiskohteet\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/porvoonkodit.fi\\\/en\\\/asunnon-hakijalle\\\/kohteet\\\/uudiskohteet\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/porvoonkodit.fi\\\/en\\\/asunnon-hakijalle\\\/kohteet\\\/uudiskohteet\\\/#primaryimage\",\"url\":\"https:\\\/\\\/porvoonkodit.fi\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/Porvoon-Asunnot-Opistokuja-1-Julkisivun-havainnekuva-31.7.2026-scaled.jpg\",\"contentUrl\":\"https:\\\/\\\/porvoonkodit.fi\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/Porvoon-Asunnot-Opistokuja-1-Julkisivun-havainnekuva-31.7.2026-scaled.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/porvoonkodit.fi\\\/en\\\/asunnon-hakijalle\\\/kohteet\\\/uudiskohteet\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Etusivu\",\"item\":\"https:\\\/\\\/porvoonkodit.fi\\\/en\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"For Applicants\",\"item\":\"https:\\\/\\\/porvoonkodit.fi\\\/en\\\/asunnon-hakijalle\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Explore our properties\",\"item\":\"https:\\\/\\\/porvoonkodit.fi\\\/en\\\/asunnon-hakijalle\\\/kohteet\\\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"New Developments\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/porvoonkodit.fi\\\/#website\",\"url\":\"https:\\\/\\\/porvoonkodit.fi\\\/\",\"name\":\"Porvoon kodit Oy\",\"description\":\"Tervetuloa kotiin\",\"publisher\":{\"@id\":\"https:\\\/\\\/porvoonkodit.fi\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/porvoonkodit.fi\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/porvoonkodit.fi\\\/#organization\",\"name\":\"Porvoon kodit Oy\",\"url\":\"https:\\\/\\\/porvoonkodit.fi\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/porvoonkodit.fi\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/porvoonkodit.fi\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/Logo-tummempi-oranssi.png\",\"contentUrl\":\"https:\\\/\\\/porvoonkodit.fi\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/Logo-tummempi-oranssi.png\",\"width\":480,\"height\":150,\"caption\":\"Porvoon kodit Oy\"},\"image\":{\"@id\":\"https:\\\/\\\/porvoonkodit.fi\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/AyhtiotAbolagen\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"New Developments - Porvoon Kodit","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:\/\/porvoonkodit.fi\/en\/asunnon-hakijalle\/kohteet\/uudiskohteet\/","og_locale":"en_US","og_type":"article","og_title":"New Developments - Porvoon Kodit","og_url":"https:\/\/porvoonkodit.fi\/en\/asunnon-hakijalle\/kohteet\/uudiskohteet\/","og_site_name":"Porvoon Kodit","article_publisher":"https:\/\/www.facebook.com\/AyhtiotAbolagen\/","article_modified_time":"2026-09-01T13:17:18+00:00","og_image":[{"width":2560,"height":1682,"url":"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/08\/Porvoon-Asunnot-Opistokuja-1-Julkisivun-havainnekuva-31.7.2026-scaled.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/porvoonkodit.fi\/en\/asunnon-hakijalle\/kohteet\/uudiskohteet\/","url":"https:\/\/porvoonkodit.fi\/en\/asunnon-hakijalle\/kohteet\/uudiskohteet\/","name":"New Developments - Porvoon Kodit","isPartOf":{"@id":"https:\/\/porvoonkodit.fi\/#website"},"primaryImageOfPage":{"@id":"https:\/\/porvoonkodit.fi\/en\/asunnon-hakijalle\/kohteet\/uudiskohteet\/#primaryimage"},"image":{"@id":"https:\/\/porvoonkodit.fi\/en\/asunnon-hakijalle\/kohteet\/uudiskohteet\/#primaryimage"},"thumbnailUrl":"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/08\/Porvoon-Asunnot-Opistokuja-1-Julkisivun-havainnekuva-31.7.2026-scaled.jpg","datePublished":"2025-08-14T07:11:12+00:00","dateModified":"2026-09-01T13:17:18+00:00","breadcrumb":{"@id":"https:\/\/porvoonkodit.fi\/en\/asunnon-hakijalle\/kohteet\/uudiskohteet\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/porvoonkodit.fi\/en\/asunnon-hakijalle\/kohteet\/uudiskohteet\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/porvoonkodit.fi\/en\/asunnon-hakijalle\/kohteet\/uudiskohteet\/#primaryimage","url":"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/08\/Porvoon-Asunnot-Opistokuja-1-Julkisivun-havainnekuva-31.7.2026-scaled.jpg","contentUrl":"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2026\/08\/Porvoon-Asunnot-Opistokuja-1-Julkisivun-havainnekuva-31.7.2026-scaled.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/porvoonkodit.fi\/en\/asunnon-hakijalle\/kohteet\/uudiskohteet\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Etusivu","item":"https:\/\/porvoonkodit.fi\/en\/"},{"@type":"ListItem","position":2,"name":"For Applicants","item":"https:\/\/porvoonkodit.fi\/en\/asunnon-hakijalle\/"},{"@type":"ListItem","position":3,"name":"Explore our properties","item":"https:\/\/porvoonkodit.fi\/en\/asunnon-hakijalle\/kohteet\/"},{"@type":"ListItem","position":4,"name":"New Developments"}]},{"@type":"WebSite","@id":"https:\/\/porvoonkodit.fi\/#website","url":"https:\/\/porvoonkodit.fi\/","name":"Porvoon kodit Oy","description":"Tervetuloa kotiin","publisher":{"@id":"https:\/\/porvoonkodit.fi\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/porvoonkodit.fi\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/porvoonkodit.fi\/#organization","name":"Porvoon kodit Oy","url":"https:\/\/porvoonkodit.fi\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/porvoonkodit.fi\/#\/schema\/logo\/image\/","url":"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2025\/07\/Logo-tummempi-oranssi.png","contentUrl":"https:\/\/porvoonkodit.fi\/wp-content\/uploads\/2025\/07\/Logo-tummempi-oranssi.png","width":480,"height":150,"caption":"Porvoon kodit Oy"},"image":{"@id":"https:\/\/porvoonkodit.fi\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/AyhtiotAbolagen\/"]}]}},"_links":{"self":[{"href":"https:\/\/porvoonkodit.fi\/en\/wp-json\/wp\/v2\/pages\/3566","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/porvoonkodit.fi\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/porvoonkodit.fi\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/porvoonkodit.fi\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/porvoonkodit.fi\/en\/wp-json\/wp\/v2\/comments?post=3566"}],"version-history":[{"count":8,"href":"https:\/\/porvoonkodit.fi\/en\/wp-json\/wp\/v2\/pages\/3566\/revisions"}],"predecessor-version":[{"id":9891,"href":"https:\/\/porvoonkodit.fi\/en\/wp-json\/wp\/v2\/pages\/3566\/revisions\/9891"}],"up":[{"embeddable":true,"href":"https:\/\/porvoonkodit.fi\/en\/wp-json\/wp\/v2\/pages\/3411"}],"wp:attachment":[{"href":"https:\/\/porvoonkodit.fi\/en\/wp-json\/wp\/v2\/media?parent=3566"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}