(function(){
	var W = window;
	var Store = {
		_nodes: new Set(),
		_meta: (typeof Map === 'function') ? new Map() : null,
		_live: (typeof Map === 'function') ? new Map() : null,
		_uiState: (typeof Map === 'function') ? new Map() : null,
		_levels: (typeof Map === 'function') ? new Map() : null,
		_playlist: (typeof Map === 'function') ? new Map() : null,
		_selection: (typeof Map === 'function') ? new Map() : null,
		init: function(root){
			if (!root || !(root instanceof Element)) return;
			Store._nodes.add(root);
		},
		setMeta: function(root, data){
			if (!root || !data || typeof data !== 'object') return;
			var out = {
				plugin_version: typeof data.plugin_version === 'string' ? data.plugin_version : '',
				plugin_codename: typeof data.plugin_codename === 'string' ? data.plugin_codename : '',
				plugin_build: typeof data.plugin_build === 'string' ? data.plugin_build : '',
				track: typeof data.track === 'string' ? data.track : '',
				variant: typeof data.variant === 'string' ? data.variant : '',
				sample_rate: typeof data.sample_rate === 'string' ? data.sample_rate : '',
				bit_depth: typeof data.bit_depth === 'string' ? data.bit_depth : '',
				channels: typeof data.channels === 'string' ? data.channels : '',
				audiocontext: typeof data.audiocontext === 'string' ? data.audiocontext : ''
			};
			if (Store._meta && typeof Store._meta.set === 'function') {
				Store._meta.set(root, out);
			} else {
				root._thesplMeta = out;
			}
		},
		getMeta: function(root){
			if (Store._meta && typeof Store._meta.get === 'function') {
				var stored = Store._meta.get(root);
				if (stored && typeof stored === 'object') {
					return {
						plugin_version: String(stored.plugin_version || ''),
						plugin_codename: String(stored.plugin_codename || ''),
						plugin_build: String(stored.plugin_build || ''),
						track: String(stored.track || ''),
						variant: String(stored.variant || ''),
						sample_rate: String(stored.sample_rate || ''),
						bit_depth: String(stored.bit_depth || ''),
						channels: String(stored.channels || ''),
						audiocontext: String(stored.audiocontext || '')
					};
				}
			}
			var wrap = root ? root.querySelector('.thespl-player__audio-info') : null;
			var get = function(key){
				var el = wrap ? wrap.querySelector('[data-thespl-audio-info="' + key + '"]') : null;
				return el ? String(el.textContent || '') : '';
			};
			return {
				plugin_version: get('plugin_version'),
				plugin_codename: get('plugin_codename'),
				plugin_build: get('plugin_build'),
				track: get('track'),
				variant: get('variant'),
				sample_rate: get('sample_rate'),
				bit_depth: get('bit_depth'),
				channels: get('channels'),
				audiocontext: get('audiocontext')
			};
		},
		setLive: function(root, data){
			if (!root || !data || typeof data !== 'object') return;
			var out = {
				playback: typeof data.playback === 'string' ? data.playback : '',
				buffer: typeof data.buffer === 'string' ? data.buffer : ''
			};
			if (typeof data.audiocontext === 'string') {
				out.audiocontext = data.audiocontext;
			}
			if (typeof data.bufferFraction === 'number' && isFinite(data.bufferFraction)) {
				out.bufferFraction = data.bufferFraction;
			}
			if (typeof data.aheadSec === 'number' && isFinite(data.aheadSec)) {
				out.aheadSec = data.aheadSec;
			}
			if (Store._live && typeof Store._live.set === 'function') {
				Store._live.set(root, out);
			} else {
				root._thesplLive = out;
			}
		},
		setUiState: function(root, state){
			if (!root || !state || typeof state !== 'object') return;
			var phase = typeof state.phase === 'string' ? state.phase : '';
			var error = typeof state.error === 'string' ? state.error : '';
			var isBinaural = !!state.isBinaural;
			var uiMessageKey = typeof state.uiMessageKey === 'string' ? state.uiMessageKey : '';
			var uiFlags = state.uiFlags && typeof state.uiFlags === 'object' ? state.uiFlags : null;
			var prev = null;
			if (Store._uiState && typeof Store._uiState.get === 'function') {
				prev = Store._uiState.get(root) || null;
			} else if (root && root._thesplUiState && typeof root._thesplUiState === 'object') {
				prev = root._thesplUiState;
			}
			var hasPlayedOnce = !!(prev && prev.hasPlayedOnce);
			if (!hasPlayedOnce && phase === 'playing') {
				hasPlayedOnce = true;
			}
			var uiPhase = phase;
			if (!hasPlayedOnce && phase === 'buffering') {
				uiPhase = 'idle';
			}
			var out = {
				phase: phase,
				error: error,
				isBinaural: isBinaural,
				uiPhase: uiPhase,
				hasPlayedOnce: hasPlayedOnce,
				uiMessageKey: uiMessageKey,
				uiFlags: uiFlags
			};
			if (Store._uiState && typeof Store._uiState.set === 'function') {
				Store._uiState.set(root, out);
			} else {
				root._thesplUiState = out;
			}
		},
		getUiState: function(root){
			if (Store._uiState && typeof Store._uiState.get === 'function') {
				var stored = Store._uiState.get(root);
				if (stored && typeof stored === 'object') {
					return {
						phase: String(stored.phase || ''),
						error: String(stored.error || ''),
						isBinaural: !!stored.isBinaural,
						uiPhase: typeof stored.uiPhase === 'string' ? stored.uiPhase : String(stored.phase || ''),
						hasPlayedOnce: !!stored.hasPlayedOnce,
						uiMessageKey: typeof stored.uiMessageKey === 'string' ? stored.uiMessageKey : '',
						uiFlags: stored.uiFlags && typeof stored.uiFlags === 'object' ? stored.uiFlags : null
					};
				}
			}
			var fallback = root && root._thesplUiState && typeof root._thesplUiState === 'object' ? root._thesplUiState : null;
			if (fallback) {
				return {
					phase: String(fallback.phase || ''),
					error: String(fallback.error || ''),
					isBinaural: !!fallback.isBinaural,
					uiPhase: typeof fallback.uiPhase === 'string' ? fallback.uiPhase : String(fallback.phase || ''),
					hasPlayedOnce: !!fallback.hasPlayedOnce,
					uiMessageKey: typeof fallback.uiMessageKey === 'string' ? fallback.uiMessageKey : '',
					uiFlags: fallback.uiFlags && typeof fallback.uiFlags === 'object' ? fallback.uiFlags : null
				};
			}
			return {
				phase: '',
				error: '',
				isBinaural: false,
				uiPhase: '',
				hasPlayedOnce: false,
				uiMessageKey: '',
				uiFlags: null
			};
		},
		getLive: function(root){
			if (Store._live && typeof Store._live.get === 'function') {
				var live = Store._live.get(root);
				if (live && typeof live === 'object') {
					return {
						playback: String(live.playback || ''),
						buffer: String(live.buffer || ''),
						audiocontext: typeof live.audiocontext === 'string' ? live.audiocontext : '',
						bufferFraction: typeof live.bufferFraction === 'number' && isFinite(live.bufferFraction) ? live.bufferFraction : 0,
						aheadSec: typeof live.aheadSec === 'number' && isFinite(live.aheadSec) ? live.aheadSec : 0
					};
				}
			}
			var wrap = root ? root.querySelector('.thespl-player__audio-info') : null;
			var get = function(key){
				var el = wrap ? wrap.querySelector('[data-thespl-audio-info="' + key + '"]') : null;
				return el ? String(el.textContent || '') : '';
			};
			return {
				playback: get('playback'),
				buffer: get('buffer'),
				bufferFraction: 0,
				aheadSec: 0
			};
		},
		getLevels: function(root){
			if (Store._levels && typeof Store._levels.get === 'function') {
				var stored = Store._levels.get(root);
				if (stored && stored.length) {
					return stored.map(function(item){
						var label = item && typeof item.label === 'string' ? item.label : '';
						var rms = item && typeof item.rms === 'string' ? item.rms : '';
						var peak = item && typeof item.peak === 'string' ? item.peak : '';
						var outItem = {
							label: label,
							rms: rms,
							peak: peak
						};
						if (item && typeof item.rmsDbfs === 'number') {
							outItem.rmsDbfs = item.rmsDbfs;
						}
						if (item && typeof item.peakDbfs === 'number') {
							outItem.peakDbfs = item.peakDbfs;
						}
						if (item && (typeof item.active === 'number' || typeof item.active === 'boolean')) {
							outItem.active = item.active ? 1 : 0;
						}
						return outItem;
					});
				}
			}
			var wrap = root ? root.querySelector('.thespl-player__audio-info') : null;
			var lvWrap = wrap ? wrap.querySelector('[data-thespl-audio-info-levels]') : null;
			var rows = lvWrap ? lvWrap.querySelectorAll('.thespl-player__audio-info-level-row') : [];
			var out = [];
			rows.forEach(function(row){
				var label = row.querySelector('.thespl-player__audio-info-level-label');
				var nums = row.querySelectorAll('.thespl-player__audio-info-level-num');
				var rms = nums.length > 0 ? String(nums[0].textContent || '') : '';
				var peak = nums.length > 1 ? String(nums[1].textContent || '') : '';
				out.push({
					label: label ? String(label.textContent || '') : '',
					rms: rms,
					peak: peak
				});
			});
			return out;
		},
		setLevels: function(root, levels){
			if (!root) return;
			if (!levels || !levels.length) {
				if (Store._levels && typeof Store._levels.delete === 'function') {
					Store._levels.delete(root);
				}
				return;
			}
			var out = [];
			for (var i = 0; i < levels.length; i++) {
				var src = levels[i] || {};
				var label = typeof src.label === 'string' ? src.label : '';
				var rms = typeof src.rms === 'string' ? src.rms : '';
				var peak = typeof src.peak === 'string' ? src.peak : '';
				var item = {
					label: label,
					rms: rms,
					peak: peak
				};
				if (typeof src.rmsDbfs === 'number') {
					item.rmsDbfs = src.rmsDbfs;
				}
				if (typeof src.peakDbfs === 'number') {
					item.peakDbfs = src.peakDbfs;
				}
				if (typeof src.active === 'number' || typeof src.active === 'boolean') {
					item.active = src.active ? 1 : 0;
				}
				out.push(item);
			}
			if (Store._levels && typeof Store._levels.set === 'function') {
				Store._levels.set(root, out);
			} else {
				root._thesplLevels = out;
			}
		},
		setPlaylist: function(root, data){
			if (!root || !data || typeof data !== 'object') return;
			var tracks = Array.isArray(data.tracks) ? data.tracks : [];
			var currentTrackIndex = Number.isFinite(data.currentTrackIndex) ? data.currentTrackIndex : 0;
			var currentVariantIndex = Number.isFinite(data.currentVariantIndex) ? data.currentVariantIndex : 0;
			var maxVariants = Number.isFinite(data.maxVariants) ? data.maxVariants : 0;
			if (maxVariants < 1) {
				maxVariants = 1;
			}
			if (currentVariantIndex < 0) {
				currentVariantIndex = 0;
			} else if (currentVariantIndex >= maxVariants) {
				currentVariantIndex = maxVariants - 1;
			}
			var out = {
				tracks: tracks,
				currentTrackIndex: currentTrackIndex,
				currentVariantIndex: currentVariantIndex,
				maxVariants: maxVariants
			};
			if (Store._playlist && typeof Store._playlist.set === 'function') {
				Store._playlist.set(root, out);
			} else {
				root._thesplPlaylist = out;
			}
		},
		getPlaylist: function(root){
			var stored = null;
			if (Store._playlist && typeof Store._playlist.get === 'function') {
				stored = Store._playlist.get(root) || null;
			} else if (root && root._thesplPlaylist) {
				stored = root._thesplPlaylist;
			}
			if (!stored || typeof stored !== 'object') {
				return {
					tracks: [],
					currentTrackIndex: 0,
					currentVariantIndex: 0,
					maxVariants: 0
				};
			}
			var tracks = Array.isArray(stored.tracks) ? stored.tracks : [];
			var currentTrackIndex = Number.isFinite(stored.currentTrackIndex) ? stored.currentTrackIndex : 0;
			var currentVariantIndex = Number.isFinite(stored.currentVariantIndex) ? stored.currentVariantIndex : 0;
			var maxVariants = Number.isFinite(stored.maxVariants) ? stored.maxVariants : 0;
			if (maxVariants < 1) {
				maxVariants = 1;
			}
			if (currentVariantIndex < 0) {
				currentVariantIndex = 0;
			} else if (currentVariantIndex >= maxVariants) {
				currentVariantIndex = maxVariants - 1;
			}
			return {
				tracks: tracks,
				currentTrackIndex: currentTrackIndex,
				currentVariantIndex: currentVariantIndex,
				maxVariants: maxVariants
			};
		},
		setSelection: function(root, sel){
			if (!root || !sel || typeof sel !== 'object') return;
			var trackIndex = Number.isFinite(sel.trackIndex) ? sel.trackIndex : 0;
			var variantIndex = Number.isFinite(sel.variantIndex) ? sel.variantIndex : 0;
			var out = {
				trackIndex: trackIndex,
				variantIndex: variantIndex
			};
			if (Store._selection && typeof Store._selection.set === 'function') {
				Store._selection.set(root, out);
			} else {
				root._thesplSelection = out;
			}
		},
		getSelection: function(root){
			var stored = null;
			if (Store._selection && typeof Store._selection.get === 'function') {
				stored = Store._selection.get(root) || null;
			} else if (root && root._thesplSelection) {
				stored = root._thesplSelection;
			}
			if (!stored || typeof stored !== 'object') {
				return {
					trackIndex: 0,
					variantIndex: 0
				};
			}
			var trackIndex = Number.isFinite(stored.trackIndex) ? stored.trackIndex : 0;
			var variantIndex = Number.isFinite(stored.variantIndex) ? stored.variantIndex : 0;
			return {
				trackIndex: trackIndex,
				variantIndex: variantIndex
			};
		},
		subscribe: function(root, fn){
			if (!root || typeof fn !== 'function') return function(){};
			var audio = root.querySelector('.thespl-player__audio');
			var tick = function(){ fn(); };
			var on = function(ev){ try { fn(); } catch(e){} };
			var id = window.setInterval(tick, 300);
			if (audio) {
				audio.addEventListener('timeupdate', on);
				audio.addEventListener('progress', on);
				audio.addEventListener('play', on);
				audio.addEventListener('pause', on);
				audio.addEventListener('waiting', on);
				audio.addEventListener('stalled', on);
			}
			return function(){ try { window.clearInterval(id); } catch(e){} if (audio) { try { audio.removeEventListener('timeupdate', on); } catch(e){} try { audio.removeEventListener('progress', on); } catch(e){} try { audio.removeEventListener('play', on); } catch(e){} try { audio.removeEventListener('pause', on); } catch(e){} try { audio.removeEventListener('waiting', on); } catch(e){} try { audio.removeEventListener('stalled', on); } catch(e){} } };
		}
	};
	W.THESPL_Player_Store = Store;
})();
