1<!DOCTYPE html> 2<html lang="en"> 3 <head> 4 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 5 <!-- force IE browsers in compatibility mode to use their most aggressive rendering engine --> 6 7 <meta charset="utf-8"> 8 <title>Voipfone Status</title> 9 <meta name="description" content="Welcome to Voipfone's home for real-time and historical data on system performance."> 10 11 <!-- Mobile viewport optimization --> 12 <meta name="HandheldFriendly" content="True"> 13 <meta name="MobileOptimized" content="320"> 14 <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"> 15 16 <!-- Time this page was rendered - http://purl.org/dc/terms/issued --> 17 <meta name="issued" content="1791188164"> 18 19 <!-- Mobile IE allows us to activate ClearType technology for smoothing fonts for easy reading --> 20 <meta http-equiv="cleartype" content="on"> 21 22 <!-- Atlassian Sans & Mono Fonts --> 23<link 24 rel="preconnect" 25 href="https://ds-cdn.prod-east.frontend.public.atl-paas.net" /> 26<link 27 rel="preload" 28 href="https://ds-cdn.prod-east.frontend.public.atl-paas.net/assets/fonts/atlassian-sans/v3/AtlassianSans-latin.woff2" 29 as="font" type="font/woff2" crossorigin /> 30<link 31 rel="preload" 32 href="https://ds-cdn.prod-east.frontend.public.atl-paas.net/assets/font-rules/v5/atlassian-fonts.css" 33 as="style" crossorigin /> 34 35 <style> 36 /* Dynamic Font Stack based on Feature Flag */ 37 /* Using Atlassian Sans & Mono */ 38 :root { 39 --font-stack-a: "Atlassian Sans", "Helvetica Neue", Helvetica, Arial, Sans-Serif; 40 --font-stack-b: "Atlassian Mono", "SFMono-Medium", "SF Mono", "Segoe UI Mono", "Roboto Mono", "Ubuntu Mono", Menlo, Consolas, Courier, monospace; 41 } 42</style> 43 44 45 <link rel="icon" type="image/x-icon" href="//dka575ofm4ao0.cloudfront.net/pages-favicon_logos/original/16003/uFVlAwiSTaskFLgaj06A" /> 46 47 <link rel="shortcut icon" href='//dka575ofm4ao0.cloudfront.net/pages-favicon_logos/original/16003/uFVlAwiSTaskFLgaj06A'> 48 49 <link rel="alternate" type="application/atom+xml" href="https://www.voipfonestatus.co.uk/history.atom" title="Voipfone Status History - Atom Feed"> 50 <link rel="alternate" type="application/rss+xml" href="https://www.voipfonestatus.co.uk/history.rss" title="Voipfone Status History - RSS Feed"> 51 52 <!-- Canonical Link to ensure that only the custom domain is indexed when present --> 53 <link rel="canonical" href="https://www.voipfonestatus.co.uk"> 54 55 <meta name="_globalsign-domain-verification" content="y_VzfckMy4iePo5oDJNivyYIjh8LffYa4jzUndm_bZ"/> 56 57 58 <link rel="alternate" type="application/atom+xml" title="ATOM" href="https://www.voipfonestatus.co.uk/history.atom" /> 59 60 <!-- Le styles --> 61 <link rel="stylesheet" href="https://dka575ofm4ao0.cloudfront.net/packs/0.a7d86fc6a129fa9540bc.css" media="screen" /> 62 <link rel="stylesheet" href="https://dka575ofm4ao0.cloudfront.net/assets/status/status_manifest-e7416fcfeedbe261454d619d119599335f4c7b18c9e245c13722dbb0998dc023.css" media="all" /> 63 64
64<script src="https://dka575ofm4ao0.cloudfront.net/assets/jquery-3.5.1.min-729e416557a365062a8a20f0562f18aa171da57298005d392312670c706c68de.js"></script>
64 65 66
66<script> 67 window.pageColorData = {"blue":"#3498DB","border":"#E0E0E0","body_background":"#ffffff","font":"#333333","graph":"#3498db","green":"#2fcc66","light_font":"#AAAAAA","link":"#3498db","orange":"#e67e22","red":"#e74c3c","yellow":"#f1c40f","no_data":"#b3bac5"}; 68 </script>
68 69 <style> 70 /* BODY BACKGROUND */ /* BODY BACKGROUND */ /* BODY BACKGROUND */ /* BODY BACKGROUND */ /* BODY BACKGROUND */ 71 body, 72 .layout-content.status.status-api .section .example-container .example-opener .color-secondary, 73 .grouped-items-selector, 74 .layout-content.status.status-full-history .history-nav a.current, 75 div[id^="subscribe-modal"] .modal-footer, 76 div[id^="subscribe-modal"], 77 div[id^="updates-dropdown"] .updates-dropdown-section, 78 #uptime-tooltip .tooltip-box { 79 background-color:#ffffff; 80 } 81 82 #uptime-tooltip .pointer-container .pointer-smaller { 83 border-bottom-color:#ffffff; 84 } 85 86 87 88 89 /* PRIMARY FONT COLOR */ /* PRIMARY FONT COLOR */ /* PRIMARY FONT COLOR */ /* PRIMARY FONT COLOR */ 90 body.status, 91 .color-primary, 92 .color-primary:hover, 93 .layout-content.status-index .status-day .update-title.impact-none a, 94 .layout-content.status-index .status-day .update-title.impact-none a:hover, 95 .layout-content.status-index .timeframes-container .timeframe.active, 96 .layout-content.status-full-history .month .incident-container .impact-none, 97 .layout-content.status.status-index .incidents-list .incident-title.impact-none a, 98 .incident-history .impact-none, 99 .layout-content.status .grouped-items-selector.inline .grouped-item.active, 100 .layout-content.status.status-full-history .history-nav a.current, 101 .layout-content.status.status-full-history .history-nav a:not(.current):hover, 102 div[id^="subscribe-modal"] .modal-header .close, 103 .grouped-item-label, 104 #uptime-tooltip .tooltip-box .tooltip-content .related-events .related-event a.related-event-link { 105 color:#333333; 106 } 107 108 .layout-content.status.status-index .components-statuses .component-container .name { 109 color:#333333; 110 color:rgba(51,51,51,.8); 111 } 112 113 114 115 116 /* SECONDARY FONT COLOR */ /* SECONDARY FONT COLOR */ /* SECONDARY FONT COLOR */ /* SECONDARY FONT COLOR */ 117 small, 118 .layout-content.status .table-row .date, 119 .color-secondary, 120 .layout-content.status .grouped-items-selector.inline .grouped-item, 121 .layout-content.status.status-full-history .history-footer .pagination a.disabled, 122 .layout-content.status.status-full-history .history-nav a, 123 #uptime-tooltip .tooltip-box .tooltip-content .related-events #related-event-header { 124 color:#AAAAAA; 125 } 126 127 128 129 130 /* BORDER COLOR */ /* BORDER COLOR */ /* BORDER COLOR */ /* BORDER COLOR */ /* BORDER COLOR */ /* BORDER COLOR */ 131 body.status .layout-content.status .border-color, 132 hr, 133 .tooltip-base, 134 .markdown-display table, 135 div[id^="subscribe-modal"], 136 #uptime-tooltip .tooltip-box { 137 border-color:#E0E0E0; 138 } 139 140 div[id^="subscribe-modal"] .modal-footer, 141 .markdown-display table td { 142 border-top-color:#E0E0E0; 143 } 144 145 .markdown-display table td + td, .markdown-display table th + th { 146 border-left-color:#E0E0E0; 147 } 148 149 div[id^="subscribe-modal"] .modal-header, 150 #uptime-tooltip .pointer-container .pointer-larger { 151 border-bottom-color:#E0E0E0; 152 } 153 154 #uptime-tooltip .tooltip-box .outage-field { 155 /* 156 Generate the background-color for the outage-field from the css_body_background_color and css_border_color. 157 158 For the default background (#ffffff) and default css_border_color (#e0e0e0), use the luminosity of the default background with a magic number to arrive at 159 the original outage-field background color (#f4f5f7). I used the formula Target Color = Color * alpha + Background * (1 - alpha) to find the magic number of ~0.08. 160 161 For darker css_body_background_color, luminosity values are lower so alpha trends toward becoming transparent (thus outage-field background becomes same as css_body_background_color). 162 */ 163 background-color: rgba(224,224,224,0.31); 164 165 /* 166 outage-field border-color alpha is inverse to the luminosity of css_body_background_color. 167 That is to say, with a default white background this border is transparent, but on a black background, it's opaque css_border_color. 168 */ 169 border-color: rgba(224,224,224,0.0); 170 } 171 172 173 174 175 /* CSS REDS */ /* CSS REDS */ /* CSS REDS */ /* CSS REDS */ /* CSS REDS */ /* CSS REDS */ /* CSS REDS */ 176 .layout-content.status.status-index .status-day .update-title.impact-critical a, 177 .layout-content.status.status-index .status-day .update-title.impact-critical a:hover, 178 .layout-content.status.status-index .page-status.status-critical, 179 .layout-content.status.status-index .unresolved-incident.impact-critical .incident-title, 180 .flat-button.background-red {
181 background-color:#e74c3c; 182 } 183 184 .layout-content.status-index .components-statuses .component-container.status-red:after, 185 .layout-content.status-full-history .month .incident-container .impact-critical, 186 .layout-content.status-incident .incident-name.impact-critical, 187 .layout-content.status.status-index .incidents-list .incident-title.impact-critical a, 188 .status-red .icon-indicator, 189 .incident-history .impact-critical, 190 .components-container .component-inner-container.status-red .component-status, 191 .components-container .component-inner-container.status-red .icon-indicator { 192 color:#e74c3c; 193 } 194 195 .layout-content.status.status-index .unresolved-incident.impact-critical .updates { 196 border-color:#e74c3c; 197 } 198 199 200 201 202 /* CSS ORANGES */ /* CSS ORANGES */ /* CSS ORANGES */ /* CSS ORANGES */ /* CSS ORANGES */ /* CSS ORANGES */ 203 .layout-content.status.status-index .status-day .update-title.impact-major a, 204 .layout-content.status.status-index .status-day .update-title.impact-major a:hover, 205 .layout-content.status.status-index .page-status.status-major, 206 .layout-content.status.status-index .unresolved-incident.impact-major .incident-title { 207 background-color:#e67e22; 208 } 209 210 .layout-content.status-index .components-statuses .component-container.status-orange:after, 211 .layout-content.status-full-history .month .incident-container .impact-major, 212 .layout-content.status-incident .incident-name.impact-major, 213 .layout-content.status.status-index .incidents-list .incident-title.impact-major a, 214 .status-orange .icon-indicator, 215 .incident-history .impact-major, 216 .components-container .component-inner-container.status-orange .component-status, 217 .components-container .component-inner-container.status-orange .icon-indicator { 218 color:#e67e22; 219 } 220 221 .layout-content.status.status-index .unresolved-incident.impact-major .updates { 222 border-color:#e67e22; 223 } 224 225 226 227 228 /* CSS YELLOWS */ /* CSS YELLOWS */ /* CSS YELLOWS */ /* CSS YELLOWS */ /* CSS YELLOWS */ /* CSS YELLOWS */ 229 .layout-content.status.status-index .status-day .update-title.impact-minor a, 230 .layout-content.status.status-index .status-day .update-title.impact-minor a:hover, 231 .layout-content.status.status-index .page-status.status-minor, 232 .layout-content.status.status-index .unresolved-incident.impact-minor .incident-title, 233 .layout-content.status.status-index .scheduled-incidents-container .tab { 234 background-color:#f1c40f; 235 } 236 237 .layout-content.status-index .components-statuses .component-container.status-yellow:after, 238 .layout-content.status-full-history .month .incident-container .impact-minor, 239 .layout-content.status-incident .incident-name.impact-minor, 240 .layout-content.status.status-index .incidents-list .incident-title.impact-minor a, 241 .status-yellow .icon-indicator, 242 .incident-history .impact-minor, 243 .components-container .component-inner-container.status-yellow .component-status, 244 .components-container .component-inner-container.status-yellow .icon-indicator, 245 .layout-content.status.manage-subscriptions .confirmation-infobox .fa { 246 color:#f1c40f; 247 } 248 249 .layout-content.status.status-index .unresolved-incident.impact-minor .updates, 250 .layout-content.status.status-index .scheduled-incidents-container { 251 border-color:#f1c40f; 252 } 253 254 255 256 257 /* CSS BLUES */ /* CSS BLUES */ /* CSS BLUES */ /* CSS BLUES */ /* CSS BLUES */ /* CSS BLUES */ 258 .layout-content.status.status-index .status-day .update-title.impact-maintenance a, 259 .layout-content.status.status-index .status-day .update-title.impact-maintenance a:hover, 260 .layout-content.status.status-index .page-status.status-maintenance, 261 .layout-content.status.status-index .unresolved-incident.impact-maintenance .incident-title, 262 .layout-content.status.status-index .scheduled-incidents-container .tab { 263 background-color:#3498DB; 264 } 265 266 .layout-content.status-index .components-statuses .component-container.status-blue:after, 267 .layout-content.status-full-history .month .incident-container .impact-maintenance, 268 .layout-content.status-incident .incident-name.impact-maintenance, 269 .layout-content.status.status-index .incidents-list .incident-title.impact-maintenance a, 270 .status-blue .icon-indicator, 271 .incident-history .impact-maintenance, 272 .components-container .component-inner-container.status-blue .component-status, 273 .components-container .component-inner-container.status-blue .icon-indicator { 274 color:#3498DB; 275 } 276 277 .layout-content.status.status-index .unresolved-incident.impact-maintenance .updates, 278 .layout-content.status.status-index .scheduled-incidents-container { 279 border-color:#3498DB; 280 } 281 282 283 284 285 /* CSS GREENS */ /* CSS GREENS */ /* CSS GREENS */ /* CSS GREENS */ /* CSS GREENS */ /* CSS GREENS */ /* CSS GREENS */ 286 .layout-content.status.status-index .page-status.status-none { 287 background-color:#2fcc66; 288 } 289 .layout-content.status-index .components-statuses .component-container.status-green:after, 290 .status-green .icon-indicator, 291 .components-container .component-inner-container.status-green .component-status, 292 .components-container .component-inner-container.status-green .icon-indicator { 293 color:#2fcc66; 294 } 295 296 297 298 299 /* CSS LINK COLOR */ /* CSS LINK COLOR */ /* CSS LINK COLOR */ /* CSS LINK COLOR */ /* CSS LINK COLOR */ /* CSS LINK COLOR */ 300 a, 301 a:hover, 302 .layout-content.status-index .page-footer span a:hover, 303 .layout-content.status-index .timeframes-container .timeframe:not(.active):hover, 304 .layout-content.status-incident .subheader a:hover { 305 color:#3498db; 306 } 307 308 .flat-button, 309 .masthead .updates-dropdown-container .show-updates-dropdown, 310 .layout-content.status-full-history .show-filter.open { 311 background-color:#3498db; 312 } 313 314 315 316 317 /* CUSTOM COLOR OVERRIDES FOR UPTIME SHOWCASE */ 318 .components-section .components-uptime-link { 319 color: #aaaaaa; 320 } 321 322 .layout-content.status .shared-partial.uptime-90-days-wrapper .legend .legend-item { 323 color: #aaaaaa; 324 opacity: 1; 325 } 326 .layout-content.status .shared-partial.uptime-90-days-wrapper .legend .legend-item.light { 327 color: #aaaaaa; 328 opacity: 1; 329 } 330 .layout-content.status .shared-partial.uptime-90-days-wrapper .legend .spacer { 331 background: #aaaaaa; 332 opacity: 1; 333 } 334</style> 335 336 337 <!-- custom css --> 338 <link rel="stylesheet" type="text/css" href="//dka575ofm4ao0.cloudfront.net/page_display_customizations-custom_css_externals/15953/external20151019-19655-1pkdy7p.css"> 339 340 <!-- polyfills --> 341
341<script crossorigin="anonymous" src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.js"></script>
341 342 343 <!-- Le HTML5 shim --> 344 <!--[if lt IE 9]> 345
345<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
345 346 <![endif]--> 347 348 <!-- injection for static --> 349 350 351 352 </head> 353 354 355 <body class="status index status-none sp-a11y-status-focus-visibility a11y-focus-indicators"> 356 357 358 359 360 361 <div class="layout-content status status-index premium"> 362 <div class="masthead-container premium"> 363 <div class="masthead"> 364 <div class="images-container" id="cover-image-container" data-js-hook="images-container"></div> 365 <style> 366 #cover-image-container { 367 background-image:url("//dka575ofm4ao0.cloudfront.net/pages-hero_covers/normal/16003/G2c4voyqSRa37wPXSOry"); 368 } 369 370 @media only screen and (-webkit-min-device-pixel-ratio: 2), 371 only screen and (min-resolution: 192dpi) { 372 #cover-image-container { 373 background-image:url("//dka575ofm4ao0.cloudfront.net/pages-hero_covers/retina/16003/G2c4voyqSRa37wPXSOry") !important; 374 } 375 } 376 </style> 377 378 <div class="text-container"> 379 <span class="page-name font-largest"> 380 <a href="http://www.voipfone.co.uk">Voipfone</a> 381 </span> 382 383 <div class="updates-dropdown-container" data-js-hook="updates-dropdown-container"> 384 <a href="#" data-js-hook="show-updates-dropdown" id="show-updates-dropdown" class="show-updates-dropdown" aria-label="Subscribe to updates" aria-expanded="false" aria-haspopup="dialog" role="button"> 385 <span class="subscribe-text-full">Subscribe to Updates</span><span class="subscribe-text-short">Subscribe</span> 386 </a> 387 388<!-- Accessibility guidelines for tabs: https://www.w3.org/TR/wai-aria-practices-1.1/examples/tabs/tabs-1/tabs.html --> 389 <div class="updates-dropdown" data-js-hook="updates-dropdown" id="updates-dropdown" style="display:none" role="dialog" aria-modal="false" aria-label="Subscribe to updates"> 390 <div class="updates-dropdown-nav nav-items-5" role="tablist" aria-label="Subscribe to updates"> 391 <a href="#updates-dropdown-email" aria-controls="updates-dropdown-email" aria-label="Subscribe via email" role="tab" aria-selected="true" id="updates-dropdown-email-btn"> 392 <span class="icon-container email"> 393 </a> 394 <a href="#updates-dropdown-sms" aria-controls="updates-dropdown-sms" aria-label="Subscribe via SMS" role="tab" id="updates-dropdown-sms-btn"> 395 <span class="icon-container sms"> 396 </a> 397 <a href="#updates-dropdown-twitter" aria-controls="updates-dropdown-twitter" aria-label="Subscribe via twitter" role="tab" id="updates-dropdown-twitter-btn"> 398 <span class="icon-container twitter"> 399 </a> 400 <a href="#updates-dropdown-atom" aria-controls="updates-dropdown-atom" aria-label="Subscribe via RSS" role="tab" id="updates-dropdown-atom-btn"> 401 <span class="icon-container rss"> 402 </a> 403 <button data-js-hook="updates-dropdown-close" aria-label="Close subscribe form" id="updates-dropdown-close-btn"> 404 x 405 </button> 406 </div> 407 <div class="updates-dropdown-sections-container"> 408 <div class="updates-dropdown-section email" id="updates-dropdown-email" style="display:none" role="tabpanel" aria-labelledby="updates-dropdown-email-btn"> 409 <div class="directions"> 410 Get email notifications whenever Voipfone <strong>creates</strong>, <strong>updates</strong> or <strong>resolves</strong> an incident. 411 </div> 412 <form id="subscribe-form-email" action="/subscriptions/new-email" accept-charset="UTF-8" data-remote="true" method="post"><input type="hidden" name="authenticity_token" value="ifgJO8Rt4q-7wbkNFn2OntQO6cieQeqlrlSO1uVU9jI-MsAcbfa_5ucY0VxgMPhNI4311wvVkiyMNP_ueOap5Q" autocomplete="off" /> 413 <input type="hidden" name="email_otp_verify_flow" id="email_otp_verify_flow" value="false" autocomplete="off" /> 414 <!-- make sure not to put cookie values in here since this gets cached --> 415 <label for="email">Email address:</label> 416 <input name="email" id="email" type="text" class="full-width" data-js-hook="email-notification-field" autocomplete="email"> 417 <input name="email_otp_auth_token" type='hidden' id="email-
417otp-token-field"> 418 <div class="opt-container-section" id="email-otp-container", style="display:none" > 419 <label for="email-otp">Enter OTP:</label> 420 <input name="otp" id="email-otp" type="text" value="" class="prepend full-width"> 421 <p id="email-otp-timer">Resend OTP in: <span id="email-otp-countdown"></span> seconds </p> 422 <p id="resend-email-otp"> 423 Didn't receive the OTP? 424 <a href="#" id="resend-email-otp-btn" >Resend OTP </a> 425 </p> 426 </div> 427 <input type="hidden" name="captcha_error" id="captcha_error" value="false" autocomplete="off" /> 428 <input type="submit" value="Subscribe via Email" class="flat-button full-width g-recaptcha" id="subscribe-btn-email" data-disabled-text="Subscribing..." data-sitekey=6LdTS8AUAAAAAOIbCKoCAP4LQku1olYGrywPTaZz data-callback="submitNewEmailSubscriber" data-error-callback="emailSubscriberCaptchaError" > 429 <div class="terms_and_privacy_information bottom small"> This site is protected by reCAPTCHA and the Google <a target="_blank" rel="noopener" class="accessible-link" href="https://policies.google.com/privacy">Privacy Policy</a> and <a target="_blank" rel="noopener" class="accessible-link" data-js-hook="captcha-terms-of-service-link" href="https://policies.google.com/terms">Terms of Service</a> apply.</div> 430</form> </div> 431 432 <div class="updates-dropdown-section phone" id="updates-dropdown-sms" style="display:none" role="tabpanel" aria-labelledby="updates-dropdown-sms-btn"> 433 <div class="directions"> 434 Get text message notifications whenever Voipfone <strong>creates</strong> or <strong>resolves</strong> an incident. 435 </div> 436 <form id="subscribe-form-sms" action="/subscriptions/new-sms" accept-charset="UTF-8" data-remote="true" method="post"><input type="hidden" name="authenticity_token" value="sckwI8zj9V8gE-_YERrVnq1i7sxcaqCsdp3DGSPHJroGA_kEZXioFnzKh4lnV6NNWuHy08n-2CVU_bIhvnV5bQ" autocomplete="off" /> 437 <input type="hidden" name="otp_verify_flow" id="otp_verify_flow" value="false" autocomplete="off" /> 438 <input type="hidden" name="subscriber_code" id="subscriber_code" value="" autocomplete="off" /> 439 <div class="control-group"> 440 <div class="controls externalities-sms-container"> 441 <!-- make sure not to put cookie values in here since this gets cached --> 442 <label for="phone-country">Country code:</label> 443 <div id="phone-number-country-code" class="phone-country-wrapper" 444 data-otp-enabled="false"> 445 <select name="phone_country" id="phone-country" data-js-hook="phone-country" class="phone-country"><option value="af" data-otp-enabled="false" >Afghanistan (+93)</option> 446<option value="al" data-otp-enabled="false" >Albania (+355)</option> 447<option value="dz" data-otp-enabled="false" >Algeria (+213)</option> 448<option value="as" data-otp-enabled="false" >American Samoa (+1)</option> 449<option value="ad" data-otp-enabled="false" >Andorra (+376)</option> 450<option value="ao" data-otp-enabled="false" >Angola (+244)</option> 451<option value="ai" data-otp-enabled="false" >Anguilla (+1)</option> 452<option value="ag" data-otp-enabled="false" >Antigua and Barbuda (+1)</option> 453<option value="ar" data-otp-enabled="false" >Argentina (+54)</option> 454<option value="am" data-otp-enabled="false" >Armenia (+374)</option> 455<option value="aw" data-otp-enabled="false" >Aruba (+297)</option> 456<option value="au" data-otp-enabled="false" >Australia/Cocos/Christmas Island (+61)</option> 457<option value="at" data-otp-enabled="false" >Austria (+43)</option> 458<option value="az" data-otp-enabled="false" >Azerbaijan (+994)</option> 459<option value="bs" data-otp-enabled="false" >Bahamas (+1)</option> 460<option value="bh" data-otp-enabled="false" >Bahrain (+973)</option> 461<option value="bd" data-otp-enabled="false" >Bangladesh (+880)</option> 462<option value="bb" data-otp-enabled="false" >Barbados (+1)</option> 463<option value="by" data-otp-enabled="false" >Belarus (+375)</option> 464<option value="be" data-otp-enabled="false" >Belgium (+32)</option> 465<option value="bz" data-otp-enabled="false" >Belize (+501)</option> 466<option value="bj" data-otp-enabled="false" >Benin (+229)</option> 467<option value="bm" data-otp-enabled="false" >Bermuda (+1)</option> 468<option value="bo" data-otp-enabled="false" >Bolivia (+591)</option> 469<option value="ba" data-otp-enabled="false" >Bosnia and Herzegovina (+387)</option> 470<option value="bw" data-otp-enabled="false" >Botswana (+267)</option> 471<option value="br" data-otp-enabled="false" >Brazil (+55)</option> 472<option value="bn" data-otp-enabled="false" >Brunei (+673)</option> 473<option value="bg" data-otp-enabled="false" >Bulgaria (+359)</option> 474<option value="bf" data-otp-enabled="false" >Burkina Faso (+226)</option> 475<option value="bi" data-otp-enabled="false" >Burundi (+257)</option> 476<option value="kh" data-otp-enabled="false" >Cambodia (+855)</option> 477<option value="cm" data-otp-enabled="false" >Cameroon (+237)</option> 478<option value="ca" data-otp-enabled="false" >Canada (+1)</option> 479<option value="cv" data-otp-enabled="false" >Cape Verde (+238)</option> 480<option value="ky" data-otp-enabled="false" >Cayman Islands (+1)</option> 481<option value="cf" data-otp-enabled="false" >Central Africa (+236)</option> 482<option value="td" data-otp-enabled="false" >Chad (+235)</option> 483<option value="cl" data-otp-enabled="false" >Chile (+56)</option> 484<option value="cn" data-otp-enabled="false" >China (+86)</option> 485<option value="co" data-otp-enabled="false" >Colombia (+57)</option> 486<option value="km" data-otp-enabled="false" >Comoros (+269)</option> 487<option value="cg" data-otp-enabled="false" >Congo (+242)</option> 488<option value="cd" data-otp-enabled="false" >Congo, Dem Rep (+243)</option> 489<option value="cr" data-otp-enabled="false" >Costa Rica (+506)</option> 490<option value="hr" data-otp-enabled="false" >Croatia (+385)</option> 491<option value="cy" data-otp-enabled="false" >Cyprus (+357)</option> 492<option value="cz" data-otp-enabled="false" >Czech Republic (+420)</option> 493<option value="dk" data-otp-enabled="false" >Denmark (+45)</option> 494<option value="dj" data-otp-enabled="false" >Djibouti (+253)</option> 495<option value="dm" data-otp-enabled="false" >Dominica (+1)</option> 496<option value="do" data-otp-enabled="false" >Dominican Republic (+1)</option> 497<option value="eg" data-otp-enabled="false" >Egypt (+20)</option> 498<option value="sv" data-otp-enabled="false" >El Salvador (+503)</option> 499<option value="gq" data-otp-enabled="false" >Equatorial Guinea (+240)</option> 500<option value="ee" data-otp-enabled="false" >Estonia (+372)</option> 501<option value="et" data-otp-enabled="false" >Ethiopia (+251)</option> 502<option value="fo" data-otp-enabled="false" >Faroe Islands (+298)</option> 503<option value="fj" data-otp-enabled="false" >Fiji (+679)</option> 504<option value="fi" data-otp-enabled="false" >Finland/Aland Islands (+358)</option> 505<option value="fr" data-otp-enabled="false" >France (+33)</option> 506<option value="gf" data-otp-enabled="false" >French Guiana (+594)</option> 507<option value="pf" data-otp-enabled="false" >French Polynesia (+689)</option> 508<option value="ga" data-otp-enabled="false" >Gabon (+241)</option> 509<option value="gm" data-otp-enabled="false" >Gambia (+220)</option> 510<option value="ge" data-otp-enabled="false" >Georgia (+995)</option> 511<option value="de" data-otp-enabled="false" >Germany (+49)</option> 512<option value="gh" data-otp-enabled="false" >Ghana (+233)</option> 513<option value="gi" data-otp-enabled="false" >Gibraltar (+350)</option> 514<option value="gr" data-otp-enabled="false" >Greece (+30)</option> 515<option value="gl" data-otp-enabled="false" >Greenland (+299)</option> 516<option value="gd" data-otp-enabled="false" >Grenada (+1)</option> 517<option value="gp" data-otp-enabled="false" >Guadeloupe (+590)</option> 518<option value="gu" data-otp-enabled="false" >
518Guam (+1)</option> 519<option value="gt" data-otp-enabled="false" >Guatemala (+502)</option> 520<option value="gn" data-otp-enabled="false" >Guinea (+224)</option> 521<option value="gy" data-otp-enabled="false" >Guyana (+592)</option> 522<option value="ht" data-otp-enabled="false" >Haiti (+509)</option> 523<option value="hn" data-otp-enabled="false" >Honduras (+504)</option> 524<option value="hk" data-otp-enabled="false" >Hong Kong (+852)</option> 525<option value="hu" data-otp-enabled="false" >Hungary (+36)</option> 526<option value="is" data-otp-enabled="false" >Iceland (+354)</option> 527<option value="in" data-otp-enabled="false" >India (+91)</option> 528<option value="id" data-otp-enabled="false" >Indonesia (+62)</option> 529<option value="iq" data-otp-enabled="false" >Iraq (+964)</option> 530<option value="ie" data-otp-enabled="false" >Ireland (+353)</option> 531<option value="il" data-otp-enabled="false" >Israel (+972)</option> 532<option value="it" data-otp-enabled="false" >Italy (+39)</option> 533<option value="jm" data-otp-enabled="false" >Jamaica (+1)</option> 534<option value="jp" data-otp-enabled="false" >Japan (+81)</option> 535<option value="jo" data-otp-enabled="false" >Jordan (+962)</option> 536<option value="ke" data-otp-enabled="false" >Kenya (+254)</option> 537<option value="kr" data-otp-enabled="false" >Korea, Republic of (+82)</option> 538<option value="xk" data-otp-enabled="false" >Kosovo (+383)</option> 539<option value="kw" data-otp-enabled="false" >Kuwait (+965)</option> 540<option value="kg" data-otp-enabled="false" >Kyrgyzstan (+996)</option> 541<option value="la" data-otp-enabled="false" >Laos (+856)</option> 542<option value="lv" data-otp-enabled="false" >Latvia (+371)</option> 543<option value="lb" data-otp-enabled="false" >Lebanon (+961)</option> 544<option value="ls" data-otp-enabled="false" >Lesotho (+266)</option> 545<option value="lr" data-otp-enabled="false" >Liberia (+231)</option> 546<option value="ly" data-otp-enabled="false" >Libya (+218)</option> 547<option value="li" data-otp-enabled="false" >Liechtenstein (+423)</option> 548<option value="lt" data-otp-enabled="false" >Lithuania (+370)</option> 549<option value="lu" data-otp-enabled="false" >Luxembourg (+352)</option> 550<option value="mo" data-otp-enabled="false" >Macao (+853)</option> 551<option value="mk" data-otp-enabled="false" >Macedonia (+389)</option> 552<option value="mg" data-otp-enabled="false" >Madagascar (+261)</option> 553<option value="mw" data-otp-enabled="false" >Malawi (+265)</option> 554<option value="my" data-otp-enabled="false" >Malaysia (+60)</option> 555<option value="mv" data-otp-enabled="false" >Maldives (+960)</option> 556<option value="ml" data-otp-enabled="false" >Mali (+223)</option> 557<option value="mt" data-otp-enabled="false" >Malta (+356)</option> 558<option value="mq" data-otp-enabled="false" >Martinique (+596)</option> 559<option value="mr" data-otp-enabled="false" >Mauritania (+222)</option> 560<option value="mu" data-otp-enabled="false" >Mauritius (+230)</option> 561<option value="mx" data-otp-enabled="false" >Mexico (+52)</option> 562<option value="mc" data-otp-enabled="false" >Monaco (+377)</option> 563<option value="mn" data-otp-enabled="false" >Mongolia (+976)</option> 564<option value="me" data-otp-enabled="false" >Montenegro (+382)</option> 565<option value="ms" data-otp-enabled="false" >Montserrat (+1)</option> 566<option value="ma" data-otp-enabled="false" >Morocco/Western Sahara (+212)</option> 567<option value="mz" data-otp-enabled="false" >Mozambique (+258)</option> 568<option value="na" data-otp-enabled="false" >Namibia (+264)</option> 569<option value="np" data-otp-enabled="false" >Nepal (+977)</option> 570<option value="nl" data-otp-enabled="false" >Netherlands (+31)</option> 571<option value="nz" data-otp-enabled="false" >New Zealand (+64)</option> 572<option value="ni" data-otp-enabled="false" >Nicaragua (+505)</option> 573<option value="ne" data-otp-enabled="false" >Niger (+227)</option> 574<option value="ng" data-otp-enabled="false" >Nigeria (+234)</option> 575<option value="no" data-otp-enabled="false" >Norway (+47)</option> 576<option value="om" data-otp-enabled="false" >Oman (+968)</option> 577<option value="pk" data-otp-enabled="false" >Pakistan (+92)</option> 578<option value="ps" data-otp-enabled="false" >Palestinian Territory (+970)</option> 579<option value="pa" data-otp-enabled="false" >Panama (+507)</option> 580<option value="py" data-otp-enabled="false" >Paraguay (+595)</option> 581<option value="pe" data-otp-enabled="false" >Peru (+51)</option> 582<option value="ph" data-otp-enabled="false" >Philippines (+63)</option> 583<option value="pl" data-otp-enabled="false" >Poland (+48)</option> 584<option value="pt" data-otp-enabled="false" >Portugal (+351)</option> 585<option value="pr" data-otp-enabled="false" >Puerto Rico (+1)</option> 586<option value="qa" data-otp-enabled="false" >Qatar (+974)</option> 587<option value="re" data-otp-enabled="false" >Reunion/Mayotte (+262)</option> 588<option value="ro" data-otp-enabled="false" >Romania (+40)</option> 589<option value="ru" data-otp-enabled="false" >Russia/Kazakhstan (+7)</option> 590<option value="rw" data-otp-enabled="false" >Rwanda (+250)</option> 591<option value="ws" data-otp-enabled="false" >Samoa (+685)</option> 592<option value="sm" data-otp-enabled="false" >San Marino (+378)</option> 593<option value="sa" data-otp-enabled="false" >Saudi Arabia (+966)</option> 594<option value="sn" data-otp-enabled="false" >Senegal (+221)</option> 595<option value="rs" data-otp-enabled="false" >Serbia (+381)</option> 596<option value="sc" data-otp-enabled="false" >Seychelles (+248)</option> 597<option value="sl" data-otp-enabled="false" >Sierra Leone (+232)</option> 598<option value="sg" data-otp-enabled="false" >Singapore (+65)</option> 599<option value="sk" data-otp-enabled="false" >Slovakia (+421)</option> 600<option value="si" data-otp-enabled="false" >Slovenia (+386)</option> 601<option value="za" data-otp-enabled="false" >South Africa (+27)</option> 602<option value="es" data-otp-enabled="false" >Spain (+34)</option> 603<option value="lk" data-otp-enabled="false" >Sri Lanka (+94)</option> 604<option value="kn" data-otp-enabled="false" >St Kitts and Nevis (+1)</option> 605<option value="lc" data-otp-enabled="false" >St Lucia (+1)</option> 606<option value="vc" data-otp-enabled="false" >St Vincent Grenadines (+1)</option> 607<option value="sd" data-otp-enabled="false" >Sudan (+249)</option> 608<option value="sr" data-otp-enabled="false" >Suriname (+597)</option> 609<option value="sz" data-otp-enabled="false" >Swaziland (+268)</option> 610<option value="se" data-otp-enabled="false" >Sweden (+46)</option> 611<option value="ch" data-otp-enabled="false" >Switzerland (+41)</option> 612<option value="tw" data-otp-enabled="false" >Taiwan (+886)</option> 613<option value="tj" data-otp-enabled="false" >Tajikistan (+992)</option> 614<option value="tz" data-otp-enabled="false" >Tanzania (+255)</option> 615<option value="th" data-otp-enabled="false" >Thailand (+66)</option> 616<option value="tg" data-otp-enabled="false" >Togo (+228)</option> 617<option value="to" data-otp-enabled="false" >Tonga (+676)</option> 618<option value="tt" data-otp-enabled="false" >Trinidad and Tobago (+1)</option> 619<option value="tn" data-otp-enabled="false" >Tunisia (+216)</option> 620<option value="tr" data-otp-enabled="false" >Turkey (+90)</option> 621<option value="tc" data-otp-enabled="false" >Turks and Caicos Islands (+1)</option> 622<option value="ug" data-otp-enabled="false" >Uganda (+256)</option> 623<option value="ua" data-otp-enabled="false" >Ukraine (+380)</option> 624<option value="ae" data-otp-enabled="false" >United Arab Emirates (+971)</option> 625<option value="gb" data-otp-enabled="false" selected>United Kingdom (+44)</option> 626<option value="us" data-otp-enabled="false" >United States (+1)</option> 627<option value="uy" data-otp-enabled="false" >Uruguay (+598)</option> 628<option value="uz" data-otp-enabled="false" >Uzbekistan (+998)</option> 629<option value="ve" data-otp-enabled="false" >Venezuela (+58)</option> 630<option value="vn" data-otp-enabled="false" >Vietnam (+84)</option> 631<option value="vg" data-otp-enabled="false" >Virgin Islands, British (+1)</option> 632<option value="vi" data-otp-enabled="false" >Virgin Islands, U.S. (+1)</option> 633<option value="ye" data-otp-enabled="false" >Yemen (+967)</option> 634<option value="zm" data-otp-enabled="false" >Zambia (+260)</option> 635<option value="zw" data-otp-enabled="false" >Zimbabwe (+263)</option></select> 636 </div> 637 <label for="phone-number">Phone number:</label> 638 <input name="phone_number" id="phone-number" type="text" class="prepend full-width" data-js-hook="sms-notification-field"> 639 <div class="sms-atl-error" id="sms-atl-error"></div> 640 <div class="clearfix"></div> 641 <div class="opt-container-section" id="otp-container" style="display:none">
642 <a href="#" id="btn-subcriber-change-number">Change number</a> 643 <label for="otp">Enter OTP:</label> 644 <input name="otp" id="otp" type="text" class="prepend full-width"> 645 <p id="timer">Resend OTP in: <span id="countdown">30</span> seconds </p> 646 <p id="resend"> 647 Didn't receive the OTP? 648 <a href="#" id="resend-otp-btn" >Resend OTP </a> 649 </p> 650 </div> 651 </div> 652 </div> 653 654 <input type="hidden" name="captcha_error" id="captcha_error" value="false" autocomplete="off" /> 655 <input type="submit" value="Subscribe via Text Message" class="flat-button full-width g-recaptcha" id="subscribe-btn-sms" data-disabled-text="Subscribing..." data-sitekey=6LcH-b0UAAAAACVQtMb14LBhflMA9y0Nmu7l_W6d data-callback="submitNewSmsSubscriber" data-error-callback="smsSubscriberCaptchaError"> 656 <div class="terms_and_privacy_information bottom small">Message and data rates may apply. By subscribing you agree to the Atlassian <a target="_blank" rel="noopener" class="accessible-link" href="https://www.atlassian.com/legal/product-specific-terms#statuspage-specific-terms">Terms of Service</a>, and the Atlassian <a target="_blank" rel="noopener" class="accessible-link" href="https://www.atlassian.com/legal/privacy-policy">Privacy Policy</a>. This site is protected by reCAPTCHA and the Google <a target="_blank" rel="noopener" class="accessible-link" href="https://policies.google.com/privacy">Privacy Policy</a> and <a target="_blank" rel="noopener" class="accessible-link" data-js-hook="captcha-terms-of-service-link" href="https://policies.google.com/terms">Terms of Service</a> apply.</div> 657</form> </div> 658 659 660 661 662 <div class="updates-dropdown-section twitter" id="updates-dropdown-twitter" style="display:none" role="tabpanel" aria-labelledby="updates-dropdown-twitter-btn"> 663 <a href="https://twitter.com/Voipfonestatus" class="twitter-follow-button" data-show-count="false" data-show-screen-name="true" data-width="59px">Follow @Voipfonestatus</a> 664 or 665 <a href="https://twitter.com/Voipfonestatus" target="_blank">view our profile</a>. 666 <style> 667 .twitter-follow-button { 668 margin-bottom: -6px; 669 } 670 </style> 671 672
672<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
672 673 </div> 674 675 676 <div class="updates-dropdown-section atom" id="updates-dropdown-atom" role="tabpanel" aria-labelledby="updates-dropdown-atom-btn"> 677 Get the <a href="https://www.voipfonestatus.co.uk/history.atom" target="_blank">Atom Feed</a> or <a href="https://www.voipfonestatus.co.uk/history.rss" target="_blank">RSS Feed</a>. 678 </div> 679 </div> 680 </div> 681 </div> 682
683<script> 684 $(function () { 685 const phoneNumberInput = $('#phone-number'); 686 const errorDiv = $('#sms-atl-error') 687 if(errorDiv.length){ 688 function checkSelectedCountry() { 689 const selectedCountry = $('#phone-country').val(); 690 const isOtpEnabled = $('#phone-number-country-code').attr('data-otp-enabled') === 'true'; 691 const form = document.getElementById('subscribe-form-sms'); 692 form.action = '/subscriptions/new-sms'; 693 const isOtpFlow = document.getElementById('otp_verify_flow'); 694 document.getElementById('otp-container').style.display = "none"; 695 if(false && selectedCountry === 'sg') { // Replace 'SG' with the actual value representing Singapore in your select tag 696 phoneNumberInput.prop('disabled', true); 697 errorDiv.html(`Due to new Singapore government regulations, we're currently not supporting text subscriptions in Singapore.<a href="https://community.atlassian.com/t5/Statuspage-articles/Attention-SMS-notifications-will-be-disabled-on-August-1st-2023/ba-p/2424398" target="_blank"> Learn more.</a> <br> Select another method to subscribe.`); 698 } else { 699 phoneNumberInput.prop('readonly', false); 700 errorDiv.html(''); 701 if(false){ 702 if(isOtpEnabled){ 703 document.getElementById('subscribe-btn-sms').value = "Send OTP"; 704 } 705 else { 706 isOtpFlow.value = false; 707 document.getElementById('subscribe-btn-sms').value = "Subscribe via Text Message"; 708 } 709 } 710 } 711 } 712 713 $('#phone-country').on('change', checkSelectedCountry); 714 checkSelectedCountry(); 715 } 716 }); 717 718 document.addEventListener('DOMContentLoaded', function() { 719 const dropdown = document.querySelector('#phone-number-country-code .phone-country'); 720 if (dropdown){ 721 const wrapperDiv = document.getElementById('phone-number-country-code'); 722 const selectedOption = dropdown.options[dropdown.selectedIndex]; 723 const otpEnabled = selectedOption.getAttribute('data-otp-enabled'); 724 725 wrapperDiv.setAttribute('data-otp-enabled', otpEnabled); 726 727 dropdown.addEventListener('change', function() { 728 const selectedOption = dropdown.options[dropdown.selectedIndex]; 729 const otpEnabled = selectedOption.getAttribute('data-otp-enabled'); 730 731 wrapperDiv.setAttribute('data-otp-enabled', otpEnabled); 732 }); 733 } 734 }); 735 736 var countdownTimer; 737 var resendBtn = document.getElementById('resend'); 738 var timer = document.getElementById('timer'); 739 var form = document.getElementById('subscribe-form-sms'); 740 var RESEND_TIMER = 30; 741 $(function() { 742 $('#subscribe-form-sms').on('ajax:success', function(e, data, status, xhr){ 743 const form = this; 744 const action = form.getAttribute('action'); 745 if (data.type === 'success' && data.otp_flow === true) { 746 document.getElementById('subscriber_code').value = data.subscriber_code 747 document.getElementById('otp-container').style.display = "block"; 748 $('#phone-number').prop('readonly', true); 749 var display = document.getElementById('countdown'); 750 disableResend(); 751 startTimer(RESEND_TIMER, display) 752 document.getElementById('subscribe-btn-sms').value = "Verify OTP and Subscribe"; 753 document.getElementById('otp_verify_flow').value = true; 754 form.action = '/subscriptions/verify-otp'; 755 } else if (data.type === 'success' && action.includes('verify')){ 756 document.getElementById('otp-container').style.display = "none"; 757 $('#phone-number').val('').prop('readonly', false); 758 $('#otp').val(''); 759 document.getElementById('subscribe-btn-sms').value = "Send OTP"; 760 document.getElementById('otp_verify_flow').value = false; 761 form.action = '/subscriptions/new-sms'; 762 SP.currentPage.updatesDropdown.hide(); 763 } 764 }); 765 $("#btn-subcriber-change-number").on('click', () => { 766 document.getElementById('otp-container').style.display = "none"; 767 $('#phone-number').prop('readonly', false); 768 document.getElementById('subscribe-btn-sms').value = "Send OTP"; 769 form.action = '/subscriptions/new-sms'; 770 return false 771 }) 772 $('#resend-otp-btn').on('click', function(e) { 773 e.preventDefault(); 774 let phoneNumber = $('#phone-number').val(); 775 let countryCode = $('.phone-country').val(); 776 $.ajax({ 777 type: 'POST', 778 url: "/subscriptions/new-sms", 779 data: { 780 phone_number: phoneNumber, 781 phone_country: countryCode, 782 type: 'resend' 783 }, 784 }).done(function(data) { 785 var messageOptions = (data.type !== undefined && data.type !== null) ? { cssClass: data.type } : {}; 786 HRB.utils.notify(data.text, messageOptions); 787 var display = document.getElementById('countdown'); 788 disableResend(); 789 timer.style.display = "none" 790 if (data.type === 'success') { 791 startTimer(RESEND_TIMER, display); 792 } 793 }) 794 }); 795 }) 796 797 function startTimer(duration, display){ 798 var timer = duration, seconds; 799 clearInterval(countdownTimer); 800 countdownTimer = setInterval(function () { 801 seconds = parseInt(timer % 60, 10); 802 display.textContent = seconds; 803 if(--timer < 0){ 804 enableResend(); 805 clearInterval(countdownTimer); 806 } 807 }, 1000); 808 disableResend(); 809 } 810 function enableResend(){ 811 resendBtn.style.display = "block"; 812 timer.style.display = "none" 813 } 814 function disableResend(){ 815 resendBtn.style.display = "none"; 816 timer.style.display = "block" 817 } 818 819 $(function() { 820 $('#subscribe-form-email').on('submit', function() {
821 var tokenField = document.getElementById('email-otp-token-field'); 822 if (!tokenField) { 823 return; 824 } 825 let page_code = "g1j7mrrz279t" 826 let key = keyForEmailOtpToken($('#email').val(), page_code); 827 tokenField.value = localStorage.getItem(key); 828 }); 829 }); 830 831 var emailOtpCountdownTimer; 832 var emailOtpResendBtn = document.getElementById('resend-email-otp'); 833 var emailOtpTimer = document.getElementById('email-otp-timer'); 834 var emailOtpForm = document.getElementById('subscribe-form-email'); 835 var EMAIL_OTP_RESEND_TIMER = 600; 836 $(function() { 837 $('#subscribe-form-email').on('ajax:success', function(e, data, status, xhr){ 838 const form = this; 839 const action = form.getAttribute('action'); 840 if (data.type === 'success' && data.email_otp_verify_flow === true) { 841 document.getElementById('email-otp-container').style.display = "block"; 842 var display = document.getElementById('email-otp-countdown'); 843 display.textContent = EMAIL_OTP_RESEND_TIMER; 844 disableEmailOtpResend(); 845 startEmailOtpTimer(EMAIL_OTP_RESEND_TIMER, display) 846 document.getElementById('subscribe-btn-email').value = "Verify OTP and Subscribe"; 847 document.getElementById('email_otp_verify_flow').value = true; 848 form.action = '/subscriptions/verify-email-otp'; 849 } else if (data.type === 'success' && action.includes('verify')){ 850 let email = $('#email') 851 let page_code = "g1j7mrrz279t" 852 let key = keyForEmailOtpToken(email.val(), page_code); 853 localStorage.setItem(key, data.email_otp_auth_token); 854 855 document.getElementById('email-otp-container').style.display = "none"; 856 email.val('').prop('readonly', false); 857 $('#email-otp').val(''); 858 document.getElementById('subscribe-btn-email').value = "Send OTP"; 859 document.getElementById('email_otp_verify_flow').value = false; 860 form.action = '/subscriptions/new-email'; 861 SP.currentPage.updatesDropdown.hide(); 862 } 863 }); 864 $('#resend-email-otp-btn').on('click', function(e) { 865 e.preventDefault(); 866 let email = $('#email').val(); 867 $.ajax({ 868 type: 'POST', 869 url: "/subscriptions/new-email", 870 data: { 871 email: email 872 }, 873 }).done(function(data) { 874 var messageOptions = (data.type !== undefined && data.type !== null) ? { cssClass: data.type } : {}; 875 HRB.utils.notify(data.text, messageOptions); 876 if (data.type === 'success') { 877 var display = document.getElementById('email-otp-countdown'); 878 display.textContent = EMAIL_OTP_RESEND_TIMER; 879 disableEmailOtpResend(); 880 emailOtpTimer.style.display = "none" 881 startEmailOtpTimer(EMAIL_OTP_RESEND_TIMER, display); 882 } 883 }) 884 }); 885 }) 886 887 function startEmailOtpTimer(duration, display){ 888 var timer = duration, seconds; 889 clearInterval(emailOtpCountdownTimer); 890 emailOtpCountdownTimer = setInterval(function () { 891 seconds = parseInt(timer, 10); 892 display.textContent = seconds; 893 if(--timer < 0){ 894 enableEmailOtpResend(); 895 clearInterval(emailOtpCountdownTimer); 896 } 897 }, 1000); 898 disableEmailOtpResend(); 899 } 900 901 function enableEmailOtpResend(){ 902 emailOtpResendBtn.style.display = "block"; 903 emailOtpTimer.style.display = "none" 904 } 905 function disableEmailOtpResend(){ 906 emailOtpResendBtn.style.display = "none"; 907 emailOtpTimer.style.display = "block" 908 } 909 function keyForEmailOtpToken(email, pageCode) { 910 return email + '|' + pageCode+ '|SUBSCRIBE_VIA_EMAIL'; 911 } 912</script>
912 913 914 </div> 915 </div> 916 917</div> 918 <!-- this is outside of the .container so that the cover photo can go full width on mobile --> 919 920 <div class="container" role="main"> 921 <div class="page-status status-none"> 922 <h2 class="status font-large"> 923 All Systems Operational 924 </h2> 925 <span class="last-updated-stamp font-small"></span> 926 </div> 927 928 929 <div class="text-section"> 930 <h2 class="font-largest"> 931 <a id="about-this-site" href="#about-this-site" class="no-link">About This Site</a> 932 </h2> 933 <p class="color-secondary font-regular"> 934 Welcome to <a href="http://www.voipfone.co.uk" title="Visit our website!">Voipfone</a>'s status page. As an award-winning Internet Telephony Service Provider, we are proud to offer a reliable service to our customers. However, from time to time, we may experience issues â rest assured, our engineers will always be on top of the problem to restore functionality as quickly as possible. We are continuously improving our platform and, in order to do that, we schedule our maintenance windows outside business hours. Follow us on <a href="https://x.com/voipfonestatus" title="See our Voipfone Status X page">X</a> or subscribe to updates on this page to receive notifications of any works carried out or incidents involving our network. 935 </p> 936 </div> 937 938 <div class="components-section font-regular"> 939 <i class="component-status hidden major_outage"></i> 940 <div class="components-uptime-link history-footer-link"> 941 Uptime over the past <var data-var="num" data-pluralize="90">90</var> days. <a href="/uptime">View historical uptime.</a> 942 </div> 943 <div class="components-container one-column"> 944 <div class="component-container border-color is-group "> 945 946<div data-component-id="qkvw844ykqgj" 947 class="component-inner-container status-green showcased" 948 data-component-status="operational" 949 data-js-hook="component-group-opener"> 950 951 <span class="name" role="heading" aria-level="2"> 952 <span class="fa group-parent-indicator color-secondary font-small fa-plus-square-o" role="button" aria-expanded="false" aria-label="Toggle Voice Services" tabindex="0"></span> 953 <span> 954 Voice Services 955 </span> 956 </span> 957 958 959 <span 960 class="component-status " 961 role="button" tabindex="0" data-js-hook="tooltip" 962 data-original-title="Groups take on the status of their most degraded child component or service. Click to see the status of the individual children." 963 > 964 965 Operational 966 967 </span> 968 969 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 970 971 <div class="uptime-lazy-placeholder" data-uptime-lazy="qkvw844ykqgj" aria-hidden="true"></div> 972</div> 973 974 975 <!-- children components --> 976 <div class="child-components-container mix-match-showcase"> 977 978<div data-component-id="czxfbk7fwcv5" 979 class="component-inner-container status-green " 980 data-component-status="operational" 981 data-js-hook=""> 982 983 <span class="name" role="heading" aria-level="2"> 984 Outbound UK Landline Calls 985 </span> 986 987 988 <span 989 class="component-status " 990 991 title="" 992 > 993 994 Operational 995 996 </span> 997 998 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 999 1000</div> 1001 1002 1003<div data-component-id="ppmwxspps50q" 1004 class="component-inner-container status-green " 1005 data-component-status="operational" 1006 data-js-hook=""> 1007 1008 <span class="name" role="heading" aria-level="2"> 1009 Outbound UK Mobile Calls 1010 </span> 1011 1012 1013 <span 1014 class="component-status " 1015 1016 title="" 1017 > 1018 1019 Operational 1020 1021 </span> 1022 1023 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1024 1025</div> 1026 1027 1028<div data-component-id="rx2tvhdt861z" 1029 class="component-inner-container status-green " 1030 data-component-status="operational" 1031 data-js-hook=""> 1032 1033 <span class="name" role="heading" aria-level="2"> 1034 Outbound UK Non-Geographic Calls 1035 </span> 1036 1037 1038 <span 1039 class="component-status " 1040 1041 title="" 1042 > 1043 1044 Operational 1045 1046 </span> 1047 1048 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1049 1050</div> 1051 1052 1053<div data-component-id="fy3g9w17y2rm" 1054 class="component-inner-container status-green " 1055 data-component-status="operational" 1056 data-js-hook=""> 1057 1058 <span class="name" role="heading" aria-level="2"> 1059 Outbound International Calls 1060 </span> 1061 1062 1063 <span 1064 class="component-status " 1065 1066 title="" 1067 > 1068 1069 Operational 1070 1071 </span> 1072 1073 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1074 1075</div> 1076 1077 1078<div data-component-id="3rhs3t75tfrw" 1079 class="component-inner-container status-green " 1080 data-component-status="operational" 1081 data-js-hook=""> 1082 1083 <span class="name" role="heading" aria-level="2"> 1084 Inbound Calls to UK Landline Numbers 1085 </span> 1086 1087 1088 <span 1089 class="component-status " 1090 1091 title="" 1092 > 1093 1094 Operational 1095 1096 </span> 1097 1098 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1099 1100</div> 1101 1102 1103<div data-component-id="hgkjp5zymh33" 1104 class="component-inner-container status-green " 1105 data-component-status="operational" 1106 data-js-hook=""> 1107 1108 <span class="name" role="heading" aria-level="2"> 1109 Inbound Calls to UK Non-Geographic Numbers 1110 </span> 1111 1112 1113 <span 1114 class="component-status " 1115 1116 title="" 1117 > 1118 1119 Operational 1120 1121 </span> 1122 1123 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1124 1125</div> 1126 1127 1128<div data-component-id="3rtvhclm17qf" 1129 class="component-inner-container status-green " 1130 data-component-status="operational" 1131 data-js-hook=""> 1132 1133 <span class="name" role="heading" aria-level="2"> 1134 Inbound Calls to International Numbers 1135 </span> 1136 1137 1138 <span 1139 class="component-status " 1140 1141 title="" 1142 > 1143 1144 Operational 1145 1146 </span> 1147 1148 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1149 1150</div> 1151 1152 1153<div data-component-id="8cpdrlz3ln4y"
1154 class="component-inner-container status-green " 1155 data-component-status="operational" 1156 data-js-hook=""> 1157 1158 <span class="name" role="heading" aria-level="2"> 1159 CPS 1160 </span> 1161 1162 1163 <span 1164 class="component-status " 1165 1166 title="" 1167 > 1168 1169 Operational 1170 1171 </span> 1172 1173 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1174 1175</div> 1176 1177 1178<div data-component-id="mk3s9jmmw263" 1179 class="component-inner-container status-green showcased" 1180 data-component-status="operational" 1181 data-js-hook=""> 1182 1183 <span class="name" role="heading" aria-level="2"> 1184 Voipfone Softphone 1185 </span> 1186 1187 1188 <span 1189 class="component-status " 1190 1191 title="" 1192 > 1193 1194 Operational 1195 1196 </span> 1197 1198 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1199 1200 <div class="uptime-lazy-placeholder" data-uptime-lazy="mk3s9jmmw263" aria-hidden="true"></div> 1201</div> 1202 1203 1204<div data-component-id="vx9f49ltyhw8" 1205 class="component-inner-container status-green showcased" 1206 data-component-status="operational" 1207 data-js-hook=""> 1208 1209 <span class="name" role="heading" aria-level="2"> 1210 Voicemail 1211 </span> 1212 1213 1214 <span 1215 class="component-status " 1216 1217 title="" 1218 > 1219 1220 Operational 1221 1222 </span> 1223 1224 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1225 1226 <div class="uptime-lazy-placeholder" data-uptime-lazy="vx9f49ltyhw8" aria-hidden="true"></div> 1227</div> 1228 1229 1230<div data-component-id="9xfgc7lq662h" 1231 class="component-inner-container status-green showcased" 1232 data-component-status="operational" 1233 data-js-hook=""> 1234 1235 <span class="name" role="heading" aria-level="2"> 1236 Conference Call 1237 </span> 1238 1239 1240 <span 1241 class="component-status " 1242 1243 title="" 1244 > 1245 1246 Operational 1247 1248 </span> 1249 1250 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1251 1252 <div class="uptime-lazy-placeholder" data-uptime-lazy="9xfgc7lq662h" aria-hidden="true"></div> 1253</div> 1254 1255 </div> 1256</div> 1257 1258 <div class="component-container border-color is-group "> 1259 1260<div data-component-id="dh524gth3dp0" 1261 class="component-inner-container status-green " 1262 data-component-status="operational" 1263 data-js-hook="component-group-opener"> 1264 1265 <span class="name" role="heading" aria-level="2"> 1266 <span class="fa group-parent-indicator color-secondary font-small fa-plus-square-o" role="button" aria-expanded="false" aria-label="Toggle Fax Services" tabindex="0"></span> 1267 <span> 1268 Fax Services 1269 </span> 1270 </span> 1271 1272 1273 <span 1274 class="component-status " 1275 role="button" tabindex="0" data-js-hook="tooltip" 1276 data-original-title="Groups take on the status of their most degraded child component or service. Click to see the status of the individual children." 1277 > 1278 1279 Operational 1280 1281 </span> 1282 1283 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1284 1285</div> 1286 1287 1288 <!-- children components --> 1289 <div class="child-components-container "> 1290 1291<div data-component-id="73gcnvfhdq0l" 1292 class="component-inner-container status-green " 1293 data-component-status="operational" 1294 data-js-hook=""> 1295 1296 <span class="name" role="heading" aria-level="2"> 1297 Outbound Faxes 1298 </span> 1299 1300 1301 <span 1302 class="component-status " 1303 1304 title="" 1305 > 1306 1307 Operational 1308 1309 </span> 1310 1311 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1312 1313</div> 1314 1315 1316<div data-component-id="zpfls7j8gyng" 1317 class="component-inner-container status-green " 1318 data-component-status="operational" 1319 data-js-hook=""> 1320 1321 <span class="name" role="heading" aria-level="2"> 1322 Inbound Faxes 1323 </span> 1324 1325 1326 <span 1327 class="component-status " 1328 1329 title="" 1330 > 1331 1332 Operational 1333 1334 </span> 1335 1336 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1337 1338</div> 1339 1340 </div> 1341</div> 1342 1343 <div class="component-container border-color is-group "> 1344 1345<div data-component-id="ts5dl12ykdt7" 1346 class="component-inner-container status-green " 1347 data-component-status="operational" 1348 data-js-hook="component-group-opener"> 1349 1350 <span class="name" role="heading" aria-level="2">
1351 <span class="fa group-parent-indicator color-secondary font-small fa-plus-square-o" role="button" aria-expanded="false" aria-label="Toggle SMS Services" tabindex="0"></span> 1352 <span> 1353 SMS Services 1354 </span> 1355 </span> 1356 1357 1358 <span 1359 class="component-status " 1360 role="button" tabindex="0" data-js-hook="tooltip" 1361 data-original-title="Groups take on the status of their most degraded child component or service. Click to see the status of the individual children." 1362 > 1363 1364 Operational 1365 1366 </span> 1367 1368 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1369 1370</div> 1371 1372 1373 <!-- children components --> 1374 <div class="child-components-container "> 1375 1376<div data-component-id="2695qbg7gwcw" 1377 class="component-inner-container status-green " 1378 data-component-status="operational" 1379 data-js-hook=""> 1380 1381 <span class="name" role="heading" aria-level="2"> 1382 Outbound SMS 1383 </span> 1384 1385 1386 <span 1387 class="component-status " 1388 1389 title="" 1390 > 1391 1392 Operational 1393 1394 </span> 1395 1396 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1397 1398</div> 1399 1400 1401<div data-component-id="z3p3nlgglc9r" 1402 class="component-inner-container status-green " 1403 data-component-status="operational" 1404 data-js-hook=""> 1405 1406 <span class="name" role="heading" aria-level="2"> 1407 Inbound SMS 1408 </span> 1409 1410 1411 <span 1412 class="component-status " 1413 1414 title="" 1415 > 1416 1417 Operational 1418 1419 </span> 1420 1421 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1422 1423</div> 1424 1425 </div> 1426</div> 1427 1428 <div class="component-container border-color"> 1429 1430<div data-component-id="tp7y6ygl3124" 1431 class="component-inner-container status-green " 1432 data-component-status="operational" 1433 data-js-hook=""> 1434 1435 <span class="name" role="heading" aria-level="2"> 1436 Line Rental 1437 </span> 1438 1439 1440 <span 1441 class="component-status " 1442 1443 title="" 1444 > 1445 1446 Operational 1447 1448 </span> 1449 1450 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1451 1452</div> 1453 1454 </div> 1455 <div class="component-container border-color"> 1456 1457<div data-component-id="j59vkz4f8fn5" 1458 class="component-inner-container status-green " 1459 data-component-status="operational" 1460 data-js-hook=""> 1461 1462 <span class="name" role="heading" aria-level="2"> 1463 Broadband 1464 </span> 1465 1466 1467 <span 1468 class="component-status " 1469 1470 title="" 1471 > 1472 1473 Operational 1474 1475 </span> 1476 1477 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1478 1479</div> 1480 1481 </div> 1482 <div class="component-container border-color"> 1483 1484<div data-component-id="wljm4jccbtb4" 1485 class="component-inner-container status-green " 1486 data-component-status="operational" 1487 data-js-hook=""> 1488 1489 <span class="name" role="heading" aria-level="2"> 1490 Billing and Payments 1491 </span> 1492 1493 <button 1494 type="button" 1495 class="tooltip-base tool" 1496 data-js-hook="tooltip" 1497 tabindex="0" 1498 aria-label="More information about Billing and Payments" 1499 aria-describedby="tooltip-wljm4jccbtb4" 1500 data-original-title="Card Payment processing, general invoicing and credit transactions etc." 1501 >?</button> 1502 1503 <span 1504 class="component-status " 1505 1506 title="" 1507 > 1508 1509 Operational 1510 1511 </span> 1512 1513 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1514 1515</div> 1516 1517 </div> 1518 <div class="component-container border-color"> 1519 1520<div data-component-id="d8sffd95b24c" 1521 class="component-inner-container status-green " 1522 data-component-status="operational" 1523 data-js-hook=""> 1524 1525 <span class="name" role="heading" aria-level="2"> 1526 Control Panel 1527 </span> 1528 1529 <button 1530 type="button" 1531 class="tooltip-base tool" 1532 data-js-hook="tooltip" 1533 tabindex="0" 1534 aria-label="More information about Control Panel" 1535 aria-describedby="tooltip-d8sffd95b24c"
1536 data-original-title="my.voipfone.co.uk website" 1537 >?</button> 1538 1539 <span 1540 class="component-status " 1541 1542 title="" 1543 > 1544 1545 Operational 1546 1547 </span> 1548 1549 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1550 1551</div> 1552 1553 </div> 1554 <div class="component-container border-color"> 1555 1556<div data-component-id="j9p5m0396clb" 1557 class="component-inner-container status-green " 1558 data-component-status="operational" 1559 data-js-hook=""> 1560 1561 <span class="name" role="heading" aria-level="2"> 1562 Website 1563 </span> 1564 1565 <button 1566 type="button" 1567 class="tooltip-base tool" 1568 data-js-hook="tooltip" 1569 tabindex="0" 1570 aria-label="More information about Website" 1571 aria-describedby="tooltip-j9p5m0396clb" 1572 data-original-title="www.voipfone.co.uk website" 1573 >?</button> 1574 1575 <span 1576 class="component-status " 1577 1578 title="" 1579 > 1580 1581 Operational 1582 1583 </span> 1584 1585 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1586 1587</div> 1588 1589 </div> 1590 <div class="component-container border-color"> 1591 1592<div data-component-id="562qvych6ft8" 1593 class="component-inner-container status-green showcased" 1594 data-component-status="operational" 1595 data-js-hook=""> 1596 1597 <span class="name" role="heading" aria-level="2"> 1598 Virtual PA 1599 </span> 1600 1601 1602 <span 1603 class="component-status " 1604 1605 title="" 1606 > 1607 1608 Operational 1609 1610 </span> 1611 1612 <button type="button" class="tool icon-indicator fa fa-check status-icon-button" aria-label="Operational" data-js-hook="tooltip" data-original-title="Operational"></button> 1613 1614 <div class="uptime-lazy-placeholder" data-uptime-lazy="562qvych6ft8" aria-hidden="true"></div> 1615</div> 1616 1617 </div> 1618 </div> 1619 <div class="component-statuses-legend font-small"> 1620 <div class="legend-item status-green"> 1621 <span class="icon-indicator fa fa-check"></span> 1622 Operational 1623 </div> 1624 <div class="legend-item status-yellow"> 1625 <span class="icon-indicator fa fa-minus-square"></span> 1626 Degraded Performance 1627 </div> 1628 <div class="legend-item status-orange"> 1629 <span class="icon-indicator fa fa-exclamation-triangle"></span> 1630 Partial Outage 1631 </div> 1632 <div class="breaker"></div> 1633 <div class="legend-item status-red"> 1634 <span class="icon-indicator fa fa-times"></span> 1635 Major Outage 1636 </div> 1637 <div class="legend-item status-blue"> 1638 <span class="icon-indicator fa fa-wrench"></span> 1639 Maintenance 1640 </div> 1641</div> 1642 1643 </div> 1644 1645 <div id="uptime-tooltip"> 1646 <div class="pointer-container"> 1647 <div class="pointer-larger"></div> 1648 <div class="pointer-smaller"></div> 1649 </div> 1650 <div class="tooltip-box"> 1651 <div class="tooltip-content"> 1652 <div class="tooltip-close"> 1653 <i class="fa fa-times"></i> 1654 </div> 1655 <div class="date"></div> 1656 <div class="outages"> 1657 <div class="outage-field major"> 1658 <span class="label"> 1659 <i class="component-status page-colors text-color major_outage"></i> 1660 Major outage 1661 </span> 1662 <span class="value-hrs"></span> 1663 <span class="value-mins"></span> 1664 </div> 1665 <div class="outage-field partial"> 1666 <span class="label"> 1667 <i class="component-status page-colors text-color partial_outage"></i> 1668 Partial outage 1669 </span> 1670 <span class="value-hrs"></span> 1671 <span class="value-mins"></span> 1672 </div> 1673 <div class="no-outages-msg"> 1674 No downtime recorded on this day. 1675 </div> 1676 <div class="no-data-msg"> 1677 No data exists for this day. 1678 </div> 1679 <div id="major-outage-group-count" class="outage-count"> 1680 <i class="component-status page-colors text-color major_outage"></i> 1681 <span class="count"></span> 1682 had a major outage. 1683 </div> 1684 <div id="partial-outage-group-count" class="outage-count"> 1685 <i class="component-status page-colors text-color partial_outage"></i>
1686 <span class="count"></span> 1687 had a partial outage. 1688 </div> 1689 </div> 1690 <div class="related-events"> 1691 <h3 id="related-event-header">Related</h3> 1692 <ul id="related-events-list"></ul> 1693 </div> 1694 <div class="no-related-msg"> 1695 <p>No incidents or maintenance related to this downtime.</p> 1696 </div> 1697 </div> 1698 </div> 1699</div> 1700
1701<script src="https://dka575ofm4ao0.cloudfront.net/assets/vendor/bowser-1643ca34a6d589b2d4d42163a891e4512d5d7657125e09bb5f3d44288114e6bd.js"></script>
vendor: 1 bytes, line 1701
1701
1702<script type="text/javascript"> 1703 /** 1704 This file contains the code needed to handle display of the uptime tooltips on status. 1705 Note: because it's in ERB, only ES5 syntax is allowed. 1706 */ 1707 1708 window.uptimeData = window.uptimeData || {}; 1709 var uptimeData = window.uptimeData; 1710 var timeoutId; 1711 var monthStrings = [ 1712 'Jan', 'Feb', 'Mar', 1713 'Apr', 'May', 'Jun', 1714 'Jul', 'Aug', 'Sep', 1715 'Oct', 'Nov', 'Dec' 1716 ]; 1717 var EVENT_MAX_LENGTH = 90; 1718 1719 // Detect device (desktop vs. touch device) 1720 function touchDevice() { 1721 var browser = bowser.getParser(window.navigator.userAgent); 1722 // if type is either mobile or tablet, return true 1723 return browser.parse().parsedResult.platform.type !== 'desktop'; 1724 } 1725 1726 // Class is in format day-<number>. Convert to just number 1727 function dayNumberFromClass(className) { 1728 return parseInt(className.split('-')[1]); 1729 } 1730 1731 // Class is in format component-<code>. Convert to just code 1732 function componentCodeFromClass(className) { 1733 return className.split('-')[1]; 1734 } 1735 1736 // Convert number to string pixel measurement 1737 function intToPixels(number) { 1738 return number.toString() + 'px'; 1739 } 1740 1741 function truncate(str) { 1742 return str.substring(0, EVENT_MAX_LENGTH) + 1743 (str.length > EVENT_MAX_LENGTH ? '...' : ''); 1744 } 1745 1746 // Tooltip Handling class constructor 1747 function UptimeTooltipHandler(frameWidth) { 1748 this.visible = false; 1749 this.activeDay = { 1750 hovered: false 1751 }; 1752 this.tooltip = document.getElementById('uptime-tooltip'); 1753 this.frameWidth = frameWidth === undefined ? window.innerWidth : frameWidth; 1754 this.scrolling = false; 1755 1756 window.addEventListener('mousemove', this.tooltipListener.bind(this)); 1757 window.addEventListener('orientationchange', this.orientationListener.bind(this)); 1758 1759 // on tooltip creation, determine whether to display touch-specific controls 1760 var tooltipCloseButton = document.querySelector('.tooltip-close'); 1761 1762 if (touchDevice()) { 1763 var componentsContainer = document.querySelector('.components-container'); 1764 componentsContainer.addEventListener('touchstart', this.handleTouch.bind(this)); 1765 1766 tooltipCloseButton.addEventListener('touchstart', this.unhoverTooltip.bind(this)); 1767 } else { 1768 window.addEventListener('resize', this.resizeListener.bind(this)); 1769 // classList not supported by IE < 9 1770 tooltipCloseButton.className += ' hidden'; 1771 } 1772 1773 // Handle toggle of group elements 1774 var groupComponents = document.querySelectorAll('[data-js-hook=component-group-opener]'); 1775 for (var i = 0; i < groupComponents.length; i++) { 1776 groupComponents[i].addEventListener('click', this.hideTooltip.bind(this)); 1777 } 1778 1779 var tooltipBox = document.querySelector('#uptime-tooltip .tooltip-box'); 1780 tooltipBox.addEventListener('mouseenter', this.mouseEnteredTooltip.bind(this)); 1781 tooltipBox.addEventListener('mouseleave', this.unhoverTooltip.bind(this)); 1782 } 1783 1784 // STATUS-801: extracted so the lazy loader (_uptime_showcase_lazy_js) can bind 1785 // focus/blur/keydown handlers on rects that are injected AFTER initial paint. 1786 // Pass a root element to bind only that subtree's rects (avoids re-binding 1787 // existing ones); defaults to the whole document for the inline render path. 1788 function bindUptimeDayRects(root) { 1789 (root || document).querySelectorAll('.uptime-day').forEach(function (rect) { 1790 rect.addEventListener('focus', function (event) { 1791 var tooltipHandler = new UptimeTooltipHandler(); 1792 tooltipHandler.updateHoveredDay(event); 1793 tooltipHandler.updateTooltip(event); 1794 }); 1795 1796 rect.addEventListener('blur', function () { 1797 var tooltipHandler = new UptimeTooltipHandler(); 1798 tooltipHandler.unhoverTooltip(); 1799 }); 1800 1801 rect.addEventListener('keydown', function (event) { 1802 if (event.key === 'Escape' || event.keyCode === 27) { 1803 var tooltipHandler = new UptimeTooltipHandler(); 1804 tooltipHandler.unhoverTooltip(); 1805 } 1806 }); 1807 }); 1808 } 1809 window.bindUptimeDayRects = bindUptimeDayRects; 1810 bindUptimeDayRects(document); 1811 1812 UptimeTooltipHandler.prototype.tooltipListener = function(event) { 1813 if (!this.tooltipHovered) { 1814 this.updateHoveredDay(event); 1815 this.updateTooltip(event); 1816 } 1817 } 1818 1819 // this handler will accommodate for mobile orientation change 1820 UptimeTooltipHandler.prototype.orientationListener = function(event) { 1821 // just close the tooltip 1822 this.unhoverTooltip(); 1823 } 1824 1825 UptimeTooltipHandler.prototype.resizeListener = function(event) { 1826 this.frameWidth = window.innerWidth; 1827 } 1828 1829 UptimeTooltipHandler.prototype.handleTouch = function (event) { 1830 if (event.target.classList.contains('uptime-day')) { 1831 event.stopPropagation(); 1832 this.bladeTouched(event); 1833 } 1834 } 1835 1836 UptimeTooltipHandler.prototype.mouseEnteredTooltip = function() { 1837 // Necessary to clear the timeout set for closing the tooltip when the mouse 1838 // moves off the blade or timeline, so the tooltip isnt closed on hover 1839 clearTimeout(timeoutId); 1840 // Sets it to null so the timeout can be set later, as clearTimeout only 1841 // cancels the timer, and we need to allow it to be reset in the mouse 1842 // move handler below 1843 timeoutId = null; 1844 this.tooltipHovered = true; 1845 } 1846 1847 UptimeTooltipHandler.prototype.unhoverTooltip = function() { 1848 this.tooltipHovered = false;
1849 this.activeDay.hovered = false; 1850 this.hideTooltip(); 1851 } 1852 1853 UptimeTooltipHandler.prototype.bladeTouched = function (event) { 1854 event.preventDefault(); 1855 var classes = event.target.getAttribute('class').split(' '); 1856 var componentCode = componentCodeFromClass(classes[1]) 1857 var index = dayNumberFromClass(classes[2]); 1858 1859 // If open and tapped on same component and day, close tooltip 1860 if (this.visible && this.activeDay.component === componentCode && this.activeDay.index === index) { 1861 this.hideTooltip(); 1862 } else { 1863 this.updateHoveredDay(event); 1864 this.updateTooltip(event); 1865 } 1866 } 1867 1868 UptimeTooltipHandler.prototype.updateHoveredDay = function(event) { 1869 var classes = event.target.getAttribute('class'); // classList doesn't work in IE 1870 var onDay = classes != null && classes.split(' ').indexOf('uptime-day') !== -1; 1871 1872 if (onDay) { 1873 classes = classes.split(' '); 1874 1875 var componentCode = componentCodeFromClass(classes[1]); 1876 1877 this.activeDay = { 1878 index: dayNumberFromClass(classes[2]), 1879 component: componentCode, 1880 bounds: event.target.getBoundingClientRect(), 1881 isGroup: uptimeData[componentCode].component.isGroup, 1882 hovered: true 1883 } 1884 } else { 1885 this.activeDay.hovered = false; 1886 } 1887 } 1888 1889 UptimeTooltipHandler.prototype.updateTooltip = function(event) { 1890 var classes = event.target.getAttribute('class'); // classList doesn't work in IE 1891 var hoveredOnGraphic = classes != null && classes.split(' ').indexOf('availability-time-line-graphic') !== -1; 1892 1893 if (this.activeDay.hovered) { 1894 this.updateTooltipData(); 1895 this.positionTooltip(); 1896 } else if (this.visible && !this.activeDay.hovered && !hoveredOnGraphic) { 1897 // Important: since this is on mouse move it will be called multiple times 1898 // which will clear timeoutId and reset it to the new value, meaning 1899 // it is a race condition to cancel it 1900 if (!timeoutId) { 1901 var _this = this; 1902 timeoutId = setTimeout(function() { 1903 _this.hideTooltip(); 1904 timeoutId = null; 1905 }, 250); 1906 } 1907 } 1908 } 1909 1910 UptimeTooltipHandler.prototype.updateTooltipData = function() { 1911 // Get the data for the day we're hovered on 1912 var day = uptimeData[this.activeDay.component].days[this.activeDay.index]; 1913 1914 // Update the date for the tooltip 1915 var date = new Date(day.date); 1916 1917 // Get the component's start date. Note that it will be undefined here unless it is populated in our database 1918 var startDay = uptimeData[this.activeDay.component].component.startDate; 1919 var startDate = startDay ? new Date(startDay) : null; 1920 1921 // Determine whether current date falls before component's start date. 1922 var beforeStartDate = startDate ? date.getTime() < startDate.getTime() : false; 1923 1924 // UTC necessary since days are passed yyyy-mm-dd, and new Date uses midnight UTC, so local times 1925 // are presented as the day before 1926 var dateString = date.getUTCDate() + " " + monthStrings[date.getUTCMonth()] + " " + date.getUTCFullYear(); 1927 document.querySelector('#uptime-tooltip .date').innerHTML = dateString; 1928 1929 // Update the outage fields 1930 if (this.activeDay.isGroup) { 1931 this.updateGroupOutageFields() 1932 } else { 1933 this.updateOutageFields(day.outages.p, day.outages.m, day.related_events, beforeStartDate); 1934 } 1935 } 1936 1937 UptimeTooltipHandler.prototype.hoursFromSeconds = function(s) { 1938 return Math.floor(s / 3600); 1939 } 1940 1941 UptimeTooltipHandler.prototype.minutesFromSeconds = function(s) { 1942 // If less than a minute, round up to 1 minute to show that some outage existed 1943 if (s > 0 && s < 60) { 1944 return 1; 1945 } 1946 1947 // Otherwise use floor 1948 return Math.floor((s % 3600) / 60); 1949 } 1950 1951 UptimeTooltipHandler.prototype.updateGroupOutageFields = function() { 1952 // Hide time info 1953 document.querySelector('#uptime-tooltip .outage-field.major').style.display = 'none'; 1954 document.querySelector('#uptime-tooltip .outage-field.partial').style.display = 'none'; 1955 document.querySelector(".related-events h3").style.display = 'none'; 1956 document.querySelector('.no-related-msg').style.display = 'none'; 1957 1958 var eventList = document.getElementById("related-events-list") 1959 var cloneList = eventList.cloneNode(false); 1960 eventList.parentNode.replaceChild(cloneList, eventList); 1961 1962 var partialCount = 0; 1963 var majorCount = 0; 1964 1965 /** 1966 We were originally using the operationalCount as part of the no outage copy for group components, 1967 but ultimately decided not to use it. I opted to leave the variable in place in case we ever 1968 decide to use it in the future. 1969 */ 1970 var operationalCount = 0;
1971 var noDataCount = 0; 1972 var showcasedComponentsCount = 0; 1973 1974 var components = uptimeData[this.activeDay.component].component.group 1975 1976 for (var i = 0; i < components.length; i++) { 1977 if (!uptimeData[components[i]]) continue; 1978 1979 showcasedComponentsCount++; 1980 1981 var outages = uptimeData[components[i]].days[this.activeDay.index].outages; 1982 1983 var currentDay = uptimeData[components[i]].days[this.activeDay.index]; 1984 var currentDate = new Date(currentDay.date); 1985 1986 // Get the component's start date. Note that it will be undefined here unless it is populated in our database 1987 var startDay = uptimeData[components[i]].component.startDate; 1988 var startDate = startDay ? new Date(startDay) : null; 1989 1990 if (outages.p) { 1991 partialCount += 1; 1992 } 1993 1994 if (outages.m) { 1995 majorCount += 1; 1996 } 1997 1998 // Only increase operational count if component has data for this day 1999 if (!outages.p && !outages.m) { 2000 if (startDate && currentDate.getTime() < startDate.getTime()) { 2001 noDataCount +=1; 2002 } 2003 else { 2004 operationalCount +=1; 2005 } 2006 } 2007 } 2008 2009 document.querySelector('#major-outage-group-count').style.display = majorCount ? 'block' : 'none'; 2010 document.querySelector('#partial-outage-group-count').style.display = partialCount ? 'block' : 'none'; 2011 2012 document.querySelector('#major-outage-group-count .count').innerText = majorCount + (majorCount === 1 ? " component" : " components"); 2013 document.querySelector('#partial-outage-group-count .count').innerText = partialCount + (partialCount === 1 ? " component" : " components "); 2014 2015 // Show no data message only if we do not have data for any showcased components in the group 2016 var showNoDataMessage = noDataCount === showcasedComponentsCount; 2017 2018 // Show no outages message if we have data for the components and no outages in that data 2019 document.querySelector('#uptime-tooltip .no-outages-msg').style.display = (majorCount || partialCount || showNoDataMessage) ? 'none' : 'block'; 2020 document.querySelector('#uptime-tooltip .no-data-msg').style.display = showNoDataMessage ? 'block' : 'none'; 2021 } 2022 2023 UptimeTooltipHandler.prototype.updateOutageFields = function(partial, major, relatedEvents, beforeStartDate) { 2024 // Hide group info 2025 document.querySelector('#major-outage-group-count').style.display = 'none'; 2026 document.querySelector('#partial-outage-group-count').style.display = 'none'; 2027 2028 // Show the message that no outage present, if none is present 2029 if (partial || major || beforeStartDate) { 2030 document.querySelector('#uptime-tooltip .no-outages-msg').style.display = 'none'; 2031 } else { 2032 document.querySelector('#uptime-tooltip .no-outages-msg').style.display = 'block'; 2033 } 2034 2035 if (beforeStartDate) { 2036 document.querySelector('#uptime-tooltip .no-data-msg').style.display = 'block'; 2037 } 2038 else { 2039 document.querySelector('#uptime-tooltip .no-data-msg').style.display = 'none'; 2040 } 2041 2042 // Update partial outage field if an outage exists, otherwise hide it 2043 if (partial) { 2044 var hrs = this.hoursFromSeconds(partial); 2045 var mins = this.minutesFromSeconds(partial); 2046 document.querySelector('#uptime-tooltip .outage-field.partial .value-hrs').innerHTML = hrs.toString() + ' hrs'; 2047 document.querySelector('#uptime-tooltip .outage-field.partial .value-mins').innerHTML = mins.toString() + ' mins'; 2048 document.querySelector('#uptime-tooltip .outage-field.partial').style.display = 'flex'; 2049 } else { 2050 document.querySelector('#uptime-tooltip .outage-field.partial').style.display = 'none'; 2051 } 2052 2053 // Update major outage field if an outage exists, otherwise hide it 2054 if (major) { 2055 var hrs = this.hoursFromSeconds(major); 2056 var mins = this.minutesFromSeconds(major); 2057 document.querySelector('#uptime-tooltip .outage-field.major .value-hrs').innerHTML = hrs.toString() + ' hrs'; 2058 document.querySelector('#uptime-tooltip .outage-field.major .value-mins').innerHTML = mins.toString() + ' mins'; 2059 document.querySelector('#uptime-tooltip .outage-field.major').style.display = 'flex'; 2060 } else { 2061 document.querySelector('#uptime-tooltip .outage-field.major').style.display = 'none'; 2062 } 2063 2064 var eventList = document.getElementById("related-events-list") 2065 var cloneList = eventList.cloneNode(false); 2066 document.querySelector(".related-events h3").style.display = (relatedEvents.length ? 'block' : 'none'); 2067 2068 for (var i = 0; i < relatedEvents.length; i++) { 2069 var listItem = document.createElement("li"); 2070 listItem.className = "related-event"; 2071 var anchor = document.createElement("a"); 2072 anchor.className = "related-event-link"; 2073 anchor.target = "_blank"; 2074 anchor.href = window.Routes.incident_path(relatedEvents[i].code); 2075 2076 2077 var text = document.createTextNode(truncate(relatedEvents[i].name)); 2078 anchor.appendChild(text); 2079 listItem.appendChild(anchor); 2080 cloneList.appendChild(listItem); 2081 } 2082 2083 const displayNoRelatedMsg = ((major || partial) && !relatedEvents.length); 2084 document.querySelector('.no-related-msg').style.display = (displayNoRelatedMsg ? 'block' : 'none'); 2085 2086 eventList.parentNode.replaceChild(cloneList, eventList); 2087 } 2088 2089 UptimeTooltipHandler.prototype.positionTooltip = function() { 2090 this.calculatePointerCenter(); 2091 this.calculateBoxPosition(); 2092 2093 // show tooltip 2094 this.tooltip.style.display = 'block'; 2095 2096 // position pointer 2097 var pointer = this.tooltip.getElementsByClassName('pointer-container')[0]; 2098 pointer.style.left = intToPixels(this.pointerCenter.x - 8); 2099 pointer.style.top = intToPixels(this.pointerCenter.y - 5); 2100 2101 // position display box 2102 var box = this.tooltip.getElementsByClassName('tooltip-box')[0]; 2103 box.style.left = intToPixels(this.boxLeft); 2104 box.style.top = intToPixels(this.pointerCenter.y + 5); 2105 2106 this.visible = true; 2107 } 2108 2109 UptimeTooltipHandler.prototype.calculatePointerCenter = function() { 2110 var bounds = this.activeDay.bounds; 2111 var rectLeft = bounds.left + window.pageXOffset; 2112 var rectBottom = bounds.bottom + window.pageYOffset; 2113 var rectWidth = bounds.right - bounds.left; 2114 2115 this.pointerCenter = { 2116 x: rectLeft + Math.floor(rectWidth / 2), 2117 y: rectBottom + 5 2118 } 2119 } 2120 2121 UptimeTooltipHandler.prototype.calculateBoxPosition = function() { 2122 var sideWidth = 162.5; 2123 if (this.pointerCenter.x - sideWidth < 0) { 2124 this.boxLeft = 0; 2125 } else if (this.pointerCenter.x + sideWidth > this.frameWidth) { 2126 this.boxLeft = this.frameWidth - sideWidth * 2; 2127 } else { 2128 this.boxLeft = this.pointerCenter.x - sideWidth; 2129 } 2130 } 2131 2132 UptimeTooltipHandler.prototype.hideTooltip = function() { 2133 this.tooltip.style.display = 'none'; 2134 this.visible = false;
2135 } 2136 2137 new UptimeTooltipHandler(); 2138 2139</script>
2139 2140 2141 2142
2142<script type="text/javascript"> 2143 /** 2144 * STATUS-801: viewport-triggered loader for the 90-day uptime showcase. 2145 * 2146 * When LAZY_UPTIME_SHOWCASE is enabled the status document ships WITHOUT the 2147 * per-component SVG bars and the multi-MB inline `uptimeData` blob (that inline 2148 * payload is what caused `200 OK` + `ERR_HTTP2_PROTOCOL_ERROR` truncation on 2149 * large pages). Each showcase-eligible component instead renders a small 2150 * placeholder (`[data-uptime-lazy="<code>"]`). This script watches those 2151 * placeholders and, as they scroll into view, fetches their bars in small 2152 * batches from `status#uptime_showcase`, replaces the placeholder with the 2153 * returned markup, merges the tooltip data into `window.uptimeData`, and wires 2154 * up hover/keyboard tooltips + responsive (30/60/90-day) resizing. 2155 * 2156 * ES5 only (matches the rest of the status inline scripts). No hard dependency 2157 * on fetch/IntersectionObserver: falls back gracefully when unavailable. 2158 */ 2159 (function () { 2160 var ENDPOINT = "/uptime_showcase"; 2161 var BATCH_LIMIT = 60; // must stay <= SHOWCASE_BATCH_LIMIT server-side 2162 var FLUSH_DELAY_MS = 60; // coalesce rapidly-observed placeholders 2163 var MAX_WIDTH_30_DAYS = 600; 2164 var MAX_WIDTH_60_DAYS = 1024; 2165 var PRELOAD_MARGIN = '250px 0px'; // start fetching just before they scroll in 2166 2167 // code -> {ninety, sixty, thirty} for responsive legend updates. 2168 var uptimeValues = {}; 2169 // code -> true while queued/in-flight, to avoid duplicate requests. 2170 var inFlight = {}; 2171 var queue = []; 2172 var flushTimer = null; 2173 var observer = null; 2174 2175 function init() { 2176 var placeholders = document.querySelectorAll('[data-uptime-lazy]'); 2177 if (!placeholders.length) return; 2178 2179 window.uptimeData = window.uptimeData || {}; 2180 2181 if ('IntersectionObserver' in window) { 2182 observer = new IntersectionObserver(onIntersect, { rootMargin: PRELOAD_MARGIN }); 2183 for (var i = 0; i < placeholders.length; i++) { 2184 observer.observe(placeholders[i]); 2185 } 2186 } else { 2187 // Older browsers: no lazy behaviour, just load everything in batches. 2188 for (var j = 0; j < placeholders.length; j++) { 2189 enqueue(placeholders[j].getAttribute('data-uptime-lazy')); 2190 } 2191 } 2192 2193 var resizeTimer; 2194 window.addEventListener('resize', function () { 2195 clearTimeout(resizeTimer); 2196 resizeTimer = setTimeout(resizeSvgViewBoxes, 150); 2197 }); 2198 } 2199 2200 function onIntersect(entries) { 2201 for (var i = 0; i < entries.length; i++) { 2202 if (entries[i].isIntersecting) { 2203 enqueue(entries[i].target.getAttribute('data-uptime-lazy')); 2204 } 2205 } 2206 } 2207 2208 function enqueue(code) { 2209 if (!code || inFlight[code]) return; 2210 inFlight[code] = true; 2211 queue.push(code); 2212 if (!flushTimer) flushTimer = setTimeout(flush, FLUSH_DELAY_MS); 2213 } 2214 2215 function flush() { 2216 flushTimer = null; 2217 if (!queue.length) return; 2218 var batch = queue.splice(0, BATCH_LIMIT); 2219 fetchBatch(batch); 2220 if (queue.length && !flushTimer) flushTimer = setTimeout(flush, FLUSH_DELAY_MS); 2221 } 2222 2223 function fetchBatch(codes) { 2224 var xhr = new XMLHttpRequest(); 2225 xhr.open('GET', ENDPOINT + '?components=' + encodeURIComponent(codes.join(',')), true); 2226 xhr.setRequestHeader('Accept', 'application/json'); 2227 xhr.onreadystatechange = function () { 2228 if (xhr.readyState !== 4) return; 2229 if (xhr.status >= 200 && xhr.status < 300) { 2230 var data; 2231 try { data = JSON.parse(xhr.responseText); } 2232 catch (e) { release(codes); return; } 2233 applyBatch(data, codes); 2234 } else { 2235 // Transient failure: allow these codes to be retried if re-observed. 2236 release(codes); 2237 } 2238 }; 2239 xhr.send(); 2240 } 2241 2242 // Free codes so a future intersection can retry them (e.g. after a 5xx). 2243 function release(codes) { 2244 for (var i = 0; i < codes.length; i++) inFlight[codes[i]] = false; 2245 } 2246 2247 function applyBatch(data, codes) { 2248 var timelines = data.timelines || {}; 2249 for (var key in timelines) { 2250 if (timelines.hasOwnProperty(key)) window.uptimeData[key] = timelines[key]; 2251 } 2252 2253 var values = data.values || []; 2254 for (var v = 0; v < values.length; v++) { 2255 uptimeValues[values[v].component] = values[v]; 2256 } 2257 2258 var components = data.components || {}; 2259 for (var c = 0; c < codes.length; c++) { 2260 var code = codes[c]; 2261 var placeholder = document.querySelector('[data-uptime-lazy="' + code + '"]'); 2262 if (!placeholder) continue; 2263 if (observer) observer.unobserve(placeholder); 2264 2265 var html = components[code]; 2266 if (!html) { 2267 // Server returned no markup for this code (not actually showcased): 2268 // drop the placeholder and stop retrying. 2269 if (placeholder.parentNode) placeholder.parentNode.removeChild(placeholder); 2270 continue; 2271 } 2272 2273 // Replace the neutral placeholder with the fetched `.uptime-90-days-wrapper` 2274 // so the resulting DOM matches the inline (non-lazy) render exactly. 2275 var holder = document.createElement('div'); 2276 holder.innerHTML = html; 2277 var node = holder.firstElementChild; 2278 if (node && placeholder.parentNode) { 2279 placeholder.parentNode.replaceChild(node, placeholder); 2280 if (window.bindUptimeDayRects) window.bindUptimeDayRects(node); 2281 } 2282 } 2283 2284 resizeSvgViewBoxes(); 2285 } 2286 2287 /* ----- responsive resize (adapted from components_js) ----------------- */ 2288 2289 function calculateViewbox(dayCount, rectWidth, rectPadding) { 2290 var viewBox = []; 2291 if (dayCount === 90) {
2292 viewBox.push(0); 2293 } else { 2294 var offset = 90 - dayCount; 2295 viewBox.push((offset * rectWidth) + (rectPadding * offset)); 2296 } 2297 viewBox.push(0); 2298 viewBox.push((rectWidth * dayCount) + (rectPadding * (dayCount - 1))); 2299 viewBox.push(34); 2300 return viewBox.join(' '); 2301 } 2302 2303 function getKeyAndCount(width) { 2304 if (width <= MAX_WIDTH_30_DAYS) return { dayCount: 30, uptimeKey: 'thirty' }; 2305 if (width <= MAX_WIDTH_60_DAYS) return { dayCount: 60, uptimeKey: 'sixty' }; 2306 return { dayCount: 90, uptimeKey: 'ninety' }; 2307 } 2308 2309 function setUptimeValue(values, uptimeKey) { 2310 var current = document.querySelector('.legend-item-' + values.component); 2311 if (!current) return; 2312 var clone = current.cloneNode(false); 2313 var uptimeSpan = document.createElement('span'); 2314 uptimeSpan.id = 'uptime-percent-' + values.component; 2315 uptimeSpan.innerText = values[uptimeKey]; 2316 clone.appendChild(uptimeSpan); 2317 clone.appendChild(document.createTextNode(' % uptime')); 2318 current.parentNode.replaceChild(clone, current); 2319 } 2320 2321 function setDayCount(el, dayCount) { 2322 var clone = el.cloneNode(false); 2323 var dateSpan = document.createElement('span'); 2324 dateSpan.className = 'availability-time-line-legend-day-count'; 2325 dateSpan.innerText = dayCount; 2326 clone.appendChild(dateSpan); 2327 clone.appendChild(document.createTextNode(' days ago')); 2328 el.parentNode.replaceChild(clone, el); 2329 } 2330 2331 function resizeSvgViewBoxes() { 2332 var svgs = document.getElementsByClassName('availability-time-line-graphic'); 2333 if (!svgs.length) return; 2334 2335 var rects = svgs[0].getElementsByTagName('rect'); 2336 if (rects.length < 2) return; 2337 2338 var rectWidth = parseInt(rects[0].getAttribute('width')); 2339 var rectPadding = parseInt(rects[1].getAttribute('x')) - parseInt(rects[0].getAttribute('x')) - rectWidth; 2340 var info = getKeyAndCount(window.innerWidth); 2341 var newViewbox = calculateViewbox(info.dayCount, rectWidth, rectPadding); 2342 2343 for (var i = 0; i < svgs.length; i++) { 2344 if (svgs[i].getAttribute('viewBox') !== newViewbox) { 2345 svgs[i].setAttribute('viewBox', newViewbox); 2346 } 2347 } 2348 2349 var dayCountElements = document.querySelectorAll('.legend-item-date-range:first-of-type'); 2350 for (var d = 0; d < dayCountElements.length; d++) { 2351 setDayCount(dayCountElements[d], info.dayCount); 2352 } 2353 2354 for (var code in uptimeValues) { 2355 if (uptimeValues.hasOwnProperty(code)) setUptimeValue(uptimeValues[code], info.uptimeKey); 2356 } 2357 2358 var uptimeLinkVar = document.querySelector('.components-uptime-link > var'); 2359 if (uptimeLinkVar) uptimeLinkVar.innerHTML = info.dayCount; 2360 } 2361 2362 if (document.readyState === 'loading') { 2363 document.addEventListener('DOMContentLoaded', init); 2364 } else { 2365 init(); 2366 } 2367 })(); 2368</script>
2368 2369 2370 2371 2372 2373 2374 2375 <div class="incidents-list format-expanded"> 2376 <h2 class="font-largest no-link" id="past-incidents">Past Incidents</h2> 2377 2378 <div class="status-day font-regular no-incidents"> 2379 <h3 class="date border-color font-large">Oct <var data-var="date"> 5</var>, <var data-var="year">2026</var></h3> 2380 <p class="color-secondary">No incidents reported today.</p> 2381 </div> 2382 2383 2384 <div class="status-day font-regular no-incidents"> 2385 <h3 class="date border-color font-large">Oct <var data-var="date"> 4</var>, <var data-var="year">2026</var></h3> 2386 <p class="color-secondary">No incidents reported.</p> 2387 </div> 2388 2389 2390 <div class="status-day font-regular no-incidents"> 2391 <h3 class="date border-color font-large">Oct <var data-var="date"> 3</var>, <var data-var="year">2026</var></h3> 2392 <p class="color-secondary">No incidents reported.</p> 2393 </div> 2394 2395 2396 <div class="status-day font-regular no-incidents"> 2397 <h3 class="date border-color font-large">Oct <var data-var="date"> 2</var>, <var data-var="year">2026</var></h3> 2398 <p class="color-secondary">No incidents reported.</p> 2399 </div> 2400 2401 2402 <div class="status-day font-regular no-incidents"> 2403 <h3 class="date border-color font-large">Oct <var data-var="date"> 1</var>, <var data-var="year">2026</var></h3> 2404 <p class="color-secondary">No incidents reported.</p> 2405 </div> 2406 2407 2408 <div class="status-day font-regular no-incidents"> 2409 <h3 class="date border-color font-large">Sep <var data-var="date">30</var>, <var data-var="year">2026</var></h3> 2410 <p class="color-secondary">No incidents reported.</p> 2411 </div> 2412 2413 2414 <div class="status-day font-regular no-incidents"> 2415 <h3 class="date border-color font-large">Sep <var data-var="date">29</var>, <var data-var="year">2026</var></h3> 2416 <p class="color-secondary">No incidents reported.</p> 2417 </div> 2418 2419 2420 <div class="status-day font-regular no-incidents"> 2421 <h3 class="date border-color font-large">Sep <var data-var="date">28</var>, <var data-var="year">2026</var></h3> 2422 <p class="color-secondary">No incidents reported.</p> 2423 </div> 2424 2425 2426 <div class="status-day font-regular no-incidents"> 2427 <h3 class="date border-color font-large">Sep <var data-var="date">27</var>, <var data-var="year">2026</var></h3> 2428 <p class="color-secondary">No incidents reported.</p> 2429 </div> 2430 2431 2432 <div class="status-day font-regular no-incidents"> 2433 <h3 class="date border-color font-large">Sep <var data-var="date">26</var>, <var data-var="year">2026</var></h3> 2434 <p class="color-secondary">No incidents reported.</p> 2435 </div> 2436 2437 2438 <div class="status-day font-regular no-incidents"> 2439 <h3 class="date border-color font-large">Sep <var data-var="date">25</var>, <var data-var="year">2026</var></h3> 2440 <p class="color-secondary">No incidents reported.</p> 2441 </div> 2442 2443 2444 <div class="status-day font-regular no-incidents"> 2445 <h3 class="date border-color font-large">Sep <var data-var="date">24</var>, <var data-var="year">2026</var></h3> 2446 <p class="color-secondary">No incidents reported.</p> 2447 </div> 2448 2449 2450 <div class="status-day font-regular no-incidents"> 2451 <h3 class="date border-color font-large">Sep <var data-var="date">23</var>, <var data-var="year">2026</var></h3> 2452 <p class="color-secondary">No incidents reported.</p> 2453 </div> 2454 2455 2456 <div class="status-day font-regular no-incidents"> 2457 <h3 class="date border-color font-large">Sep <var data-var="date">22</var>, <var data-var="year">2026</var></h3> 2458 <p class="color-secondary">No incidents reported.</p> 2459 </div> 2460 2461 2462 <div class="status-day font-regular no-incidents"> 2463 <h3 class="date border-color font-large">Sep <var data-var="date">21</var>, <var data-var="year">2026</var></h3> 2464 <p class="color-secondary">No incidents reported.</p> 2465 </div> 2466 2467 </div> 2468 2469 2470 <div class="page-footer border-color font-small"> 2471 <a href="/history" class="history-footer-link"><span style="font-family:arial" aria-hidden="true">←</span> Incident History</a> 2472
2473 <span class="color-secondary powered-by"><a class="color-secondary" target="_blank" rel="noopener noreferrer nofollow" href="https://www.atlassian.com/software/statuspage?utm_campaign=www.voipfonestatus.co.uk&utm_content=SP-notifications&utm_medium=powered-by&utm_source=inapp">Powered by Atlassian Statuspage</a></span> 2474 </div> 2475 </div> 2476 2477 2478 2479 </div> 2480 2481 2482 2483 2484 2485 2486 2487
2487<script src="https://dka575ofm4ao0.cloudfront.net/assets/status_manifest-b790849ccb41192b3f7d9c14d5a4a6d5142add81fc8522649ca5c82f6a1fbb0e.js"></script>
2487 2488 <div id="cpt-notification-container" role="status" aria-live="polite" aria-atomic="true"></div> 2489 2490 2491 2492 2493 2494 <!-- all of the content_for stuff --> 2495
2495<script src="https://dka575ofm4ao0.cloudfront.net/assets/register_subscription_form-589b657fec607087fc5c740c568270907310bc4f6aaa20256e70f01b103025ca.js"></script>
2495 2496 2497
2497<script type="text/javascript"> 2498 $(function() { 2499 SP.currentPage.registerSubscriptionForm('email'); 2500 2501 SP.currentPage.registerSubscriptionForm('sms'); 2502 2503 2504 }); 2505 2506 2507 2508 2509 2510 </script>
2510 2511
2511<script src="https://dka575ofm4ao0.cloudfront.net/assets/status_common-a7b1e9f22a2c94a83d347ec517cabf21494ca11867ebf891f46f89c9b4101811.js"></script>
2511 2512
2512<script> 2513 SP.pollForChanges('/api/v2/status.json'); 2514 </script>
2514 2515 2516
2516<script> 2517 $(function() { 2518 $('.tool').tooltipster({ 2519 animationDuration: 100, 2520 contentAsHTML: true, 2521 delay: 100, 2522 theme: 'tooltipster-borderless', 2523 functionInit: function (instance, helper) { 2524 var $origin = $(helper.origin), 2525 dataOptions = $origin.attr('data-tooltip-config'); 2526 if (dataOptions){ 2527 dataOptions = JSON.parse(dataOptions); 2528 $.each(dataOptions, function(name, option){ 2529 instance.option(name, option); 2530 }); 2531 } 2532 } 2533 }); 2534 // clicks on first tab in subscribe popout since we won't know which is first 2535 // upon construction in the ruby code 2536 $('.updates-dropdown-nav > a').eq(0).click(); 2537 2538 // twitter follow button needs some margin 2539 $('.twitter-follow-button').css('margin-right', '6px'); 2540 }); 2541 2542 $(function() { 2543 // open/close component groups 2544 HRB.utils.djshook('component-group-opener').on('click', function() { 2545 var groupParentIndicator = $(this).find('.group-parent-indicator'); 2546 groupParentIndicator.toggleClass('fa-plus-square-o').toggleClass('fa-minus-square-o').end().parent().toggleClass('open'); 2547 toggleGroup(groupParentIndicator) 2548 }); 2549 }); 2550 2551 $(function() { 2552 HRB.utils.djshook('component-group-opener').on('keydown', function(event) { 2553 if (event.key !== "Enter" && event.key !== " ") { 2554 return; 2555 } 2556 event.preventDefault() 2557 var groupParentIndicator = $(this).find('.group-parent-indicator'); 2558 groupParentIndicator.toggleClass('fa-plus-square-o').toggleClass('fa-minus-square-o').end().parent().toggleClass('open'); 2559 toggleGroup(groupParentIndicator) 2560 }); 2561 }); 2562 2563 function toggleGroup(groupParentIndicator) { 2564 var isOpen = groupParentIndicator.attr('aria-expanded') 2565 if (isOpen == 'false') { 2566 groupParentIndicator.attr('aria-expanded', 'true'); 2567 } else { 2568 groupParentIndicator.attr('aria-expanded', 'false'); 2569 } 2570 } 2571 2572 $(function() { 2573 $(document).on('ajax:complete', '.modal.in', function(e) { 2574 // Close the active modal. 2575 $('.modal.in').modal('hide'); 2576 }); 2577 }); 2578 2579 </script>
2579 2580 2581 2582
2582<script> 2583 /** INITIALIZATION **/ 2584 var recaptchaIds = {} 2585 2586 // Unfortunately there's no unique selectors on the parent divs that recaptcha adds. The first unique selector 2587 // is the iframe rendered 2 levels deep. So this waits until the iframes are added to the page, then finds 2588 // the parent div and sets the z index so that it'll render above our modals & dropdowns from the start. 2589 function setZIndex(captchaCount, startTime) { 2590 // bail after 10s just in case so we don't do this forever if something whaky happens 2591 if (new Date() - startTime > 10000) { 2592 return; 2593 } 2594 2595 var iframes = document.querySelectorAll('iframe[title="recaptcha challenge"]'); 2596 if (iframes.length != captchaCount) { 2597 setTimeout(function() { 2598 setZIndex(captchaCount, startTime); 2599 }, 500); 2600 } 2601 2602 for (var i = 0; i < iframes.length; i++) { 2603 // incident subscribe modal is 1050, so this has to be above that 2604 iframes[i].parentElement.parentElement.style.zIndex = "1100"; 2605 } 2606 } 2607 2608 function updateCaptchaIframeTitle(captchaCount, startTime, updates=0) { 2609 2610 if (new Date() - startTime > 10000 || captchaCount === updates) { 2611 return; 2612 } 2613 var iframesWithTitle = document.querySelectorAll('iframe[title="recaptcha challenge expires in two minutes"]'); 2614 2615 if (iframesWithTitle.length != captchaCount) { 2616 setTimeout(function() { 2617 updateCaptchaIframeTitle(captchaCount, startTime, iframesWithTitle.length + updates); 2618 }, 500); 2619 } 2620 2621 for (var i = 0; i < iframesWithTitle.length; i++) { 2622 iframesWithTitle[i].title = "recaptcha"; 2623 } 2624 } 2625 2626 function addIncidentCaptcha() { 2627 var incidentCaptcha = document.createElement('div'); 2628 incidentCaptcha.setAttribute('id', 'subscribe-incident-recaptcha'); 2629 incidentCaptcha.setAttribute('class', 'g-recaptcha'); 2630 incidentCaptcha.setAttribute('data-sitekey', '6LcZ-b0UAAAAAENi956aWzynTT2ZJ80dGU3F80Op'); 2631 incidentCaptcha.setAttribute('data-callback', 'submitIncidentSubscriberSuccess'); 2632 incidentCaptcha.setAttribute('data-error-callback', 'submitIncidentSubscriberError'); 2633 incidentCaptcha.setAttribute('data-size', 'invisible'); 2634 document.body.appendChild(incidentCaptcha); 2635 var incidentCode = document.createElement('input'); 2636 incidentCode.setAttribute('type', 'hidden'); 2637 incidentCode.setAttribute('id', 'submit_incident_code'); 2638 document.body.appendChild(incidentCode); 2639 } 2640 2641 var onloadCallback = function() { 2642 // if there is an incident, then add incident captcha element 2643 if (document.getElementsByClassName('modal-open-incident-subscribe').length > 0) { 2644 addIncidentCaptcha(); 2645 } 2646 2647 var captchas = document.getElementsByClassName("g-recaptcha"); 2648 2649 for(var i = 0; i < captchas.length; i++) { 2650 var elId = captchas[i].id; 2651 recaptchaIds[elId] = grecaptcha.enterprise.render(elId); 2652 } 2653 2654 setZIndex(captchas.length, new Date()); 2655 updateCaptchaIframeTitle(captchas.length, new Date()); 2656 } 2657 2658 2659 /** SUBSCRIBE DROPDOWN */ 2660 2661 // callbacks for captcha success 2662 function submitNewSubscriber(type, error) { 2663 if (error) document.querySelector('#subscribe-form-' + type + ' #captcha_error').value = 'true'; 2664 2665 document.getElementById('subscribe-form-' + type).dispatchEvent(new Event('submit', {bubbles: true, cancelable: true})); 2666 grecaptcha.enterprise.reset(recaptchaIds['subscribe-btn-' + type]); 2667 } 2668 function submitNewEmailSubscriber(token) { 2669 submitNewSubscriber('email'); 2670 } 2671 function submitNewSmsSubscriber(token) { 2672 submitNewSubscriber('sms'); 2673 } 2674 function submitNewWebhookSubscriber(token) { 2675 submitNewSubscriber('webhook'); 2676 } 2677 function submitIncidentSubscriber(token, error, incidentCodeOverride) { 2678 var incidentCode = incidentCodeOverride; 2679 if (!incidentCode) { 2680 var incidentCodeEl = document.getElementById('submit_incident_code'); 2681 incidentCode = incidentCodeEl && incidentCodeEl.value; 2682 } 2683 var incidentForm = incidentCode && document.getElementById('subscribe-form-' + incidentCode); 2684 if (!incidentForm) { 2685 return; 2686 } 2687 2688 var captchaError = incidentForm.querySelector('input[name="captcha_error"]'); 2689 var recaptchaResponse = incidentForm.querySelector('input[name="g-recaptcha-response"]'); 2690 if (captchaError) { 2691 captchaError.value = error; 2692 } 2693 if (recaptchaResponse) { 2694 recaptchaResponse.value = token; 2695 } 2696 incidentForm.dispatchEvent(new Event('submit', {bubbles: true, cancelable: true})); 2697 if (window.grecaptcha && grecaptcha.enterprise && recaptchaIds['subscribe-incident-recaptcha'] != null) { 2698 grecaptcha.enterprise.reset(recaptchaIds['subscribe-incident-recaptcha']); 2699 } 2700 } 2701 function submitIncidentSubscriberSuccess(token) { 2702 submitIncidentSubscriber(token, 'false'); 2703 } 2704 2705 // callbacks if we get captcha network errors 2706 function emailSubscriberCaptchaError(token) { 2707 submitNewSubscriber('email', true); 2708 } 2709 function smsSubscriberCaptchaError(token) { 2710 submitNewSubscriber('sms', true); 2711 } 2712 function webhookSubscriberCaptchaError(token) { 2713 submitNewSubscriber('webhook', true); 2714 } 2715 function submitIncidentSubscriberError(token) { 2716 submitIncidentSubscriber(token, 'true'); 2717 } 2718 2719 // tracking clicks 2720 ['email', 'sms', 'webhook'].forEach(function(type) { 2721 var el = document.getElementById('subscribe-btn-' + type); 2722 el && el.addEventListener("click", function() { 2723 $.ajax({ 2724 type: "POST", 2725 url: "/subscriptions/track_attempt", 2726 data: { 2727 type: type 2728 } 2729 }) 2730 }) 2731 }) 2732 2733 // form submission success callbacks 2734 $('#subscribe-form-email').on('ajax:success', function(e, data, status, xhr){ 2735 if (data.type === 'success') { 2736 SP.currentPage.updatesDropdown.hide(); 2737 var emailField = document.getElementById('email'); 2738 if (emailField) { 2739 emailField.value = ''; 2740 } 2741 } 2742 }); 2743 $('#subscribe-form-sms').on('ajax:success', function(e, data, status, xhr){ 2744 if (data.type === 'success' && data.otp_flow !== true) { 2745 SP.currentPage.updatesDropdown.hide(); 2746 var phoneField = document.getElementById('phone-number'); 2747 if (phoneField) { 2748 phoneField.value = ''; 2749 } 2750 } 2751 }); 2752 $('#subscribe-form-webhook').on('ajax:success', function(e, data, status, xhr){ 2753 if (data.type === 'success') { 2754 SP.currentPage.updatesDropdown.hide(); 2755 document.getElementById('endpoint-webhooks').value = ''; 2756 document.getElementById('email-webhooks').value = ''; 2757 } 2758 }); 2759 2760 $('a.subscribe').on('click', function() { 2761 document.body.style.overflow = "hidden"; 2762 document.body.style.height = "100vh"; 2763 }); 2764 2765 $('div.modal-open-incident-subscribe').on('hidden', function(){ 2766 document.body.style.overflow = ""; 2767 document.body.style.height = ""; 2768 }); 2769 2770 function submitCaptchaIncidentSubscribe(event) { 2771 var incidentCode = event.target.id.split('-')[2]; 2772 event.preventDefault(); 2773 2774 $.ajax({ 2775 type: "POST", 2776 url: "/subscriptions/track_attempt", 2777 data: { 2778 type: 'incident' 2779 } 2780 }) 2781 2782 var incidentCodeField = document.getElementById('submit_incident_code'); 2783 if (incidentCodeField) { 2784 incidentCodeField.value = incidentCode; 2785 } 2786 2787 // Recaptcha's onloadCallback is what creates #submit_incident_code and the 2788 // widget id. If the enterprise.js script is blocked (ad blockers, CI url 2789 // blacklist), execute() and .value on a null node throw and the subscribe 2790 // click never reaches the server. 2791 var recaptchaId = recaptchaIds['subscribe-incident-recaptcha']; 2792 if (window.grecaptcha && grecaptcha.enterprise && typeof grecaptcha.enterprise.execute === 'function' && recaptchaId != null) { 2793 grecaptcha.enterprise.execute(recaptchaId); 2794 } else { 2795 submitIncidentSubscriber('', 'true', incidentCode); 2796 } 2797 } 2798</script>
vendor: 135 bytes, lines 2798-2804
2798 2799 2800<script src='https://www.recaptcha.net/recaptcha/enterprise.js?onload=onloadCallback&render=explicit' async defer></script> 2801 2802 2803 2804
2804<script src="https://dka575ofm4ao0.cloudfront.net/packs/common-b57e85f6a60348cdd566.chunk.js"></script>
2804 2805
2805<script src="https://dka575ofm4ao0.cloudfront.net/packs/globals-79d49f8cfe179f020629.chunk.js"></script>
2805 2806 2807
2807<script src="https://dka575ofm4ao0.cloudfront.net/packs/runtime-e9fe27ac357824763c7d.js"></script>
2807 2808 2809 2810 2811 2812
2812<script> 2813 window.addEventListener('load', function () { 2814 const urlParams = new URLSearchParams(window.location.search); 2815 const messageToken = urlParams.get('slack_message_token'); 2816 const channelName = escape(urlParams.get('channel_name')); 2817 2818 if(!!messageToken) { 2819 switch(messageToken) { 2820 case 'slack_auth_error': 2821 HRB.utils.notify('The Slack authorization attempt was unsuccessful. Try again.', {cssClass:'error'}); 2822 break; 2823 case 'subscribers_disabled_error': 2824 HRB.utils.notify('Slack subscriptions are not enabled on this page.', {cssClass:'error'}); 2825 break; 2826 case 'direct_message_channel_error': 2827 HRB.utils.notify('Subscriptions arenât supported in direct messages. Try subscribing again and choose a channel instead.', {cssClass:'error'}); 2828 break 2829 case 'duplicate_error': 2830 HRB.utils.notify("You're already subscribed to get Slack notifications in that channel.", {cssClass:'error'}); 2831 break; 2832 case 'duplicate_private_channel_error': 2833 HRB.utils.notify(`You're already subscribed to get Slack notifications in #${channelName}. Invite the @Statuspage app to that channel to start getting status updates.`, {cssClass: 'error'}); 2834 break; 2835 case 'default_success': 2836 HRB.utils.notify("You're now subscribed to get Statuspage updates in Slack!", {cssClass:'success'}); 2837 break; 2838 case 'private_channel_success': 2839 HRB.utils.notify(`IMPORTANT: Invite the @Statuspage app to your Slack channel #${channelName} to start getting status updates.`, {cssClass:'success'}); 2840 break; 2841 } 2842 } 2843 }); 2844</script>
2844 2845 2846 2847<!-- FOR FLASH NOTICES --> 2848 2849<!-- FOR ERROR --> 2850 2851 2852
2852<script> 2853 $(function() { 2854 var $link = $('<span class="color-secondary powered-by"><a class="color-secondary" target="_blank" rel="noopener noreferrer nofollow" href="https://www.atlassian.com/software/statuspage?utm_campaign=www.voipfonestatus.co.uk&utm_content=SP-notifications&utm_medium=powered-by&utm_source=inapp">Powered by Atlassian Statuspage</a></span>'); 2855 2856 var setPoweredByStyles = function() { 2857 if (!$('.powered-by').length) { 2858 $link.appendTo($('.page-footer')) 2859 } 2860 $('.powered-by').attr('style', 'display: inline !important; visibility:visible !important; opacity: 1 !important; position:static !important; text-indent:0px !important; transform:scale(1) !important'); 2861 } 2862 2863 setInterval(setPoweredByStyles, 1000); 2864 }); 2865</script>
2865 2866 2867 2868 2869 2870 2871 </body> 2872</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.