{"id":581,"date":"2026-09-12T15:46:47","date_gmt":"2026-09-12T10:46:47","guid":{"rendered":"https:\/\/forexsource.net\/portal\/table\/"},"modified":"2026-09-13T17:34:12","modified_gmt":"2026-09-13T12:34:12","slug":"table","status":"publish","type":"portal","link":"https:\/\/forexsource.net\/portal\/table\/","title":{"rendered":"Table"},"content":{"rendered":"\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\n<title>Interest Rate Probability<\/title>\n\n<script id=\"irp-custom-mapping\">\n\nwindow.IRP_MAPPING_CONFIG = {\n\n    targetBank: \"Fed\",\n\n    fieldKeys: {\n\n        bankCode: \"us_bank_code\",\n        bankFullName: \"us_central_bank\",\n        rate: \"us_current_rate\",\n        nextMeeting: \"us_meeting_date\",\n        implBp: \"us_change_expected\",\n        move: \"us_probable_move\",\n        cut: \"us_cut_pct\",\n        hold: \"us_hold_pct\",\n        hike: \"us_hike_pct\",\n        bias: \"us_bias_label\"\n\n    },\n\n    commentaryKeys: {\n\n        longCommentary: \"us_commentry\",\n        shortCommentary: \"us_commentry_short\"\n\n    },\n\n    sentimentAndVotes: {\n\n        biasConfidence: \"us_bias_confidence\",\n        totalBankersVote: \"us_bankers_vote\",\n        dovishBankers: \"us_dovish_bankers\",\n        neutralBankers: \"us_neutral_bankers\",\n        hawkishBankers: \"us_hawkish_bankers\"\n\n    }\n\n};\n\n<\/script>\n\n\n<style>\n\n\/* ============================================================\n   DARK + LIGHT THEME VARIABLES\n   ============================================================ *\/\n\n#irp-widget-container {\n\n    \/* -------------------------\n       DARK MODE PRESET\n       ------------------------- *\/\n\n    --dark-bg: rgb(25, 27, 31);\n\n    --dark-table-bg: rgb(25, 27, 31);\n\n    --dark-header-bg: #000000;\n\n    --dark-header-text: #ffffff;\n\n    --dark-border: #222c3d;\n\n    --dark-text-primary: #ffffff;\n\n    --dark-text-muted: #94a3b8;\n\n    --dark-row-hover: #252a31;\n\n    --dark-filter-btn-bg: transparent;\n\n    --dark-filter-active-bg: #1e293b;\n\n    --dark-sticky-bg: rgb(25, 27, 31);\n\n\n    \/* -------------------------\n       LIGHT MODE PRESET\n       ------------------------- *\/\n\n    --light-bg: #ffffff;\n\n    --light-table-bg: #ffffff;\n\n    --light-header-bg: #f8fafc;\n\n    --light-header-text: #0f172a;\n\n    --light-border: #e2e8f0;\n\n    --light-text-primary: #0f172a;\n\n    --light-text-muted: #64748b;\n\n    --light-row-hover: #f1f5f9;\n\n    --light-filter-btn-bg: #f1f5f9;\n\n    --light-filter-active-bg: #0f172a;\n\n    --light-sticky-bg: #ffffff;\n\n\n    \/* ========================================================\n       ACTIVE THEME\n       DARK BY DEFAULT\n       ======================================================== *\/\n\n    --bg-color: var(--dark-bg);\n\n    --table-bg: var(--dark-table-bg);\n\n    --header-bg: var(--dark-header-bg);\n\n    --header-text: var(--dark-header-text);\n\n    --border-color: var(--dark-border);\n\n    --text-primary: var(--dark-text-primary);\n\n    --text-muted: var(--dark-text-muted);\n\n    --row-hover-bg: var(--dark-row-hover);\n\n    --filter-btn-bg: var(--dark-filter-btn-bg);\n\n    --filter-active-bg: var(--dark-filter-active-bg);\n\n    --sticky-bg: var(--dark-sticky-bg);\n\n\n    \/* ========================================================\n       OTHER EXISTING VARIABLES\n       ======================================================== *\/\n\n    --accent-bank: #a35a1f;\n\n    --accent-cut: #ff4d4d;\n\n    --accent-hike: #00d2c4;\n\n    --accent-bias: #a35a1f;\n\n\n    --png-btn-bg: #182234;\n\n    --png-btn-hover-bg: #23324a;\n\n    --png-btn-text-color: #ffffff;\n\n    --png-btn-border-radius: 6px;\n\n\n    --export-width: 1200px;\n\n    --export-height: 678px;\n\n    --export-file-prefix: \"Fed-Rate-Probability\";\n\n\n    --container-pad-top: 32px;\n\n    --container-pad-bottom: 32px;\n\n    --container-pad-left: 32px;\n\n    --container-pad-right: 32px;\n\n\n    --table-pad-top: 20px;\n\n    --table-pad-bottom: 20px;\n\n    --table-pad-left: 20px;\n\n    --table-pad-right: 20px;\n\n\n    --cell-pad-v: 8px;\n\n    --cell-pad-h: 6px;\n\n\n    --heading-font-size-desktop: 26px;\n\n    --table-font-size-desktop: 14px;\n\n    --filter-font-size-desktop: 13px;\n\n\n    --heading-font-size-mobile: 20px;\n\n    --table-font-size-mobile: 12px;\n\n    --filter-font-size-mobile: 10px;\n\n\n    --modal-bg-color: var(--bg-color);\n\n    --modal-title-size: 20px;\n\n    --modal-title-color: var(--accent-bank);\n\n    --modal-text-size: 14px;\n\n    --modal-label-size: 11px;\n\n\n    width: 100%;\n\n    max-width: 1200px;\n\n    margin: 0 auto;\n\n\n    color: var(--text-primary);\n\n\n    font-family:\n        -apple-system,\n        BlinkMacSystemFont,\n        \"Segoe UI\",\n        Roboto,\n        Helvetica,\n        Arial,\n        sans-serif;\n\n\n    text-align: left;\n\n    overflow: visible !important;\n\n}\n\n\n\/* ============================================================\n   LIGHT MODE MODIFIER\n   ============================================================ *\/\n\n#irp-widget-container.theme-light {\n\n    --bg-color: var(--light-bg);\n\n    --table-bg: var(--light-table-bg);\n\n    --header-bg: var(--light-header-bg);\n\n    --header-text: var(--light-header-text);\n\n    --border-color: var(--light-border);\n\n    --text-primary: var(--light-text-primary);\n\n    --text-muted: var(--light-text-muted);\n\n    --row-hover-bg: var(--light-row-hover);\n\n    --filter-btn-bg: var(--light-filter-btn-bg);\n\n    --filter-active-bg: var(--light-filter-active-bg);\n\n    --sticky-bg: var(--light-sticky-bg);\n\n    --modal-bg-color: var(--light-bg);\n\n}\n\n\n\/* ============================================================\n   RESET INSIDE WIDGET\n   ============================================================ *\/\n\n#irp-widget-container *,\n#irp-widget-container *::before,\n#irp-widget-container *::after {\n\n    box-sizing: border-box;\n\n}\n\n\n#irp-widget-container button {\n\n    outline: none !important;\n\n    -webkit-tap-highlight-color: transparent !important;\n\n}\n\n\n\/* ============================================================\n   MAIN CAPTURE AREA\n   ============================================================ *\/\n\n#irp-widget-container #capture-area {\n\n    width: 100%;\n\n    padding:\n\n        var(--container-pad-top)\n\n        var(--container-pad-right)\n\n        var(--container-pad-bottom)\n\n        var(--container-pad-left);\n\n\n    background-color: var(--bg-color);\n\n    border-radius: 8px;\n\n}\n\n\n\/* ============================================================\n   HEADER\n   ============================================================ *\/\n\n#irp-widget-container .header-wrapper {\n\n    display: flex;\n\n    justify-content: space-between;\n\n    align-items: center;\n\n    margin-bottom: 24px;\n\n}\n\n\n#irp-widget-container h1 {\n\n    margin: 0;\n\n    font-size:\n        var(--heading-font-size-desktop);\n\n    font-weight: 600;\n\n    color: var(--text-primary);\n\n    letter-spacing: -0.5px;\n\n    line-height: 1.2;\n\n}\n\n\n\/* ============================================================\n   PNG BUTTON\n   ============================================================ *\/\n\n#irp-widget-container .png-btn {\n\n    background-color:\n        var(--png-btn-bg);\n\n    color:\n        var(--png-btn-text-color);\n\n    border:\n        1px solid var(--border-color);\n\n    padding:\n        8px 18px;\n\n    border-radius:\n        var(--png-btn-border-radius);\n\n    font-size:\n        13px;\n\n    font-weight:\n        700;\n\n    cursor:\n        pointer;\n\n    transition:\n        background-color 0.2s,\n        border-color 0.2s;\n\n    letter-spacing:\n        0.5px;\n\n    white-space:\n        nowrap;\n\n}\n\n\n#irp-widget-container .png-btn:hover {\n\n    background-color:\n        var(--png-btn-hover-bg);\n\n    border-color:\n        #3b4d6c;\n\n}\n\n\n#irp-widget-container.theme-light .png-btn {\n\n    background-color:\n        #f1f5f9;\n\n    color:\n        #0f172a;\n\n    border-color:\n        #cbd5e1;\n\n}\n\n\n#irp-widget-container.theme-light .png-btn:hover {\n\n    background-color:\n        #e2e8f0;\n\n}\n\n\n\/* ============================================================\n   FILTER BAR\n   ============================================================ *\/\n\n#irp-widget-container .filter-bar {\n\n    display: flex;\n\n    gap: 10px;\n\n    margin-bottom: 20px;\n\n    flex-wrap: wrap;\n\n}\n\n\n#irp-widget-container .filter-section-label {\n\n    width: 100%;\n\n    font-size: 11px;\n\n    text-transform: uppercase;\n\n    letter-spacing: 1px;\n\n    color: var(--text-muted);\n\n    margin-bottom: -4px;\n\n    font-weight: 600;\n\n}\n\n\n#irp-widget-container .filter-btn {\n\n    background-color:\n        var(--filter-btn-bg);\n\n    border:\n        1px solid var(--border-color);\n\n    color:\n        var(--text-muted);\n\n    padding:\n        7px 16px;\n\n    border-radius:\n        20px;\n\n    font-size:\n        var(--filter-font-size-desktop);\n\n    cursor:\n        pointer;\n\n    transition:\n        all 0.2s ease;\n\n}\n\n\n#irp-widget-container .filter-btn:hover {\n\n    border-color:\n        var(--text-muted);\n\n    color:\n        var(--text-primary);\n\n}\n\n\n#irp-widget-container .filter-btn.active {\n\n    background-color:\n        var(--filter-active-bg);\n\n    color:\n        #ffffff;\n\n    border-color:\n        var(--filter-active-bg);\n\n}\n\n\n\/* ============================================================\n   TABLE CONTAINER\n   ============================================================ *\/\n\n#irp-widget-container .table-container {\n\n    width: 100%;\n\n    border:\n        1px solid var(--border-color);\n\n    border-radius:\n        6px;\n\n    background-color:\n        var(--table-bg);\n\n    padding:\n\n        var(--table-pad-top)\n\n        var(--table-pad-right)\n\n        var(--table-pad-bottom)\n\n        var(--table-pad-left);\n\n}\n\n\n\/* ============================================================\n   TABLE\n   ============================================================ *\/\n\n#irp-widget-container table {\n\n    width: 100%;\n\n    border-collapse:\n        collapse;\n\n    text-align:\n        center;\n\n    table-layout:\n        fixed;\n\n    background-color:\n        var(--table-bg);\n\n    border:\n        none;\n\n}\n\n\n#irp-widget-container th:nth-child(1) {\n    width: 10%;\n}\n\n#irp-widget-container th:nth-child(2) {\n    width: 10%;\n}\n\n#irp-widget-container th:nth-child(3) {\n    width: 15%;\n}\n\n#irp-widget-container th:nth-child(4) {\n    width: 11%;\n}\n\n#irp-widget-container th:nth-child(5) {\n    width: 11%;\n}\n\n#irp-widget-container th:nth-child(6) {\n    width: 10%;\n}\n\n#irp-widget-container th:nth-child(7) {\n    width: 10%;\n}\n\n#irp-widget-container th:nth-child(8) {\n    width: 10%;\n}\n\n#irp-widget-container th:nth-child(9) {\n    width: 13%;\n}\n\n\n\/* ============================================================\n   TABLE HEADER\n   ============================================================ *\/\n\n#irp-widget-container th {\n\n    background-color:\n        var(--header-bg);\n\n    color:\n        var(--header-text);\n\n    font-size:\n        var(--table-font-size-desktop);\n\n    font-weight:\n        600;\n\n    padding:\n        var(--cell-pad-v)\n        var(--cell-pad-h);\n\n    border-bottom:\n        1px solid var(--border-color);\n\n    border-right:\n        1px solid var(--border-color);\n\n    cursor:\n        pointer;\n\n    user-select:\n        none;\n\n    transition:\n        color 0.2s;\n\n    white-space:\n        nowrap;\n\n    text-align:\n        center;\n\n}\n\n\n#irp-widget-container th:hover {\n\n    opacity: 0.85;\n\n}\n\n\n#irp-widget-container th:last-child {\n\n    border-right:\n        none;\n\n}\n\n\n#irp-widget-container th.col-bank {\n\n    color:\n        var(--accent-bank);\n\n}\n\n\n#irp-widget-container th.col-cut {\n\n    color:\n        var(--accent-cut);\n\n}\n\n\n#irp-widget-container th.col-hike {\n\n    color:\n        var(--accent-hike);\n\n}\n\n\n#irp-widget-container th.col-bias {\n\n    color:\n        var(--accent-bias);\n\n}\n\n\n\/* ============================================================\n   SORT ICON\n   ============================================================ *\/\n\n#irp-widget-container .sort-indicator {\n\n    font-size:\n        11px;\n\n    margin-left:\n        2px;\n\n    color:\n        var(--header-text);\n\n    opacity:\n        0.7;\n\n}\n\n\n#irp-widget-container\nth.sorted-asc\n.sort-indicator::after {\n\n    content: \"\u25b2\";\n\n}\n\n\n#irp-widget-container\nth.sorted-desc\n.sort-indicator::after {\n\n    content: \"\u25bc\";\n\n}\n\n\n#irp-widget-container\nth:not(.sorted-asc):not(.sorted-desc)\n.sort-indicator::after {\n\n    content: \"\u2195\";\n\n    opacity: 0.4;\n\n}\n\n\n\/* ============================================================\n   TABLE CELLS\n   ============================================================ *\/\n\n#irp-widget-container td {\n\n    padding:\n        var(--cell-pad-v)\n        var(--cell-pad-h);\n\n    font-size:\n        var(--table-font-size-desktop);\n\n    border-bottom:\n        1px solid var(--border-color);\n\n    border-right:\n        1px solid var(--border-color);\n\n    color:\n        var(--text-primary);\n\n    background-color:\n        var(--table-bg);\n\n    white-space:\n        nowrap;\n\n    text-align:\n        center;\n\n}\n\n\n#irp-widget-container td:last-child {\n\n    border-right:\n        none;\n\n}\n\n\n#irp-widget-container tr:last-child td {\n\n    border-bottom:\n        none;\n\n}\n\n\n\/* ============================================================\n   ADAPTIVE ROW HOVER\n   ============================================================ *\/\n\n#irp-widget-container tbody tr:hover td {\n\n    background-color:\n        var(--row-hover-bg) !important;\n\n}\n\n\n\/* ============================================================\n   BANK BUTTON\n   ============================================================ *\/\n\n#irp-widget-container .bank-action-btn {\n\n    background-color:\n        var(--filter-btn-bg);\n\n    border:\n        1px solid var(--border-color);\n\n    color:\n        var(--accent-bank);\n\n    padding:\n        4px 8px;\n\n    border-radius:\n        12px;\n\n    font-size:\n        var(--table-font-size-desktop);\n\n    font-weight:\n        600;\n\n    cursor:\n        pointer;\n\n    transition:\n        all 0.2s ease;\n\n    display:\n        inline-flex;\n\n    align-items:\n        center;\n\n    justify-content:\n        center;\n\n    width:\n        100%;\n\n    max-width:\n        70px;\n\n    margin:\n        0 auto;\n\n}\n\n\n#irp-widget-container .bank-action-btn:hover {\n\n    border-color:\n        var(--accent-bank);\n\n}\n\n\n\/* ============================================================\n   DATA COLORS\n   ============================================================ *\/\n\n#irp-widget-container .text-hike {\n\n    color:\n        var(--accent-hike);\n\n    font-weight:\n        500;\n\n}\n\n\n#irp-widget-container .text-cut {\n\n    color:\n        var(--accent-cut);\n\n    font-weight:\n        500;\n\n}\n\n\n#irp-widget-container .text-hold {\n\n    color:\n        var(--text-primary);\n\n}\n\n\n#irp-widget-container .text-dovish {\n\n    color:\n        var(--accent-cut);\n\n    font-weight:\n        500;\n\n}\n\n\n#irp-widget-container .text-hawkish {\n\n    color:\n        var(--accent-hike);\n\n    font-weight:\n        500;\n\n}\n\n\n#irp-widget-container .text-neutral {\n\n    color:\n        var(--text-primary);\n\n}\n\n\n\/* ============================================================\n   API ERROR\n   ============================================================ *\/\n\n#irp-widget-container .api-error-card {\n\n    padding:\n        24px 20px;\n\n    text-align:\n        center;\n\n    background-color:\n        rgba(239,68,68,0.08);\n\n    border:\n        1px dashed #ef4444;\n\n    border-radius:\n        8px;\n\n    margin:\n        10px 0;\n\n}\n\n\n#irp-widget-container .api-error-title {\n\n    color:\n        #ef4444;\n\n    font-size:\n        15px;\n\n    font-weight:\n        700;\n\n    margin-bottom:\n        6px;\n\n}\n\n\n#irp-widget-container .api-error-desc {\n\n    color:\n        var(--text-primary);\n\n    font-size:\n        13px;\n\n    line-height:\n        1.5;\n\n    margin-bottom:\n        8px;\n\n    white-space:\n        normal;\n\n}\n\n\n#irp-widget-container .api-error-code {\n\n    font-family:\n        monospace;\n\n    font-size:\n        12px;\n\n    background:\n        rgba(0,0,0,0.3);\n\n    padding:\n        2px 8px;\n\n    border-radius:\n        4px;\n\n    color:\n        #fca5a5;\n\n    display:\n        inline-block;\n\n    margin-bottom:\n        12px;\n\n}\n\n\n#irp-widget-container .api-error-retry-btn {\n\n    background:\n        #ef4444;\n\n    color:\n        #ffffff;\n\n    border:\n        none;\n\n    padding:\n        6px 14px;\n\n    border-radius:\n        4px;\n\n    font-size:\n        12px;\n\n    font-weight:\n        600;\n\n    cursor:\n        pointer;\n\n}\n\n\n\/* ============================================================\n   MODAL\n   ============================================================ *\/\n\n#irp-modal-overlay {\n\n    position:\n        fixed;\n\n    top:\n        0;\n\n    left:\n        0;\n\n    width:\n        100vw;\n\n    height:\n        100vh;\n\n    background:\n        rgba(15,23,42,0.65);\n\n    backdrop-filter:\n        blur(8px);\n\n    -webkit-backdrop-filter:\n        blur(8px);\n\n    z-index:\n        999999;\n\n    display:\n        flex;\n\n    justify-content:\n        center;\n\n    align-items:\n        center;\n\n    opacity:\n        0;\n\n    visibility:\n        hidden;\n\n    transition:\n        opacity 0.3s ease,\n        visibility 0.3s ease;\n\n}\n\n\n#irp-modal-overlay.show {\n\n    opacity:\n        1;\n\n    visibility:\n        visible;\n\n}\n\n\n#irp-modal-content {\n\n    background-color:\n        var(--modal-bg-color);\n\n    border:\n        1px solid var(--border-color);\n\n    border-radius:\n        12px;\n\n    width:\n        90%;\n\n    max-width:\n        500px;\n\n    max-height:\n        85vh;\n\n    overflow-y:\n        auto;\n\n    padding:\n        28px;\n\n    box-shadow:\n        0 25px 50px -12px\n        rgba(0,0,0,0.6);\n\n    position:\n        relative;\n\n}\n\n\n#irp-modal-close {\n\n    position:\n        absolute;\n\n    top:\n        20px;\n\n    right:\n        20px;\n\n    background:\n        transparent;\n\n    border:\n        none;\n\n    color:\n        var(--text-muted);\n\n    font-size:\n        24px;\n\n    cursor:\n        pointer;\n\n}\n\n\n#irp-modal-title {\n\n    font-size:\n        var(--modal-title-size);\n\n    font-weight:\n        700;\n\n    color:\n        var(--modal-title-color);\n\n    margin-bottom:\n        24px;\n\n    padding-bottom:\n        12px;\n\n    border-bottom:\n        1px solid var(--border-color);\n\n}\n\n\n#irp-widget-container .modal-section {\n\n    margin-bottom:\n        20px;\n\n}\n\n\n#irp-widget-container .modal-label {\n\n    font-weight:\n        700;\n\n    color:\n        var(--text-muted);\n\n    text-transform:\n        uppercase;\n\n    font-size:\n        var(--modal-label-size);\n\n    letter-spacing:\n        0.5px;\n\n    margin-bottom:\n        8px;\n\n}\n\n\n#irp-widget-container .modal-val {\n\n    color:\n        var(--text-primary);\n\n    font-size:\n        var(--modal-text-size);\n\n    line-height:\n        1.6;\n\n    word-break:\n        break-word;\n\n    white-space:\n        pre-wrap;\n\n}\n\n\n\/* ============================================================\n   MOBILE\n   ============================================================ *\/\n\n@media screen and (max-width: 850px) {\n\n    #irp-widget-container h1 {\n\n        font-size:\n            var(--heading-font-size-mobile)\n            !important;\n\n    }\n\n\n    #irp-widget-container th,\n    #irp-widget-container td,\n    #irp-widget-container .bank-action-btn {\n\n        font-size:\n            var(--table-font-size-mobile)\n            !important;\n\n    }\n\n\n    #irp-widget-container .filter-bar {\n\n        display:\n            flex !important;\n\n        flex-wrap:\n            nowrap !important;\n\n        overflow-x:\n            auto !important;\n\n        gap:\n            4px !important;\n\n        padding-bottom:\n            4px !important;\n\n        -webkit-overflow-scrolling:\n            touch !important;\n\n    }\n\n\n    #irp-widget-container .filter-section-label {\n\n        display:\n            none !important;\n\n    }\n\n\n    #irp-widget-container .filter-btn {\n\n        font-size:\n            var(--filter-font-size-mobile)\n            !important;\n\n        padding:\n            4px 10px !important;\n\n        flex:\n            0 0 auto !important;\n\n        white-space:\n            nowrap !important;\n\n    }\n\n\n    body\n    #irp-widget-container\n    #capture-area\n    .table-container {\n\n        display:\n            block !important;\n\n        width:\n            100% !important;\n\n        max-width:\n            100vw !important;\n\n        overflow-x:\n            auto !important;\n\n        overflow-y:\n            hidden !important;\n\n        -webkit-overflow-scrolling:\n            touch !important;\n\n        padding-bottom:\n            16px !important;\n\n        padding-left:\n            0 !important;\n\n        padding-right:\n            0 !important;\n\n    }\n\n\n    body\n    #irp-widget-container\n    #capture-area\n    .table-container\n    table#rateTable {\n\n        display:\n            table !important;\n\n        width:\n            840px !important;\n\n        min-width:\n            840px !important;\n\n        max-width:\n            840px !important;\n\n        table-layout:\n            fixed !important;\n\n    }\n\n\n    \/* ========================================================\n       STICKY FIRST COLUMN\n       100% OPAQUE IN BOTH THEMES\n       ======================================================== *\/\n\n    body\n    #irp-widget-container\n    #capture-area\n    .table-container\n    table#rateTable\n    th:nth-child(1),\n\n    body\n    #irp-widget-container\n    #capture-area\n    .table-container\n    table#rateTable\n    td:nth-child(1) {\n\n        position:\n            sticky !important;\n\n        left:\n            0 !important;\n\n        z-index:\n            5 !important;\n\n        background-color:\n            var(--sticky-bg) !important;\n\n        opacity:\n            1 !important;\n\n        background-image:\n            none !important;\n\n        box-shadow:\n            4px 0 8px -2px\n            rgba(0,0,0,0.4)\n            !important;\n\n    }\n\n\n    body\n    #irp-widget-container\n    #capture-area\n    .table-container\n    table#rateTable\n    th:nth-child(1) {\n\n        background-color:\n            var(--header-bg)\n            !important;\n\n        opacity:\n            1 !important;\n\n        z-index:\n            6 !important;\n\n    }\n\n\n    body\n    #irp-widget-container\n    #capture-area\n    .table-container\n    table#rateTable\n    td:nth-child(1) {\n\n        background-color:\n            var(--sticky-bg)\n            !important;\n\n        opacity:\n            1 !important;\n\n    }\n\n\n    \/*\n       Keep sticky cell opaque\n       even when row is hovered\n    *\/\n\n    body\n    #irp-widget-container\n    #capture-area\n    table#rateTable\n    tbody\n    tr:hover\n    td:nth-child(1) {\n\n        background-color:\n            var(--sticky-bg)\n            !important;\n\n        opacity:\n            1 !important;\n\n    }\n\n\n    body\n    #irp-widget-container\n    #capture-area\n    .table-container::-webkit-scrollbar {\n\n        height:\n            8px !important;\n\n        display:\n            block !important;\n\n    }\n\n\n    body\n    #irp-widget-container\n    #capture-area\n    .table-container::-webkit-scrollbar-track {\n\n        background:\n            #182234 !important;\n\n        border-radius:\n            4px;\n\n    }\n\n\n    body\n    #irp-widget-container\n    #capture-area\n    .table-container::-webkit-scrollbar-thumb {\n\n        background:\n            var(--accent-bank);\n\n        border-radius:\n            4px;\n\n    }\n\n}\n\n<\/style>\n\n\n<!-- =========================================================\n     WIDGET HTML\n     ========================================================= -->\n\n<div id=\"irp-widget-container\">\n\n    <div id=\"capture-area\">\n\n        <div class=\"header-wrapper\">\n\n            <h1>\n                Fed Interest Rate Probability\n            <\/h1>\n\n            <button\n                class=\"png-btn\"\n                id=\"downloadPngBtn\"\n                type=\"button\"\n            >\n                PNG\n            <\/button>\n\n        <\/div>\n\n\n        <div\n            class=\"filter-bar\"\n            id=\"filterBar\"\n        >\n\n            <div\n                class=\"filter-section-label bank-filter-label\"\n                style=\"display:none;\"\n            >\n                Central Banks\n            <\/div>\n\n        <\/div>\n\n\n        <div class=\"table-container\">\n\n            <table id=\"rateTable\">\n\n                <thead>\n\n                    <tr>\n\n                        <th\n                            class=\"col-bank\"\n                            data-column=\"0\"\n                        >\n                            Bank\n                            <span class=\"sort-indicator\"><\/span>\n                        <\/th>\n\n                        <th data-column=\"1\">\n                            Rate\n                            <span class=\"sort-indicator\"><\/span>\n                        <\/th>\n\n                        <th data-column=\"2\">\n                            Next\n                            <span class=\"sort-indicator\"><\/span>\n                        <\/th>\n\n                        <th data-column=\"3\">\n                            Impl bp\n                            <span class=\"sort-indicator\"><\/span>\n                        <\/th>\n\n                        <th data-column=\"4\">\n                            Move\n                            <span class=\"sort-indicator\"><\/span>\n                        <\/th>\n\n                        <th\n                            class=\"col-cut\"\n                            data-column=\"5\"\n                        >\n                            Cut\n                            <span class=\"sort-indicator\"><\/span>\n                        <\/th>\n\n                        <th data-column=\"6\">\n                            Hold\n                            <span class=\"sort-indicator\"><\/span>\n                        <\/th>\n\n                        <th\n                            class=\"col-hike\"\n                            data-column=\"7\"\n                        >\n                            Hike\n                            <span class=\"sort-indicator\"><\/span>\n                        <\/th>\n\n                        <th\n                            class=\"col-bias\"\n                            data-column=\"8\"\n                        >\n                            Bias\n                            <span class=\"sort-indicator\"><\/span>\n                        <\/th>\n\n                    <\/tr>\n\n                <\/thead>\n\n\n                <tbody id=\"tableBody\">\n\n                    <tr>\n\n                        <td\n                            colspan=\"9\"\n                            style=\"\n                                text-align:center;\n                                color:var(--text-muted);\n                            \"\n                        >\n\n                            Loading live Fed data&#8230;\n\n                        <\/td>\n\n                    <\/tr>\n\n                <\/tbody>\n\n            <\/table>\n\n        <\/div>\n\n    <\/div>\n\n\n    <!-- =====================================================\n         COMMENTARY MODAL\n         ===================================================== -->\n\n    <div id=\"irp-modal-overlay\">\n\n        <div id=\"irp-modal-content\">\n\n            <button\n                id=\"irp-modal-close\"\n                type=\"button\"\n            >\n                &times;\n            <\/button>\n\n\n            <div id=\"irp-modal-title\">\n\n                Federal Reserve Analysis\n\n            <\/div>\n\n\n            <div class=\"modal-section\">\n\n                <div class=\"modal-label\">\n\n                    US Commentary\n\n                <\/div>\n\n                <div\n                    class=\"modal-val\"\n                    id=\"modal-val-long\"\n                >\n\n                    Loading live data&#8230;\n\n                <\/div>\n\n            <\/div>\n\n\n            <div class=\"modal-section\">\n\n                <div class=\"modal-label\">\n\n                    US Commentary Short\n\n                <\/div>\n\n                <div\n                    class=\"modal-val\"\n                    id=\"modal-val-short\"\n                >\n\n                    Loading live data&#8230;\n\n                <\/div>\n\n            <\/div>\n\n        <\/div>\n\n    <\/div>\n\n<\/div>\n\n\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/html2canvas\/1.4.1\/html2canvas.min.js\"><\/script>\n\n\n<script>\n\n(function () {\n\n\n    \/* =========================================================\n       ELEMENTS\n       ========================================================= *\/\n\n    const widgetContainer =\n        document.getElementById(\n            \"irp-widget-container\"\n        );\n\n\n    const IRP_CONFIG =\n        window.IRP_MAPPING_CONFIG;\n\n\n    if (\n        !widgetContainer ||\n        !IRP_CONFIG\n    ) {\n\n        console.error(\n            \"Interest Rate widget configuration missing.\"\n        );\n\n        return;\n    }\n\n\n    \/* =========================================================\n       API\n       ========================================================= *\/\n\n    const API_URL =\n        \"https:\/\/api.forexsource.net\/read\/us_interest_rates?Instance=55558_usa_rate_probability\";\n\n\n    const API_BEARER_KEY =\n        \"sk_live_y1ngrf9dpv63jcy7ql\";\n\n\n    \/* =========================================================\n       STATE\n       ========================================================= *\/\n\n    let globalData = [];\n\n    let currentSortColumn = null;\n\n    let currentSortDirection = \"asc\";\n\n\n    \/* =========================================================\n       MODAL REFERENCES\n       ========================================================= *\/\n\n    const modalOverlay =\n        document.getElementById(\n            \"irp-modal-overlay\"\n        );\n\n\n    const modalCloseBtn =\n        document.getElementById(\n            \"irp-modal-close\"\n        );\n\n\n    const modalTitle =\n        document.getElementById(\n            \"irp-modal-title\"\n        );\n\n\n    const modalValLong =\n        document.getElementById(\n            \"modal-val-long\"\n        );\n\n\n    const modalValShort =\n        document.getElementById(\n            \"modal-val-short\"\n        );\n\n\n    \/* =========================================================\n       FIELD READER\n       ========================================================= *\/\n\n    function readMapped(\n        item,\n        keyName,\n        fallback = \"\"\n    ) {\n\n        if (!item) {\n\n            return fallback;\n\n        }\n\n\n        const field =\n            IRP_CONFIG.fieldKeys[keyName]\n            ||\n            keyName;\n\n\n        return (\n            item[field] !== undefined &&\n            item[field] !== null\n        )\n\n            ? item[field]\n\n            : fallback;\n\n    }\n\n\n    \/* =========================================================\n       HTML ESCAPE\n       ========================================================= *\/\n\n    function escapeHtml(\n        value\n    ) {\n\n        return String(\n            value ?? \"\"\n        )\n\n        .replace(\n            \/&\/g,\n            \"&amp;\"\n        )\n\n        .replace(\n            \/<\/g,\n            \"&lt;\"\n        )\n\n        .replace(\n            \/>\/g,\n            \"&gt;\"\n        )\n\n        .replace(\n            \/\"\/g,\n            \"&quot;\"\n        )\n\n        .replace(\n            \/'\/g,\n            \"&#039;\"\n        );\n\n    }\n\n\n    \/* =========================================================\n       THEME DETECTION\n       ========================================================= *\/\n\n    function syncWebsiteTheme() {\n\n        try {\n\n            const html =\n                document.documentElement;\n\n\n            const body =\n                document.body;\n\n\n            \/* =================================================\n               STEP A\n               EXPLICIT WEBSITE THEME FLAGS\n               ================================================= *\/\n\n            const htmlTheme =\n                html.getAttribute(\n                    \"data-theme\"\n                );\n\n\n            const bodyTheme =\n                body.getAttribute(\n                    \"data-theme\"\n                );\n\n\n            const storedTheme =\n                localStorage.getItem(\n                    \"theme\"\n                );\n\n\n            const sureDashTheme =\n                localStorage.getItem(\n                    \"suredash_theme\"\n                );\n\n\n            const isExplicitLight =\n\n                htmlTheme === \"light\"\n\n                ||\n\n                bodyTheme === \"light\"\n\n                ||\n\n                html.classList.contains(\n                    \"light\"\n                )\n\n                ||\n\n                html.classList.contains(\n                    \"light-mode\"\n                )\n\n                ||\n\n                body.classList.contains(\n                    \"light\"\n                )\n\n                ||\n\n                body.classList.contains(\n                    \"light-mode\"\n                )\n\n                ||\n\n                storedTheme === \"light\"\n\n                ||\n\n                sureDashTheme === \"light\";\n\n\n            const isExplicitDark =\n\n                htmlTheme === \"dark\"\n\n                ||\n\n                bodyTheme === \"dark\"\n\n                ||\n\n                html.classList.contains(\n                    \"dark\"\n                )\n\n                ||\n\n                html.classList.contains(\n                    \"dark-mode\"\n                )\n\n                ||\n\n                body.classList.contains(\n                    \"dark\"\n                )\n\n                ||\n\n                body.classList.contains(\n                    \"dark-mode\"\n                )\n\n                ||\n\n                storedTheme === \"dark\"\n\n                ||\n\n                sureDashTheme === \"dark\";\n\n\n            let isLight;\n\n\n            if (\n                isExplicitLight\n            ) {\n\n                isLight =\n                    true;\n\n            }\n\n            else if (\n                isExplicitDark\n            ) {\n\n                isLight =\n                    false;\n\n            }\n\n            else {\n\n                \/* =============================================\n                   STEP B\n                   PERCEPTUAL LUMINANCE FALLBACK\n                   ============================================= *\/\n\n                let detected =\n                    false;\n\n\n                let parent =\n                    widgetContainer\n                        .parentElement;\n\n\n                while (\n                    parent &&\n                    parent !==\n                    document.body\n                ) {\n\n                    const background =\n                        window\n                        .getComputedStyle(\n                            parent\n                        )\n                        .backgroundColor;\n\n\n                    if (\n                        background &&\n                        background !==\n                        \"transparent\" &&\n                        background !==\n                        \"rgba(0, 0, 0, 0)\"\n                    ) {\n\n                        const rgb =\n                            background\n                            .match(\n                                \/\\d+(?:\\.\\d+)?\/g\n                            );\n\n\n                        if (\n                            rgb &&\n                            rgb.length >= 3\n                        ) {\n\n                            const r =\n                                Number(\n                                    rgb[0]\n                                );\n\n\n                            const g =\n                                Number(\n                                    rgb[1]\n                                );\n\n\n                            const b =\n                                Number(\n                                    rgb[2]\n                                );\n\n\n                            const luminance =\n\n                                0.299 * r\n\n                                +\n\n                                0.587 * g\n\n                                +\n\n                                0.114 * b;\n\n\n                            isLight =\n                                luminance > 128;\n\n\n                            detected =\n                                true;\n\n\n                            break;\n\n                        }\n\n                    }\n\n\n                    parent =\n                        parent.parentElement;\n\n                }\n\n\n                \/* =============================================\n                   BODY BACKGROUND FALLBACK\n                   ============================================= *\/\n\n                if (!detected) {\n\n                    const bodyBackground =\n                        window\n                        .getComputedStyle(\n                            body\n                        )\n                        .backgroundColor;\n\n\n                    const rgb =\n                        bodyBackground\n                        .match(\n                            \/\\d+(?:\\.\\d+)?\/g\n                        );\n\n\n                    if (\n                        rgb &&\n                        rgb.length >= 3\n                    ) {\n\n                        const r =\n                            Number(\n                                rgb[0]\n                            );\n\n\n                        const g =\n                            Number(\n                                rgb[1]\n                            );\n\n\n                        const b =\n                            Number(\n                                rgb[2]\n                            );\n\n\n                        const luminance =\n\n                            0.299 * r\n\n                            +\n\n                            0.587 * g\n\n                            +\n\n                            0.114 * b;\n\n\n                        isLight =\n                            luminance > 128;\n\n                    }\n\n                    else {\n\n                        isLight =\n                            false;\n\n                    }\n\n                }\n\n            }\n\n\n            \/* =================================================\n               STEP C\n               APPLY WIDGET CLASS\n               ================================================= *\/\n\n            widgetContainer\n                .classList\n                .toggle(\n                    \"theme-light\",\n                    isLight\n                );\n\n\n        }\n\n        catch (error) {\n\n            console.warn(\n                \"Theme synchronization error:\",\n                error\n            );\n\n        }\n\n    }\n\n\n    \/* =========================================================\n       REAL-TIME THEME LISTENING\n       ========================================================= *\/\n\n    syncWebsiteTheme();\n\n\n    const themeObserver =\n        new MutationObserver(\n            function () {\n\n                syncWebsiteTheme();\n\n            }\n        );\n\n\n    themeObserver.observe(\n\n        document.documentElement,\n\n        {\n\n            attributes:\n                true,\n\n            attributeFilter: [\n\n                \"class\",\n\n                \"data-theme\",\n\n                \"style\"\n\n            ]\n\n        }\n\n    );\n\n\n    themeObserver.observe(\n\n        document.body,\n\n        {\n\n            attributes:\n                true,\n\n            attributeFilter: [\n\n                \"class\",\n\n                \"data-theme\",\n\n                \"style\"\n\n            ]\n\n        }\n\n    );\n\n\n    let themeClickTimer;\n\n\n    document.addEventListener(\n\n        \"click\",\n\n        function () {\n\n            clearTimeout(\n                themeClickTimer\n            );\n\n\n            themeClickTimer =\n                setTimeout(\n\n                    syncWebsiteTheme,\n\n                    80\n\n                );\n\n        }\n\n    );\n\n\n    \/* =========================================================\n       API ERROR DISPLAY\n       ========================================================= *\/\n\n    function renderApiError(\n        title,\n        detailMessage,\n        statusCode\n    ) {\n\n        const tbody =\n            widgetContainer\n            .querySelector(\n                \"#tableBody\"\n            );\n\n\n        const filterBar =\n            widgetContainer\n            .querySelector(\n                \"#filterBar\"\n            );\n\n\n        if (filterBar) {\n\n            filterBar.style.display =\n                \"none\";\n\n        }\n\n\n        tbody.innerHTML = `\n\n            <tr>\n\n                <td\n                    colspan=\"9\"\n                    style=\"padding:16px;\"\n                >\n\n                    <div class=\"api-error-card\">\n\n                        <div class=\"api-error-title\">\n\n                            API Error:\n                            ${escapeHtml(title)}\n\n                        <\/div>\n\n\n                        <div class=\"api-error-desc\">\n\n                            ${escapeHtml(\n                                detailMessage\n                            )}\n\n                        <\/div>\n\n\n                        <div class=\"api-error-code\">\n\n                            HTTP Status:\n                            ${escapeHtml(\n                                statusCode\n                                ||\n                                \"Network \/ Client Error\"\n                            )}\n\n                        <\/div>\n\n\n                        <div>\n\n                            <button\n                                class=\"api-error-retry-btn\"\n                                type=\"button\"\n                                id=\"irpRetryButton\"\n                            >\n\n                                Retry Request\n\n                            <\/button>\n\n                        <\/div>\n\n                    <\/div>\n\n                <\/td>\n\n            <\/tr>\n        `;\n\n\n        const retryButton =\n            document.getElementById(\n                \"irpRetryButton\"\n            );\n\n\n        if (retryButton) {\n\n            retryButton\n                .addEventListener(\n\n                    \"click\",\n\n                    fetchInterestRateData\n\n                );\n\n        }\n\n    }\n\n\n    \/* =========================================================\n       API FETCH\n       ========================================================= *\/\n\n    async function\n    fetchInterestRateData() {\n\n        const tbody =\n            widgetContainer\n            .querySelector(\n                \"#tableBody\"\n            );\n\n\n        tbody.innerHTML = `\n\n            <tr>\n\n                <td\n                    colspan=\"9\"\n                    style=\"\n                        text-align:center;\n                        color:var(--text-muted);\n                    \"\n                >\n\n                    Loading live Fed data...\n\n                <\/td>\n\n            <\/tr>\n        `;\n\n\n        try {\n\n            const response =\n                await fetch(\n\n                    API_URL,\n\n                    {\n\n                        method:\n                            \"GET\",\n\n                        mode:\n                            \"cors\",\n\n                        cache:\n                            \"no-store\",\n\n                        credentials:\n                            \"omit\",\n\n                        headers: {\n\n                            \"Accept\":\n                                \"application\/json\",\n\n                            \"Authorization\":\n                                \"Bearer \"\n                                +\n                                API_BEARER_KEY\n\n                        }\n\n                    }\n\n                );\n\n\n            const responseText =\n                await response.text();\n\n\n            if (!response.ok) {\n\n                let errorTitle =\n                    \"Request Failed\";\n\n\n                let detail =\n                    responseText\n                    ||\n                    response.statusText\n                    ||\n                    \"The API rejected the request.\";\n\n\n                if (\n                    response.status ===\n                    401\n                ) {\n\n                    errorTitle =\n                        \"Unauthorized (401)\";\n\n\n                    detail =\n                        \"The API rejected the Bearer key.\";\n\n                }\n\n                else if (\n                    response.status ===\n                    403\n                ) {\n\n                    errorTitle =\n                        \"Forbidden (403)\";\n\n\n                    detail =\n                        \"The API rejected this website or request.\";\n\n                }\n\n                else if (\n                    response.status ===\n                    404\n                ) {\n\n                    errorTitle =\n                        \"Not Found (404)\";\n\n\n                    detail =\n                        \"The API endpoint or Instance value could not be found.\";\n\n                }\n\n                else if (\n                    response.status >=\n                    500\n                ) {\n\n                    errorTitle =\n                        \"Server Error (\"\n                        +\n                        response.status\n                        +\n                        \")\";\n\n                }\n\n\n                renderApiError(\n\n                    errorTitle,\n\n                    detail,\n\n                    response.status\n\n                );\n\n\n                return;\n\n            }\n\n\n            let result;\n\n\n            try {\n\n                result =\n                    JSON.parse(\n                        responseText\n                    );\n\n            }\n\n            catch (error) {\n\n                renderApiError(\n\n                    \"Invalid JSON\",\n\n                    \"The API returned a response that was not valid JSON.\",\n\n                    response.status\n\n                );\n\n\n                return;\n\n            }\n\n\n            let rawList;\n\n\n            if (\n                Array.isArray(\n                    result\n                )\n            ) {\n\n                rawList =\n                    result;\n\n            }\n\n            else if (\n                result &&\n                Array.isArray(\n                    result.data\n                )\n            ) {\n\n                rawList =\n                    result.data;\n\n            }\n\n            else if (\n                result &&\n                Array.isArray(\n                    result.rates\n                )\n            ) {\n\n                rawList =\n                    result.rates;\n\n            }\n\n            else {\n\n                rawList =\n                    [result];\n\n            }\n\n\n            if (\n                !rawList ||\n                rawList.length === 0\n            ) {\n\n                renderApiError(\n\n                    \"No Data Returned\",\n\n                    \"The API returned no records.\",\n\n                    \"200\"\n\n                );\n\n\n                return;\n\n            }\n\n\n            const filterBar =\n                widgetContainer\n                .querySelector(\n                    \"#filterBar\"\n                );\n\n\n            if (filterBar) {\n\n                filterBar.style.display =\n                    \"flex\";\n\n            }\n\n\n            if (\n                IRP_CONFIG.targetBank\n            ) {\n\n                const target =\n                    IRP_CONFIG\n                    .targetBank\n                    .toLowerCase();\n\n\n                const filtered =\n                    rawList.filter(\n\n                        function (\n                            item\n                        ) {\n\n                            const code =\n                                String(\n                                    readMapped(\n                                        item,\n                                        \"bankCode\"\n                                    )\n                                )\n                                .trim()\n                                .toLowerCase();\n\n\n                            const name =\n                                String(\n                                    readMapped(\n                                        item,\n                                        \"bankFullName\"\n                                    )\n                                )\n                                .trim()\n                                .toLowerCase();\n\n\n                            return (\n\n                                code.includes(\n                                    target\n                                )\n\n                                ||\n\n                                name.includes(\n                                    target\n                                )\n\n                                ||\n\n                                name.includes(\n                                    \"federal reserve\"\n                                )\n\n                            );\n\n                        }\n\n                    );\n\n\n                globalData =\n\n                    filtered.length\n\n                    ? filtered\n\n                    : rawList.slice(\n                        0,\n                        1\n                    );\n\n            }\n\n            else {\n\n                globalData =\n                    rawList;\n\n            }\n\n\n            buildBankFilterButtons();\n\n\n            renderTable();\n\n\n            syncWebsiteTheme();\n\n        }\n\n        catch (error) {\n\n            console.error(\n\n                \"API Connectivity Error:\",\n\n                error\n\n            );\n\n\n            renderApiError(\n\n                \"Connection Failed\",\n\n                error.message\n                ||\n                \"Could not connect to the API.\",\n\n                \"Network \/ CORS\"\n\n            );\n\n        }\n\n    }\n\n\n    window.irpRetryFetch =\n        fetchInterestRateData;\n\n\n    \/* =========================================================\n       FILTER BUTTONS\n       ========================================================= *\/\n\n    function\n    buildBankFilterButtons() {\n\n        const filterBar =\n            widgetContainer\n            .querySelector(\n                \"#filterBar\"\n            );\n\n\n        filterBar\n            .querySelectorAll(\n                \".filter-btn\"\n            )\n            .forEach(\n\n                function (\n                    element\n                ) {\n\n                    element.remove();\n\n                }\n\n            );\n\n\n        const banks = [\n\n            ...new Set(\n\n                globalData\n\n                .map(\n\n                    function (\n                        item\n                    ) {\n\n                        return (\n\n                            readMapped(\n                                item,\n                                \"bankCode\"\n                            )\n\n                            ||\n\n                            readMapped(\n                                item,\n                                \"bankFullName\"\n                            )\n\n                        );\n\n                    }\n\n                )\n\n                .filter(\n                    Boolean\n                )\n\n            )\n\n        ];\n\n\n        if (\n            banks.length ===\n            0\n        ) {\n\n            return;\n\n        }\n\n\n        const label =\n            filterBar\n            .querySelector(\n                \".bank-filter-label\"\n            );\n\n\n        if (label) {\n\n            label.style.display =\n                \"block\";\n\n        }\n\n\n        const allBtn =\n            document\n            .createElement(\n                \"button\"\n            );\n\n\n        allBtn.type =\n            \"button\";\n\n\n        allBtn.className =\n            \"filter-btn filter-all-btn active\";\n\n\n        allBtn.textContent =\n            \"All\";\n\n\n        allBtn.addEventListener(\n\n            \"click\",\n\n            function () {\n\n                filterBar\n                    .querySelectorAll(\n                        \".bank-filter-btn\"\n                    )\n                    .forEach(\n\n                        function (\n                            button\n                        ) {\n\n                            button\n                                .classList\n                                .remove(\n                                    \"active\"\n                                );\n\n                        }\n\n                    );\n\n\n                allBtn\n                    .classList\n                    .add(\n                        \"active\"\n                    );\n\n\n                renderTable();\n\n            }\n\n        );\n\n\n        filterBar.appendChild(\n            allBtn\n        );\n\n\n        banks.forEach(\n\n            function (\n                bank\n            ) {\n\n                const btn =\n                    document\n                    .createElement(\n                        \"button\"\n                    );\n\n\n                btn.type =\n                    \"button\";\n\n\n                btn.className =\n                    \"filter-btn bank-filter-btn\";\n\n\n                btn.setAttribute(\n\n                    \"data-filter-bank\",\n\n                    bank\n\n                );\n\n\n                btn.textContent =\n                    bank;\n\n\n                btn.addEventListener(\n\n                    \"click\",\n\n                    function () {\n\n                        btn\n                            .classList\n                            .toggle(\n                                \"active\"\n                            );\n\n\n                        if (\n                            btn\n                            .classList\n                            .contains(\n                                \"active\"\n                            )\n                        ) {\n\n                            allBtn\n                                .classList\n                                .remove(\n                                    \"active\"\n                                );\n\n                        }\n\n\n                        const anyActive =\n\n                            Array\n                            .from(\n\n                                filterBar\n                                .querySelectorAll(\n                                    \".bank-filter-btn\"\n                                )\n\n                            )\n                            .some(\n\n                                function (\n                                    button\n                                ) {\n\n                                    return button\n                                        .classList\n                                        .contains(\n                                            \"active\"\n                                        );\n\n                                }\n\n                            );\n\n\n                        if (!anyActive) {\n\n                            allBtn\n                                .classList\n                                .add(\n                                    \"active\"\n                                );\n\n                        }\n\n\n                        renderTable();\n\n                    }\n\n                );\n\n\n                filterBar\n                    .appendChild(\n                        btn\n                    );\n\n            }\n\n        );\n\n    }\n\n\n    \/* =========================================================\n       SORT VALUES\n       ========================================================= *\/\n\n    function getColumnValue(\n        item,\n        column\n    ) {\n\n        switch (column) {\n\n            case 0:\n                return (\n                    readMapped(\n                        item,\n                        \"bankCode\"\n                    )\n                    ||\n                    readMapped(\n                        item,\n                        \"bankFullName\"\n                    )\n                );\n\n            case 1:\n                return readMapped(\n                    item,\n                    \"rate\"\n                );\n\n            case 2:\n                return readMapped(\n                    item,\n                    \"nextMeeting\"\n                );\n\n            case 3:\n                return readMapped(\n                    item,\n                    \"implBp\"\n                );\n\n            case 4:\n                return readMapped(\n                    item,\n                    \"move\"\n                );\n\n            case 5:\n                return readMapped(\n                    item,\n                    \"cut\"\n                );\n\n            case 6:\n                return readMapped(\n                    item,\n                    \"hold\"\n                );\n\n            case 7:\n                return readMapped(\n                    item,\n                    \"hike\"\n                );\n\n            case 8:\n                return readMapped(\n                    item,\n                    \"bias\"\n                );\n\n            default:\n                return \"\";\n\n        }\n\n    }\n\n\n    \/* =========================================================\n       TABLE\n       ========================================================= *\/\n\n    function renderTable() {\n\n        const tbody =\n            widgetContainer\n            .querySelector(\n                \"#tableBody\"\n            );\n\n\n        tbody.innerHTML =\n            \"\";\n\n\n        if (\n            !globalData ||\n            globalData.length ===\n            0\n        ) {\n\n            tbody.innerHTML = `\n\n                <tr>\n\n                    <td\n                        colspan=\"9\"\n                        style=\"\n                            text-align:center;\n                            color:var(--text-muted);\n                        \"\n                    >\n\n                        No Federal Reserve data available.\n\n                    <\/td>\n\n                <\/tr>\n            `;\n\n\n            return;\n\n        }\n\n\n        let processedData =\n            [...globalData];\n\n\n        if (\n            currentSortColumn !==\n            null\n        ) {\n\n            processedData.sort(\n\n                function (\n                    a,\n                    b\n                ) {\n\n                    let valA =\n                        getColumnValue(\n                            a,\n                            currentSortColumn\n                        )\n                        ||\n                        \"\";\n\n\n                    let valB =\n                        getColumnValue(\n                            b,\n                            currentSortColumn\n                        )\n                        ||\n                        \"\";\n\n\n                    if (\n                        currentSortColumn ===\n                        2\n                    ) {\n\n                        const dateA =\n                            Date.parse(\n                                valA\n                            )\n                            ||\n                            0;\n\n\n                        const dateB =\n                            Date.parse(\n                                valB\n                            )\n                            ||\n                            0;\n\n\n                        return (\n\n                            currentSortDirection ===\n                            \"asc\"\n\n                        )\n\n                            ? dateA - dateB\n\n                            : dateB - dateA;\n\n                    }\n\n\n                    if (\n                        [\n                            1,\n                            3,\n                            5,\n                            6,\n                            7\n                        ]\n                        .includes(\n                            currentSortColumn\n                        )\n                    ) {\n\n                        let numA =\n                            parseFloat(\n\n                                String(\n                                    valA\n                                )\n                                .replace(\n                                    \/[^0-9.-]+\/g,\n                                    \"\"\n                                )\n\n                            );\n\n\n                        let numB =\n                            parseFloat(\n\n                                String(\n                                    valB\n                                )\n                                .replace(\n                                    \/[^0-9.-]+\/g,\n                                    \"\"\n                                )\n\n                            );\n\n\n                        numA =\n                            isNaN(\n                                numA\n                            )\n                            ? 0\n                            : numA;\n\n\n                        numB =\n                            isNaN(\n                                numB\n                            )\n                            ? 0\n                            : numB;\n\n\n                        return (\n\n                            currentSortDirection ===\n                            \"asc\"\n\n                        )\n\n                            ? numA - numB\n\n                            : numB - numA;\n\n                    }\n\n\n                    valA =\n                        String(\n                            valA\n                        )\n                        .toLowerCase();\n\n\n                    valB =\n                        String(\n                            valB\n                        )\n                        .toLowerCase();\n\n\n                    if (\n                        valA < valB\n                    ) {\n\n                        return (\n\n                            currentSortDirection ===\n                            \"asc\"\n\n                        )\n                            ? -1\n                            : 1;\n\n                    }\n\n\n                    if (\n                        valA > valB\n                    ) {\n\n                        return (\n\n                            currentSortDirection ===\n                            \"asc\"\n\n                        )\n                            ? 1\n                            : -1;\n\n                    }\n\n\n                    return 0;\n\n                }\n\n            );\n\n        }\n\n\n        const activeBankFilters =\n\n            Array\n            .from(\n\n                widgetContainer\n                .querySelectorAll(\n                    \".bank-filter-btn.active\"\n                )\n\n            )\n            .map(\n\n                function (\n                    button\n                ) {\n\n                    return button\n                        .getAttribute(\n                            \"data-filter-bank\"\n                        );\n\n                }\n\n            )\n            .filter(\n                Boolean\n            );\n\n\n        const showAll =\n            activeBankFilters.length ===\n            0;\n\n\n        processedData.forEach(\n\n            function (\n                item\n            ) {\n\n                const bank =\n                    readMapped(\n                        item,\n                        \"bankCode\",\n                        \"Fed\"\n                    );\n\n\n                const rate =\n                    readMapped(\n                        item,\n                        \"rate\",\n                        \"--\"\n                    );\n\n\n                const nextMeeting =\n                    readMapped(\n                        item,\n                        \"nextMeeting\",\n                        \"--\"\n                    );\n\n\n                const implBp =\n                    readMapped(\n                        item,\n                        \"implBp\",\n                        \"--\"\n                    );\n\n\n                const move =\n                    readMapped(\n                        item,\n                        \"move\",\n                        \"Hold\"\n                    );\n\n\n                const cut =\n                    readMapped(\n                        item,\n                        \"cut\",\n                        \"0.0%\"\n                    );\n\n\n                const hold =\n                    readMapped(\n                        item,\n                        \"hold\",\n                        \"0.0%\"\n                    );\n\n\n                const hike =\n                    readMapped(\n                        item,\n                        \"hike\",\n                        \"0.0%\"\n                    );\n\n\n                const bias =\n                    readMapped(\n                        item,\n                        \"bias\",\n                        \"Neutral\"\n                    );\n\n\n                if (\n                    !showAll &&\n                    !activeBankFilters\n                    .includes(\n                        bank\n                    )\n                ) {\n\n                    return;\n\n                }\n\n\n                const moveLower =\n                    String(\n                        move\n                    )\n                    .toLowerCase();\n\n\n                const biasLower =\n                    String(\n                        bias\n                    )\n                    .toLowerCase();\n\n\n                const moveClass =\n\n                    moveLower ===\n                    \"hike\"\n\n                        ? \"text-hike\"\n\n                        : moveLower ===\n                          \"cut\"\n\n                            ? \"text-cut\"\n\n                            : \"text-hold\";\n\n\n                const biasClass =\n\n                    biasLower ===\n                    \"hawkish\"\n\n                        ? \"text-hawkish\"\n\n                        : biasLower ===\n                          \"dovish\"\n\n                            ? \"text-dovish\"\n\n                            : \"text-neutral\";\n\n\n                const tr =\n                    document\n                    .createElement(\n                        \"tr\"\n                    );\n\n\n                tr.innerHTML = `\n\n                    <td>\n\n                        <button\n                            class=\"bank-action-btn\"\n                            type=\"button\"\n                            data-bank=\"${escapeHtml(bank)}\"\n                        >\n\n                            ${escapeHtml(bank)}\n\n                        <\/button>\n\n                    <\/td>\n\n\n                    <td>\n                        ${escapeHtml(rate)}\n                    <\/td>\n\n\n                    <td>\n                        ${escapeHtml(nextMeeting)}\n                    <\/td>\n\n\n                    <td>\n                        ${escapeHtml(implBp)}\n                    <\/td>\n\n\n                    <td class=\"${moveClass}\">\n                        ${escapeHtml(move)}\n                    <\/td>\n\n\n                    <td class=\"text-cut\">\n                        ${escapeHtml(cut)}\n                    <\/td>\n\n\n                    <td class=\"text-hold\">\n                        ${escapeHtml(hold)}\n                    <\/td>\n\n\n                    <td class=\"text-hike\">\n                        ${escapeHtml(hike)}\n                    <\/td>\n\n\n                    <td class=\"${biasClass}\">\n                        ${escapeHtml(bias)}\n                    <\/td>\n\n                `;\n\n\n                tbody\n                    .appendChild(\n                        tr\n                    );\n\n            }\n\n        );\n\n\n        syncWebsiteTheme();\n\n    }\n\n\n    \/* =========================================================\n       MODAL\n       ========================================================= *\/\n\n    function openModal(\n        bankIdentifier\n    ) {\n\n        const matchedItem =\n\n            globalData.find(\n\n                function (\n                    item\n                ) {\n\n                    return (\n\n                        readMapped(\n                            item,\n                            \"bankCode\"\n                        )\n                        ===\n                        bankIdentifier\n\n                        ||\n\n                        readMapped(\n                            item,\n                            \"bankFullName\"\n                        )\n                        ===\n                        bankIdentifier\n\n                    );\n\n                }\n\n            )\n\n            ||\n\n            globalData[0];\n\n\n        if (!matchedItem) {\n\n            return;\n\n        }\n\n\n        modalTitle.textContent =\n\n            readMapped(\n\n                matchedItem,\n\n                \"bankFullName\",\n\n                \"Federal Reserve\"\n\n            )\n\n            +\n\n            \" Analysis\";\n\n\n        const longField =\n            IRP_CONFIG\n            .commentaryKeys\n            .longCommentary;\n\n\n        const shortField =\n            IRP_CONFIG\n            .commentaryKeys\n            .shortCommentary;\n\n\n        modalValLong.textContent =\n\n            matchedItem[\n                longField\n            ]\n\n            ||\n\n            \"No commentary available.\";\n\n\n        modalValShort.textContent =\n\n            matchedItem[\n                shortField\n            ]\n\n            ||\n\n            \"No short commentary available.\";\n\n\n        modalOverlay\n            .classList\n            .add(\n                \"show\"\n            );\n\n    }\n\n\n    function closeModal() {\n\n        modalOverlay\n            .classList\n            .remove(\n                \"show\"\n            );\n\n    }\n\n\n    modalCloseBtn.addEventListener(\n\n        \"click\",\n\n        closeModal\n\n    );\n\n\n    modalOverlay.addEventListener(\n\n        \"click\",\n\n        function (\n            event\n        ) {\n\n            if (\n                event.target ===\n                modalOverlay\n            ) {\n\n                closeModal();\n\n            }\n\n        }\n\n    );\n\n\n    \/* =========================================================\n       MAIN WIDGET EVENTS\n       ========================================================= *\/\n\n    widgetContainer.addEventListener(\n\n        \"click\",\n\n        function (\n            event\n        ) {\n\n            const bankButton =\n                event.target\n                .closest(\n                    \".bank-action-btn\"\n                );\n\n\n            if (bankButton) {\n\n                openModal(\n\n                    bankButton\n                    .getAttribute(\n                        \"data-bank\"\n                    )\n\n                );\n\n\n                return;\n\n            }\n\n\n            const th =\n                event.target\n                .closest(\n                    \"#rateTable th\"\n                );\n\n\n            if (!th) {\n\n                return;\n\n            }\n\n\n            const column =\n                parseInt(\n\n                    th.getAttribute(\n                        \"data-column\"\n                    ),\n\n                    10\n\n                );\n\n\n            if (\n                isNaN(\n                    column\n                )\n            ) {\n\n                return;\n\n            }\n\n\n            if (\n                currentSortColumn ===\n                column\n            ) {\n\n                if (\n                    currentSortDirection ===\n                    \"asc\"\n                ) {\n\n                    currentSortDirection =\n                        \"desc\";\n\n                }\n\n                else {\n\n                    currentSortColumn =\n                        null;\n\n\n                    currentSortDirection =\n                        \"asc\";\n\n                }\n\n            }\n\n            else {\n\n                currentSortColumn =\n                    column;\n\n\n                currentSortDirection =\n                    \"asc\";\n\n            }\n\n\n            widgetContainer\n                .querySelectorAll(\n                    \"#rateTable th\"\n                )\n                .forEach(\n\n                    function (\n                        header\n                    ) {\n\n                        header\n                            .classList\n                            .remove(\n\n                                \"sorted-asc\",\n\n                                \"sorted-desc\"\n\n                            );\n\n                    }\n\n                );\n\n\n            if (\n                currentSortColumn !==\n                null\n            ) {\n\n                th.classList.add(\n\n                    currentSortDirection ===\n                    \"asc\"\n\n                        ? \"sorted-asc\"\n\n                        : \"sorted-desc\"\n\n                );\n\n            }\n\n\n            renderTable();\n\n        }\n\n    );\n\n\n    \/* =========================================================\n       PNG EXPORT\n       ========================================================= *\/\n\n    const pngButton =\n        widgetContainer\n        .querySelector(\n            \"#downloadPngBtn\"\n        );\n\n\n    if (pngButton) {\n\n        pngButton.addEventListener(\n\n            \"click\",\n\n            function () {\n\n                const captureArea =\n                    widgetContainer\n                    .querySelector(\n                        \"#capture-area\"\n                    );\n\n\n                const rootStyles =\n                    getComputedStyle(\n                        widgetContainer\n                    );\n\n\n                const targetWidth =\n                    parseInt(\n\n                        rootStyles\n                        .getPropertyValue(\n                            \"--export-width\"\n                        ),\n\n                        10\n\n                    )\n                    ||\n                    1200;\n\n\n                const targetHeight =\n                    parseInt(\n\n                        rootStyles\n                        .getPropertyValue(\n                            \"--export-height\"\n                        ),\n\n                        10\n\n                    )\n                    ||\n                    678;\n\n\n                const filePrefix =\n\n                    rootStyles\n                    .getPropertyValue(\n                        \"--export-file-prefix\"\n                    )\n                    .trim()\n                    .replace(\n                        \/['\"]+\/g,\n                        \"\"\n                    )\n\n                    ||\n\n                    \"Fed-Rate-Probability\";\n\n\n                const now =\n                    new Date();\n\n\n                const dd =\n                    String(\n                        now.getDate()\n                    )\n                    .padStart(\n                        2,\n                        \"0\"\n                    );\n\n\n                const monthNames = [\n\n                    \"JAN\",\n\n                    \"FEB\",\n\n                    \"MAR\",\n\n                    \"APR\",\n\n                    \"MAY\",\n\n                    \"JUN\",\n\n                    \"JUL\",\n\n                    \"AUG\",\n\n                    \"SEP\",\n\n                    \"OCT\",\n\n                    \"NOV\",\n\n                    \"DEC\"\n\n                ];\n\n\n                const mmm =\n                    monthNames[\n                        now.getMonth()\n                    ];\n\n\n                const yy =\n                    String(\n                        now.getFullYear()\n                    )\n                    .slice(\n                        -2\n                    );\n\n\n                const dateStr =\n                    `${dd}-${mmm}-${yy}`;\n\n\n                html2canvas(\n\n                    captureArea,\n\n                    {\n\n                        backgroundColor:\n\n                            rootStyles\n                            .getPropertyValue(\n                                \"--bg-color\"\n                            )\n                            .trim(),\n\n                        scale:\n                            2,\n\n                        logging:\n                            false,\n\n                        useCORS:\n                            true\n\n                    }\n\n                )\n\n                .then(\n\n                    function (\n                        canvas\n                    ) {\n\n                        const finalCanvas =\n                            document\n                            .createElement(\n                                \"canvas\"\n                            );\n\n\n                        finalCanvas.width =\n                            targetWidth;\n\n\n                        finalCanvas.height =\n                            targetHeight;\n\n\n                        const ctx =\n                            finalCanvas\n                            .getContext(\n                                \"2d\"\n                            );\n\n\n                        ctx.drawImage(\n\n                            canvas,\n\n                            0,\n\n                            0,\n\n                            targetWidth,\n\n                            targetHeight\n\n                        );\n\n\n                        const link =\n                            document\n                            .createElement(\n                                \"a\"\n                            );\n\n\n                        link.download =\n                            `${filePrefix}-${dateStr}.png`;\n\n\n                        link.href =\n                            finalCanvas\n                            .toDataURL(\n                                \"image\/png\"\n                            );\n\n\n                        link.click();\n\n                    }\n\n                )\n\n                .catch(\n\n                    function (\n                        error\n                    ) {\n\n                        console.error(\n\n                            \"PNG export error:\",\n\n                            error\n\n                        );\n\n                    }\n\n                );\n\n            }\n\n        );\n\n    }\n\n\n    \/* =========================================================\n       INITIAL LOAD\n       ========================================================= *\/\n\n    function initializeWidget() {\n\n        syncWebsiteTheme();\n\n\n        fetchInterestRateData();\n\n    }\n\n\n    if (\n        document.readyState ===\n        \"loading\"\n    ) {\n\n        document.addEventListener(\n\n            \"DOMContentLoaded\",\n\n            initializeWidget,\n\n            {\n                once:\n                    true\n            }\n\n        );\n\n    }\n\n    else {\n\n        initializeWidget();\n\n    }\n\n})();\n\n<\/script>\n","protected":false},"featured_media":0,"comment_status":"open","ping_status":"closed","template":"","portal_group":[16],"class_list":["post-581","portal","type-portal","status-publish","hentry","portal_group-economic-indicators"],"tpgb_featured_images":null,"tpgb_post_meta_info":{"get_date":"September 12, 2026","get_modified_date":"September 13, 2026","category_list":{"portal_group":[{"term_id":16,"name":"Economic Indicators","slug":"economic-indicators","term_group":0,"term_taxonomy_id":16,"taxonomy":"portal_group","description":"","parent":0,"count":3,"filter":"raw"}]},"comment_count":0,"post_likes":0,"post_views":0},"tpgb_post_category":{"portal_group":"<a href=\"https:\/\/forexsource.net\/portal_group\/economic-indicators\/\" alt=\"Economic Indicators\"  class=\"portal_group-economic-indicators\">Economic Indicators<\/a> "},"_links":{"self":[{"href":"https:\/\/forexsource.net\/wp-json\/wp\/v2\/portal\/581","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/forexsource.net\/wp-json\/wp\/v2\/portal"}],"about":[{"href":"https:\/\/forexsource.net\/wp-json\/wp\/v2\/types\/portal"}],"replies":[{"embeddable":true,"href":"https:\/\/forexsource.net\/wp-json\/wp\/v2\/comments?post=581"}],"wp:attachment":[{"href":"https:\/\/forexsource.net\/wp-json\/wp\/v2\/media?parent=581"}],"wp:term":[{"taxonomy":"portal_group","embeddable":true,"href":"https:\/\/forexsource.net\/wp-json\/wp\/v2\/portal_group?post=581"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}