Eurozone Posts Upside Growth Surprise in Q3
/*jshint esversion: 6 */
var socket;
var assigned_server = 3001;
var distributor_server = 3010;
var publisher_channel = '';
var broadcaster_channel = '';
var remote_ip = '';
var session_info = {};
var logging_interval;
var logging_interval_time = 120000;
var socket_emits = 0;
var session_start_time;
var reconnectionDelayGrowFactor = 1.2;
var reconnection_delay = 1000;
var playing = false;
var connected_to_assigned = false;
var socket_close_timeout;
var player_disconnected_annoucement_play_delay = 1500;
var player_disconnected_annoucement_play_timeout = null;
const TOKEN_ENDPOINT = "https://www.livesquawk.com/api/get_token.php";
self.onmessage = function (msg) {
switch(msg.data.action) {
case 'Reactivate': reactivate(); break;
case 'ConnectDistributor': connect_to_distributor(msg); break;
case 'SessionStaticInfo': session_static_info(msg); break;
case 'SessionInfo': update_session_info(msg.data); break;
case 'PauseLogging': clearTimeout(logging_interval); break;
case 'RestartLogging': postMessage({action: 'RequestSessionStaticInfo' }); break;
case 'JoinPublisherChannel': join_publisher_channel(msg.data); break;
case 'JoinPlayerChannel': join_player_channel(msg.data); break;
case 'CheckChannelStatus': check_channel_status(msg.data); break;
case 'PlayerLogResponse': player_log_response(msg.data); break;
case 'CloseSocket': close_socket(); break;
case 'RequestMessageSearch': request_message_search(msg.data); break;
case 'RequestMoreMessages': request_more_messages(msg.data); break;
case 'PlayerDisconnectedAnnoucementTimeoutStart': player_disconnected_annoucement_timeout_start(); break;
case 'PlayerDisconnectedAnnoucementTimeoutClear': player_disconnected_annoucement_timeout_clear(); break;
case 'GetConnectionState': checkSocketConnectionState(); break;
}
};
function player_disconnected_annoucement_timeout_clear() {
clearTimeout(player_disconnected_annoucement_play_timeout);
player_disconnected_annoucement_play_timeout = null;
}
function player_disconnected_annoucement_timeout_start() {
player_disconnected_annoucement_play_timeout = setTimeout(function() { send_play_disconnect_annoucement(); }, player_disconnected_annoucement_play_delay );
}
function send_play_disconnect_annoucement() {
postMessage({action: "PlayDisconnectAnnoucement"});
}
function reactivate() {
playing = false;
connect_to_assigned_server();
}
function player_log_response(data) {
var data_array = {};
data_array.type = 'PlayerLogResponse';
data_array.respond_to_socket_final = data.respond_to_socket_final;
data_array.respond_to_socket = data.respond_to_socket;
data_array.player_socket_id = data.player_socket_id;
data_array.logs = data.logs;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
function request_message_search(data) {
var data_array = {};
data_array.type = 'request_message_search';
data_array.publisher_channel = data.publisher_channel;
data_array.search_term = data.search_term;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
function request_more_messages(data) {
var data_array = {};
data_array.type = 'request_more_messages';
data_array.publisher_channel = data.publisher_channel;
data_array.last_record_id = data.last_record_id;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
function check_channel_status(data) {
var data_array = {};
data_array.type = 'check_channel_status';
data_array.app_name = data.app_name;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1 && connected_to_assigned) { socket.send(msg_string); }
else { setTimeout(function() { check_channel_status(data); },500); }
}
function check_channel_status_response(data) {
postMessage({ action: 'CheckChannelStatusReponse', stream_status: data.stream_status.status, onair: data.stream_status.onair, connected: data.stream_status.connected });
}
async function join_publisher_channel(data) {
if (typeof data.jwt_token === 'string' && data.jwt_token !== '') {
if (!socket || socket.readyState !== WebSocket.OPEN) {
console.warn("[Page worker] JWT join skipped: socket not open");
return;
}
socket.send(JSON.stringify({
type: "join_publisher_channel",
jwt_token: data.jwt_token,
publisher_channel: data.publisher_channel,
username: data.username,
subscriber_group: data.subscriber_group,
display_name: data.display_name,
single_sign_on: data.single_sign_on,
remote_ip: data.remote_ip,
http_referrer: data.http_referrer,
current_page: data.current_page,
php_session_id: data.php_session_id,
from_react: data.from_react,
...(typeof data.api_key === "string" && data.api_key.trim() !== "" ? { api_key: data.api_key } : {}),
}));
console.log("[Page worker] Sent supplied JWT join");
postMessage({ action: 'PublisherChannelJoined' });
return;
}
const joinSocket = socket; if (!joinSocket || joinSocket.readyState !== WebSocket.OPEN) { return; }
const apiKey = typeof data.api_key === "string" ? data.api_key.trim() : "";
const partnerName = partnerFromCurrentPage(data.current_page);
let tokenBody;
if (apiKey !== "") { tokenBody = { api_key: apiKey }; }
else if (partnerName) { tokenBody = { partner_name: partnerName }; }
else { tokenBody = { username: data.username || "", publisher_channel: data.publisher_channel || "", }; }
let jwtToken = null;
try {
const requestStartedAt = Date.now();
const response = await fetch(TOKEN_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(tokenBody),
credentials: "same-origin",
cache: "no-store",
});
if (!response.ok) {
throw new Error(`token endpoint returned ${response.status}`);
}
const tokenData = await response.json();
if ( !tokenData || typeof tokenData.token !== "string" || tokenData.token === "" ) {
throw new Error("token endpoint returned no token");
}
const expiresIn = Number(tokenData.expires_in);
if (!Number.isFinite(expiresIn) || expiresIn <= 0) {
throw new Error("token endpoint returned an invalid lifetime");
}
const expiresAt = requestStartedAt + (expiresIn * 1000);
if (expiresAt <= Date.now() + 30000) {
throw new Error("token response has insufficient remaining lifetime");
}
jwtToken = tokenData.token;
}
catch (error) {
console.warn("[Page worker] Token request failed", error);
// API-key requests must not silently bypass token authentication.
if (apiKey !== "") { postMessage({ action: "auth_failed" }); return; }
}
// A reconnect during the fetch makes this join attempt obsolete.
if ( socket !== joinSocket || joinSocket.readyState !== WebSocket.OPEN ) { return; }
const payload = {
type: "join_publisher_channel",
publisher_channel: data.publisher_channel,
username: data.username,
subscriber_group: data.subscriber_group,
display_name: data.display_name,
single_sign_on: data.single_sign_on,
remote_ip: data.remote_ip,
http_referrer: data.http_referrer,
current_page: data.current_page,
php_session_id: data.php_session_id,
from_react: data.from_react,
};
if (apiKey !== "") { payload.api_key = apiKey; }
if (jwtToken) { payload.jwt_token = jwtToken; }
console.log( jwtToken ? "[Page worker] Sending fetched JWT with legacy details" : "[Page worker] Sending legacy join without JWT" );
joinSocket.send(JSON.stringify(payload));
postMessage({ action: "PublisherChannelJoined" });
}
function partnerFromCurrentPage(current_page) {
try {
if (!current_page) return '';
const fullUrl = current_page.startsWith('http') ? current_page : `https://${current_page}`;
return new URL(fullUrl).searchParams.get('partner_name') || '';
} catch (e) { return ''; }
}
function session_static_info(msg) {
set_static_session_info(msg.data);
start_log();
}
function connect_to_distributor(msg) {
publisher_channel = msg.data.publisher_channel;
remote_ip = msg.data.remote_ip;
socket = new WebSocket("wss://ws.livesquawk.com/ws"+distributor_server);
socket.onopen = function(event) { request_server_assignment(); };
socket.onmessage = function(event) {
var msg_string = event.data.toString();
var data = JSON.parse(msg_string);
switch(data.type) {
case 'server_assignment_response': server_assignment_response(data); break;
}
};
}
function session_info_interval() {
postMessage({action: 'RequestSessionInfo' });
logging_interval = setTimeout(session_info_interval,logging_interval_time);
}
function server_assignment_response(data) {
assigned_server = data.selected_server;
socket.close();
connect_to_assigned_server();
}
function request_server_assignment() {
var data_array = {};
data_array.type = 'request_server_assignment';
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
function connect_to_assigned_server() {
socket = new WebSocket("wss://ws.livesquawk.com/ws"+assigned_server);
socket.onopen = function(event) {
postMessage({ action: 'VisibleConsole',console_string: "Connected to server "+assigned_server });
console.log("Connected to server "+assigned_server);
postMessage({ action: 'ConnectedToAssigned' });
connected_to_assigned = true;
if (playing) {
postMessage({ action: 'RejoinPlayerChannel' });
}
};
socket.onmessage = function(event) {
var msg_string = event.data.toString();
var data = JSON.parse(msg_string);
if (data.type != 'server_ping') { /* console.log(data.type); */ }
switch(data.type) {
case 'reconnect': postMessage({ action: 'VisibleConsole',console_string: "Reconnected" }); break;
case 'reload': postMessage({ action: 'Reload' }); break;
case 'start_log_response': start_log_response(data); break;
case 'application_refresh_start': application_refresh_start(data); break;
case 'application_refresh_stop': application_refresh_stop(data); break;
case 'player_log_request':
case 'check_channel_status_response': check_channel_status_response(data); break;
case 'PlayerLogRequest':
case 'new_tweet':
case 'new_latest_news':
case 'delete_report':
case 'add_report':
case 'add_ref_doc':
case 'calendar_change':
case 'calendar_insert':
case 'calendar_delete':
case 'new_note':
case 'AppStart':
case 'AppStop':
case 'BroadcasterStarted':
case 'BroadcasterStopped':
case 'added_cme_report':
case 'updated_cme_report':
case 'added_cme_commentary':
case 'updated_cme_commentary':
case 'server_assignment_response':
case 'initial_messages':
case 'message_categories':
case 'more_messages':
case 'matched_messages':
pass_straight_to_post_message(data);
break;
case 'output':
case 'server_ping':
case 'reconnect':
case 'disconnect':
break;
}
};
socket.onerror = function(event) {
postMessage({ action: 'VisibleConsole',console_string: "LS Socket Error" + event.type });
console.log(event);
postMessage({ action: 'LSSocketConnectionError' });
};
socket.onclose = function(event) {
console.log('Socket is closed. Reconnect will be attempted in 1 second.', event.reason);
socket_close_timeout = setTimeout(connect_to_assigned_server, reconnection_delay);
reconnection_delay = reconnection_delay*reconnectionDelayGrowFactor;
connected_to_assigned = false;
};
}
function checkSocketConnectionState() {
postMessage({ action: 'SocketConnectionState', connected: Boolean(socket && socket.readyState === WebSocket.OPEN && connected_to_assigned ), });
}
function close_socket() {
clearTimeout(socket_close_timeout);
socket_close_timeout = null;
socket.onclose = function(event) {};
socket.onmessage = function(event) {};
socket.onerror = function(event) {};
socket.close(1000);
console.log('Socket Closed');
}
function pass_straight_to_post_message(data) {
data.action = data.type;
postMessage(data);
}
function join_player_channel(data) {
var data_array = {};
data_array.type = 'join_player_channel';
data_array.player_channel = data.player_channel;
data_array.remote_ip = data.remote_ip;
data_array.username = data.username;
data_array.app_name = data.app_name;
data_array.onair_status = data.onair_status;
data_array.http_referrer = data.http_referrer;
data_array.current_page = data.current_page;
data_array.php_session_id = data.php_session_id;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
postMessage({action: 'PlayerChannelJoined' });
playing = true;
}
function start_log_response(data) {
session_info.session_id = data.log_record_id;
session_info_interval();
}
function application_refresh_start(data) {
if (data.app_name == session_info.application_name) { postMessage({action: 'ApplicationRefreshStart' }); }
}
function application_refresh_stop(data) {
if (data.app_name == session_info.application_name) { postMessage({action: 'ApplicationRefreshStop' }); }
}
function set_static_session_info(data) {
session_info.browser_codename = data.browser_codename;
session_info.browser_name = data.browser_name;
session_info.user_agent = data.user_agent;
session_info.browser_version = data.browser_version;
session_info.cookies_enabled = data.cookies_enabled;
session_info.platform = data.platform;
session_info.player_version = data.player_version;
session_info.stream = data.stream;
session_info.connection_protocol = data.protocol;
session_info.delay_target = data.delay_target;
session_info.session_email = data.session_email;
session_info.remote_ip = data.remote_ip;
session_info.php_session_id = data.php_session_id;
session_info.application_name = data.application_name;
session_info.http_referrer = data.http_referrer;
}
function start_log() {
var session_start_date = new Date();
session_start_time = session_start_date.getTime();
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var session_start_date_string = session_start_date.getDate() + " " + months[session_start_date.getMonth()] + " " + session_start_date.getFullYear();
var data_array = {};
data_array.type = 'webrtc_start_log';
data_array.remote_ip = session_info.remote_ip;
data_array.username = session_info.session_email;
data_array.php_session_id = session_info.php_session_id;
data_array.webrtc_protocol = '';
data_array.session_start_time = (session_start_time/1000).toFixed(0);
data_array.stream_name = session_info.stream;
data_array.session_start_date = session_start_date_string;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
function update_session_info(data) {
var data_array = {};
var msg_string = '';
var current_date = new Date();
var current_time = current_date.getTime();
session_info.protocol = data.protocol;
session_info.curr_delay = (data.effective_latency / 1000).toFixed(2);
session_info.session_length = current_time - session_start_time;
session_info.ping_time = data.ping_time;
session_info.jitter = data.jitter;
session_info.packet_loss = data.packet_loss;
session_info.effective_latency = data.effective_latency;
session_info.mean_opinion_score = data.mean_opinion_score;
session_info.restarts = data.restarts;
if (socket_emits == 0) {
data_array = {};
data_array.type = 'webrtc_log_data_full';
data_array.connection_protocol = session_info.protocol;
data_array.threshold = 0;
data_array.curr_delay = session_info.curr_delay;
data_array.session_length = session_info.session_length;
data_array.date = current_time;
data_array.browser_codename = session_info.browser_codename;
data_array.browser_name = session_info.browser_name;
data_array.user_agent = session_info.user_agent;
data_array.browser_version = session_info.browser_version;
data_array.cookies_enabled = session_info.cookies_enabled;
data_array.platform = session_info.platform;
data_array.player_version = session_info.player_version;
data_array.stream = session_info.stream;
data_array.restarts = session_info.restarts;
data_array.delay_target = 0;
data_array.op_sys = '';
data_array.flash_version = '';
data_array.remote_ip = session_info.remote_ip;
data_array.http_referrer = session_info.http_referrer;
data_array.php_session_id = session_info.php_session_id;
data_array.user_email = session_info.session_email;
data_array.webrtc_protocol = session_info.protocol;
data_array.ping_time = session_info.ping_time;
data_array.jitter = session_info.jitter;
data_array.packet_loss = session_info.packet_loss;
data_array.effective_latency = session_info.effective_latency;
data_array.mean_opinion_score = session_info.mean_opinion_score;
data_array.session_id = session_info.session_id;
msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
else {
data_array = {};
data_array.type = 'webrtc_log_data';
data_array.session_id = session_info.session_id;
data_array.php_session_id = session_info.php_session_id;
data_array.connection_protocol = session_info.protocol;
data_array.restarts = session_info.restarts;
data_array.threshold = 0;
data_array.curr_delay = session_info.curr_delay;
data_array.session_length = session_info.session_length;
data_array.date = current_time;
data_array.webrtc_protocol = session_info.protocol;
data_array.ping_time = session_info.ping_time;
data_array.jitter = session_info.jitter;
data_array.packet_loss = session_info.packet_loss;
data_array.effective_latency = session_info.effective_latency;
data_array.mean_opinion_score = session_info.mean_opinion_score;
data_array.stream = session_info.stream;
msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
socket_emits++;
if (socket_emits == 100) { socket_emits = 0; }
}
- Repeated support from strong Irish performance
- Big Four mostly weaker
- High energy prices challenge economies
By Eric Culp, European Editor
LiveSquawk News
@eculp.bsky.social
@EricCulpLS
30 October 2026 | 10:55 GMT
Euro area economic growth last quarter was twice what economists had expected but still fell short of the mark set in Q2, which surged on the back of a double-digit gain in Ireland.
Quarterly GDP growth in the Eurozone rose 0.4% in the July-September, The EU statistics office Eurostat said. The latest number compared to a market estimate of 0.2% and 0.6% in the prior period, when a 10.2% jump in Ireland data pushed the overall Eurozone reading higher. This time, the Emerald Isle led the results with an increase of 5.5%.
The annual growth rate for the single currency area improved to 1.3% in Q3 versus the 1.1% estimate and the 1.2% reading from Q2.
Oxford Economics said the quarterly increase was “a decent 0.2% excluding Ireland. Growth is becoming increasingly uneven across countries, with Germany and Spain gaining traction while France and Italy slow.”
Top economies falter
Germany beat the market consensus for growth with a quarterly rise of 0.2%, which was double the estimate, but the result was below the Q2 showing of 0.3%.
French GDP disappointed, falling unexpectedly with a contraction of 0.1% after a flat Q2. Economists had predicted an improvement to 0.1%.
A surprisingly large slowdown in Italy GDP took the quarterly number to a flat reading versus the 0.1% forecast and a 0.2% rise in April-June.
Spain reported 4.9% growth, which matched the market estimate and the Q2 result.
Purchasing managers’ indices during the third quarter had presaged the improvement for the Eurozone. July’s composite measure improved to an eight-month high of 52.0 points, a return to growth territory above the 50 mark, which delineates expansion from contraction below that level. The measure was unchanged in August on a rise in the number for manufacturing but a decline in the services reading. And the indicator hit 53.1 in September, its best in 41 months as manufacturing PMI climbed to its highest point in 52 months.
“With energy prices still rising steadily, including gas prices, the winter months will see an additional growth challenge,” warned ING chief economist Bert Colijn. “On top of that, interest rates are now higher and businesses indicate less appetite for borrowing.
“Taking the Irish volatility out of the mix, a modest growth rate is what can be expected in the months ahead.”
Sign up for LiveSquawk and receive a discount with the code LSQEC$