@vault-tec/pip-boy 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import*as e from"@angular/core";import{input as t,ViewChild as n,Component as a,signal as o,Injectable as i,InjectionToken as s,effect as r,inject as l,output as d,EventEmitter as c,Output as m,Input as p,computed as u,viewChild as b,HostListener as g}from"@angular/core";import h from"gsap";import{CommonModule as f}from"@angular/common";import v from"jszip";class y{replayTimeoutSeconds=t(8,...ngDevMode?[{debugName:"replayTimeoutSeconds"}]:[]);screen=t.required(...ngDevMode?[{debugName:"screen"}]:[]);scanSpeedSeconds=t(5,...ngDevMode?[{debugName:"scanSpeedSeconds"}]:[]);tailLengthPx=t(300,...ngDevMode?[{debugName:"tailLengthPx"}]:[]);scanColorRgb=t("58, 208, 58",...ngDevMode?[{debugName:"scanColorRgb"}]:[]);scanlineRef;scanTween=null;resizeObserver=null;ngAfterViewInit(){if(window.matchMedia("(prefers-reduced-motion: reduce)").matches)return;const e=this.scanlineRef.nativeElement,t=this.screen(),n=()=>{e.style.height=`${this.tailLengthPx()}px`;const n=t.clientHeight,a=e.offsetHeight;if(n<=0||a<=0)return;const o=-a,i=n+a;this.scanTween&&(this.scanTween.kill(),this.scanTween=null),h.set(e,{y:o});const s=this.replayTimeoutSeconds(),r=s>0?Math.random()*s:0;this.scanTween=h.to(e,{y:i,duration:this.scanSpeedSeconds(),ease:"none",repeat:-1,repeatDelay:s,delay:r})};n(),this.resizeObserver=new ResizeObserver(()=>{n()}),this.resizeObserver.observe(t)}ngOnDestroy(){this.scanTween&&(this.scanTween.kill(),this.scanTween=null),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null)}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:y,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.1.0",version:"21.0.8",type:y,isStandalone:!0,selector:"pip-boy-screen-scan-lines",inputs:{replayTimeoutSeconds:{classPropertyName:"replayTimeoutSeconds",publicName:"replayTimeoutSeconds",isSignal:!0,isRequired:!1,transformFunction:null},screen:{classPropertyName:"screen",publicName:"screen",isSignal:!0,isRequired:!0,transformFunction:null},scanSpeedSeconds:{classPropertyName:"scanSpeedSeconds",publicName:"scanSpeedSeconds",isSignal:!0,isRequired:!1,transformFunction:null},tailLengthPx:{classPropertyName:"tailLengthPx",publicName:"tailLengthPx",isSignal:!0,isRequired:!1,transformFunction:null},scanColorRgb:{classPropertyName:"scanColorRgb",publicName:"scanColorRgb",isSignal:!0,isRequired:!1,transformFunction:null}},viewQueries:[{propertyName:"scanlineRef",first:!0,predicate:["scanline"],descendants:!0,static:!0}],ngImport:e,template:'<div\n #scanline\n class="screen-scanline"\n [style.--scanline-color-rgb]="scanColorRgb()"\n aria-hidden="true"\n></div>\n',styles:['.screen>:not(.screen-scanline){position:relative;z-index:1}.screen-scanline{position:absolute;left:0;right:0;top:0;height:140px;z-index:0;pointer-events:none;background:linear-gradient(to bottom,rgba(var(--scanline-color-rgb, 58, 208, 58),0),rgba(var(--scanline-color-rgb, 58, 208, 58),.04) 35%,rgba(var(--scanline-color-rgb, 58, 208, 58),.12) 65%,rgba(var(--scanline-color-rgb, 58, 208, 58),.16) 85%);mix-blend-mode:screen;opacity:.5;filter:blur(5px)}.screen-scanline:after{content:"";position:absolute;left:0;right:0;bottom:8px;height:2px;background:rgba(var(--scanline-color-rgb, 58, 208, 58),.3)}\n']})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:y,decorators:[{type:a,args:[{selector:"pip-boy-screen-scan-lines",template:'<div\n #scanline\n class="screen-scanline"\n [style.--scanline-color-rgb]="scanColorRgb()"\n aria-hidden="true"\n></div>\n',styles:['.screen>:not(.screen-scanline){position:relative;z-index:1}.screen-scanline{position:absolute;left:0;right:0;top:0;height:140px;z-index:0;pointer-events:none;background:linear-gradient(to bottom,rgba(var(--scanline-color-rgb, 58, 208, 58),0),rgba(var(--scanline-color-rgb, 58, 208, 58),.04) 35%,rgba(var(--scanline-color-rgb, 58, 208, 58),.12) 65%,rgba(var(--scanline-color-rgb, 58, 208, 58),.16) 85%);mix-blend-mode:screen;opacity:.5;filter:blur(5px)}.screen-scanline:after{content:"";position:absolute;left:0;right:0;bottom:8px;height:2px;background:rgba(var(--scanline-color-rgb, 58, 208, 58),.3)}\n']}]}],propDecorators:{replayTimeoutSeconds:[{type:e.Input,args:[{isSignal:!0,alias:"replayTimeoutSeconds",required:!1}]}],screen:[{type:e.Input,args:[{isSignal:!0,alias:"screen",required:!0}]}],scanSpeedSeconds:[{type:e.Input,args:[{isSignal:!0,alias:"scanSpeedSeconds",required:!1}]}],tailLengthPx:[{type:e.Input,args:[{isSignal:!0,alias:"tailLengthPx",required:!1}]}],scanColorRgb:[{type:e.Input,args:[{isSignal:!0,alias:"scanColorRgb",required:!1}]}],scanlineRef:[{type:n,args:["scanline",{static:!0}]}]}});class w{static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:w,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"21.0.8",type:w,isStandalone:!0,selector:"pip-boy-2000-mk-vi",ngImport:e,template:'<section #screen class="screen">\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="200"\n />\n</section>\n',styles:[":host{background:#030703;box-sizing:border-box;color:#3ad03a;display:block;height:100%;width:100%}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:1rem;position:relative;width:100%}\n"],dependencies:[{kind:"component",type:y,selector:"pip-boy-screen-scan-lines",inputs:["replayTimeoutSeconds","screen","scanSpeedSeconds","tailLengthPx","scanColorRgb"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:w,decorators:[{type:a,args:[{selector:"pip-boy-2000-mk-vi",standalone:!0,imports:[y],template:'<section #screen class="screen">\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="200"\n />\n</section>\n',styles:[":host{background:#030703;box-sizing:border-box;color:#3ad03a;display:block;height:100%;width:100%}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:1rem;position:relative;width:100%}\n"]}]}]});class x{dbPromise=this.openDb();imageUrls=o({},...ngDevMode?[{debugName:"imageUrls"}]:[]);loading=new Set;getImageUrl(e){if(!e)return null;const t=this.imageUrls()[e];return t||(this.loadImageUrl(e),null)}async saveFile(e){const t=this.createId(),n={id:t,fileName:e.name,mime:e.type||"application/octet-stream"};return await this.putRecord({...n,blob:e}),this.cacheUrl(t,URL.createObjectURL(e)),n}async saveBlobWithId(e,t,n,a){await this.putRecord({id:e,blob:t,fileName:n,mime:a}),this.cacheUrl(e,URL.createObjectURL(t))}async saveDataUrlWithId(e,t){const n=await fetch(t),a=await n.blob(),o=a.type||"application/octet-stream",i=`image-${e}${this.extensionFromMime(o)}`;await this.saveBlobWithId(e,a,i,o)}async getRecord(e){const t=await this.dbPromise;return new Promise((n,a)=>{const o=t.transaction("images","readonly").objectStore("images").get(e);o.onsuccess=()=>{n(o.result??null)},o.onerror=()=>a(o.error)})}async getBlob(e){const t=await this.getRecord(e);return t?.blob??null}extensionFromMime(e){switch(e){case"image/png":return".png";case"image/jpeg":return".jpg";case"image/webp":return".webp";case"image/gif":return".gif";case"image/svg+xml":return".svg";default:return""}}generateId(){return this.createId()}cacheUrl(e,t){this.imageUrls.update(n=>({...n,[e]:t}))}async loadImageUrl(e){if(!this.loading.has(e)){this.loading.add(e);try{const t=await this.getBlob(e);if(!t)return;this.cacheUrl(e,URL.createObjectURL(t))}finally{this.loading.delete(e)}}}async putRecord(e){const t=await this.dbPromise;return new Promise((n,a)=>{const o=t.transaction("images","readwrite").objectStore("images").put(e);o.onsuccess=()=>n(),o.onerror=()=>a(o.error)})}openDb(){return new Promise((e,t)=>{const n=indexedDB.open("pipBoy3000Images",1);n.onupgradeneeded=()=>{const e=n.result;e.objectStoreNames.contains("images")||e.createObjectStore("images",{keyPath:"id"})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}createId(){return"undefined"!=typeof crypto&&"randomUUID"in crypto?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:x,deps:[],target:e.ɵɵFactoryTarget.Injectable});static"ɵprov"=e.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:x,providedIn:"root"})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:x,decorators:[{type:i,args:[{providedIn:"root"}]}]});const k=[{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Ant Meat",val:4,wg:1},{effects:"INT +2,CHA +2,STR +4,Usage Monitor Effect 20",name:"Ant Nectar",val:20,wg:.25},{effects:"CHA +3,INT +3,PER +3",name:"Ant Queen Pheromones",val:75,wg:1},{effects:"INT +1,STR +1,CHA +1",name:"Beer",val:2,wg:1},{effects:"INT +5",name:"Berry Mentats",val:20,wg:0},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Blamco Mac and Cheese",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Bloatfly Meat",val:4,wg:1},{effects:"Restore Health 19,Restore Health 1",name:"Blood Pack",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Brahmin Steak",val:5,wg:1},{effects:"Restore Health 1,Restore Health 1,Damage Rads 1",name:"Bubblegum",val:1,wg:1},{name:"Buffout",wg:0,val:20,effects:"STR +2,END +3,Increased Health - Buffout 60,Usage Monitor Effect 30"},{effects:"Restore Health 5,Restore Rads 10",name:"Cave Fungus",val:50,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Cram",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Crispy Squirrel Bits",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Crunchy Mutfruit",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Dandy Boy Apples",val:5,wg:1},{effects:"Restore Health 10,Restore Health 2,Damage Rads 6",name:"Dirty Water",val:10,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Dog Meat",val:4,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Fancy Lads Snack Cakes",val:5,wg:1},{effects:"AGL +4,INT +3,Increased Fire Resistance 25",name:"Fire Ant Nectar",val:20,wg:1},{effects:"Restore Health 10",name:"Fresh Apple",val:5,wg:1},{effects:"Restore Health 10",name:"Fresh Carrot",val:5,wg:1},{effects:"Restore Health 10",name:"Fresh Pear",val:5,wg:1},{effects:"Restore Health 10",name:"Fresh Potato",val:5,wg:1},{effects:"CHA +5",name:"Grape Mentats",val:20,wg:0},{effects:"Restore Health 1,Damage Rads 1,Restore Health 1",name:"Gum Drops",val:2,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Hatchling Mirelurk Meat",val:4,wg:1},{effects:"Restore Health 25,Restore Health 5,Damage Rads 10",name:"Human Flesh",val:0,wg:1},{name:"Ice Cold Nuka-Cola",wg:1,val:20,effects:"Restore Health 20,Nuka-Cola Add Cap Effect,Restore Health 4,Damage Rads 3"},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Iguana Bits",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Iguana on a Stick",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"InstaMash",val:5,wg:1},{effects:"Increase Action Points - Jet 30,Usage Monitor Effect 30",name:"Jet",val:20,wg:0},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Junk Food",val:5,wg:1},{effects:"Increase Damage Resistance - Psycho 25,Usage Monitor Effect 30",name:"Med-X",val:20,wg:0},{effects:"INT +5,PER +5,Usage Monitor Effect 30",name:"Mentats",val:20,wg:0},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Mirelurk Cakes",val:5,wg:1},{effects:"Restore Health 20,Restore Health 4,Damage Rads 3",name:"Mirelurk Meat",val:20,wg:1},{effects:"STR +1,INT +1,Increased Action Points 20,Damage Rads 5",name:"Miss. Quantum Pie",val:20,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Mole Rat Meat",val:4,wg:1},{effects:"Restore Health 20,Restore Health 4,Damage Rads 3",name:"Mole Rat Wonder Meat",val:20,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Mutfruit",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Noodles",val:5,wg:1},{name:"Nuka-Cola Quantum",wg:1,val:30,effects:"Nuka-Cola Add Cap Effect,Increased Action Points 20,Damage Rads 10,Usage Monitor Effect 12"},{name:"Nuka-Cola",wg:1,val:20,effects:"Restore Health 10,Nuka-Cola Add Cap Effect,Restore Health 2,Damage Rads 3"},{name:"NukaLurk Meat",wg:1,val:7,effects:"Restore Health 20,Restore Health 4,Increased Action Points 10,Damage Rads 5"},{effects:"PER +5",name:"Orange Mentats",val:20,wg:0},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Pork N' Beans",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Potato Crisps",val:5,wg:1},{effects:"Damage +25%,Usage Monitor Effect 30",name:"Psycho",val:20,wg:0},{effects:"Restore Health 20",name:"Purified Water",val:20,wg:1},{effects:"Restore Rads 50",name:"RadAway",val:20,wg:0},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Radroach Meat",val:4,wg:1},{effects:"Increased Radiation Resistance 25",name:"Rad-X",val:20,wg:0},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Salisbury Steak",val:5,wg:1},{effects:"STR +1,INT +1,CHA +1",name:"Scotch",val:10,wg:1},{effects:"Restore Health 30,Restore Health 6,Damage Rads 3",name:"Softshell Mirelurk Meat",val:30,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Squirrel on a Stick",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Squirrel Stew",val:5,wg:1},{effects:"Stealth Field 75,Increased Sneak 100,Stealth Field Stop Combat",name:"Stealth Boy",val:100,wg:1},{effects:"Restore Health & Conditions 30,Restore Health & Conditions 36",name:"Stimpak",val:25,wg:0},{effects:"Restore Health 5,Damage Rads 3,Restore Health 1",name:"Strange Meat Pie",val:2,wg:1},{effects:"Restore Health 5,Damage Rads 3,Restore Health 1",name:"Strange Meat",val:2,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Sugar Bombs",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1",name:"Sweetroll",val:5,wg:1},{effects:"Increase Action Points - Jet 40,Usage Monitor Effect 12",name:"Ultrajet",val:50,wg:0},{effects:"STR +1,INT +1,CHA +1",name:"Vodka",val:20,wg:1},{effects:"STR +1,INT +1,CHA +1",name:"Whiskey",val:10,wg:1},{effects:"STR +1,INT +1,CHA +1",name:"Wine",val:10,wg:1},{effects:"Restore Health 10,Restore Health 2,Damage Rads 10,Damage +10%",name:"Yao Guai Meat",val:30,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"YumYum Deviled Eggs",val:5,wg:1}],S=[{name:".308 Caliber Round",val:3,wg:0},{name:".32 Caliber Round",val:1,wg:0},{name:".44 Round, Magnum",val:2,wg:0},{name:"10mm Round",val:1,wg:0},{name:"5.56mm Round",val:1,wg:0},{name:"5.56mm Round",val:0,wg:0},{name:"5mm Round",val:1,wg:0},{name:"5mm Round",val:1,wg:0},{name:"Alien Power Cell",val:10,wg:0},{name:"BB",val:1,wg:0},{name:"Dart",val:1,wg:0},{name:"Dart",val:1,wg:0},{name:"Electron Charge Pack",val:1,wg:0},{name:"Electron Charge Pack",val:1,wg:0},{name:"Energy Cell",val:2,wg:0},{name:"Energy Cell",val:0,wg:0},{name:"Flamer Fuel",val:1,wg:0},{name:"Flamer Fuel",val:0,wg:0},{name:"Mesmetron Power Cell",val:10,wg:0},{name:"Microfusion Cell",val:3,wg:0},{name:"Microfusion Cell",val:0,wg:0},{name:"Mini Nuke",val:250,wg:0},{name:"Missile",val:50,wg:0},{name:"Missile",val:1,wg:0},{name:"Missile",val:50,wg:0},{name:"Missile",val:1,wg:0},{name:"Railway Spikes",val:2,wg:0},{name:"Shotgun Shell",val:2,wg:0},{name:"Shotgun Shell",val:2,wg:0},{name:"Sonic Energy",val:10,wg:0}],M=[{cnd:3e3,dr:40,name:'"Robo-Thor" Armor',val:820,wg:45},{cnd:125,dr:8,name:'"Robo-Thor" Helmet',val:120,wg:5},{cnd:25,dr:8,name:"Advanced Radiation Suit",val:100,wg:7},{cnd:100,dr:3,name:"All-Purpose Science Suit",val:8,wg:2},{cnd:1200,dr:36,name:"Apocalypse Gladiator Armor",val:460,wg:30},{cnd:75,dr:5,name:"Apocalypse Gladiator Helmet",val:70,wg:3},{cnd:100,dr:12,name:"Armored Vault 101 Jumpsuit",val:180,wg:15},{cnd:100,dr:12,name:"Armored Vault 101 Jumpsuit",val:180,wg:15},{cnd:1e3,dr:40,name:"Army Power Armor",val:740,wg:45},{cnd:100,dr:2,name:"Athlete of the Wastes Outfit",val:30,wg:2},{cnd:10,dr:1,name:"Ballcap with Glasses",val:6,wg:1},{cnd:10,dr:2,name:"Bandana",val:6,wg:1},{cnd:10,dr:1,name:"Biker Goggles",val:6,wg:1},{cnd:100,dr:0,name:"BirthSkirt",val:0,wg:0},{cnd:100,dr:1,name:"Blast Off Helmet",val:30,wg:1},{cnd:100,dr:2,name:"Blast Off Pajamas",val:30,wg:2},{cnd:100,dr:8,name:"Boogeyman's Hood",val:110,wg:3},{cnd:100,dr:2,name:"Brahmin-Skin Outfit",val:6,wg:2},{cnd:1e3,dr:40,name:"Brotherhood Power Armor",val:740,wg:45},{cnd:75,dr:8,name:"Brotherhood Power Helmet",val:110,wg:5},{cnd:100,dr:2,name:"Brotherhood Scribe Robe",val:6,wg:2},{cnd:100,dr:1,name:"Button's Wig",val:20,wg:1},{cnd:100,dr:0,name:"",val:30,wg:1},{cnd:25,dr:0,name:"ChildBlastoffHelmet",val:0,wg:0},{cnd:15,dr:1,name:"Chinese Commando Hat",val:6,wg:1},{cnd:100,dr:6,name:"Chinese Jumpsuit",val:10,wg:2},{cnd:100,dr:10,name:"Colonel Autumn's Uniform",val:12,wg:3},{cnd:400,dr:32,name:"Combat Armor",val:390,wg:25},{cnd:50,dr:5,name:"Combat Helmet",val:50,wg:3},{cnd:150,dr:24,name:"Commando Armor",val:160,wg:15},{cnd:600,dr:28,name:"Composite Recon Armor",val:180,wg:20},{cnd:70,dr:4,name:"Composite Recon Helmet",val:40,wg:3},{cnd:25,dr:5,name:"Crow's Eyebot Helmet",val:20,wg:10},{cnd:100,dr:2,name:"Dad's Wasteland Outfit",val:6,wg:20},{cnd:150,dr:24,name:"Defender Armor",val:160,wg:15},{cnd:50,dr:6,name:"Dirty Chinese Jumpsuit",val:6,wg:2},{cnd:50,dr:6,name:"Dirty Chinese Jumpsuit",val:6,wg:2},{cnd:100,dr:3,name:"Dirty Pre-War Businesswear",val:8,wg:2},{cnd:100,dr:3,name:"Dirty Pre-War Casualwear",val:6,wg:2},{cnd:100,dr:2,name:"Dirty Pre-War Kid's Outfit",val:30,wg:2},{cnd:100,dr:3,name:"Dirty Pre-War Parkstroller Outfit",val:5,wg:10},{cnd:100,dr:3,name:"Dirty Pre-War Relaxedwear",val:6,wg:5},{cnd:100,dr:3,name:"Dirty Pre-War Spring Outfit",val:5,wg:2},{cnd:100,dr:4,name:"Dirty Pre-War Spring Outfit",val:40,wg:2},{cnd:100,dr:1,name:"Doctor Li's Glasses",val:6,wg:0},{cnd:100,dr:3,name:"Doctor Li's Outfit",val:8,wg:2},{cnd:100,dr:3,name:"Elder Lyons' Robe",val:8,wg:2},{cnd:15,dr:1,name:"Enclave Officer Hat",val:6,wg:1},{cnd:100,dr:5,name:"Enclave Officer Uniform",val:8,wg:3},{cnd:1200,dr:40,name:"Enclave Power Armor",val:780,wg:45},{cnd:1200,dr:40,name:"Enclave Power Armor",val:780,wg:45},{cnd:75,dr:9,name:"Enclave Power Helmet",val:110,wg:5},{cnd:100,dr:3,name:"Enclave Scientist Outfit",val:8,wg:2},{cnd:1500,dr:40,name:"Enclave Shocktrooper Armor",val:900,wg:45},{cnd:125,dr:7,name:"Enclave Shocktrooper Helmet",val:150,wg:5},{cnd:25,dr:6,name:"Environment Suit",val:100,wg:5},{cnd:15,dr:1,name:"Eulogy Jones' Hat",val:6,wg:1},{cnd:100,dr:2,name:"Eulogy Jones' Suit",val:6,wg:3},{cnd:100,dr:12,name:"Explorer's Gear",val:50,wg:3},{cnd:25,dr:5,name:"Eyebot Helmet",val:20,wg:3},{cnd:150,dr:1,name:"Eyeglasses",val:8,wg:0},{cnd:100,dr:3,name:"Ghoul Mask",val:50,wg:1},{cnd:150,dr:0,name:"GlassesReadingChild",val:12,wg:0},{cnd:100,dr:3,name:"Grimy Pre-War Businesswear",val:6,wg:2},{cnd:100,dr:15,name:"Hand-Me-Down Raider Armor",val:180,wg:15},{cnd:100,dr:2,name:"Handyman Jumpsuit",val:6,wg:1},{cnd:20,dr:1,name:"Hat of the People",val:30,wg:1},{cnd:10,dr:1,name:"Head Wrap",val:0,wg:0},{cnd:10,dr:1,name:"Head Wrap",val:0,wg:0},{cnd:10,dr:1,name:"Head Wrap",val:0,wg:0},{cnd:10,dr:1,name:"Head Wrap",val:0,wg:0},{cnd:100,dr:15,name:"Highway Scar Armor",val:180,wg:15},{cnd:15,dr:3,name:"Hockey Mask",val:10,wg:1},{cnd:100,dr:2,name:"Junior Officer Outfit",val:30,wg:2},{cnd:100,dr:1,name:"Kid's Ballcap with Glasses",val:30,wg:1},{cnd:150,dr:1,name:"Kid's Baseball Cap",val:40,wg:1},{cnd:100,dr:2,name:"Kid's Cave Rat Outfit",val:30,wg:2},{cnd:100,dr:2,name:"Kid's Murray the Mole Hat",val:30,wg:1},{cnd:10,dr:1,name:"Kid's Party Hat",val:5,wg:1},{cnd:150,dr:1,name:"Kid's Police Hat",val:40,wg:1},{cnd:100,dr:3,name:"Lab Technician Outfit",val:8,wg:2},{cnd:150,dr:24,name:"Leather Armor",val:160,wg:15},{cnd:150,dr:24,name:"Leather Armor",val:160,wg:15},{cnd:150,dr:24,name:"Leather Armor",val:160,wg:15},{cnd:150,dr:24,name:"Leather Armor",val:160,wg:15},{cnd:25,dr:4,name:"Ledoux's Hockey Mask",val:100,wg:1},{cnd:200,dr:5,name:"Lesko's Lab Coat",val:150,wg:1},{cnd:50,dr:1,name:"Lincoln's Hat",val:40,wg:1},{cnd:1e3,dr:40,name:"Linden's Outcast Power Armor",val:740,wg:45},{cnd:150,dr:1,name:"Lucky Shades",val:40,wg:1},{cnd:1e3,dr:40,name:"Lyons' Pride Power Armor",val:740,wg:45},{cnd:15,dr:6,name:"MacCready's Helmet",val:60,wg:1},{cnd:25,dr:3,name:"Makeshift Gas Mask",val:40,wg:2},{cnd:150,dr:15,name:"Maple's Garb",val:200,wg:2},{cnd:100,dr:2,name:"Mayor MacCready's Outfit",val:30,wg:2},{cnd:100,dr:12,name:"Merc Adventurer Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Adventurer Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Charmer Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Charmer Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Cruiser Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Cruiser Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Grunt Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Grunt Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Troublemaker Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Troublemaker Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Veteran Outfit",val:50,wg:8},{cnd:500,dr:36,name:"Metal Armor",val:460,wg:30},{cnd:50,dr:5,name:"Metal Helmet",val:70,wg:3},{cnd:100,dr:1,name:"Modified Utility Jumpsuit",val:30,wg:2},{cnd:10,dr:5,name:"Motorcycle Helmet",val:6,wg:1},{cnd:100,dr:2,name:"Mysterious Stranger Hat",val:30,wg:1},{cnd:100,dr:5,name:"Mysterious Stranger Outfit",val:40,wg:3},{cnd:100,dr:1,name:"Naughty Nightwear",val:200,wg:1},{cnd:10,dr:2,name:"Oasis Druid Hood",val:6,wg:1},{cnd:10,dr:2,name:"Oasis Exile Hood",val:30,wg:1},{cnd:100,dr:4,name:"Oasis Robe",val:30,wg:3},{cnd:100,dr:4,name:"Oasis Villager Robe",val:6,wg:2},{cnd:1e3,dr:40,name:"Outcast Power Armor",val:740,wg:45},{cnd:75,dr:8,name:"Outcast Power Helmet",val:110,wg:5},{cnd:400,dr:28,name:"Outcast Recon Armor",val:180,wg:20},{cnd:40,dr:4,name:"Outcast Recon Helmet",val:40,wg:3},{cnd:10,dr:1,name:"Party Hat",val:5,wg:1},{cnd:10,dr:0,name:"Party HatStanley",val:5,wg:1},{cnd:150,dr:6,name:"Pint-Sized Slasher Mask",val:60,wg:1},{cnd:1e5,dr:0,name:"Pip-Boy 3000",val:0,wg:0},{cnd:1e5,dr:0,name:"Pip-Boy 3000",val:0,wg:0},{cnd:1e5,dr:0,name:"Pip-Boy Glove",val:30,wg:0},{cnd:150,dr:1,name:"Police Hat",val:8,wg:1},{cnd:50,dr:2,name:"Poplar's Hood",val:100,wg:1},{cnd:1e3,dr:40,name:"Power Armor",val:740,wg:45},{cnd:1e3,dr:40,name:"Power Armor",val:510,wg:45},{cnd:1500,dr:40,name:"Power Armor",val:740,wg:45},{cnd:75,dr:8,name:"Power Helmet",val:110,wg:5},{cnd:100,dr:3,name:"Power-Suit Armor",val:12,wg:2},{cnd:15,dr:1,name:"Pre-War Baseball Cap",val:8,wg:1},{cnd:15,dr:1,name:"Pre-War Bonnet",val:8,wg:1},{cnd:100,dr:3,name:"Pre-War Casualwear",val:8,wg:2},{cnd:100,dr:3,name:"Pre-War Casualwear",val:12,wg:2},{cnd:15,dr:1,name:"Pre-War Hat",val:8,wg:1},{cnd:100,dr:1,name:"Pre-War Kid's Outfit",val:30,wg:2},{cnd:100,dr:2,name:"Pre-War Outfit and Watch",val:30,wg:2},{cnd:100,dr:2,name:"Pre-War Outfit and Watch",val:6,wg:2},{cnd:100,dr:3,name:"Pre-War Parkstroller Outfit",val:6,wg:2},{cnd:100,dr:3,name:"Pre-War Parkstroller Outfit",val:10,wg:2},{cnd:100,dr:3,name:"Pre-War Relaxedwear",val:8,wg:2},{cnd:100,dr:3,name:"Pre-War Spring Outfit",val:8,wg:2},{cnd:1e3,dr:40,name:"Prototype Medic Power Armor",val:1e3,wg:45},{cnd:15,dr:3,name:"Pyro Helmet",val:20,wg:3},{cnd:15,dr:6,name:"Radiation Suit",val:60,wg:5},{cnd:100,dr:2,name:"Ragamuffin Outfit",val:30,wg:2},{cnd:100,dr:1,name:"Ragamuffin Tophat",val:30,wg:1},{cnd:15,dr:3,name:"Raider Arclight Helmet",val:20,wg:3},{cnd:100,dr:16,name:"Raider Badlands Armor",val:180,wg:15},{cnd:100,dr:16,name:"Raider Blastmaster Armor",val:180,wg:15},{cnd:15,dr:3,name:"Raider Blastmaster Helmet",val:20,wg:3},{cnd:100,dr:16,name:"Raider Painspike Armor",val:180,wg:15},{cnd:15,dr:3,name:"Raider Psycho-Tic Helmet",val:20,wg:3},{cnd:100,dr:16,name:"Raider Sadist Armor",val:180,wg:15},{cnd:15,dr:3,name:"Raider Wastehound Helmet",val:20,wg:3},{cnd:1100,dr:39,name:"Ranger Battle Armor",val:430,wg:27},{cnd:50,dr:6,name:"Ranger Battle Helmet",val:60,wg:5},{cnd:150,dr:1,name:"Reading Glasses",val:12,wg:0},{cnd:40,dr:4,name:"Recon Armor Helmet",val:40,wg:3},{cnd:400,dr:28,name:"Recon Armor",val:180,wg:20},{cnd:100,dr:2,name:"Red Racer Jumpsuit",val:6,wg:1},{cnd:10,dr:2,name:"Red's Bandana",val:30,wg:1},{cnd:100,dr:3,name:"Red's Jumpsuit",val:40,wg:1},{cnd:150,dr:10,name:"Regulator Duster",val:70,wg:3},{cnd:25,dr:4,name:"Rivet City Security Helmet",val:50,wg:3},{cnd:100,dr:24,name:"Rivet City Security Uniform",val:330,wg:20},{cnd:150,dr:24,name:"Road Rascal Leather Armor",val:160,wg:15},{cnd:100,dr:2,name:"RobCo Jumpsuit",val:6,wg:1},{cnd:10,dr:1,name:"Roving Trader Hat",val:6,wg:1},{cnd:100,dr:2,name:"Roving Trader Outfit",val:6,wg:2},{cnd:100,dr:3,name:"Scientist Outfit",val:8,wg:2},{cnd:100,dr:1,name:"Sexy Sleepwear",val:6,wg:1},{cnd:50,dr:1,name:"Shady Hat",val:40,wg:1},{cnd:100,dr:15,name:"Sharp-Dressed Raider's Armor",val:180,wg:15},{cnd:400,dr:32,name:"Shellshocked Combat Armor",val:390,wg:25},{cnd:50,dr:5,name:"Shellshocked Combat Helmet",val:50,wg:3},{cnd:150,dr:5,name:"Sheriff's Duster",val:35,wg:3},{cnd:40,dr:1,name:"Sheriff's Hat",val:35,wg:1},{cnd:150,dr:3,name:"Slave Collar",val:50,wg:5},{cnd:400,dr:4,name:"Slave Collar",val:100,wg:5},{cnd:100,dr:1,name:"Sleepwear",val:10,wg:1},{cnd:10,dr:1,name:"Stormchaser Hat",val:6,wg:1},{cnd:150,dr:1,name:"Sunglasses",val:8,wg:0},{cnd:10,dr:1,name:"Surgical Mask",val:6,wg:1},{cnd:2e3,dr:50,name:"T-51b Power Armor",val:1e3,wg:40},{cnd:100,dr:10,name:"T-51b Power Helmet",val:120,wg:4},{cnd:15,dr:1,name:"Takoma Park Little Leaguer Cap",val:60,wg:1},{cnd:300,dr:28,name:"Talon Combat Armor",val:275,wg:25},{cnd:1e3,dr:32,name:"Talon Combat Armor",val:390,wg:25},{cnd:40,dr:4,name:"Talon Combat Helmet",val:60,wg:3},{cnd:50,dr:5,name:"Talon Combat Helmet",val:60,wg:3},{cnd:25,dr:4,name:"Tenpenny Security Helmet",val:50,wg:1},{cnd:100,dr:24,name:"Tenpenny Security Uniform",val:180,wg:20},{cnd:100,dr:2,name:"Tenpenny's Suit",val:8,wg:2},{cnd:1500,dr:43,name:"Tesla Armor",val:820,wg:45},{cnd:1500,dr:40,name:"Tesla Armor",val:820,wg:45},{cnd:100,dr:9,name:"Tesla Helmet",val:120,wg:5},{cnd:100,dr:20,name:"The AntAgonizer's Costume",val:120,wg:15},{cnd:50,dr:6,name:"The AntAgonizer's Helmet",val:60,wg:5},{cnd:15,dr:3,name:"The Devil's Pigtails",val:20,wg:3},{cnd:100,dr:20,name:"The Mechanist's Costume",val:30,wg:15},{cnd:50,dr:6,name:"The Mechanist's Helmet",val:60,wg:5},{cnd:100,dr:2,name:"The Surgeon's Lab Coat",val:30,wg:1},{cnd:150,dr:1,name:"Three Dog's Glasses",val:12,wg:0},{cnd:15,dr:2,name:"Three Dog's Head Wrap",val:200,wg:0},{cnd:150,dr:1,name:"Tinted Reading Glasses",val:12,wg:0},{cnd:15,dr:2,name:"Torcher's Mask",val:20,wg:3},{cnd:150,dr:1,name:"Tortiseshell Glasses",val:8,wg:0},{cnd:100,dr:4,name:"Tunnel Snake Outfit",val:8,wg:2},{cnd:100,dr:4,name:"Tunnel Snake Outfit",val:40,wg:3},{cnd:100,dr:0,name:"Underwear",val:2,wg:1},{cnd:100,dr:10,name:"Vance's Longcoat Outfit",val:100,wg:4},{cnd:100,dr:1,name:"Vault 101 Child's Jumpsuit",val:5,wg:2},{cnd:100,dr:1,name:"Vault 101 Jumpsuit",val:8,wg:1},{cnd:100,dr:12,name:"Vault 101 Security Armor",val:70,wg:15},{cnd:25,dr:3,name:"Vault 101 Security Helmet",val:30,wg:3},{cnd:100,dr:1,name:"Vault 101 Utility Jumpsuit",val:10,wg:1},{cnd:100,dr:1,name:"Vault 106 Jumpsuit",val:6,wg:1},{cnd:100,dr:1,name:"Vault 108 Jumpsuit",val:6,wg:1},{cnd:100,dr:1,name:"Vault 112 Jumpsuit",val:6,wg:1},{cnd:100,dr:1,name:"Vault 77 Jumpsuit",val:6,wg:1},{cnd:100,dr:1,name:"Vault 87 Jumpsuit",val:6,wg:1},{cnd:100,dr:1,name:"Vault 92 Jumpsuit",val:6,wg:1},{cnd:100,dr:2,name:"Vault Lab Uniform",val:6,wg:1},{cnd:150,dr:24,name:"Wanderer's Leather Armor",val:160,wg:15},{cnd:100,dr:2,name:"Wasteland Doctor Fatigues",val:6,wg:2},{cnd:100,dr:12,name:"Wasteland Legend Outfit",val:50,wg:8},{cnd:100,dr:1,name:"Wasteland Scout Hat",val:30,wg:1},{cnd:100,dr:2,name:"Wasteland Scout Uniform",val:30,wg:2},{cnd:100,dr:2,name:"Wasteland Settler Outfit",val:6,wg:2},{cnd:100,dr:2,name:"Wasteland Surgeon Outfit",val:6,wg:2},{cnd:100,dr:2,name:"Wasteland Wanderer Outfit",val:6,wg:2},{cnd:100,dr:12,name:"Wastelander's Gear",val:50,wg:2}],I=[{name:"10 Ball",val:2,wg:1},{name:"13 Ball",val:2,wg:1},{name:"2 Ball",val:2,wg:1},{name:"5 Ball",val:2,wg:1},{name:"8 Ball",val:2,wg:1},{name:"Abraxo Cleaner",val:5,wg:1},{name:"Action Abe Action Figure",val:5,wg:1},{name:"Android Component",val:0,wg:0},{name:"Ant Resin",val:3,wg:1},{name:"Antique Lincoln Coin Collection",val:5,wg:1},{name:"Archives Prize Voucher",val:0,wg:1},{name:"Ashtray",val:1,wg:1},{name:"Baseball Glove",val:4,wg:1},{name:"Baseball",val:2,wg:1},{name:"Basketball",val:1,wg:1},{name:"Bent Tin Can",val:1,wg:1},{name:"Big Spoon",val:1,wg:1},{name:"Bill of Rights",val:0,wg:1},{name:"Birch's Sap",val:0,wg:1},{name:"Blue Pass Card",val:1,wg:0},{name:"Bobblehead - Agility",val:0,wg:0},{name:"Bobblehead - Barter",val:0,wg:0},{name:"Bobblehead - Big Guns",val:0,wg:0},{name:"Bobblehead - Charisma",val:0,wg:0},{name:"Bobblehead - Endurance",val:0,wg:0},{name:"Bobblehead - Energy Weapons",val:0,wg:0},{name:"Bobblehead - Explosives",val:0,wg:0},{name:"Bobblehead - Intelligence",val:0,wg:0},{name:"Bobblehead - Lockpick",val:0,wg:0},{name:"Bobblehead - Luck",val:0,wg:0},{name:"Bobblehead - Medicine",val:0,wg:0},{name:"Bobblehead - Melee Weapons",val:0,wg:0},{name:"Bobblehead - Perception",val:0,wg:0},{name:"Bobblehead - Repair",val:0,wg:0},{name:"Bobblehead - Science",val:0,wg:0},{name:"Bobblehead - Small Guns",val:0,wg:0},{name:"Bobblehead - Sneak",val:0,wg:0},{name:"Bobblehead - Speech",val:0,wg:0},{name:"Bobblehead - Strength",val:0,wg:0},{name:"Bobblehead - Unarmed",val:0,wg:0},{name:"Bobby Pin",val:1,wg:0},{name:"Bonesaw",val:5,wg:2},{name:"Bottle Cap",val:1,wg:0},{name:"Box of Detergent",val:1,wg:1},{name:"Brahmin Skull",val:1,wg:2},{name:"Brotherhood of Steel Holotag",val:1,wg:0},{name:"Butter Knife",val:1,wg:1},{name:"Butter Knife",val:1,wg:1},{name:"Camera",val:5,wg:1},{name:"Card Catalog Holotape",val:0,wg:0},{name:"Carton of Cigarettes",val:50,wg:2},{name:"Ceramic Dinner Plate",val:1,wg:1},{name:"",val:1,wg:1},{name:"",val:1,wg:1},{name:"",val:1,wg:1},{name:"",val:1,wg:1},{name:"Chandelier",val:2,wg:14},{name:"Charon's Employment Contract",val:1,wg:0},{name:"Cherry Bomb",val:5,wg:0},{name:"Chessboard",val:1,wg:1},{name:"Cigarette",val:1,wg:0},{name:"Civil War Draft Poster",val:5,wg:1},{name:"Clipboard",val:1,wg:1},{name:"Coffee Mug",val:1,wg:1},{name:"Coffee Pot",val:1,wg:1},{name:"Computer Password Module",val:0,wg:0},{name:"Conductor",val:30,wg:5},{name:"Constitution of the United States",val:1,wg:1},{name:"Control Collar",val:1,wg:5},{name:"Crumpled Note",val:1,wg:1},{name:"Crutch",val:5,wg:2},{name:"Cue Ball",val:3,wg:1},{name:"Cup",val:1,wg:1},{name:"Cutting Board",val:1,wg:1},{name:"Damaged Garden Gnome",val:1,wg:4},{name:"Danielle's Book",val:1,wg:1},{name:"Deathclaw Hand",val:25,wg:1},{name:"Declaration of Independence",val:0,wg:1},{name:"Dinner Plate",val:1,wg:1},{name:"Dog Bowl",val:1,wg:1},{name:"Donovan's Wrench",val:75,wg:0},{name:"Door Component",val:1,wg:1},{name:"Drinking Glass",val:1,wg:1},{name:"Ear",val:1,wg:0},{name:"Earnings Clipboard",val:1,wg:1},{name:"Emancipation Proclamation",val:1,wg:1},{name:"Empty Nuka-Cola Bottle",val:2,wg:1},{name:"Empty Sap Container",val:0,wg:1},{name:"Empty Soda Bottle",val:1,wg:1},{name:"Empty Syringe",val:5,wg:1},{name:"Empty Whisky Bottle",val:1,wg:1},{name:"Experimental Rho ID",val:1,wg:0},{name:"Factory Employee ID",val:1,wg:0},{name:"Finance Clipboard",val:1,wg:1},{name:"Finger",val:1,wg:0},{name:"Firehose Nozzle",val:5,wg:1},{name:"Fission Battery",val:75,wg:10},{name:"Flour",val:2,wg:1},{name:"Food Sanitizer",val:150,wg:7},{name:"Forceps",val:5,wg:1},{name:"Forged Declaration",val:0,wg:1},{name:"Fork",val:1,wg:.5},{name:"Fuse",val:0,wg:0},{name:"Fusion Pulse Charge",val:1,wg:0},{name:"G.E.C.K.",val:0,wg:5},{name:"Garden Gnome",val:1,wg:5},{name:"Geomapper Module",val:20,wg:1},{name:"Gettysburg Address",val:1,wg:1},{name:"Glass Pitcher",val:1,wg:1},{name:"Green Plate",val:1,wg:1},{name:"Hammer",val:3,wg:2},{name:"Harmonica",val:2,wg:1},{name:"Holotape",val:0,wg:0},{name:"Hot Plate",val:5,wg:2},{name:"House: Explorer Theme",val:1e3,wg:0},{name:"House: Jukebox",val:500,wg:0},{name:"House: Love Machine Theme",val:1e3,wg:0},{name:"House: My First Infirmary",val:1200,wg:0},{name:"House: My First Laboratory",val:1200,wg:0},{name:"House: Nuka-Cola Machine",val:500,wg:0},{name:"House: Pre-War Theme",val:1e3,wg:0},{name:"House: Raider Theme",val:1e3,wg:0},{name:"House: Scientist Theme",val:1e3,wg:0},{name:"House: Vault Theme",val:1e3,wg:0},{name:"House: Workbench",val:500,wg:0},{name:"Ink Container",val:0,wg:0},{name:"Intact Garden Gnome",val:1,wg:5},{name:"Iron",val:2,wg:5},{name:"John Wilkes Booth Wanted Poster",val:5,wg:1},{name:"Junders Plunkett's Finger",val:1,wg:0},{name:"Lacy Underwear",val:3,wg:0},{name:"Large Burned Book",val:1,wg:1},{name:"Large Destroyed Book",val:1,wg:1},{name:"Large Ruined Book",val:1,wg:1},{name:"Large Scorched Book",val:1,wg:1},{name:"Large Whiskey Bottle",val:5,wg:2},{name:"Laurel's Liniment",val:0,wg:1},{name:"Lawn Mower Blade",val:10,wg:2},{name:"Leaf Blower",val:15,wg:2},{name:"Leather Belt",val:5,wg:1},{name:"Lincoln Memorial Poster",val:0,wg:1},{name:"Lincoln's Diary",val:5,wg:1},{name:"Lincoln's Voice",val:5,wg:2},{name:"Lucky 8 Ball",val:4,wg:1},{name:"Lucy's Sealed Envelope",val:0,wg:0},{name:"Lunchbox",val:3,wg:1},{name:"Magna Carta",val:0,wg:1},{name:"Media Archives Holotape",val:0,wg:0},{name:"Medical Brace",val:10,wg:2},{name:"Medical Brace",val:1,wg:2},{name:"Medical Clipboard",val:1,wg:1},{name:"Metal Cooking Pan",val:5,wg:1},{name:"Metal Cooking Pot",val:1,wg:1},{name:"Metal Spoon",val:1,wg:.5},{name:"Metro Ticket",val:1,wg:0},{name:"Military ID",val:1,wg:0},{name:"Military School Brochure",val:0,wg:0},{name:"Milk Bottle",val:1,wg:1},{name:"Modified FEV Virus",val:0,wg:1},{name:"Monroe Doctrine",val:1,wg:1},{name:"Motorcycle Gas Tank",val:25,wg:5},{name:"Motorcycle Handbrake",val:15,wg:1},{name:"Museum Token",val:1,wg:0},{name:"Mutilated Arm",val:0,wg:2},{name:"Mutilated Leg",val:0,wg:2},{name:"Mutilated Organs",val:0,wg:2},{name:"Mutilated Skull",val:0,wg:2},{name:"Mutilated Torso",val:0,wg:2},{name:"Nuka-Cola Clear Formula",val:150,wg:1},{name:"Nuka-Cola Truck",val:5,wg:2},{name:"Observer",val:0,wg:1},{name:"Office Employee ID",val:1,wg:0},{name:"Opthalmoscope",val:4,wg:1},{name:"Pack of Cigarettes",val:10,wg:.5},{name:"Paint Gun",val:15,wg:5},{name:"Paperweight",val:1,wg:1},{name:"Pencil",val:1,wg:0},{name:"Pilot Light",val:14,wg:1},{name:"Plunger",val:1,wg:1},{name:"Pool Ball",val:2,wg:1},{name:"Pot",val:0,wg:2},{name:"Pressure Cooker",val:15,wg:5},{name:"Pre-War Book",val:5,wg:1},{name:"Pre-War Book",val:1,wg:1},{name:"Pre-war Money",val:10,wg:0},{name:"Radscorpion Poison Gland",val:30,wg:1},{name:"Rake",val:1,wg:2},{name:"Red Pass Card",val:1,wg:0},{name:"Red Plate",val:1,wg:1},{name:"Rivet City Historical Record",val:0,wg:1},{name:"RobCo Processor Widget",val:0,wg:1},{name:"Rollerskate",val:4,wg:1},{name:"Scalpel",val:5,wg:1},{name:"Schematics - Bottlecap Mine",val:300,wg:0},{name:"Schematics - Dart Gun",val:500,wg:0},{name:"Schematics - Deathclaw Gauntlet",val:800,wg:0},{name:"Schematics - Nuka-Grenade",val:300,wg:0},{name:"Schematics - Railway Rifle",val:800,wg:0},{name:"Schematics - Rock-It Launcher",val:800,wg:0},{name:"Schematics - Shishkebab",val:500,wg:0},{name:"Scissors",val:3,wg:1},{name:"Scrap Metal",val:1,wg:1},{name:"Sensor Module",val:30,wg:2},{name:"Sheet Music Book",val:100,wg:1},{name:"Shot glass",val:1,wg:1},{name:"Slave Collar",val:0,wg:1},{name:"Small Burned Book",val:1,wg:1},{name:"Small Destroyed Book",val:1,wg:1},{name:"Small Ruined Book",val:1,wg:1},{name:"Small Scorched Book",val:1,wg:1},{name:"Soil Stradivarius",val:0,wg:3},{name:"Spatula",val:1,wg:1},{name:"Spork",val:1,wg:.5},{name:"Steam Gauge Assembly",val:25,wg:10},{name:"Surgical Tubing",val:10,wg:1},{name:"Teddy Bear",val:3,wg:1},{name:"Tin Can",val:1,wg:1},{name:"Tin Plate",val:1,wg:1},{name:"Toaster",val:5,wg:3},{name:"Toaster",val:5,wg:3},{name:"Toy Car",val:5,wg:1},{name:"Triangle",val:1,wg:1},{name:"Turpentine",val:10,wg:2},{name:"Tweezers",val:3,wg:1},{name:"U.S. Declaration of War on China",val:1,wg:1},{name:"U.S. Declaration of War on Germany",val:1,wg:1},{name:"Utility Worker ID",val:1,wg:0},{name:"Vacuum Cleaner",val:20,wg:10},{name:"Vance's Proposal",val:0,wg:0},{name:"Virgo II Dish",val:0,wg:1},{name:"Wasteland Survival Guide",val:1,wg:2},{name:"Whet Stone",val:1,wg:2},{name:"White Plate",val:1,wg:1},{name:"Wonderglue",val:10,wg:1},{name:"Wood Chipper",val:25,wg:50},{name:"Wrench",val:1,wg:1},{name:"Yew's Bear Charm",val:50,wg:1}],R=[{description:"With the Action Boy perk, you gain an additional 25 Action Points to use in V.A.T.S.",id:1,maxRanks:1,name:"Action Boy",value:0},{description:"With the Action Girl perk, you gain an additional 25 Action Points to use in V.A.T.S.",id:2,maxRanks:1,name:"Action Girl",value:0},{description:"With the Adamantium Skeleton perk, your limbs only receive 50% of the damage they normally would.",id:3,maxRanks:1,name:"Adamantium Skeleton",value:0},{description:"At the first rank of this perk, animals simply won't attack. At the second rank, they will actually come to your aid in combat, but never against another animal. This perk affects the Dog, Yao Guai, Mole Rat, and Brahmin. ",id:4,maxRanks:2,name:"Animal Friend",value:0},{description:"Your body has been genetically enhanced with the strength and flame resistance of the Grayditch Fire Ants! Your Strength has increased by 1 and you are now 25% resistant to fire.",id:5,maxRanks:1,name:"Ant Might",value:0},{description:"Your body has been genetically enhanced with the perception and flame resistance of the Grayditch Fire Ants! Your Perception has increased by 1 and you are now 25% resistant to fire.",id:6,maxRanks:1,name:"Ant Sight",value:0},{description:"You've been exposed to Harold's mutation and your skin is now as hard as tree bark. As a result, you've gained a permanent +5% to Damage Resistance.",id:7,maxRanks:1,name:"Barkskin",value:0},{description:"With the Better Criticals perk, you gain a 50% damage bonus every time a critical hit is scored on an opponent.",id:8,maxRanks:1,name:"Better Criticals",value:0},{description:"In combat, you do +10% damage against male opponents. Outside of combat, you'll sometimes have access to unique dialogue options when dealing with the opposite sex. ",id:9,maxRanks:1,name:"Black Widow",value:0},{description:"With the Bloody Mess perk, characters and creatures you kill will often explode into a red, gut-ridden, eyeball-strewn paste. Fun! Oh, and you'll do 5% extra damage with all weapons.",id:10,maxRanks:1,name:"Bloody Mess",value:0},{description:"With the Cannibal perk, when you're in Sneak mode, you gain the option to eat a corpse to regain Health. But every time you feed, you lose Karma, and if the act is witnessed, it is considered a crime against nature.",id:11,maxRanks:1,name:"Cannibal",value:0},{description:"Having the Chem Resistant perk means you're 50% less likely to develop an addiction to chems, like Psycho or Jet.",id:12,maxRanks:1,name:"Chem Resistant",value:0},{description:"With the Chemist perk, any chems you take last twice as long.",id:13,maxRanks:1,name:"Chemist",value:0},{description:"The Child at Heart perk greatly improves your interactions with children, usually in the form of unique dialogue choices.",id:14,maxRanks:1,name:"Child at Heart",value:0},{description:"While using a rifle (or similar two-handed weapon), your accuracy in V.A.T.S. is significantly increased.",id:15,maxRanks:1,name:"Commando",value:0},{description:"With the Comprehension perk, you gain one additional skill point whenever a skill book is read.",id:16,maxRanks:1,name:"Comprehension",value:0},{description:"Fail a hack attempt and get locked out of a computer? Not if you're a Computer Whiz! With this perk, you can attempt to re-hack any computer you were previously locked out of.",id:17,maxRanks:1,name:"Computer Whiz",value:0},{description:"With Concentrated Fire, your accuracy to hit any body part in V.A.T.S. increases slightly with each subsequent hit on that body part.",id:18,maxRanks:1,name:"Concentrated Fire",value:0},{description:"Once you have the Contract Killer perk, any good character you kill will have an ear on their corpse. This ear can then be sold to a certain person (whose identity is disclosed when you take the perk) for caps and negative Karma. ",id:19,maxRanks:1,name:"Contract Killer",value:0},{description:"You've made permanent enhancements to your body! The Cyborg perk instantly adds +10% to your Damage, Poison, and Radiation Resistances, and 10 points to the Energy Weapons skill.",id:20,maxRanks:1,name:"Cyborg",value:0},{description:"Just like dear old Dad, you've devoted your time to intellectual pursuits. You gain an additional 5 points to both the Science and Medicine skills.",id:21,maxRanks:3,name:"Daddy's Boy",value:0},{description:"Just like dear old Dad, you've devoted your time to intellectual pursuits. You gain an additional 5 points to both the Science and Medicine skills.",id:22,maxRanks:3,name:"Daddy's Girl",value:0},{description:"With each rank of this perk, all of your explosive weapons do an additional 20% damage. ",id:23,maxRanks:3,name:"Demolition Expert",value:0},{description:"Something about your presence dampens others' desires to exceed. Any enemy's chance of getting critical hits on you is reduced by 50%. ",id:24,maxRanks:1,name:"Dream Crusher",value:0},{description:"With the Educated perk, you gain three more skill points every time you advance in level. This perk is best taken early on, to maximize its effectiveness.",id:25,maxRanks:1,name:"Educated",value:0},{description:"With the Entomologist perk, you do an additional +50% damage every time you attack a mutated insect, like the Radroach, Giant Ant, or Radscorpion.",id:26,maxRanks:1,name:"Entomologist",value:0},{description:"When you choose the Explorer perk, every location in the world is revealed on your map. So get out there and explore!",id:27,maxRanks:1,name:"Explorer",value:0},{description:"With the Fast Metabolism perk, you gain a 20% Health bonus when using Stimpaks.",id:28,maxRanks:1,name:"Fast Metabolism",value:0},{description:"With the Finesse perk, you have a higher chance to score a critical hit on an opponent in combat, equivalent to 5 extra points of Luck.",id:29,maxRanks:1,name:"Finesse",value:0},{description:"With the Fortune Finder perk, you'll find considerably more Nuka-Cola caps in containers than you normally would. ",id:30,maxRanks:1,name:"Fortune Finder",value:0},{description:"If you kill a target in V.A.T.S., all your Action Points are restored upon exiting V.A.T.S.",id:31,maxRanks:1,name:"Grim Reaper's Sprint",value:0},{description:"You're obsessed with using and maintaining a wide variety of conventional firearms. With each rank of the Gun Nut perk, you gain an additional 5 points to the Small Guns and Repair skills.",id:32,maxRanks:3,name:"Gun Nut",value:0},{description:"While using a pistol (or similar one-handed weapon), your accuracy in V.A.T.S. is significantly increased.",id:33,maxRanks:1,name:"Gunslinger",value:0},{description:"This perk allows you to regain health by consuming Bloodpacks.",id:34,maxRanks:1,name:"Hematophage",value:0},{description:"The Here and Now perk immediately grants an additional experience level, complete with all the advantages that brings.",id:35,maxRanks:1,name:"Here and Now",value:0},{description:"With the Impartial Mediation perk, you gain an extra 30 points to Speech... so long as you maintain a Neutral Karma level.",id:36,maxRanks:1,name:"Impartial Mediation",value:0},{description:'With Infiltrator, if a lock is broken, and can\'t normally be picked again, you can attempt to pick it again one more time. This includes locks previously broken by a "Force Lock" attempt.',id:37,maxRanks:1,name:"Infiltrator",value:0},{description:"With the Intense Training perk, you can put a single point into any of your S.P.E.C.I.A.L. attributes.",id:38,maxRanks:10,name:"Intense Training",value:0},{description:"With the Iron Fist perk, you do an additional 5 points of Unarmed damage per rank.",id:39,maxRanks:3,name:"Iron Fist",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you're still alive to tell the tale. You've gained +2% bonus to Poison Resistance and Radiation Resistance, and +5 points to maximum Health.",id:40,maxRanks:1,name:"Junior Survivor",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you're still alive to tell the tale. You've gained +2% bonus to Poison Resistance and Radiation Resistance, and 2 points to both the Medicine and Science skills.",id:41,maxRanks:1,name:"Junior Survivor",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you're still alive to tell the tale. You've gained +2% bonus to Poison Resistance, Radiation Resistance and Damage Resistance.",id:42,maxRanks:1,name:"Junior Survivor",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you're still alive to tell the tale. You've gained +2% bonus to Poison Resistance & Radiation Resistance, and 2 points to both the Speech and Sneak skills.",id:43,maxRanks:1,name:"Junior Survivor",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you're still alive to tell the tale. You've gained +2% bonus to Poison Resistance and Radiation Resistance, and a +1% bonus to Critical Chance.",id:44,maxRanks:1,name:"Junior Survivor",value:0},{description:"In combat, you do +10% damage against female opponents. Outside of combat, you'll sometimes have access to unique dialogue options when dealing with the opposite sex. ",id:45,maxRanks:1,name:"Lady Killer",value:0},{description:"Once you have the Lawbringer perk, any evil character you kill will have a finger on their corpse. This finger can then be sold to a certain person (whose identity is disclosed when you take the perk) for caps and positive Karma. ",id:46,maxRanks:1,name:"Lawbringer",value:0},{description:"With the Lead Belly perk, you take 50% less radiation every time you drink from an irradiated water source.",id:47,maxRanks:1,name:"Lead Belly",value:0},{description:"With the Life Giver perk, you gain an additional 30 Hit Points.",id:48,maxRanks:1,name:"Life Giver",value:0},{description:"With the Light Step perk, you'll never set off an enemy's mines or floor-based traps.",id:49,maxRanks:1,name:"Light Step",value:0},{description:"Years as the Vault little league MVP have honed your hitting and throwing. With every rank, you gain 5 points of Melee Weapons skill and 5 points of Explosives skill.",id:50,maxRanks:3,name:"Little Leaguer",value:0},{description:"When you take the Master Trader perk, the price of every item you buy from a vendor is reduced by 25%.",id:51,maxRanks:1,name:"Master Trader",value:0},{description:"With the Mister Sandman perk, when you're in Sneak mode, you gain the option to silently kill any human or Ghoul while they're sleeping. And, all Mister Sandman kills earn bonus XP.",id:52,maxRanks:1,name:"Mister Sandman",value:0},{description:"You've gained your own personal guardian angel... armed with a fully loaded .44 Magnum. With this perk, the Mysterious Stranger will appear occasionally in V.A.T.S. mode to lend a hand, with deadly efficiency.",id:53,maxRanks:1,name:"Mysterious Stranger",value:0},{description:"You've been pushed around long enough! With the Nerd Rage! perk, your Strength is raised to 10 and you gain 50% to damage resistance whenever your Health drops to 20% or below.",id:54,maxRanks:1,name:"Nerd Rage!",value:0},{description:'When the sun is down, a Night Person gains +2 to both Intelligence and Perception (up to a maximum of 10). This perk directly affects your "internal clock," and remains active both inside and outside.',id:55,maxRanks:1,name:"Night Person",value:0},{description:"The Ninja perk grants you the power of the fabled shadow warriors. When attacking with either Melee or Unarmed, you gain a +15% critical chance on every strike. Sneak attack criticals do 25% more damage than normal.",id:56,maxRanks:1,name:"Ninja",value:0},{description:"With Paralyzing Palm, you will sometimes perform a special V.A.T.S. palm strike that paralyzes your opponent for 30 seconds. Note that in order to perform the Paralyzing Palm, you must be completely unarmed.",id:57,maxRanks:1,name:"Paralyzing Palm",value:0},{description:"You have received the specialized training needed to move in any form of Power Armor.",id:58,maxRanks:1,name:"Power Armor Training",value:0},{description:"",id:59,maxRanks:1,name:"",value:0},{description:"With the Pyromaniac perk, you do +50% damage with fire-based weapons, like the Flamer and Shishkebab.",id:60,maxRanks:1,name:"Pyromaniac",value:0},{description:"After an experimental treatment, intense radiation keeps your body operating at peak performance regardless of crippling injuries... right up until death. When you suffer from Advanced Radiation Poisoning, crippled limbs automatically regenerate.",id:61,maxRanks:1,name:"Rad Regeneration",value:0},{description:"Rad Resistance allows you to -- what else? -- resist radiation. This perk grants an additional 25% to Radiation Resistance.",id:62,maxRanks:1,name:"Rad Resistance",value:0},{description:"With the Robotics perk, you do an additional 25% damage to any robot. But, even better, sneaking up on a hostile robot undetected and activating it will put that robot into a permanent shutdown state.",id:63,maxRanks:1,name:"Robotics Expert",value:0},{description:"Take the Scoundrel perk, and you can use your wily charms to influence people -- each rank raises your Speech and Barter skills by 5 points.",id:64,maxRanks:3,name:"Scoundrel",value:0},{description:"With the Scrounger perk, you'll find considerably more ammunition in containers than you normally would. ",id:65,maxRanks:1,name:"Scrounger",value:0},{description:"With the Silent Running perk, you gain an additional 10 points to Sneak, and running no longer factors into a successful sneak attempt.",id:66,maxRanks:1,name:"Silent Running",value:0},{description:"You're obsessed with really big weapons. With each rank of this perk, you gain an additional 15 points to the Big Guns skill.",id:67,maxRanks:3,name:"Size Matters",value:0},{description:"With the Sniper perk, your chance to hit an opponent's head in V.A.T.S. is significantly increased.",id:68,maxRanks:1,name:"Sniper",value:0},{description:"With the Solar Powered perk, you gain an additional 2 points to Strength when in direct sunlight, and slowly regenerate lost Health.",id:69,maxRanks:1,name:"Solar Powered",value:0},{description:"With the Strong Back perk, you can carry 50 more pounds of equipment.",id:70,maxRanks:1,name:"Strong Back",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you've not only survived - you've learned a few things. You've gained +4% bonus to Poison Resistance and Radiation Resistance, and +10 points to maximum Health.",id:71,maxRanks:1,name:"Survival Expert",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you've not only survived - you've learned a few things. You've gained +4% bonus to Poison Resistance and Radiation Resistance, and 4 points to both the Medicine and Science skills.",id:72,maxRanks:1,name:"Survival Expert",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you've not only survived - you've learned a few things. You've gained +4% bonus to Poison Resistance, Radiation Resistance and Damage Resistance.",id:73,maxRanks:1,name:"Survival Expert",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you've not only survived - you've learned a few things. You've gained +4% bonus to Poison Resistance & Radiation Resistance, and 4 points to both the Speech and Sneak skills.",id:74,maxRanks:1,name:"Survival Expert",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you've not only survived - you've learned a few things. You've gained +4% bonus to Poison Resistance and Radiation Resistance, and a +2% bonus to Critical Chance.",id:75,maxRanks:1,name:"Survival Expert",value:0},{description:"You wrote the book on how to survive in the Wasteland, and have shared your secrets with humanity. You've gained +6% bonus to Poison Resistance and Radiation Resistance, and +15 points to maximum Health.",id:76,maxRanks:1,name:"Survival Guru",value:0},{description:"You wrote the book on how to survive in the Wasteland, and have shared your secrets with humanity. You've gained +6% bonus to Poison Resistance and Radiation Resistance, and 6 points to both the Medicine and Science skills.",id:77,maxRanks:1,name:"Survival Guru",value:0},{description:"You wrote the book on how to survive in the Wasteland, and have shared your secrets with humanity. You've gained +6% bonus to Poison Resistance, Radiation Resistance and Damage Resistance.",id:78,maxRanks:1,name:"Survival Guru",value:0},{description:"You wrote the book on how to survive in the Wasteland, and have shared your secrets with humanity. You've gained +6% bonus to Poison Resistance & Radiation Resistance, and 6 points to both the Speech and Sneak skills.",id:79,maxRanks:1,name:"Survival Guru",value:0},{description:"You wrote the book on how to survive in the Wasteland, and have shared your secrets with humanity. You've gained +6% bonus to Poison Resistance & Radiation Resistance, and +3% bonus to Critical Chance.",id:80,maxRanks:1,name:"Survival Guru",value:0},{description:"With each rank in the Swift Learner perk, you gain an additional 10% to total Experience Points whenever Experience Points are earned.",id:81,maxRanks:3,name:"Swift Learner",value:0},{description:"The Tag! perk allows you to select a fourth Skill to be a Tag skill, which instantly raises it by 15 points.",id:82,maxRanks:1,name:"Tag!",value:0},{description:"With each rank of the Thief perk, you gain an immediate bonus of 5 points to both the Sneak and Lockpick skills.",id:83,maxRanks:3,name:"Thief",value:0},{description:"With the Toughness perk, you gain +10% to overall Damage Resistance, up to the maximum of 85%. ",id:84,maxRanks:1,name:"Toughness",value:0},{description:"After sleeping in a safe bed, you will wake well rested. You earn 10% more experience points for several hours.",id:85,maxRanks:1,name:"Well Rested",value:0},{description:"Advanced technology from the Commonwealth has increased your reaction speed, giving you a higher chance to hit in V.A.T.S.",id:86,maxRanks:1,name:"Wired Reflexes",value:0},{description:"",id:87,maxRanks:1,name:"",value:0}],L=[{description:"Improves buying and selling prices.",id:1,name:"Barter",value:0},{description:"Accuracy and damage with heavy weapons.",id:2,name:"Big Guns",value:0},{description:"Accuracy and damage with energy weapons.",id:3,name:"Energy Weapons",value:0},{description:"Damage with explosives and ability to disarm traps.",id:4,name:"Explosives",value:0},{description:"Ability to pick locks.",id:5,name:"Lockpick",value:0},{description:"Effectiveness of Stimpaks and healing.",id:6,name:"Medicine",value:0},{description:"Damage with melee weapons.",id:7,name:"Melee Weapons",value:0},{description:"Ability to maintain and repair items.",id:8,name:"Repair",value:0},{description:"Ability to hack terminals and use tech.",id:9,name:"Science",value:0},{description:"Accuracy and damage with small firearms.",id:10,name:"Small Guns",value:0},{description:"Ability to remain undetected.",id:11,name:"Sneak",value:0},{description:"Effectiveness in dialogue and persuasion.",id:12,name:"Speech",value:0},{description:"Damage with fists and unarmed weapons.",id:13,name:"Unarmed",value:0}],D=[{description:"Affects how much you can carry and the damage you do with melee attacks.",id:7,name:"Strength",short:"STR",value:5},{description:"Affects your ability to notice things and your accuracy in VATS.",id:6,name:"Perception",short:"PER",value:5},{description:"Affects your total Health and resistance to physical punishment over time.",id:3,name:"Endurance",short:"END",value:5},{description:"Affects your speech skills and how people react to you in conversation.",id:2,name:"Charisma",short:"CHA",value:5},{description:"Affects how many skill points you gain when leveling up.",id:4,name:"Intelligence",short:"INT",value:5},{description:"Affects your Action Points and your ability to sneak and avoid detection.",id:1,name:"Agility",short:"AGI",value:5},{description:"Affects many things in small ways, and helps you succeed at random chances.",id:5,name:"Luck",short:"LCK",value:5}],E=[{damage:6,health:100,name:".32 Pistol",value:110,weight:2},{damage:9e3,health:1e3,name:".44 Magnum",value:0,weight:3},{damage:9,health:150,name:"10mm Pistol",value:225,weight:3},{damage:9,health:150,name:"10mm Pistol",value:30,weight:2},{damage:100,health:150,name:"10mm Pistol",value:43590,weight:2},{damage:7,health:250,name:"10mm Submachine Gun",value:330,weight:5},{damage:50,health:1200,name:"A3-21's Plasma Rifle",value:2200,weight:8},{damage:40,health:100,name:"Acid Spit",value:80,weight:1},{damage:70,health:100,name:"Acid Spit",value:130,weight:1},{damage:100,health:500,name:"Alien Blaster",value:500,weight:2},{damage:4,health:250,name:"Ant's Sting",value:30,weight:1},{damage:8,health:300,name:"Assault Rifle",value:300,weight:7},{damage:9,health:400,name:"Baseball Bat",value:55,weight:3},{damage:6,health:5,name:"Baseball",value:10,weight:4},{damage:4,health:50,name:"BB Gun",value:36,weight:2},{damage:4,health:1e3,name:"BB Gun",value:36,weight:2},{damage:8,health:100,name:"Black Bart's Bane",value:60,weight:2},{damage:55,health:360,name:"Blackhawk",value:500,weight:4},{damage:5,health:100,name:"",value:20,weight:1},{damage:12,health:150,name:"Board of Education",value:60,weight:4},{damage:1,health:5,name:"Bottlecap Mine",value:75,weight:.5},{damage:6,health:200,name:"Brass Knuckles",value:20,weight:1},{damage:12,health:150,name:"Breaker",value:30,weight:4},{damage:24,health:200,name:"Burnmaster",value:500,weight:15},{damage:10,health:150,name:"Butch's Toothpick",value:50,weight:1},{damage:20,health:100,name:"Buzzsaw",value:250,weight:1},{damage:11,health:400,name:"Chinese Assault Rifle",value:500,weight:7},{damage:11,health:200,name:"Chinese Assault Rifle",value:340,weight:7},{damage:10,health:500,name:"Chinese Officer's Sword",value:75,weight:3},{damage:10,health:500,name:"Chinese Officer's Sword",value:75,weight:3},{damage:4,health:150,name:"Chinese Pistol",value:190,weight:2},{damage:15,health:500,name:"Clover's Cleaver",value:100,weight:3},{damage:13,health:225,name:"Col. Autumn's 10mm Pistol",value:325,weight:3},{damage:10,health:500,name:"Col. Autumn's Laser Pistol",value:420,weight:2},{damage:7,health:450,name:"Combat Knife",value:50,weight:1},{damage:7,health:450,name:"Combat Knife",value:50,weight:1},{damage:55,health:240,name:"Combat Shotgun",value:200,weight:7},{damage:20,health:150,name:"Combat Shotgun",value:90,weight:10},{damage:55,health:150,name:"Combat Shotgun",value:70,weight:10},{damage:13,health:600,name:"Curse Breaker",value:75,weight:3},{damage:6,health:150,name:"Dart Gun",value:500,weight:3},{damage:20,health:600,name:"Deathclaw Gauntlet",value:150,weight:10},{damage:5,health:100,name:"Electrical Zap",value:110,weight:1},{damage:7,health:1500,name:"Eugene",value:1500,weight:18},{damage:13,health:600,name:"Excalibat",value:75,weight:3},{damage:10,health:300,name:"Experimental MIRV",value:2500,weight:30},{damage:10,health:100,name:"Fat Man",value:1e3,weight:30},{damage:32,health:1e3,name:"Fawkes' Super Sledge",value:300,weight:18},{damage:100,health:1e3,name:"Fire Hydrant",value:100,weight:300},{damage:80,health:200,name:"Firelance",value:750,weight:2},{damage:25,health:600,name:"Fisto!",value:100,weight:6},{damage:0,health:2,name:"",value:0,weight:0},{damage:16,health:200,name:"Flamer",value:500,weight:15},{damage:6,health:100,name:"Flamer",value:210,weight:1},{damage:2,health:100,name:"Flamer",value:30,weight:1},{damage:6,health:100,name:"Flamer",value:210,weight:1},{damage:4,health:100,name:"Flamer",value:60,weight:1},{damage:2,health:100,name:"Flamer",value:60,weight:1},{damage:6,health:100,name:"Flamer",value:60,weight:1},{damage:1,health:5,name:"Frag Grenade",value:25,weight:.5},{damage:1,health:5,name:"Frag Mine",value:25,weight:.5},{damage:300,health:5,name:"Frag Mine",value:3900,weight:1},{damage:0,health:100,name:"GasTrap Dummy",value:0,weight:0},{damage:8,health:1500,name:"Gatling Laser",value:2e3,weight:18},{damage:9,health:1500,name:"Gatling Laser",value:611,weight:10},{damage:30,health:100,name:"Hand Laser",value:360,weight:1},{damage:30,health:100,name:"Head Laser",value:100,weight:1},{damage:10,health:500,name:"Highwayman's Friend",value:75,weight:5},{damage:25,health:500,name:"Hunting Rifle",value:150,weight:6},{damage:30,health:800,name:"Jack",value:200,weight:6},{damage:4,health:100,name:"Knife",value:20,weight:1},{damage:12,health:350,name:"Laser Pistol",value:320,weight:3},{damage:12,health:350,name:"Laser Pistol",value:320,weight:3},{damage:9,health:300,name:"Laser Pistol",value:420,weight:2},{damage:23,health:1e3,name:"Laser Rifle",value:1e3,weight:8},{damage:22,health:1e3,name:"Laser Rifle",value:1e3,weight:8},{damage:38,health:100,name:"Laser",value:1310,weight:1},{damage:8,health:50,name:"Laser",value:100,weight:1},{damage:9,health:100,name:"Laser",value:180,weight:1},{damage:10,health:150,name:"Laser",value:290,weight:1},{damage:9,health:150,name:"Law Dog",value:210,weight:2},{damage:9,health:300,name:"Lead Pipe",value:75,weight:3},{damage:1e3,health:100,name:"Liberty Laser",value:9674e3,weight:0},{damage:200,health:100,name:"LibertyPrimeWeapBomb",value:23730,weight:0},{damage:50,health:600,name:"Lincoln's Repeater",value:500,weight:5},{damage:8,health:100,name:"Love Tap",value:20,weight:1},{damage:1,health:100,name:"Mesmetron",value:500,weight:2},{damage:1,health:100,name:"Mesmetron",value:500,weight:2},{damage:5,health:1e3,name:"Minigun",value:1e3,weight:18},{damage:0,health:5,name:"Mirelurk Bait Grenade",value:5,weight:1},{damage:20,health:100,name:"Miss Launcher",value:400,weight:15},{damage:20,health:100,name:"Missile Launcher",value:500,weight:20},{damage:20,health:1e3,name:"Missile Launcher",value:4300,weight:15},{damage:8,health:60,name:"Nail Board",value:30,weight:4},{damage:8,health:60,name:"Nail Board",value:30,weight:4},{damage:1,health:5,name:"Nuka-Grenade",value:50,weight:.5},{damage:10,health:600,name:"Occam's Razor",value:65,weight:1},{damage:6,health:400,name:"O'Grady's Peacemaker",value:100,weight:2},{damage:30,health:500,name:"Ol' Painless",value:250,weight:6},{damage:1,health:5,name:"Plasma Grenade",value:50,weight:.5},{damage:60,health:400,name:"Plasma Gun",value:7200,weight:1},{damage:40,health:400,name:"Plasma Gun",value:7200,weight:1},{damage:1,health:5,name:"Plasma Mine",value:50,weight:.5},{damage:25,health:400,name:"Plasma Pistol",value:360,weight:3},{damage:45,health:900,name:"Plasma Rifle",value:1800,weight:8},{damage:12,health:200,name:"Plunkett's Valid Points",value:30,weight:1},{damage:4,health:250,name:"Police Baton",value:70,weight:2},{damage:3,health:50,name:"Pool Cue",value:15,weight:1},{damage:20,health:500,name:"Power Fist",value:100,weight:6},{damage:24,health:500,name:"Protectron's Gaze",value:320,weight:3},{damage:1,health:5,name:"Pulse Grenade",value:40,weight:.5},{damage:1,health:5,name:"Pulse Mine",value:40,weight:.5},{damage:30,health:1e3,name:"Radioactive Spit",value:130,weight:1},{damage:30,health:200,name:"Railway Rifle",value:200,weight:9},{damage:1,health:100,name:"Repellent Stick",value:120,weight:3},{damage:40,health:150,name:"Reservist's Rifle",value:500,weight:10},{damage:30,health:600,name:"Ripper",value:100,weight:6},{damage:50,health:300,name:"Rock-It Launcher",value:200,weight:8},{damage:20,health:100,name:"Rolling Pin",value:10,weight:2},{damage:3,health:100,name:"Rolling Pin",value:10,weight:1},{damage:20,health:100,name:"",value:500,weight:20},{damage:50,health:250,name:"Sawed-Off Shotgun",value:150,weight:4},{damage:50,health:100,name:"Sawed-Off Shotgun",value:190,weight:5},{damage:35,health:240,name:"Scoped .44 Magnum",value:300,weight:4},{damage:6,health:1e3,name:"SentryBot Laser Gatling",value:1070,weight:15},{damage:9,health:1e3,name:"SentryBot Minigun",value:1070,weight:15},{damage:35,health:750,name:"Shishkebab",value:200,weight:3},{damage:10,health:100,name:"Shriek",value:40,weight:1},{damage:8,health:80,name:"Silenced 10mm Pistol",value:250,weight:3},{damage:50,health:1e3,name:"Slasher Knife",value:50,weight:1},{damage:20,health:500,name:"Sledgehammer",value:130,weight:12},{damage:20,health:500,name:"Sledgehammer",value:130,weight:12},{damage:18,health:500,name:"Smuggler's End",value:450,weight:2},{damage:40,health:100,name:"Sniper Rifle",value:300,weight:10},{damage:9,health:300,name:"Spiked Knuckles",value:25,weight:1},{damage:10,health:600,name:"Stabhappy",value:65,weight:1},{damage:25,health:750,name:"Super Sledge",value:180,weight:20},{damage:25,health:250,name:"Super Sledge",value:130,weight:3},{damage:5,health:100,name:"Switchblade",value:35,weight:1},{damage:5,health:100,name:"Switchblade",value:50,weight:1},{damage:9,health:250,name:'Sydney\'s 10mm "Ultra" SMG',value:430,weight:5},{damage:9,health:250,name:'Sydney\'s 10mm "Ultra" SMG',value:430,weight:5},{damage:6,health:200,name:"The Break",value:50,weight:1},{damage:75,health:250,name:"The Kneecapper",value:350,weight:5},{damage:20,health:400,name:"The Shocker",value:150,weight:6},{damage:30,health:750,name:"The Tenderizer",value:230,weight:12},{damage:80,health:350,name:"The Terrible Shotgun",value:250,weight:10},{damage:6,health:200,name:"Tire Iron",value:40,weight:3},{damage:7,health:150,name:"Turret Gun",value:230,weight:7},{damage:10,health:150,name:"Turret Gun",value:370,weight:7},{damage:5,health:150,name:"Turret Gun",value:140,weight:7},{damage:15,health:750,name:"Vampire's Edge",value:100,weight:1},{damage:11,health:2e3,name:"Vengeance",value:2400,weight:18},{damage:10,health:30,name:"Vertibird Bomb Gun",value:1e3,weight:30},{damage:20,health:3e3,name:"Vertibird Gun",value:6040,weight:10},{damage:40,health:300,name:"Victory Rifle",value:450,weight:10},{damage:12,health:450,name:"Wanda",value:500,weight:7},{damage:28,health:1800,name:"Wazer Wifle",value:900,weight:8},{damage:12,health:400,name:"Xuanlong Assault Rifle",value:400,weight:7},{damage:4,health:200,name:"Zhu-Rong v418 Chinese Pistol",value:290,weight:2}],A="1.2.0",N=new s("PipBoy3000SettingsConfig"),T=e=>e.map(e=>({id:e.id,name:e.name,description:e.description,value:e.value,imageId:e.imageId}));class P{constructor(){this.loadFromLocalStorage(),r(()=>{this.userLevel(),this.userHealth(),this.userHealthMax(),this.userActionPoints(),this.userActionPointsMax(),this.userExperience(),this.userExperienceNextLevel(),this.userName(),this.stimpakLabel(),this.limbLabel(),this.radAwayLabel(),this.radXLabel(),this.equippedWeaponId(),this.equippedApparelId(),this.equippedAidId(),this.equippedMiscId(),this.equippedAmmoId(),this.weaponItems(),this.apparelItems(),this.aidItems(),this.miscItems(),this.ammoItems(),this.specialItems(),this.skillItems(),this.perkItems(),this.questItems(),this.generalItems(),this.notesItems(),this.radioItems(),this.selectedNotesItemId(),this.selectedRadioItemId(),this.effectItems(),this.radMeterLevel(),this.h20MeterLevel(),this.fodMeterLevel(),this.slpMeterLevel(),this.localMapImage(),this.worldMapImage(),this.radioVolume(),this.notesVolume(),this.localMapZoom(),this.worldMapZoom(),this.vaultBoyImages(),this.selectedVaultBoyImageIndex(),this.scanLinesEnabled(),this.editLockEnabled(),this.listFontScale(),this.secondaryTabSoundId(),this.mainTabSoundId(),this.clickSoundId(),this.rememberTabOnRefresh(),this.saveToLocalStorage()})}settingsConfig=l(N,{optional:!0});storageKey=this.settingsConfig?.storageKey??"pipBoy3000Settings";imageStore=l(x);userLevel=o(1,...ngDevMode?[{debugName:"userLevel"}]:[]);userHealth=o(99,...ngDevMode?[{debugName:"userHealth"}]:[]);userHealthMax=o(100,...ngDevMode?[{debugName:"userHealthMax"}]:[]);userActionPoints=o(50,...ngDevMode?[{debugName:"userActionPoints"}]:[]);userActionPointsMax=o(100,...ngDevMode?[{debugName:"userActionPointsMax"}]:[]);userExperience=o(1,...ngDevMode?[{debugName:"userExperience"}]:[]);userExperienceNextLevel=o(100,...ngDevMode?[{debugName:"userExperienceNextLevel"}]:[]);userName=o("Vault Dweller",...ngDevMode?[{debugName:"userName"}]:[]);stimpakLabel=o("(4) Stimpak",...ngDevMode?[{debugName:"stimpakLabel"}]:[]);limbLabel=o("Limbs",...ngDevMode?[{debugName:"limbLabel"}]:[]);radAwayLabel=o("RadAway",...ngDevMode?[{debugName:"radAwayLabel"}]:[]);radXLabel=o("Rad-X",...ngDevMode?[{debugName:"radXLabel"}]:[]);equippedWeaponId=o(null,...ngDevMode?[{debugName:"equippedWeaponId"}]:[]);equippedApparelId=o(null,...ngDevMode?[{debugName:"equippedApparelId"}]:[]);equippedAidId=o(null,...ngDevMode?[{debugName:"equippedAidId"}]:[]);equippedMiscId=o(null,...ngDevMode?[{debugName:"equippedMiscId"}]:[]);equippedAmmoId=o(null,...ngDevMode?[{debugName:"equippedAmmoId"}]:[]);weaponItems=o(this.getWeaponDefaults(),...ngDevMode?[{debugName:"weaponItems"}]:[]);apparelItems=o(this.getApparelDefaults(),...ngDevMode?[{debugName:"apparelItems"}]:[]);aidItems=o(this.getAidDefaults(),...ngDevMode?[{debugName:"aidItems"}]:[]);miscItems=o(this.getMiscDefaults(),...ngDevMode?[{debugName:"miscItems"}]:[]);ammoItems=o(this.getAmmoDefaults(),...ngDevMode?[{debugName:"ammoItems"}]:[]);specialItems=o(T(D),...ngDevMode?[{debugName:"specialItems"}]:[]);skillItems=o(this.getSkillDefaults(),...ngDevMode?[{debugName:"skillItems"}]:[]);perkItems=o(this.getPerkDefaults(),...ngDevMode?[{debugName:"perkItems"}]:[]);generalItems=o([],...ngDevMode?[{debugName:"generalItems"}]:[]);questItems=o([{id:1,name:"Quest item",completed:!1,tasks:[{id:1,name:"Task 1",completed:!1},{id:2,name:"Task 2",completed:!1},{id:3,name:"Task 3",completed:!1}]}],...ngDevMode?[{debugName:"questItems"}]:[]);notesItems=o([],...ngDevMode?[{debugName:"notesItems"}]:[]);radioItems=o([],...ngDevMode?[{debugName:"radioItems"}]:[]);selectedNotesItemId=o(null,...ngDevMode?[{debugName:"selectedNotesItemId"}]:[]);selectedRadioItemId=o(null,...ngDevMode?[{debugName:"selectedRadioItemId"}]:[]);effectItems=o([],...ngDevMode?[{debugName:"effectItems"}]:[]);radMeterLevel=o(0,...ngDevMode?[{debugName:"radMeterLevel"}]:[]);h20MeterLevel=o(0,...ngDevMode?[{debugName:"h20MeterLevel"}]:[]);fodMeterLevel=o(0,...ngDevMode?[{debugName:"fodMeterLevel"}]:[]);slpMeterLevel=o(0,...ngDevMode?[{debugName:"slpMeterLevel"}]:[]);localMapImage=o(null,...ngDevMode?[{debugName:"localMapImage"}]:[]);worldMapImage=o(null,...ngDevMode?[{debugName:"worldMapImage"}]:[]);radioVolume=o(100,...ngDevMode?[{debugName:"radioVolume"}]:[]);notesVolume=o(100,...ngDevMode?[{debugName:"notesVolume"}]:[]);localMapZoom=o(1,...ngDevMode?[{debugName:"localMapZoom"}]:[]);worldMapZoom=o(1,...ngDevMode?[{debugName:"worldMapZoom"}]:[]);vaultBoyImages=o([null,null,null],...ngDevMode?[{debugName:"vaultBoyImages"}]:[]);selectedVaultBoyImageIndex=o(0,...ngDevMode?[{debugName:"selectedVaultBoyImageIndex"}]:[]);scanLinesEnabled=o(!0,...ngDevMode?[{debugName:"scanLinesEnabled"}]:[]);editLockEnabled=o(!1,...ngDevMode?[{debugName:"editLockEnabled"}]:[]);listFontScale=o(1.25,...ngDevMode?[{debugName:"listFontScale"}]:[]);secondaryTabSoundId=o(null,...ngDevMode?[{debugName:"secondaryTabSoundId"}]:[]);mainTabSoundId=o(null,...ngDevMode?[{debugName:"mainTabSoundId"}]:[]);clickSoundId=o(null,...ngDevMode?[{debugName:"clickSoundId"}]:[]);rememberTabOnRefresh=o(!1,...ngDevMode?[{debugName:"rememberTabOnRefresh"}]:[]);playbackResetToken=o(0,...ngDevMode?[{debugName:"playbackResetToken"}]:[]);exportSettingsSnapshot(){return{userLevel:this.userLevel(),userHealth:this.userHealth(),userHealthMax:this.userHealthMax(),userActionPoints:this.userActionPoints(),userActionPointsMax:this.userActionPointsMax(),userExperience:this.userExperience(),userExperienceNextLevel:this.userExperienceNextLevel(),userName:this.userName(),stimpakLabel:this.stimpakLabel(),limbLabel:this.limbLabel(),radAwayLabel:this.radAwayLabel(),radXLabel:this.radXLabel(),equippedWeaponId:this.equippedWeaponId(),equippedApparelId:this.equippedApparelId(),equippedAidId:this.equippedAidId(),equippedMiscId:this.equippedMiscId(),equippedAmmoId:this.equippedAmmoId(),weaponItems:this.weaponItems(),apparelItems:this.apparelItems(),aidItems:this.aidItems(),miscItems:this.miscItems(),ammoItems:this.ammoItems(),specialItems:this.specialItems(),skillItems:this.skillItems(),perkItems:this.perkItems(),questItems:this.questItems(),generalItems:this.generalItems(),notesItems:this.notesItems(),radioItems:this.radioItems(),selectedNotesItemId:this.selectedNotesItemId(),selectedRadioItemId:this.selectedRadioItemId(),effectItems:this.effectItems(),radMeterLevel:this.radMeterLevel(),h20MeterLevel:this.h20MeterLevel(),fodMeterLevel:this.fodMeterLevel(),slpMeterLevel:this.slpMeterLevel(),localMapImage:this.localMapImage(),worldMapImage:this.worldMapImage(),radioVolume:this.radioVolume(),notesVolume:this.notesVolume(),localMapZoom:this.localMapZoom(),worldMapZoom:this.worldMapZoom(),vaultBoyImages:this.vaultBoyImages(),selectedVaultBoyImageIndex:this.selectedVaultBoyImageIndex(),scanLinesEnabled:this.scanLinesEnabled(),editLockEnabled:this.editLockEnabled(),listFontScale:this.listFontScale(),secondaryTabSoundId:this.secondaryTabSoundId(),mainTabSoundId:this.mainTabSoundId(),clickSoundId:this.clickSoundId(),rememberTabOnRefresh:this.rememberTabOnRefresh()}}exportSettingsJson(){return JSON.stringify(this.exportSettingsSnapshot())}importSettingsJson(e){const t=JSON.parse(e);this.importSettingsSnapshot(t)}importSettingsSnapshot(e){if(this.setNumberSignal(this.userLevel,e.userLevel),this.setNumberSignal(this.userHealth,e.userHealth),this.setNumberSignal(this.userHealthMax,e.userHealthMax),this.setNumberSignal(this.userActionPoints,e.userActionPoints),this.setNumberSignal(this.userActionPointsMax,e.userActionPointsMax),this.setNumberSignal(this.userExperience,e.userExperience),this.setNumberSignal(this.userExperienceNextLevel,e.userExperienceNextLevel),"string"==typeof e.userName&&this.userName.set(e.userName),"string"==typeof e.stimpakLabel&&this.stimpakLabel.set(e.stimpakLabel),"string"==typeof e.limbLabel&&this.limbLabel.set(e.limbLabel),"string"==typeof e.radAwayLabel&&this.radAwayLabel.set(e.radAwayLabel),"string"==typeof e.radXLabel&&this.radXLabel.set(e.radXLabel),"number"==typeof e.equippedWeaponId?this.equippedWeaponId.set(e.equippedWeaponId):null===e.equippedWeaponId&&this.equippedWeaponId.set(null),"number"==typeof e.equippedApparelId?this.equippedApparelId.set(e.equippedApparelId):null===e.equippedApparelId&&this.equippedApparelId.set(null),"number"==typeof e.equippedAidId?this.equippedAidId.set(e.equippedAidId):null===e.equippedAidId&&this.equippedAidId.set(null),"number"==typeof e.equippedMiscId?this.equippedMiscId.set(e.equippedMiscId):null===e.equippedMiscId&&this.equippedMiscId.set(null),"number"==typeof e.equippedAmmoId?this.equippedAmmoId.set(e.equippedAmmoId):null===e.equippedAmmoId&&this.equippedAmmoId.set(null),this.weaponItems.set(this.normalizeItems(e.weaponItems)),this.apparelItems.set(this.normalizeItems(e.apparelItems)),this.aidItems.set(this.normalizeItems(e.aidItems)),this.miscItems.set(this.normalizeItems(e.miscItems)),this.ammoItems.set(this.normalizeItems(e.ammoItems)),this.specialItems.set(this.normalizeStatItems(e.specialItems,T(D))),this.skillItems.set(this.normalizeStatItems(e.skillItems,T(L))),this.perkItems.set(this.normalizeStatItems(e.perkItems,T(R))),this.generalItems.set(this.normalizeStatItems(e.generalItems,[])),this.questItems.set(this.normalizeQuestItems(e.questItems)),this.notesItems.set(this.normalizeAudioItems(e.notesItems)),this.radioItems.set(this.normalizeAudioItems(e.radioItems)),"number"==typeof e.selectedNotesItemId?this.selectedNotesItemId.set(e.selectedNotesItemId):null===e.selectedNotesItemId&&this.selectedNotesItemId.set(null),"number"==typeof e.selectedRadioItemId?this.selectedRadioItemId.set(e.selectedRadioItemId):null===e.selectedRadioItemId&&this.selectedRadioItemId.set(null),this.effectItems.set(this.normalizeEffectItems(e.effectItems)),"number"==typeof e.radMeterLevel&&this.setUnitSignal(this.radMeterLevel,e.radMeterLevel),"number"==typeof e.h20MeterLevel&&this.setUnitSignal(this.h20MeterLevel,e.h20MeterLevel),"number"==typeof e.fodMeterLevel&&this.setUnitSignal(this.fodMeterLevel,e.fodMeterLevel),"number"==typeof e.slpMeterLevel&&this.setUnitSignal(this.slpMeterLevel,e.slpMeterLevel),"string"==typeof e.localMapImage?this.localMapImage.set(this.normalizeImageId(e.localMapImage)??null):null===e.localMapImage&&this.localMapImage.set(null),"string"==typeof e.worldMapImage?this.worldMapImage.set(this.normalizeImageId(e.worldMapImage)??null):null===e.worldMapImage&&this.worldMapImage.set(null),"number"==typeof e.radioVolume&&this.setVolumeSignal(this.radioVolume,e.radioVolume),"number"==typeof e.notesVolume&&this.setVolumeSignal(this.notesVolume,e.notesVolume),"number"==typeof e.localMapZoom&&this.setZoomSignal(this.localMapZoom,e.localMapZoom),"number"==typeof e.worldMapZoom&&this.setZoomSignal(this.worldMapZoom,e.worldMapZoom),Array.isArray(e.vaultBoyImages)){const t=this.normalizeImageSlots(e.vaultBoyImages);if(this.vaultBoyImages.set(t),"number"==typeof e.selectedVaultBoyImageIndex&&Number.isFinite(e.selectedVaultBoyImageIndex)){const n=Math.min(Math.max(0,e.selectedVaultBoyImageIndex),Math.max(0,t.length-1));this.selectedVaultBoyImageIndex.set(n)}}if("boolean"==typeof e.scanLinesEnabled&&this.scanLinesEnabled.set(e.scanLinesEnabled),"boolean"==typeof e.editLockEnabled&&this.editLockEnabled.set(e.editLockEnabled),"number"==typeof e.listFontScale){const t=Math.min(1.875,Math.max(.625,e.listFontScale));Number.isFinite(t)&&this.listFontScale.set(t)}"string"==typeof e.secondaryTabSoundId?this.secondaryTabSoundId.set(e.secondaryTabSoundId):null===e.secondaryTabSoundId&&this.secondaryTabSoundId.set(null),"string"==typeof e.mainTabSoundId?this.mainTabSoundId.set(e.mainTabSoundId):null===e.mainTabSoundId&&this.mainTabSoundId.set(null),"string"==typeof e.clickSoundId?this.clickSoundId.set(e.clickSoundId):null===e.clickSoundId&&this.clickSoundId.set(null),"boolean"==typeof e.rememberTabOnRefresh&&this.rememberTabOnRefresh.set(e.rememberTabOnRefresh),this.playbackResetToken.update(e=>e+1)}saveToLocalStorage(e){if("undefined"==typeof localStorage)return;const t=e??this.storageKey;localStorage.setItem(t,this.exportSettingsJson())}loadFromLocalStorage(e){if("undefined"==typeof localStorage)return;const t=e??this.storageKey,n=localStorage.getItem(t);n&&this.importSettingsJson(n)}resetToDefaults(){this.userLevel.set(1),this.userHealth.set(99),this.userHealthMax.set(100),this.userActionPoints.set(50),this.userActionPointsMax.set(100),this.userExperience.set(1),this.userExperienceNextLevel.set(100),this.userName.set("Vault Dweller"),this.stimpakLabel.set("(4) Stimpak"),this.limbLabel.set("Limbs"),this.radAwayLabel.set("RadAway"),this.radXLabel.set("Rad-X"),this.equippedWeaponId.set(null),this.equippedApparelId.set(null),this.equippedAidId.set(null),this.equippedMiscId.set(null),this.equippedAmmoId.set(null),this.weaponItems.set(this.getWeaponDefaults()),this.apparelItems.set(this.getApparelDefaults()),this.aidItems.set(this.getAidDefaults()),this.miscItems.set(this.getMiscDefaults()),this.ammoItems.set(this.getAmmoDefaults()),this.specialItems.set(T(D)),this.skillItems.set(this.getSkillDefaults()),this.perkItems.set(this.getPerkDefaults()),this.generalItems.set([]),this.questItems.set([{id:1,name:"Quest item",completed:!1,tasks:[{id:1,name:"Task 1",completed:!1},{id:2,name:"Task 2",completed:!1},{id:3,name:"Task 3",completed:!1}]}]),this.notesItems.set([]),this.radioItems.set([]),this.selectedNotesItemId.set(null),this.selectedRadioItemId.set(null),this.effectItems.set([]),this.radMeterLevel.set(0),this.h20MeterLevel.set(0),this.fodMeterLevel.set(0),this.slpMeterLevel.set(0),this.localMapImage.set(null),this.worldMapImage.set(null),this.radioVolume.set(100),this.notesVolume.set(100),this.localMapZoom.set(1),this.worldMapZoom.set(1),this.vaultBoyImages.set([null,null,null]),this.selectedVaultBoyImageIndex.set(0),this.scanLinesEnabled.set(!0),this.editLockEnabled.set(!1),this.listFontScale.set(1.25),this.secondaryTabSoundId.set(null),this.mainTabSoundId.set(null),this.clickSoundId.set(null),this.rememberTabOnRefresh.set(!1),this.playbackResetToken.update(e=>e+1)}getSkillDefaults(){const e=this.settingsConfig?.skillDefaults??L;return T(e)}getPerkDefaults(){const e=this.settingsConfig?.perkDefaults??R;return T(e)}getWeaponDefaults(){return(this.settingsConfig?.weaponDefaults??[]).map(e=>({...e}))}getApparelDefaults(){return(this.settingsConfig?.apparelDefaults??[]).map(e=>({...e}))}getAidDefaults(){return(this.settingsConfig?.aidDefaults??[]).map(e=>({...e}))}getMiscDefaults(){return(this.settingsConfig?.miscDefaults??[]).map(e=>({...e}))}getAmmoDefaults(){return(this.settingsConfig?.ammoDefaults??[]).map(e=>({...e}))}setNumberSignal(e,t){"number"==typeof t&&Number.isFinite(t)&&e.set(t)}setZoomSignal(e,t){if(!Number.isFinite(t))return;const n=Math.min(3,Math.max(.5,t));e.set(Number(n.toFixed(2)))}setVolumeSignal(e,t){if(!Number.isFinite(t))return;const n=Math.min(100,Math.max(0,t));e.set(Number(n.toFixed(0)))}setUnitSignal(e,t){if(!Number.isFinite(t))return;const n=Math.min(1,Math.max(0,t));e.set(Number(n.toFixed(2)))}normalizeItems(e){return Array.isArray(e)?e.filter(e=>!!e&&"number"==typeof e.id&&"string"==typeof e.name).map(e=>({id:e.id,name:e.name,damage:"number"==typeof e.damage&&Number.isFinite(e.damage)?e.damage:void 0,imageId:this.normalizeImageId(e.imageId??e.image),effects:"string"==typeof e.effects?e.effects:void 0,quantity:"number"==typeof e.quantity&&Number.isFinite(e.quantity)?e.quantity:void 0,value:"number"==typeof e.value&&Number.isFinite(e.value)?e.value:void 0,weight:"number"==typeof e.weight&&Number.isFinite(e.weight)?e.weight:void 0})):[]}normalizeStatItems(e,t){return Array.isArray(e)?e.filter(e=>!!e&&"number"==typeof e.id&&"string"==typeof e.name&&"string"==typeof e.description&&"number"==typeof e.value&&Number.isFinite(e.value)).map(e=>({id:e.id,name:e.name,description:e.description,value:e.value,imageId:this.normalizeImageId(e.imageId??e.image)})):t}normalizeAudioItems(e){return Array.isArray(e)?e.filter(e=>!!e&&"number"==typeof e.id&&"string"==typeof e.name&&"string"==typeof e.soundId).map(e=>({id:e.id,name:e.name,soundId:e.soundId})):[]}normalizeEffectItems(e){return Array.isArray(e)?e.filter(e=>!!e&&"number"==typeof e.id&&"string"==typeof e.name&&"string"==typeof e.description).map(e=>({id:e.id,name:e.name,description:e.description})):[]}normalizeQuestItems(e){return Array.isArray(e)?e.filter(e=>!!e&&"number"==typeof e.id&&"string"==typeof e.name&&"boolean"==typeof e.completed&&Array.isArray(e.tasks)).map(e=>({id:e.id,name:e.name,completed:e.completed,tasks:e.tasks.filter(e=>!!e&&"number"==typeof e.id&&"string"==typeof e.name&&"boolean"==typeof e.completed).map(e=>({id:e.id,name:e.name,completed:e.completed}))})):[]}normalizeImageSlots(e){if(!Array.isArray(e))return[];return e.map(e=>"string"!=typeof e?null:this.normalizeImageId(e)??null).slice(0,10)}normalizeImageId(e){if("string"==typeof e){if(e.startsWith("data:")){const t=this.imageStore.generateId();return this.imageStore.saveDataUrlWithId(t,e),t}return e}}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:P,deps:[],target:e.ɵɵFactoryTarget.Injectable});static"ɵprov"=e.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:P,providedIn:"root"})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:P,decorators:[{type:i,args:[{providedIn:"root"}]}],ctorParameters:()=>[]});const C="pipBoy3000TabState",z=["STATS","ITEMS","DATA"],O=["STATUS","S.P.E.C.I.A.L.","SKILLS","PERKS","GENERAL"],F=["WEAPONS","APPAREL","AID","MISC","AMMO"],V=["LOCAL MAP","WORLD MAP","QUESTS","NOTES","RADIO"],q=["CND","RAD","EFF","H20","FOD","SLP"];class W{constructor(){this.loadFromStorage(),r(()=>{this.primary(),this.secondary(),this.tertiary(),this.saveToStorage()})}primary=o("STATS",...ngDevMode?[{debugName:"primary"}]:[]);secondary=o("STATUS",...ngDevMode?[{debugName:"secondary"}]:[]);tertiary=o("CND",...ngDevMode?[{debugName:"tertiary"}]:[]);settings=l(P);selectPrimary(e){if(this.primary()!==e)switch(this.primary.set(e),e){case"STATS":this.secondary.set("STATUS"),this.tertiary.set("CND");break;case"ITEMS":this.secondary.set("WEAPONS"),this.tertiary.set(null);break;case"DATA":this.secondary.set("LOCAL MAP"),this.tertiary.set(null);break;default:throw new Error(`Unhandled primary tab selection: ${e}`)}}selectSecondary(e){this.secondary.set(e),"STATS"!==this.primary()||"STATUS"!==e?this.tertiary.set(null):null===this.tertiary()&&this.tertiary.set("CND")}selectTertiary(e){"STATS"===this.primary()&&"STATUS"===this.secondary()&&this.tertiary.set(e)}saveToStorage(){if("undefined"==typeof localStorage)return;if(!this.settings.rememberTabOnRefresh())return;const e={primary:this.primary(),secondary:this.secondary(),tertiary:this.tertiary()};localStorage.setItem(C,JSON.stringify(e))}loadFromStorage(){if("undefined"==typeof localStorage)return;if(!this.settings.rememberTabOnRefresh())return;const e=localStorage.getItem(C);if(e)try{const t=JSON.parse(e),n=t.primary&&z.includes(t.primary)?t.primary:"STATS";let a=null;a="STATS"===n?O.includes(t.secondary)?t.secondary:"STATUS":"ITEMS"===n?F.includes(t.secondary)?t.secondary:"WEAPONS":V.includes(t.secondary)?t.secondary:"LOCAL MAP";let o=null;"STATS"===n&&"STATUS"===a&&(o=q.includes(t.tertiary)?t.tertiary:"CND"),this.primary.set(n),this.secondary.set(a),this.tertiary.set(o)}catch{return}}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:W,deps:[],target:e.ɵɵFactoryTarget.Injectable});static"ɵprov"=e.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:W})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:W,decorators:[{type:i}],ctorParameters:()=>[]});class B{static nextId=0;dialogId="pip-boy-dialog-"+B.nextId++;open=t(!1,...ngDevMode?[{debugName:"open"}]:[]);title=t("Dialog",...ngDevMode?[{debugName:"title"}]:[]);subtitle=t(null,...ngDevMode?[{debugName:"subtitle"}]:[]);maxWidth=t("36rem",...ngDevMode?[{debugName:"maxWidth"}]:[]);width=t("92vw",...ngDevMode?[{debugName:"width"}]:[]);zIndex=t(110,...ngDevMode?[{debugName:"zIndex"}]:[]);closeOnBackdrop=t(!1,...ngDevMode?[{debugName:"closeOnBackdrop"}]:[]);closeResult=d();get titleId(){return`${this.dialogId}-title`}closeDialog(){this.closeResult.emit()}handleBackdropClick(){this.closeOnBackdrop()&&this.closeDialog()}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:B,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:B,isStandalone:!0,selector:"pip-boy-dialog",inputs:{open:{classPropertyName:"open",publicName:"open",isSignal:!0,isRequired:!1,transformFunction:null},title:{classPropertyName:"title",publicName:"title",isSignal:!0,isRequired:!1,transformFunction:null},subtitle:{classPropertyName:"subtitle",publicName:"subtitle",isSignal:!0,isRequired:!1,transformFunction:null},maxWidth:{classPropertyName:"maxWidth",publicName:"maxWidth",isSignal:!0,isRequired:!1,transformFunction:null},width:{classPropertyName:"width",publicName:"width",isSignal:!0,isRequired:!1,transformFunction:null},zIndex:{classPropertyName:"zIndex",publicName:"zIndex",isSignal:!0,isRequired:!1,transformFunction:null},closeOnBackdrop:{classPropertyName:"closeOnBackdrop",publicName:"closeOnBackdrop",isSignal:!0,isRequired:!1,transformFunction:null}},outputs:{closeResult:"closeResult"},ngImport:e,template:'@if (open()) {\n <div\n class="dialog-backdrop"\n [style.--dialog-z]="zIndex()"\n (click)="handleBackdropClick()"\n (keydown.escape)="closeDialog()"\n role="presentation"\n >\n <div\n class="dialog"\n role="dialog"\n aria-modal="true"\n [attr.aria-labelledby]="titleId"\n [style.--dialog-max-width]="maxWidth()"\n [style.--dialog-width]="width()"\n (click)="$event.stopPropagation()"\n (keydown.escape)="closeDialog()"\n tabindex="-1"\n >\n <header class="dialog__header">\n <div class="dialog__title-row">\n <div class="dialog__title" [id]="titleId">{{ title() }}</div>\n <ng-content select="[dialog-title-extra]"></ng-content>\n </div>\n @if (subtitle()) {\n <div class="dialog__subtitle">{{ subtitle() }}</div>\n }\n <ng-content select="[dialog-header]"></ng-content>\n </header>\n\n <div class="dialog__body">\n <ng-content></ng-content>\n </div>\n\n <footer class="dialog__actions">\n <ng-content select="[dialog-actions]"></ng-content>\n </footer>\n </div>\n </div>\n}\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{font-size:1rem}.dialog-backdrop{align-items:center;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);background:#0000009e;display:flex;inset:0;justify-content:center;padding:1rem;position:fixed;z-index:var(--dialog-z, 110)}.dialog{display:flex;flex-direction:column;overflow:hidden;margin:1rem;max-height:calc(100vh - 2rem);max-height:calc(100svh - 2rem);max-width:var(--dialog-max-width, 36rem);width:min(var(--dialog-width, 92vw),var(--dialog-max-width, 36rem));background:#062114f5;border:1px solid rgba(15,187,107,.42);border-radius:.9rem;box-shadow:0 0 34px #000000a6;color:#0fbb6b}.dialog:focus{outline:none}.dialog__header{padding:1.1rem 1.25rem .95rem;border-bottom:1px solid rgba(15,187,107,.18);background:linear-gradient(to bottom,#0fbb6b0f,#0fbb6b00)}.dialog__title-row{display:flex;align-items:baseline;gap:.5rem}.dialog__title{font-size:clamp(1.05rem,1.05rem + (1.3rem - 1.05rem) * (100vw - 360px) / (1200px - 360px),1.3rem);letter-spacing:.1em;text-transform:uppercase}.dialog__subtitle{margin-top:.35rem;color:#0fbb6bbf;font-size:clamp(.85rem,.85rem + (.95rem - .85rem) * (100vw - 360px) / (1200px - 360px),.95rem)}.dialog__body{flex:1 1 auto;min-height:0;overflow-y:auto;padding:1rem 1.25rem 0;margin-bottom:1rem;-webkit-overflow-scrolling:touch}.dialog__actions{display:flex;justify-content:flex-end;padding:.9rem 1.25rem 1.1rem;border-top:1px solid rgba(15,187,107,.12);background:#0000001f}:host ::ng-deep .dialog__actions [dialog-actions]{display:flex;justify-content:flex-end;gap:.5rem;width:100%}:host ::ng-deep .dialog__actions button{background:#0fbb6b0f;border:1px solid rgba(15,187,107,.5);border-radius:.6rem;color:#0fbb6b;cursor:pointer;padding:.55rem 1rem;text-transform:uppercase;letter-spacing:.08em}:host ::ng-deep .dialog__actions button:hover{border-color:#0fbb6b;background:#0fbb6b1f}\n"]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:B,decorators:[{type:a,args:[{selector:"pip-boy-dialog",standalone:!0,template:'@if (open()) {\n <div\n class="dialog-backdrop"\n [style.--dialog-z]="zIndex()"\n (click)="handleBackdropClick()"\n (keydown.escape)="closeDialog()"\n role="presentation"\n >\n <div\n class="dialog"\n role="dialog"\n aria-modal="true"\n [attr.aria-labelledby]="titleId"\n [style.--dialog-max-width]="maxWidth()"\n [style.--dialog-width]="width()"\n (click)="$event.stopPropagation()"\n (keydown.escape)="closeDialog()"\n tabindex="-1"\n >\n <header class="dialog__header">\n <div class="dialog__title-row">\n <div class="dialog__title" [id]="titleId">{{ title() }}</div>\n <ng-content select="[dialog-title-extra]"></ng-content>\n </div>\n @if (subtitle()) {\n <div class="dialog__subtitle">{{ subtitle() }}</div>\n }\n <ng-content select="[dialog-header]"></ng-content>\n </header>\n\n <div class="dialog__body">\n <ng-content></ng-content>\n </div>\n\n <footer class="dialog__actions">\n <ng-content select="[dialog-actions]"></ng-content>\n </footer>\n </div>\n </div>\n}\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{font-size:1rem}.dialog-backdrop{align-items:center;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);background:#0000009e;display:flex;inset:0;justify-content:center;padding:1rem;position:fixed;z-index:var(--dialog-z, 110)}.dialog{display:flex;flex-direction:column;overflow:hidden;margin:1rem;max-height:calc(100vh - 2rem);max-height:calc(100svh - 2rem);max-width:var(--dialog-max-width, 36rem);width:min(var(--dialog-width, 92vw),var(--dialog-max-width, 36rem));background:#062114f5;border:1px solid rgba(15,187,107,.42);border-radius:.9rem;box-shadow:0 0 34px #000000a6;color:#0fbb6b}.dialog:focus{outline:none}.dialog__header{padding:1.1rem 1.25rem .95rem;border-bottom:1px solid rgba(15,187,107,.18);background:linear-gradient(to bottom,#0fbb6b0f,#0fbb6b00)}.dialog__title-row{display:flex;align-items:baseline;gap:.5rem}.dialog__title{font-size:clamp(1.05rem,1.05rem + (1.3rem - 1.05rem) * (100vw - 360px) / (1200px - 360px),1.3rem);letter-spacing:.1em;text-transform:uppercase}.dialog__subtitle{margin-top:.35rem;color:#0fbb6bbf;font-size:clamp(.85rem,.85rem + (.95rem - .85rem) * (100vw - 360px) / (1200px - 360px),.95rem)}.dialog__body{flex:1 1 auto;min-height:0;overflow-y:auto;padding:1rem 1.25rem 0;margin-bottom:1rem;-webkit-overflow-scrolling:touch}.dialog__actions{display:flex;justify-content:flex-end;padding:.9rem 1.25rem 1.1rem;border-top:1px solid rgba(15,187,107,.12);background:#0000001f}:host ::ng-deep .dialog__actions [dialog-actions]{display:flex;justify-content:flex-end;gap:.5rem;width:100%}:host ::ng-deep .dialog__actions button{background:#0fbb6b0f;border:1px solid rgba(15,187,107,.5);border-radius:.6rem;color:#0fbb6b;cursor:pointer;padding:.55rem 1rem;text-transform:uppercase;letter-spacing:.08em}:host ::ng-deep .dialog__actions button:hover{border-color:#0fbb6b;background:#0fbb6b1f}\n"]}]}],propDecorators:{open:[{type:e.Input,args:[{isSignal:!0,alias:"open",required:!1}]}],title:[{type:e.Input,args:[{isSignal:!0,alias:"title",required:!1}]}],subtitle:[{type:e.Input,args:[{isSignal:!0,alias:"subtitle",required:!1}]}],maxWidth:[{type:e.Input,args:[{isSignal:!0,alias:"maxWidth",required:!1}]}],width:[{type:e.Input,args:[{isSignal:!0,alias:"width",required:!1}]}],zIndex:[{type:e.Input,args:[{isSignal:!0,alias:"zIndex",required:!1}]}],closeOnBackdrop:[{type:e.Input,args:[{isSignal:!0,alias:"closeOnBackdrop",required:!1}]}],closeResult:[{type:e.Output,args:["closeResult"]}]}});class U{static nextId=0;open=!1;title="";name="";nameLabel="Name";showName=!1;nameOptions=[];imageUrl=null;showImage=!1;fields=[];textFields=[];closeResult=new c;save=new c;nameChange=new c;values=o({},...ngDevMode?[{debugName:"values"}]:[]);draftName=o("",...ngDevMode?[{debugName:"draftName"}]:[]);draftImageUrl=o(null,...ngDevMode?[{debugName:"draftImageUrl"}]:[]);draftImageName=o(null,...ngDevMode?[{debugName:"draftImageName"}]:[]);draftImageFile=o(null,...ngDevMode?[{debugName:"draftImageFile"}]:[]);removedImage=o(!1,...ngDevMode?[{debugName:"removedImage"}]:[]);textValues=o({},...ngDevMode?[{debugName:"textValues"}]:[]);nameListId="stat-edit-name-"+U.nextId++;previewUrl=null;ngOnChanges(){if(this.open){this.draftName.set(this.name),this.draftImageUrl.set(this.imageUrl),this.draftImageName.set(null),this.draftImageFile.set(null),this.removedImage.set(!1),this.clearPreviewUrl();const e={};for(const t of this.fields)e[t.key]=t.value;this.values.set(e);const t={};for(const e of this.textFields)t[e.key]=e.value;this.textValues.set(t)}}closeModal(){this.clearPreviewUrl(),this.closeResult.emit()}updateName(e){this.draftName.set(e),this.nameChange.emit(e)}onImageSelected(e){const t=e.target,n=t.files?.[0]??null;this.draftImageName.set(n?n.name:null),n&&(this.removedImage.set(!1),this.draftImageFile.set(n),this.setPreviewUrl(URL.createObjectURL(n)),t.value="")}removeImage(){this.draftImageName.set(null),this.draftImageUrl.set(null),this.draftImageFile.set(null),this.removedImage.set(!0),this.clearPreviewUrl()}updateText(e,t){this.textValues.update(n=>({...n,[e]:t}))}onInput(e,t){const n=Number(t);this.values.update(t=>({...t,[e]:n}))}adjustFieldValue(e,t){const n=Number(this.values()[e]),a=Number.isFinite(n)?n+t:t;this.values.update(t=>({...t,[e]:a}))}submit(e){e?.preventDefault(),this.save.emit({name:this.draftName(),values:this.values(),imageFile:this.draftImageFile(),removeImage:this.removedImage(),textValues:this.textValues()}),this.clearPreviewUrl()}setPreviewUrl(e){this.clearPreviewUrl(),this.previewUrl=e,this.draftImageUrl.set(e)}clearPreviewUrl(){this.previewUrl&&(URL.revokeObjectURL(this.previewUrl),this.previewUrl=null)}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:U,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:U,isStandalone:!0,selector:"pip-boy-stat-edit-modal",inputs:{open:"open",title:"title",name:"name",nameLabel:"nameLabel",showName:"showName",nameOptions:"nameOptions",imageUrl:"imageUrl",showImage:"showImage",fields:"fields",textFields:"textFields"},outputs:{closeResult:"closeResult",save:"save",nameChange:"nameChange"},usesOnChanges:!0,ngImport:e,template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <form id="stat-edit-form" (submit)="submit($event)">\n <div class="stat-modal-body">\n @if (showName) {\n <label class="stat-modal-field">\n <span>{{ nameLabel }}</span>\n <input\n type="text"\n name="stat-name"\n [attr.list]="nameOptions.length ? nameListId : null"\n [value]="draftName()"\n (input)="updateName($any($event.target).value)"\n />\n </label>\n @if (nameOptions.length) {\n <datalist [id]="nameListId">\n @for (name of nameOptions; track name) {\n <option [value]="name"></option>\n }\n </datalist>\n }\n }\n @for (field of fields; track field.key) {\n <label class="stat-modal-field">\n <span>{{ field.label }}</span>\n <div class="number-input-row">\n <input\n type="number"\n inputmode="numeric"\n [attr.name]="\'stat-field-\' + field.key"\n [value]="values()[field.key]"\n (input)="onInput(field.key, $any($event.target).value)"\n />\n <div class="number-input-controls">\n <button\n type="button"\n class="number-input-control"\n aria-label="Increase value"\n (click)="adjustFieldValue(field.key, 1)"\n >\n &#8593;\n </button>\n <button\n type="button"\n class="number-input-control"\n aria-label="Decrease value"\n (click)="adjustFieldValue(field.key, -1)"\n >\n &#8595;\n </button>\n </div>\n </div>\n </label>\n }\n @for (field of textFields; track field.key) {\n <label class="stat-modal-field" [attr.for]="\'text-field-\' + field.key">\n <span>{{ field.label }}</span>\n @if (field.multiline) {\n <textarea\n [id]="\'text-field-\' + field.key"\n [attr.name]="\'text-field-\' + field.key"\n rows="4"\n [value]="textValues()[field.key]"\n (input)="updateText(field.key, $any($event.target).value)"\n ></textarea>\n } @else {\n <input\n [id]="\'text-field-\' + field.key"\n type="text"\n [attr.name]="\'text-field-\' + field.key"\n [value]="textValues()[field.key]"\n (input)="updateText(field.key, $any($event.target).value)"\n />\n }\n </label>\n }\n @if (showImage) {\n <div class="stat-modal-image">\n <button\n type="button"\n class="stat-modal-image-button"\n (click)="modalImageInput.click()"\n >\n {{ draftImageName() ? draftImageName() : \'Select Image\' }}\n </button>\n @if (draftImageUrl()) {\n <button\n type="button"\n class="stat-modal-image-remove"\n (click)="removeImage()"\n >\n Remove Image\n </button>\n }\n <input\n #modalImageInput\n type="file"\n accept="image/*"\n (change)="onImageSelected($event)"\n />\n @if (draftImageUrl()) {\n <img [src]="draftImageUrl()" alt="Item preview" />\n }\n </div>\n }\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="stat-edit-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.stat-modal-body{display:flex;flex-direction:column;gap:1rem}.stat-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.stat-modal-field input,.stat-modal-field textarea{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.stat-modal-field input:focus,.stat-modal-field textarea:focus{outline:none;border-color:#0fbb6b}.stat-modal-field input{height:2.5rem}.stat-modal-field textarea{min-height:6rem;resize:vertical;text-transform:none}.number-input-row{display:flex;align-items:stretch;gap:.5rem}.number-input-row input[type=number]{flex:1 1 auto;-moz-appearance:textfield}.number-input-row input[type=number]::-webkit-outer-spin-button,.number-input-row input[type=number]::-webkit-inner-spin-button{appearance:none;margin:0}.number-input-controls{display:flex;flex-direction:column;gap:.35rem}.number-input-control{flex:1 1 auto;background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.4rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);padding:.2rem .5rem;text-transform:uppercase}.number-input-control:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-modal-image{display:flex;flex-direction:column;gap:.75rem}.stat-modal-image input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.stat-modal-image img{border:1px solid rgba(15,187,107,.35);max-height:8rem;object-fit:contain;padding:.5rem}.stat-modal-image-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.stat-modal-image-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-modal-image-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.stat-modal-image-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"],dependencies:[{kind:"ngmodule",type:f},{kind:"component",type:B,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:U,decorators:[{type:a,args:[{selector:"pip-boy-stat-edit-modal",standalone:!0,imports:[f,B],template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <form id="stat-edit-form" (submit)="submit($event)">\n <div class="stat-modal-body">\n @if (showName) {\n <label class="stat-modal-field">\n <span>{{ nameLabel }}</span>\n <input\n type="text"\n name="stat-name"\n [attr.list]="nameOptions.length ? nameListId : null"\n [value]="draftName()"\n (input)="updateName($any($event.target).value)"\n />\n </label>\n @if (nameOptions.length) {\n <datalist [id]="nameListId">\n @for (name of nameOptions; track name) {\n <option [value]="name"></option>\n }\n </datalist>\n }\n }\n @for (field of fields; track field.key) {\n <label class="stat-modal-field">\n <span>{{ field.label }}</span>\n <div class="number-input-row">\n <input\n type="number"\n inputmode="numeric"\n [attr.name]="\'stat-field-\' + field.key"\n [value]="values()[field.key]"\n (input)="onInput(field.key, $any($event.target).value)"\n />\n <div class="number-input-controls">\n <button\n type="button"\n class="number-input-control"\n aria-label="Increase value"\n (click)="adjustFieldValue(field.key, 1)"\n >\n &#8593;\n </button>\n <button\n type="button"\n class="number-input-control"\n aria-label="Decrease value"\n (click)="adjustFieldValue(field.key, -1)"\n >\n &#8595;\n </button>\n </div>\n </div>\n </label>\n }\n @for (field of textFields; track field.key) {\n <label class="stat-modal-field" [attr.for]="\'text-field-\' + field.key">\n <span>{{ field.label }}</span>\n @if (field.multiline) {\n <textarea\n [id]="\'text-field-\' + field.key"\n [attr.name]="\'text-field-\' + field.key"\n rows="4"\n [value]="textValues()[field.key]"\n (input)="updateText(field.key, $any($event.target).value)"\n ></textarea>\n } @else {\n <input\n [id]="\'text-field-\' + field.key"\n type="text"\n [attr.name]="\'text-field-\' + field.key"\n [value]="textValues()[field.key]"\n (input)="updateText(field.key, $any($event.target).value)"\n />\n }\n </label>\n }\n @if (showImage) {\n <div class="stat-modal-image">\n <button\n type="button"\n class="stat-modal-image-button"\n (click)="modalImageInput.click()"\n >\n {{ draftImageName() ? draftImageName() : \'Select Image\' }}\n </button>\n @if (draftImageUrl()) {\n <button\n type="button"\n class="stat-modal-image-remove"\n (click)="removeImage()"\n >\n Remove Image\n </button>\n }\n <input\n #modalImageInput\n type="file"\n accept="image/*"\n (change)="onImageSelected($event)"\n />\n @if (draftImageUrl()) {\n <img [src]="draftImageUrl()" alt="Item preview" />\n }\n </div>\n }\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="stat-edit-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.stat-modal-body{display:flex;flex-direction:column;gap:1rem}.stat-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.stat-modal-field input,.stat-modal-field textarea{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.stat-modal-field input:focus,.stat-modal-field textarea:focus{outline:none;border-color:#0fbb6b}.stat-modal-field input{height:2.5rem}.stat-modal-field textarea{min-height:6rem;resize:vertical;text-transform:none}.number-input-row{display:flex;align-items:stretch;gap:.5rem}.number-input-row input[type=number]{flex:1 1 auto;-moz-appearance:textfield}.number-input-row input[type=number]::-webkit-outer-spin-button,.number-input-row input[type=number]::-webkit-inner-spin-button{appearance:none;margin:0}.number-input-controls{display:flex;flex-direction:column;gap:.35rem}.number-input-control{flex:1 1 auto;background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.4rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);padding:.2rem .5rem;text-transform:uppercase}.number-input-control:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-modal-image{display:flex;flex-direction:column;gap:.75rem}.stat-modal-image input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.stat-modal-image img{border:1px solid rgba(15,187,107,.35);max-height:8rem;object-fit:contain;padding:.5rem}.stat-modal-image-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.stat-modal-image-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-modal-image-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.stat-modal-image-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"]}]}],propDecorators:{open:[{type:p}],title:[{type:p}],name:[{type:p}],nameLabel:[{type:p}],showName:[{type:p}],nameOptions:[{type:p}],imageUrl:[{type:p}],showImage:[{type:p}],fields:[{type:p}],textFields:[{type:p}],closeResult:[{type:m}],save:[{type:m}],nameChange:[{type:m}]}});class H{state=l(W);settings=l(P);statModal=o(null,...ngDevMode?[{debugName:"statModal"}]:[]);statModalTitle=u(()=>{switch(this.statModal()){case"LVL":return"Edit Level";case"HP":return"Edit Health";case"AP":return"Edit Action Points";case"XP":return"Edit Experience";default:return""}},...ngDevMode?[{debugName:"statModalTitle"}]:[]);statModalFields=u(()=>{switch(this.statModal()){case"LVL":return[{key:"level",label:"Level",value:this.settings.userLevel()}];case"HP":return[{key:"current",label:"Current",value:this.settings.userHealth()},{key:"max",label:"Max",value:this.settings.userHealthMax()}];case"AP":return[{key:"current",label:"Current",value:this.settings.userActionPoints()},{key:"max",label:"Max",value:this.settings.userActionPointsMax()}];case"XP":return[{key:"current",label:"Current",value:this.settings.userExperience()},{key:"max",label:"Next Level",value:this.settings.userExperienceNextLevel()}];default:return[]}},...ngDevMode?[{debugName:"statModalFields"}]:[]);openStatModal(e){this.statModal.set(e)}closeStatModal(){this.statModal.set(null)}saveStatModal(e){const t=this.statModal();if(t){if("LVL"===t){const t=e.values.level;return Number.isFinite(t)&&this.settings.userLevel.set(t),void this.closeStatModal()}"HP"===t?this.applyPair(e.values,this.settings.userHealth,this.settings.userHealthMax):"AP"===t?this.applyPair(e.values,this.settings.userActionPoints,this.settings.userActionPointsMax):"XP"===t&&this.applyPair(e.values,this.settings.userExperience,this.settings.userExperienceNextLevel),this.closeStatModal()}}applyPair(e,t,n){Number.isFinite(e.current)&&t.set(e.current),Number.isFinite(e.max)&&n.set(e.max)}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:H,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:H,isStandalone:!0,selector:"pip-boy-3000-header",ngImport:e,template:'<header>\n <div class="header-top">\n <div class="main-title">\n <div class="main-title-left-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n <div class="main-title-text">\n @if (state.primary() === \'STATS\') {\n STATS\n } @else if (state.primary() === \'ITEMS\') {\n ITEMS\n } @else if (state.primary() === \'DATA\') {\n DATA\n }\n </div>\n <div class="main-title-right-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n </div>\n <div class="hp-title-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n <div class="ap-title-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n <div class="xp-title-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n </div>\n <div class="header-content">\n <button\n type="button"\n class="stats stat-button"\n (click)="openStatModal(\'LVL\')"\n >\n <span>LVL</span> {{ settings.userLevel() }}\n </button>\n <button type="button" class="hp stat-button" (click)="openStatModal(\'HP\')">\n <span>HP</span>\n <span>{{ settings.userHealth() }} / {{ settings.userHealthMax() }}</span>\n </button>\n <button type="button" class="ap stat-button" (click)="openStatModal(\'AP\')">\n <span>AP</span>\n {{ settings.userActionPoints() }} / {{ settings.userActionPointsMax() }}\n </button>\n <button type="button" class="xp stat-button" (click)="openStatModal(\'XP\')">\n <span>XP</span>\n {{ settings.userExperience() }} /\n {{ settings.userExperienceNextLevel() }}\n </button>\n </div>\n</header>\n<pip-boy-stat-edit-modal\n (closeResult)="closeStatModal()"\n (save)="saveStatModal($event)"\n [fields]="statModalFields()"\n [open]="statModal() !== null"\n [title]="statModalTitle()"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:50%;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}header{width:100%;box-sizing:border-box;display:flex;flex-direction:column;flex:0 0 auto;min-height:0;padding:0 1rem}header>.header-top,header>.header-content{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.25rem;padding:0}header>.header-top{height:2.25rem;align-items:center;text-transform:uppercase;overflow:visible}header>.header-top>.main-title{display:flex;align-items:center;justify-content:center;gap:.5rem;height:100%;overflow:visible}header>.header-top>.main-title>.main-title-left-line,header>.header-top>.main-title>.main-title-right-line{flex-grow:1;min-width:2rem;height:100%;position:relative;overflow:visible}header>.header-top>.main-title>.main-title-text{font-size:clamp(1.25rem,1.25rem + (1.5rem - 1.25rem) * (100vw - 360px) / (1200px - 360px),1.5rem);flex-grow:0;letter-spacing:.1em;white-space:nowrap;line-height:1}header>.header-top .main-title-left-line .bottom-half-line:before{left:0}header>.header-top .main-title-right-line .bottom-half-line:before{right:0}header>.header-top .hp-title-line,header>.header-top .ap-title-line,header>.header-top .xp-title-line{overflow:visible}header>.header-top .hp-title-line .bottom-half-line:before,header>.header-top .ap-title-line .bottom-half-line:before,header>.header-top .xp-title-line .bottom-half-line:before{right:0}header>.header-content{box-sizing:border-box;margin-top:-.5rem;font-size:calc(clamp(.9rem,.9rem + .2rem * (100vw - 360px) / 840px,1.1rem) * (1 + (var(--list-font-scale, 1) - 1) * .6))}header>.header-content>.stats,header>.header-content>.hp,header>.header-content>.ap,header>.header-content>.xp{display:flex;justify-content:flex-end;padding:0 1rem;gap:1rem}header>.header-content>.stat-button{align-items:center;background:transparent;border:none;color:inherit;cursor:pointer;font:inherit;text-align:right;text-transform:uppercase}header>.header-content>.stat-button:hover{background:#0fbb6b14}:host{font-size:inherit}\n'],dependencies:[{kind:"component",type:U,selector:"pip-boy-stat-edit-modal",inputs:["open","title","name","nameLabel","showName","nameOptions","imageUrl","showImage","fields","textFields"],outputs:["closeResult","save","nameChange"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:H,decorators:[{type:a,args:[{selector:"pip-boy-3000-header",standalone:!0,imports:[U],template:'<header>\n <div class="header-top">\n <div class="main-title">\n <div class="main-title-left-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n <div class="main-title-text">\n @if (state.primary() === \'STATS\') {\n STATS\n } @else if (state.primary() === \'ITEMS\') {\n ITEMS\n } @else if (state.primary() === \'DATA\') {\n DATA\n }\n </div>\n <div class="main-title-right-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n </div>\n <div class="hp-title-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n <div class="ap-title-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n <div class="xp-title-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n </div>\n <div class="header-content">\n <button\n type="button"\n class="stats stat-button"\n (click)="openStatModal(\'LVL\')"\n >\n <span>LVL</span> {{ settings.userLevel() }}\n </button>\n <button type="button" class="hp stat-button" (click)="openStatModal(\'HP\')">\n <span>HP</span>\n <span>{{ settings.userHealth() }} / {{ settings.userHealthMax() }}</span>\n </button>\n <button type="button" class="ap stat-button" (click)="openStatModal(\'AP\')">\n <span>AP</span>\n {{ settings.userActionPoints() }} / {{ settings.userActionPointsMax() }}\n </button>\n <button type="button" class="xp stat-button" (click)="openStatModal(\'XP\')">\n <span>XP</span>\n {{ settings.userExperience() }} /\n {{ settings.userExperienceNextLevel() }}\n </button>\n </div>\n</header>\n<pip-boy-stat-edit-modal\n (closeResult)="closeStatModal()"\n (save)="saveStatModal($event)"\n [fields]="statModalFields()"\n [open]="statModal() !== null"\n [title]="statModalTitle()"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:50%;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}header{width:100%;box-sizing:border-box;display:flex;flex-direction:column;flex:0 0 auto;min-height:0;padding:0 1rem}header>.header-top,header>.header-content{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.25rem;padding:0}header>.header-top{height:2.25rem;align-items:center;text-transform:uppercase;overflow:visible}header>.header-top>.main-title{display:flex;align-items:center;justify-content:center;gap:.5rem;height:100%;overflow:visible}header>.header-top>.main-title>.main-title-left-line,header>.header-top>.main-title>.main-title-right-line{flex-grow:1;min-width:2rem;height:100%;position:relative;overflow:visible}header>.header-top>.main-title>.main-title-text{font-size:clamp(1.25rem,1.25rem + (1.5rem - 1.25rem) * (100vw - 360px) / (1200px - 360px),1.5rem);flex-grow:0;letter-spacing:.1em;white-space:nowrap;line-height:1}header>.header-top .main-title-left-line .bottom-half-line:before{left:0}header>.header-top .main-title-right-line .bottom-half-line:before{right:0}header>.header-top .hp-title-line,header>.header-top .ap-title-line,header>.header-top .xp-title-line{overflow:visible}header>.header-top .hp-title-line .bottom-half-line:before,header>.header-top .ap-title-line .bottom-half-line:before,header>.header-top .xp-title-line .bottom-half-line:before{right:0}header>.header-content{box-sizing:border-box;margin-top:-.5rem;font-size:calc(clamp(.9rem,.9rem + .2rem * (100vw - 360px) / 840px,1.1rem) * (1 + (var(--list-font-scale, 1) - 1) * .6))}header>.header-content>.stats,header>.header-content>.hp,header>.header-content>.ap,header>.header-content>.xp{display:flex;justify-content:flex-end;padding:0 1rem;gap:1rem}header>.header-content>.stat-button{align-items:center;background:transparent;border:none;color:inherit;cursor:pointer;font:inherit;text-align:right;text-transform:uppercase}header>.header-content>.stat-button:hover{background:#0fbb6b14}:host{font-size:inherit}\n']}]}]});class _{dbPromise=this.openDb();soundUrls=o({},...ngDevMode?[{debugName:"soundUrls"}]:[]);soundLabels=o({},...ngDevMode?[{debugName:"soundLabels"}]:[]);metaLoading=new Set;activeSounds=new Set;getSoundLabel(e){if(!e)return null;const t=this.soundLabels()[e];return t||(this.loadSoundMeta(e),null)}async playSound(e){if(!e)return;const t=this.soundUrls()[e];if(t){const e=new Audio(t);return this.trackAudio(e),void await e.play().catch(()=>{this.activeSounds.delete(e)})}const n=await this.getRecord(e);if(!n)return;const a=URL.createObjectURL(n.blob);this.cacheUrl(e,a),this.cacheLabel(e,n.fileName);const o=new Audio(a);this.trackAudio(o),await o.play().catch(()=>{this.activeSounds.delete(o)})}stopAll(){for(const e of this.activeSounds)e.pause(),e.currentTime=0;this.activeSounds.clear()}async saveFile(e){const t=this.createId(),n={id:t,fileName:e.name,mime:e.type||"application/octet-stream"};return await this.putRecord({...n,blob:e}),this.cacheUrl(t,URL.createObjectURL(e)),this.cacheLabel(t,n.fileName),n}async saveBlobWithId(e,t,n,a){await this.putRecord({id:e,blob:t,fileName:n,mime:a}),this.cacheUrl(e,URL.createObjectURL(t)),this.cacheLabel(e,n)}async getRecord(e){const t=await this.dbPromise;return new Promise((n,a)=>{const o=t.transaction("sounds","readonly").objectStore("sounds").get(e);o.onsuccess=()=>{n(o.result??null)},o.onerror=()=>a(o.error)})}extensionFromMime(e){switch(e){case"audio/mpeg":case"audio/mp3":return".mp3";case"audio/wav":case"audio/x-wav":case"audio/wave":return".wav";case"audio/ogg":return".ogg";case"audio/aac":return".aac";case"audio/mp4":case"audio/x-m4a":return".m4a";case"audio/webm":return".webm";default:return""}}cacheUrl(e,t){this.soundUrls.update(n=>({...n,[e]:t}))}cacheLabel(e,t){this.soundLabels.update(n=>({...n,[e]:t}))}trackAudio(e){const t=()=>{this.activeSounds.delete(e),e.onended=null,e.onpause=null};this.activeSounds.add(e),e.onended=t,e.onpause=t}async loadSoundMeta(e){if(!this.metaLoading.has(e)){this.metaLoading.add(e);try{const t=await this.getRecord(e);if(!t)return;this.cacheLabel(e,t.fileName)}finally{this.metaLoading.delete(e)}}}async putRecord(e){const t=await this.dbPromise;return new Promise((n,a)=>{const o=t.transaction("sounds","readwrite").objectStore("sounds").put(e);o.onsuccess=()=>n(),o.onerror=()=>a(o.error)})}openDb(){return new Promise((e,t)=>{const n=indexedDB.open("pipBoy3000Sounds",1);n.onupgradeneeded=()=>{const e=n.result;e.objectStoreNames.contains("sounds")||e.createObjectStore("sounds",{keyPath:"id"})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}createId(){return"undefined"!=typeof crypto&&"randomUUID"in crypto?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:_,deps:[],target:e.ɵɵFactoryTarget.Injectable});static"ɵprov"=e.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:_,providedIn:"root"})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:_,decorators:[{type:i,args:[{providedIn:"root"}]}]});class ${category="WEAPONS";settings=l(P);settingsConfig=l(N,{optional:!0});imageStore=l(x);soundStore=l(_);showStatEditModal=o(!1,...ngDevMode?[{debugName:"showStatEditModal"}]:[]);editMode=o("EDIT",...ngDevMode?[{debugName:"editMode"}]:[]);modalName=o("",...ngDevMode?[{debugName:"modalName"}]:[]);modalImageId=o(null,...ngDevMode?[{debugName:"modalImageId"}]:[]);modalValues=o({damage:0,weight:0,value:0,quantity:0},...ngDevMode?[{debugName:"modalValues"}]:[]);modalTextValues=o({},...ngDevMode?[{debugName:"modalTextValues"}]:[]);selectedItem=u(()=>{const e=this.getEquippedId();return null===e?null:this.getItems().find(t=>t.id===e)??null},...ngDevMode?[{debugName:"selectedItem"}]:[]);itemNames=u(()=>{const e=this.getSourceNames();return Array.from(new Set(e)).sort()},...ngDevMode?[{debugName:"itemNames"}]:[]);editStatModalTitle=u(()=>{if("ADD"===this.editMode())return this.modalTitle();const e=this.selectedItem();return e?`Edit ${e.name}`:"Edit Stats"},...ngDevMode?[{debugName:"editStatModalTitle"}]:[]);statEditFields=u(()=>{const e=this.modalValues();switch(this.category){case"WEAPONS":return[{key:"damage",label:"Damage",value:e.damage??0},{key:"weight",label:"Weight",value:e.weight??0},{key:"value",label:"Value",value:e.value??0}];case"APPAREL":return[{key:"damage",label:"DR",value:e.damage??0},{key:"weight",label:"WG",value:e.weight??0},{key:"value",label:"VAL",value:e.value??0},{key:"quantity",label:"QTY",value:e.quantity??0}];default:return[{key:"weight",label:"WG",value:e.weight??0},{key:"value",label:"VAL",value:e.value??0},{key:"quantity",label:"QTY",value:e.quantity??0}]}},...ngDevMode?[{debugName:"statEditFields"}]:[]);textEditFields=u(()=>{const e=this.modalTextValues();return"AID"===this.category?[{key:"effects",label:"Effects",value:e.effects??"",multiline:!0}]:[]},...ngDevMode?[{debugName:"textEditFields"}]:[]);statRows=u(()=>{const e=this.selectedItem();return e?"WEAPONS"===this.category?[{key:"damage",label:"Damage",value:e.damage??"--"},{key:"weight",label:"Weight",value:e.weight??"--"},{key:"value",label:"Value",value:e.value??"--"}]:"APPAREL"===this.category?[{key:"damage",label:"DR",value:e.damage??"--"},{key:"weight",label:"WG",value:e.weight??"--"},{key:"value",label:"VAL",value:e.value??"--"}]:"AID"===this.category?[{key:"effects",label:"Effects",value:e.effects??"--"},{key:"weight",label:"WG",value:e.weight??"--"},{key:"value",label:"VAL",value:e.value??"--"}]:[{key:"weight",label:"WG",value:e.weight??"--"},{key:"value",label:"VAL",value:e.value??"--"}]:[]},...ngDevMode?[{debugName:"statRows"}]:[]);modalTitle=u(()=>{switch(this.category){case"WEAPONS":return"Add Weapon";case"APPAREL":return"Add Apparel";case"AID":return"Add Aid";case"MISC":return"Add Misc";case"AMMO":return"Add Ammo";default:return"Add Item"}},...ngDevMode?[{debugName:"modalTitle"}]:[]);openAddModal(){this.settings.editLockEnabled()||(this.editMode.set("ADD"),this.modalName.set(""),this.modalImageId.set(null),this.modalValues.set({damage:0,weight:0,value:0,quantity:this.defaultQuantity()}),this.modalTextValues.set({}),this.showStatEditModal.set(!0))}openStatEditModal(){if(this.settings.editLockEnabled())return;if(!this.selectedItem())return;this.playClickSound();const e=this.selectedItem();e&&(this.modalName.set(e.name),this.modalImageId.set(e.imageId??null),this.modalValues.set({damage:e.damage??0,weight:e.weight??0,value:e.value??0,quantity:this.normalizeQuantity(e.quantity)}),this.modalTextValues.set({effects:e.effects??""})),this.editMode.set("EDIT"),this.showStatEditModal.set(!0)}closeStatEditModal(){this.showStatEditModal.set(!1)}selectItem(e){const t=this.getEquippedId();this.setEquippedId(t===e?null:e),this.playClickSound()}async saveStatEditModal(e){const t=e.name?.trim()??"";if(!t)return;const n=this.selectedItem();let a;if(e.removeImage)a=void 0;else if(e.imageFile){const t=await this.imageStore.saveFile(e.imageFile);a=t.id}else a=n?.imageId;if("ADD"===this.editMode()){const n=this.supportsQuantity()?this.normalizeQuantity(e.values.quantity):void 0,o=this.getNextItemId();return this.updateItems(i=>[...i,{id:o,name:t,damage:this.normalizeStatValue(e.values.damage),weight:this.normalizeStatValue(e.values.weight),value:this.normalizeStatValue(e.values.value),imageId:a,effects:e.textValues?.effects,...this.supportsQuantity()?{quantity:n}:{}}]),this.setEquippedId(o),void this.closeStatEditModal()}const o=this.getEquippedId();null!==o&&(this.updateItems(n=>n.map(n=>n.id!==o?n:{...n,name:t,damage:this.normalizeStatValue(e.values.damage,n.damage),weight:this.normalizeStatValue(e.values.weight,n.weight),value:this.normalizeStatValue(e.values.value,n.value),imageId:a,...this.supportsQuantity()?{quantity:this.normalizeQuantity(e.values.quantity)}:{},effects:e.textValues?.effects??("AID"===this.category?n.effects:void 0)})),this.closeStatEditModal())}handleNameChange(e){if(this.modalName.set(e),"ADD"!==this.editMode())return;const t=this.getDefaultsForName(e);t&&("number"==typeof t.damage&&this.modalValues.set({...this.modalValues(),damage:t.damage}),"number"==typeof t.weight&&this.modalValues.set({...this.modalValues(),weight:t.weight}),"number"==typeof t.value&&this.modalValues.set({...this.modalValues(),value:t.value}),"string"==typeof t.effects&&this.modalTextValues.set({...this.modalTextValues(),effects:t.effects}))}dropSelected(){if(this.settings.editLockEnabled())return;const e=this.getEquippedId();null!==e&&(this.updateItems(t=>t.filter(t=>t.id!==e)),this.setEquippedId(null))}moveSelected(e){if(this.settings.editLockEnabled())return;const t=this.getEquippedId();null!==t&&this.updateItems(n=>{const a=n.findIndex(e=>e.id===t);if(-1===a)return n;const o=a+e;if(o<0||o>=n.length)return n;const i=n.slice(),[s]=i.splice(a,1);return i.splice(o,0,s),i})}displayItemName(e){const t="number"==typeof e.quantity&&Number.isFinite(e.quantity)?e.quantity:0;return this.supportsQuantity()&&t>1?`${e.name} (${t})`:e.name}getItems(){switch(this.category){case"WEAPONS":return this.settings.weaponItems();case"APPAREL":return this.settings.apparelItems();case"AID":return this.settings.aidItems();case"MISC":return this.settings.miscItems();case"AMMO":return this.settings.ammoItems();default:return[]}}updateItems(e){switch(this.category){case"WEAPONS":this.settings.weaponItems.update(t=>e(t));break;case"APPAREL":this.settings.apparelItems.update(t=>e(t));break;case"AID":this.settings.aidItems.update(t=>e(t));break;case"MISC":this.settings.miscItems.update(t=>e(t));break;case"AMMO":this.settings.ammoItems.update(t=>e(t))}}getEquippedId(){switch(this.category){case"WEAPONS":return this.settings.equippedWeaponId();case"APPAREL":return this.settings.equippedApparelId();case"AID":return this.settings.equippedAidId();case"MISC":return this.settings.equippedMiscId();case"AMMO":return this.settings.equippedAmmoId();default:return null}}setEquippedId(e){switch(this.category){case"WEAPONS":this.settings.equippedWeaponId.set(e);break;case"APPAREL":this.settings.equippedApparelId.set(e);break;case"AID":this.settings.equippedAidId.set(e);break;case"MISC":this.settings.equippedMiscId.set(e);break;case"AMMO":this.settings.equippedAmmoId.set(e)}}getSourceNames(){switch(this.category){case"WEAPONS":{const e=this.settingsConfig?.inventorySourceItems?.weapons;return(e??E).map(e=>e.name).filter(e=>e)}case"APPAREL":{const e=this.settingsConfig?.inventorySourceItems?.apparel;return(e??M).map(e=>e.name).filter(e=>e)}case"AID":{const e=this.settingsConfig?.inventorySourceItems?.aid;return(e??k).map(e=>e.name).filter(e=>e)}case"MISC":{const e=this.settingsConfig?.inventorySourceItems?.misc;return(e??I).map(e=>e.name).filter(e=>e)}case"AMMO":{const e=this.settingsConfig?.inventorySourceItems?.ammo;return(e??S).map(e=>e.name).filter(e=>e)}default:return[]}}getNextItemId(){return this.getItems().reduce((e,t)=>Math.max(e,t.id),0)+1}normalizeStatValue(e,t){return"number"==typeof e&&Number.isFinite(e)?e:t}normalizeQuantity(e){return"number"==typeof e&&Number.isFinite(e)?Math.max(1,Math.floor(e)):1}playClickSound(){this.soundStore.playSound(this.settings.clickSoundId())}supportsQuantity(){return"APPAREL"===this.category||"AID"===this.category||"MISC"===this.category||"AMMO"===this.category}defaultQuantity(){return this.supportsQuantity()?1:0}getDefaultsForName(e){if("WEAPONS"===this.category){const t=this.settingsConfig?.inventorySourceItems?.weapons,n=(t??E).find(t=>t.name===e);return n?{damage:n.damage,weight:n.weight,value:n.value}:null}if("APPAREL"===this.category){const t=this.settingsConfig?.inventorySourceItems?.apparel,n=(t??M).find(t=>t.name===e);return n?{damage:n.dr,weight:n.wg,value:n.val}:null}if("AID"===this.category){const t=this.settingsConfig?.inventorySourceItems?.aid,n=(t??k).find(t=>t.name===e);return n?{weight:n.wg,value:n.val,effects:n.effects}:null}if("MISC"===this.category){const t=this.settingsConfig?.inventorySourceItems?.misc,n=(t??I).find(t=>t.name===e);return n?{weight:n.wg,value:n.val}:null}if("AMMO"===this.category){const t=this.settingsConfig?.inventorySourceItems?.ammo,n=(t??S).find(t=>t.name===e);return n?{weight:n.wg,value:n.val}:null}return null}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:$,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:$,isStandalone:!0,selector:"pip-boy-inventory-layout",inputs:{category:"category"},ngImport:e,template:'<div class="resource-layout">\n <div class="resource-list">\n <ul class="resource-list-items">\n @for (item of getItems(); track item.id) {\n <li>\n <button\n type="button"\n class="resource-list-item"\n [class.is-selected]="getEquippedId() === item.id"\n (click)="selectItem(item.id)"\n >\n {{ displayItemName(item) }}\n </button>\n </li>\n } @empty {\n <li class="is-empty">No items added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="inventory-actions">\n <button type="button" class="resource-add" (click)="openAddModal()">\n + Add\n </button>\n @if (getEquippedId() !== null) {\n <button\n type="button"\n class="resource-edit"\n (click)="openStatEditModal()"\n >\n Edit\n </button>\n <button type="button" class="resource-drop" (click)="dropSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n <div class="resources-detail">\n @if (getItems().length > 0 && selectedItem()) {\n <button\n type="button"\n class="resource-image"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openStatEditModal()"\n >\n @if (selectedItem()?.imageId) {\n <img\n [src]="imageStore.getImageUrl(selectedItem()?.imageId)"\n alt="Selected item"\n />\n }\n </button>\n <div class="resource-stats">\n @for (row of statRows(); track row.key) {\n <button\n type="button"\n class="resource-stat"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openStatEditModal()"\n >\n <span>{{ row.label }}</span>\n <span>{{ row.value }}</span>\n </button>\n }\n </div>\n }\n </div>\n</div>\n<pip-boy-stat-edit-modal\n (closeResult)="closeStatEditModal()"\n (nameChange)="handleNameChange($event)"\n (save)="saveStatEditModal($event)"\n [open]="showStatEditModal()"\n [title]="editStatModalTitle()"\n [name]="modalName()"\n nameLabel="Item Name"\n [nameOptions]="itemNames()"\n [showName]="true"\n [imageUrl]="imageStore.getImageUrl(modalImageId())"\n [showImage]="true"\n [textFields]="textEditFields()"\n [fields]="statEditFields()"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{width:100%;height:100%;display:block;font-size:inherit}.resource-layout{box-sizing:border-box;display:flex;gap:1.5rem;height:100%;min-height:0}.resource-list{display:flex;flex:1 1 55%;flex-direction:column;gap:.5rem;min-height:0}.resource-list-items{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.resource-list-items li{margin:0;padding:0;font-size:inherit}.resource-list-items .is-empty{opacity:.6}.resource-list-item{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font-size:inherit;padding:.25rem .35rem .25rem 1.2rem;position:relative;text-align:left;width:100%}.resource-list-item:hover{background:#0fbb6b1f}.resource-list-item.is-selected{background:#0fbb6b2e}.resource-list-item.is-selected:before{content:"";position:absolute;left:.35rem;top:50%;transform:translateY(-50%);width:.45rem;height:.45rem;background:#0fbb6b}.inventory-actions{display:flex;gap:.5rem}.resource-add{background:#0fbb6b14;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-add:hover{background:#0fbb6b2e}.resource-edit{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-edit:hover{background:#0fbb6b1f}.resource-drop{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-drop:hover{background:#0fbb6b1f}.resource-move{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.resource-move:hover{background:#0fbb6b1f}.resources-detail{display:flex;flex:1 1 45%;flex-direction:column;gap:1rem;height:100%;min-height:0;overflow:auto;padding-right:1rem}.resource-image{align-items:center;background:transparent;border:none;cursor:pointer;display:flex;flex:1 1 auto;flex-direction:column;min-height:60%;justify-content:flex-start;padding:1rem;text-transform:uppercase;width:100%}.resource-image span{margin-top:auto;opacity:.7}.resource-image img{align-self:center;max-height:100%;max-width:100%;object-fit:contain;padding:0}.resource-image:hover{background:#0fbb6b1f}.resource-image.is-locked{cursor:default;pointer-events:none}.resource-stats{display:flex;flex-direction:column;gap:.5rem;margin-top:auto;padding:0 1rem;font-size:calc(1.15rem * var(--list-font-scale, 1))}.resource-stat{background:transparent;border:1px solid transparent;color:#0fbb6b;cursor:pointer;display:flex;justify-content:space-between;padding:.2rem .35rem;text-align:left;text-transform:uppercase;width:100%;font-size:inherit}.resource-stat:hover{background:#0fbb6b1f}.resource-stat.is-locked{cursor:default;pointer-events:none}.resource-stat span{padding:.25rem}.resource-stat--name{font-size:calc(clamp(.9rem,.9rem + .15rem * (100vw - 360px) / 840px,1.05rem) * var(--list-font-scale, 1));letter-spacing:.04em}@media(max-width:720px),(max-height:560px){.inventory-actions{gap:.35rem}.resource-add,.resource-edit,.resource-drop{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.resource-move{flex:0 0 1.6rem;height:2.1rem}}\n'],dependencies:[{kind:"component",type:U,selector:"pip-boy-stat-edit-modal",inputs:["open","title","name","nameLabel","showName","nameOptions","imageUrl","showImage","fields","textFields"],outputs:["closeResult","save","nameChange"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:$,decorators:[{type:a,args:[{selector:"pip-boy-inventory-layout",standalone:!0,imports:[U],template:'<div class="resource-layout">\n <div class="resource-list">\n <ul class="resource-list-items">\n @for (item of getItems(); track item.id) {\n <li>\n <button\n type="button"\n class="resource-list-item"\n [class.is-selected]="getEquippedId() === item.id"\n (click)="selectItem(item.id)"\n >\n {{ displayItemName(item) }}\n </button>\n </li>\n } @empty {\n <li class="is-empty">No items added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="inventory-actions">\n <button type="button" class="resource-add" (click)="openAddModal()">\n + Add\n </button>\n @if (getEquippedId() !== null) {\n <button\n type="button"\n class="resource-edit"\n (click)="openStatEditModal()"\n >\n Edit\n </button>\n <button type="button" class="resource-drop" (click)="dropSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n <div class="resources-detail">\n @if (getItems().length > 0 && selectedItem()) {\n <button\n type="button"\n class="resource-image"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openStatEditModal()"\n >\n @if (selectedItem()?.imageId) {\n <img\n [src]="imageStore.getImageUrl(selectedItem()?.imageId)"\n alt="Selected item"\n />\n }\n </button>\n <div class="resource-stats">\n @for (row of statRows(); track row.key) {\n <button\n type="button"\n class="resource-stat"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openStatEditModal()"\n >\n <span>{{ row.label }}</span>\n <span>{{ row.value }}</span>\n </button>\n }\n </div>\n }\n </div>\n</div>\n<pip-boy-stat-edit-modal\n (closeResult)="closeStatEditModal()"\n (nameChange)="handleNameChange($event)"\n (save)="saveStatEditModal($event)"\n [open]="showStatEditModal()"\n [title]="editStatModalTitle()"\n [name]="modalName()"\n nameLabel="Item Name"\n [nameOptions]="itemNames()"\n [showName]="true"\n [imageUrl]="imageStore.getImageUrl(modalImageId())"\n [showImage]="true"\n [textFields]="textEditFields()"\n [fields]="statEditFields()"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{width:100%;height:100%;display:block;font-size:inherit}.resource-layout{box-sizing:border-box;display:flex;gap:1.5rem;height:100%;min-height:0}.resource-list{display:flex;flex:1 1 55%;flex-direction:column;gap:.5rem;min-height:0}.resource-list-items{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.resource-list-items li{margin:0;padding:0;font-size:inherit}.resource-list-items .is-empty{opacity:.6}.resource-list-item{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font-size:inherit;padding:.25rem .35rem .25rem 1.2rem;position:relative;text-align:left;width:100%}.resource-list-item:hover{background:#0fbb6b1f}.resource-list-item.is-selected{background:#0fbb6b2e}.resource-list-item.is-selected:before{content:"";position:absolute;left:.35rem;top:50%;transform:translateY(-50%);width:.45rem;height:.45rem;background:#0fbb6b}.inventory-actions{display:flex;gap:.5rem}.resource-add{background:#0fbb6b14;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-add:hover{background:#0fbb6b2e}.resource-edit{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-edit:hover{background:#0fbb6b1f}.resource-drop{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-drop:hover{background:#0fbb6b1f}.resource-move{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.resource-move:hover{background:#0fbb6b1f}.resources-detail{display:flex;flex:1 1 45%;flex-direction:column;gap:1rem;height:100%;min-height:0;overflow:auto;padding-right:1rem}.resource-image{align-items:center;background:transparent;border:none;cursor:pointer;display:flex;flex:1 1 auto;flex-direction:column;min-height:60%;justify-content:flex-start;padding:1rem;text-transform:uppercase;width:100%}.resource-image span{margin-top:auto;opacity:.7}.resource-image img{align-self:center;max-height:100%;max-width:100%;object-fit:contain;padding:0}.resource-image:hover{background:#0fbb6b1f}.resource-image.is-locked{cursor:default;pointer-events:none}.resource-stats{display:flex;flex-direction:column;gap:.5rem;margin-top:auto;padding:0 1rem;font-size:calc(1.15rem * var(--list-font-scale, 1))}.resource-stat{background:transparent;border:1px solid transparent;color:#0fbb6b;cursor:pointer;display:flex;justify-content:space-between;padding:.2rem .35rem;text-align:left;text-transform:uppercase;width:100%;font-size:inherit}.resource-stat:hover{background:#0fbb6b1f}.resource-stat.is-locked{cursor:default;pointer-events:none}.resource-stat span{padding:.25rem}.resource-stat--name{font-size:calc(clamp(.9rem,.9rem + .15rem * (100vw - 360px) / 840px,1.05rem) * var(--list-font-scale, 1));letter-spacing:.04em}@media(max-width:720px),(max-height:560px){.inventory-actions{gap:.35rem}.resource-add,.resource-edit,.resource-drop{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.resource-move{flex:0 0 1.6rem;height:2.1rem}}\n']}]}],propDecorators:{category:[{type:p}]}});class j{constructor(){r(()=>{this.open()&&(this.draftName.set(this.name()),this.draftDescription.set(this.description()),this.draftValue.set(this.value()),this.draftImageUrl.set(this.imageUrl()),this.draftImageName.set(null),this.draftImageFile.set(null),this.removedImage.set(!1),this.clearPreviewUrl())})}static nextId=0;open=t(!1,...ngDevMode?[{debugName:"open"}]:[]);title=t("Edit Entry",...ngDevMode?[{debugName:"title"}]:[]);name=t("",...ngDevMode?[{debugName:"name"}]:[]);itemNames=t([],...ngDevMode?[{debugName:"itemNames"}]:[]);sourceItems=t([],...ngDevMode?[{debugName:"sourceItems"}]:[]);autofillEnabled=t(!1,...ngDevMode?[{debugName:"autofillEnabled"}]:[]);autofillValue=t(!1,...ngDevMode?[{debugName:"autofillValue"}]:[]);description=t("",...ngDevMode?[{debugName:"description"}]:[]);value=t(0,...ngDevMode?[{debugName:"value"}]:[]);valueLabel=t("Value",...ngDevMode?[{debugName:"valueLabel"}]:[]);valueMin=t(null,...ngDevMode?[{debugName:"valueMin"}]:[]);valueMax=t(null,...ngDevMode?[{debugName:"valueMax"}]:[]);showValue=t(!0,...ngDevMode?[{debugName:"showValue"}]:[]);imageUrl=t(null,...ngDevMode?[{debugName:"imageUrl"}]:[]);closeResult=d();save=d();draftDescription=o("",...ngDevMode?[{debugName:"draftDescription"}]:[]);draftName=o("",...ngDevMode?[{debugName:"draftName"}]:[]);draftValue=o(0,...ngDevMode?[{debugName:"draftValue"}]:[]);draftImageName=o(null,...ngDevMode?[{debugName:"draftImageName"}]:[]);draftImageUrl=o(null,...ngDevMode?[{debugName:"draftImageUrl"}]:[]);draftImageFile=o(null,...ngDevMode?[{debugName:"draftImageFile"}]:[]);removedImage=o(!1,...ngDevMode?[{debugName:"removedImage"}]:[]);nameListId="stat-entry-name-"+j.nextId++;nameInputId=`${this.nameListId}-input`;previewUrl=null;closeModal(){this.clearPreviewUrl(),this.closeResult.emit()}updateName(e){const t=e.target.value;if(this.draftName.set(t),!this.autofillEnabled())return;const n=this.sourceItems().find(e=>e.name===t);n&&(this.draftDescription.set(n.description),this.autofillValue()&&"number"==typeof n.value&&this.draftValue.set(this.clampValue(n.value)))}updateDescription(e){this.draftDescription.set(e.target.value)}updateValue(e){const t=Number(e.target.value);Number.isFinite(t)&&this.draftValue.set(this.clampValue(t))}adjustValue(e){const t=Number(this.draftValue()),n=Number.isFinite(t)?t+e:e;this.draftValue.set(this.clampValue(n))}onImageSelected(e){const t=e.target,n=t.files?.[0]??null;this.draftImageName.set(n?n.name:null),n&&(this.removedImage.set(!1),this.draftImageFile.set(n),this.setPreviewUrl(URL.createObjectURL(n)),t.value="")}removeImage(){this.draftImageName.set(null),this.draftImageUrl.set(null),this.draftImageFile.set(null),this.removedImage.set(!0),this.clearPreviewUrl()}submit(e){e?.preventDefault();const t={name:this.draftName(),description:this.draftDescription(),imageFile:this.draftImageFile(),removeImage:this.removedImage()};this.showValue()&&(t.value=this.clampValue(this.draftValue())),this.clearPreviewUrl(),this.save.emit(t),this.closeResult.emit()}clampValue(e){let t=e;const n=this.valueMin(),a=this.valueMax();return"number"==typeof n&&(t=Math.max(n,t)),"number"==typeof a&&(t=Math.min(a,t)),t}setPreviewUrl(e){this.clearPreviewUrl(),this.previewUrl=e,this.draftImageUrl.set(e)}clearPreviewUrl(){this.previewUrl&&(URL.revokeObjectURL(this.previewUrl),this.previewUrl=null)}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:j,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:j,isStandalone:!0,selector:"pip-boy-stat-entry-modal",inputs:{open:{classPropertyName:"open",publicName:"open",isSignal:!0,isRequired:!1,transformFunction:null},title:{classPropertyName:"title",publicName:"title",isSignal:!0,isRequired:!1,transformFunction:null},name:{classPropertyName:"name",publicName:"name",isSignal:!0,isRequired:!1,transformFunction:null},itemNames:{classPropertyName:"itemNames",publicName:"itemNames",isSignal:!0,isRequired:!1,transformFunction:null},sourceItems:{classPropertyName:"sourceItems",publicName:"sourceItems",isSignal:!0,isRequired:!1,transformFunction:null},autofillEnabled:{classPropertyName:"autofillEnabled",publicName:"autofillEnabled",isSignal:!0,isRequired:!1,transformFunction:null},autofillValue:{classPropertyName:"autofillValue",publicName:"autofillValue",isSignal:!0,isRequired:!1,transformFunction:null},description:{classPropertyName:"description",publicName:"description",isSignal:!0,isRequired:!1,transformFunction:null},value:{classPropertyName:"value",publicName:"value",isSignal:!0,isRequired:!1,transformFunction:null},valueLabel:{classPropertyName:"valueLabel",publicName:"valueLabel",isSignal:!0,isRequired:!1,transformFunction:null},valueMin:{classPropertyName:"valueMin",publicName:"valueMin",isSignal:!0,isRequired:!1,transformFunction:null},valueMax:{classPropertyName:"valueMax",publicName:"valueMax",isSignal:!0,isRequired:!1,transformFunction:null},showValue:{classPropertyName:"showValue",publicName:"showValue",isSignal:!0,isRequired:!1,transformFunction:null},imageUrl:{classPropertyName:"imageUrl",publicName:"imageUrl",isSignal:!0,isRequired:!1,transformFunction:null}},outputs:{closeResult:"closeResult",save:"save"},ngImport:e,template:'<pip-boy-dialog [open]="open()" [title]="title()" (closeResult)="closeModal()">\n <form id="stat-entry-form" (submit)="submit($event)">\n <div class="stat-entry-modal-body">\n <label class="stat-entry-modal-field">\n <span>Name</span>\n <input\n type="text"\n [attr.list]="nameListId"\n [attr.name]="nameInputId"\n [value]="draftName()"\n (input)="updateName($event)"\n />\n </label>\n @if (itemNames().length) {\n <datalist [id]="nameListId">\n @for (name of itemNames(); track name) {\n <option [value]="name"></option>\n }\n </datalist>\n }\n @if (showValue()) {\n <label class="stat-entry-modal-field">\n <span>{{ valueLabel() }}</span>\n <div class="number-input-row">\n <input\n type="number"\n [attr.min]="valueMin()"\n [attr.max]="valueMax()"\n name="stat-entry-value"\n [value]="draftValue()"\n (input)="updateValue($event)"\n />\n <div class="number-input-controls">\n <button\n type="button"\n class="number-input-control"\n aria-label="Increase value"\n (click)="adjustValue(1)"\n >\n &#8593;\n </button>\n <button\n type="button"\n class="number-input-control"\n aria-label="Decrease value"\n (click)="adjustValue(-1)"\n >\n &#8595;\n </button>\n </div>\n </div>\n </label>\n }\n <label class="stat-entry-modal-field stat-entry-modal-field--description">\n <span>Description</span>\n <textarea\n rows="6"\n name="stat-entry-description"\n [value]="draftDescription()"\n (input)="updateDescription($event)"\n ></textarea>\n </label>\n <div class="stat-entry-modal-image">\n <button\n type="button"\n class="stat-entry-modal-image-button"\n (click)="modalImageInput.click()"\n >\n {{ draftImageName() ? draftImageName() : \'Select Image\' }}\n </button>\n @if (draftImageUrl()) {\n <button\n type="button"\n class="stat-entry-modal-image-remove"\n (click)="removeImage()"\n >\n Remove Image\n </button>\n }\n <input\n #modalImageInput\n type="file"\n accept="image/*"\n (change)="onImageSelected($event)"\n />\n @if (draftImageUrl()) {\n <img [src]="draftImageUrl()" alt="Entry preview" />\n }\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="stat-entry-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.stat-entry-modal-body{display:flex;flex-direction:column;gap:1rem}.stat-entry-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.stat-entry-modal-field input,.stat-entry-modal-field textarea{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.stat-entry-modal-field input:focus,.stat-entry-modal-field textarea:focus{outline:none;border-color:#0fbb6b}.stat-entry-modal-field textarea{min-height:6rem;resize:vertical;text-transform:none}.number-input-row{display:flex;align-items:stretch;gap:.5rem}.number-input-row input[type=number]{flex:1 1 auto;-moz-appearance:textfield}.number-input-row input[type=number]::-webkit-outer-spin-button,.number-input-row input[type=number]::-webkit-inner-spin-button{appearance:none;margin:0}.number-input-controls{display:flex;flex-direction:column;gap:.35rem}.number-input-control{flex:1 1 auto;background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.4rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);padding:.2rem .5rem;text-transform:uppercase}.number-input-control:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-entry-modal-image{display:flex;flex-direction:column;gap:.75rem}.stat-entry-modal-image input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.stat-entry-modal-image img{border:1px solid rgba(15,187,107,.35);max-height:8rem;object-fit:contain;padding:.5rem}.stat-entry-modal-image-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.stat-entry-modal-image-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-entry-modal-image-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.stat-entry-modal-image-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"],dependencies:[{kind:"component",type:B,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:j,decorators:[{type:a,args:[{selector:"pip-boy-stat-entry-modal",standalone:!0,imports:[B],template:'<pip-boy-dialog [open]="open()" [title]="title()" (closeResult)="closeModal()">\n <form id="stat-entry-form" (submit)="submit($event)">\n <div class="stat-entry-modal-body">\n <label class="stat-entry-modal-field">\n <span>Name</span>\n <input\n type="text"\n [attr.list]="nameListId"\n [attr.name]="nameInputId"\n [value]="draftName()"\n (input)="updateName($event)"\n />\n </label>\n @if (itemNames().length) {\n <datalist [id]="nameListId">\n @for (name of itemNames(); track name) {\n <option [value]="name"></option>\n }\n </datalist>\n }\n @if (showValue()) {\n <label class="stat-entry-modal-field">\n <span>{{ valueLabel() }}</span>\n <div class="number-input-row">\n <input\n type="number"\n [attr.min]="valueMin()"\n [attr.max]="valueMax()"\n name="stat-entry-value"\n [value]="draftValue()"\n (input)="updateValue($event)"\n />\n <div class="number-input-controls">\n <button\n type="button"\n class="number-input-control"\n aria-label="Increase value"\n (click)="adjustValue(1)"\n >\n &#8593;\n </button>\n <button\n type="button"\n class="number-input-control"\n aria-label="Decrease value"\n (click)="adjustValue(-1)"\n >\n &#8595;\n </button>\n </div>\n </div>\n </label>\n }\n <label class="stat-entry-modal-field stat-entry-modal-field--description">\n <span>Description</span>\n <textarea\n rows="6"\n name="stat-entry-description"\n [value]="draftDescription()"\n (input)="updateDescription($event)"\n ></textarea>\n </label>\n <div class="stat-entry-modal-image">\n <button\n type="button"\n class="stat-entry-modal-image-button"\n (click)="modalImageInput.click()"\n >\n {{ draftImageName() ? draftImageName() : \'Select Image\' }}\n </button>\n @if (draftImageUrl()) {\n <button\n type="button"\n class="stat-entry-modal-image-remove"\n (click)="removeImage()"\n >\n Remove Image\n </button>\n }\n <input\n #modalImageInput\n type="file"\n accept="image/*"\n (change)="onImageSelected($event)"\n />\n @if (draftImageUrl()) {\n <img [src]="draftImageUrl()" alt="Entry preview" />\n }\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="stat-entry-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.stat-entry-modal-body{display:flex;flex-direction:column;gap:1rem}.stat-entry-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.stat-entry-modal-field input,.stat-entry-modal-field textarea{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.stat-entry-modal-field input:focus,.stat-entry-modal-field textarea:focus{outline:none;border-color:#0fbb6b}.stat-entry-modal-field textarea{min-height:6rem;resize:vertical;text-transform:none}.number-input-row{display:flex;align-items:stretch;gap:.5rem}.number-input-row input[type=number]{flex:1 1 auto;-moz-appearance:textfield}.number-input-row input[type=number]::-webkit-outer-spin-button,.number-input-row input[type=number]::-webkit-inner-spin-button{appearance:none;margin:0}.number-input-controls{display:flex;flex-direction:column;gap:.35rem}.number-input-control{flex:1 1 auto;background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.4rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);padding:.2rem .5rem;text-transform:uppercase}.number-input-control:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-entry-modal-image{display:flex;flex-direction:column;gap:.75rem}.stat-entry-modal-image input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.stat-entry-modal-image img{border:1px solid rgba(15,187,107,.35);max-height:8rem;object-fit:contain;padding:.5rem}.stat-entry-modal-image-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.stat-entry-modal-image-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-entry-modal-image-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.stat-entry-modal-image-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"]}]}],ctorParameters:()=>[],propDecorators:{open:[{type:e.Input,args:[{isSignal:!0,alias:"open",required:!1}]}],title:[{type:e.Input,args:[{isSignal:!0,alias:"title",required:!1}]}],name:[{type:e.Input,args:[{isSignal:!0,alias:"name",required:!1}]}],itemNames:[{type:e.Input,args:[{isSignal:!0,alias:"itemNames",required:!1}]}],sourceItems:[{type:e.Input,args:[{isSignal:!0,alias:"sourceItems",required:!1}]}],autofillEnabled:[{type:e.Input,args:[{isSignal:!0,alias:"autofillEnabled",required:!1}]}],autofillValue:[{type:e.Input,args:[{isSignal:!0,alias:"autofillValue",required:!1}]}],description:[{type:e.Input,args:[{isSignal:!0,alias:"description",required:!1}]}],value:[{type:e.Input,args:[{isSignal:!0,alias:"value",required:!1}]}],valueLabel:[{type:e.Input,args:[{isSignal:!0,alias:"valueLabel",required:!1}]}],valueMin:[{type:e.Input,args:[{isSignal:!0,alias:"valueMin",required:!1}]}],valueMax:[{type:e.Input,args:[{isSignal:!0,alias:"valueMax",required:!1}]}],showValue:[{type:e.Input,args:[{isSignal:!0,alias:"showValue",required:!1}]}],imageUrl:[{type:e.Input,args:[{isSignal:!0,alias:"imageUrl",required:!1}]}],closeResult:[{type:e.Output,args:["closeResult"]}],save:[{type:e.Output,args:["save"]}]}});class G{constructor(){r(()=>{const e=this.items(),t=this.selectedId();e.length?null!==t&&e.some(e=>e.id===t)||this.selectedId.set(e[0].id):null!==t&&this.selectedId.set(null)})}category="SPECIAL";valueLabel="Value";valueMin=null;valueMax=null;settings=l(P);settingsConfig=l(N,{optional:!0});imageStore=l(x);soundStore=l(_);showEditModal=o(!1,...ngDevMode?[{debugName:"showEditModal"}]:[]);editMode=o("EDIT",...ngDevMode?[{debugName:"editMode"}]:[]);selectedId=o(null,...ngDevMode?[{debugName:"selectedId"}]:[]);items=u(()=>this.getItems(),...ngDevMode?[{debugName:"items"}]:[]);selectedItem=u(()=>{const e=this.selectedId();return null===e?null:this.items().find(t=>t.id===e)??null},...ngDevMode?[{debugName:"selectedItem"}]:[]);sourceItems=u(()=>this.getSourceItems(),...ngDevMode?[{debugName:"sourceItems"}]:[]);itemNames=u(()=>{const e=this.getSourceItems().map(e=>e.name);return Array.from(new Set(e)).sort()},...ngDevMode?[{debugName:"itemNames"}]:[]);autofillEnabled=u(()=>"ADD"===this.editMode(),...ngDevMode?[{debugName:"autofillEnabled"}]:[]);autofillValue=u(()=>"SPECIAL"===this.category,...ngDevMode?[{debugName:"autofillValue"}]:[]);editModalTitle=u(()=>{if("ADD"===this.editMode())return"Add Entry";const e=this.selectedItem();return e?`Edit ${e.name}`:"Edit Entry"},...ngDevMode?[{debugName:"editModalTitle"}]:[]);modalName=u(()=>{const e=this.selectedItem();return"ADD"===this.editMode()?"":e?.name??""},...ngDevMode?[{debugName:"modalName"}]:[]);modalDescription=u(()=>{const e=this.selectedItem();return"ADD"===this.editMode()?"":e?.description??""},...ngDevMode?[{debugName:"modalDescription"}]:[]);modalValue=u(()=>{if("ADD"===this.editMode())return this.valueMin??0;const e=this.selectedItem();return e?.value??0},...ngDevMode?[{debugName:"modalValue"}]:[]);modalImage=u(()=>{const e=this.selectedItem();return"ADD"===this.editMode()?null:this.imageStore.getImageUrl(e?.imageId??null)},...ngDevMode?[{debugName:"modalImage"}]:[]);openAddModal(){this.settings.editLockEnabled()||(this.editMode.set("ADD"),this.showEditModal.set(!0))}openEditModal(){this.settings.editLockEnabled()||this.selectedItem()&&(this.playClickSound(),this.editMode.set("EDIT"),this.showEditModal.set(!0))}closeEditModal(){this.showEditModal.set(!1)}selectItem(e){this.selectedId.set(e),this.playClickSound()}async saveEditModal(e){const t=e.name.trim();if(!t)return;const n=this.selectedItem();let a;if(e.removeImage)a=void 0;else if(e.imageFile){const t=await this.imageStore.saveFile(e.imageFile);a=t.id}else a=n?.imageId;if("ADD"===this.editMode()){const n=this.getNextItemId(),o=this.valueMin??0;return this.updateItems(i=>[...i,{id:n,name:t,description:e.description,value:this.showValue()&&"number"==typeof e.value?e.value:o,imageId:a}]),this.selectedId.set(n),void this.closeEditModal()}const o=this.selectedId();null!==o&&(this.updateItems(n=>n.map(n=>n.id!==o?n:{...n,name:t,description:e.description,value:"number"==typeof e.value?e.value:n.value,imageId:a})),this.closeEditModal())}dropSelected(){if(this.settings.editLockEnabled())return;const e=this.selectedId();null!==e&&(this.updateItems(t=>t.filter(t=>t.id!==e)),this.selectedId.set(null))}moveSelected(e){if(this.settings.editLockEnabled())return;const t=this.selectedId();null!==t&&this.updateItems(n=>{const a=n.findIndex(e=>e.id===t);if(-1===a)return n;const o=a+e;if(o<0||o>=n.length)return n;const i=n.slice(),[s]=i.splice(a,1);return i.splice(o,0,s),i})}showValue(){return"SPECIAL"===this.category||"SKILLS"===this.category}getItems(){switch(this.category){case"SPECIAL":return this.settings.specialItems();case"SKILLS":return this.settings.skillItems();case"PERKS":return this.settings.perkItems();case"GENERAL":return this.settings.generalItems();default:return[]}}updateItems(e){switch(this.category){case"SPECIAL":this.settings.specialItems.update(e);break;case"SKILLS":this.settings.skillItems.update(e);break;case"PERKS":this.settings.perkItems.update(e);break;case"GENERAL":this.settings.generalItems.update(e)}}getSourceItems(){switch(this.category){case"SPECIAL":return this.settingsConfig?.statSourceItems?.special??D;case"SKILLS":return this.settingsConfig?.statSourceItems?.skills??L;case"PERKS":return this.settingsConfig?.statSourceItems?.perks??R;default:return[]}}getNextItemId(){return this.items().reduce((e,t)=>Math.max(e,t.id),0)+1}playClickSound(){this.soundStore.playSound(this.settings.clickSoundId())}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:G,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:G,isStandalone:!0,selector:"pip-boy-stats-layout",inputs:{category:"category",valueLabel:"valueLabel",valueMin:"valueMin",valueMax:"valueMax"},ngImport:e,template:'<div class="resource-layout">\n <div class="resource-list">\n <ul class="resource-list-items">\n @for (item of items(); track item.id) {\n <li>\n <button\n type="button"\n class="resource-list-item"\n [class.is-selected]="selectedId() === item.id"\n (click)="selectItem(item.id)"\n >\n <span class="resource-list-item-name">{{ item.name }}</span>\n @if (showValue()) {\n <span class="resource-list-item-value">{{ item.value }}</span>\n }\n </button>\n </li>\n } @empty {\n <li class="is-empty">No entries available.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="inventory-actions">\n <button type="button" class="resource-add" (click)="openAddModal()">\n + Add\n </button>\n @if (selectedId() !== null) {\n <button type="button" class="resource-edit" (click)="openEditModal()">\n Edit\n </button>\n <button type="button" class="resource-drop" (click)="dropSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n <div class="resources-detail">\n @if (selectedItem()) {\n <button\n type="button"\n class="resource-image"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openEditModal()"\n [attr.aria-label]="\n selectedItem()?.imageId ? \'Edit image\' : \'Select image\'\n "\n >\n @if (selectedItem()?.imageId) {\n <img\n [src]="imageStore.getImageUrl(selectedItem()?.imageId)"\n alt="Selected entry"\n />\n }\n </button>\n <button\n type="button"\n class="resource-description"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openEditModal()"\n [innerHTML]="selectedItem()?.description || \'Add description.\'"\n ></button>\n }\n </div>\n</div>\n<pip-boy-stat-entry-modal\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n [open]="showEditModal()"\n [title]="editModalTitle()"\n [name]="modalName()"\n [itemNames]="itemNames()"\n [sourceItems]="sourceItems()"\n [autofillEnabled]="autofillEnabled()"\n [autofillValue]="autofillValue()"\n [description]="modalDescription()"\n [value]="modalValue()"\n [valueLabel]="valueLabel"\n [valueMin]="valueMin"\n [valueMax]="valueMax"\n [showValue]="showValue()"\n [imageUrl]="modalImage()"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{width:100%;height:100%;display:block;font-size:inherit}.resource-layout{box-sizing:border-box;display:flex;gap:1.5rem;height:100%;min-height:0}.resource-list{display:flex;flex:1 1 55%;flex-direction:column;gap:.5rem;min-height:0}.resource-list-items{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.resource-list-items li{margin:0;padding:0;font-size:inherit}.resource-list-items .is-empty{opacity:.6}.resource-list-item{align-items:center;background:transparent;border:none;color:#0fbb6b;cursor:pointer;display:flex;font-size:inherit;padding:.25rem .35rem .25rem 1.2rem;position:relative;text-align:left;justify-content:space-between;gap:.75rem;width:100%}.resource-list-item:hover{background:#0fbb6b1f}.resource-list-item.is-selected{background:#0fbb6b2e}.resource-list-item.is-selected:before{content:"";position:absolute;left:.35rem;top:50%;transform:translateY(-50%);width:.45rem;height:.45rem;background:#0fbb6b}.resource-list-item-name{flex:1 1 auto}.resource-list-item-value{flex:0 0 auto;min-width:2.5rem;text-align:right}.inventory-actions{display:flex;gap:.5rem}.resource-add{background:#0fbb6b14;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-add:hover{background:#0fbb6b2e}.resource-edit{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-edit:hover{background:#0fbb6b1f}.resource-drop{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-drop:hover{background:#0fbb6b1f}.resource-move{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.resource-move:hover{background:#0fbb6b1f}.resources-detail{display:flex;flex:1 1 45%;flex-direction:column;gap:1rem;height:100%;min-height:0;overflow:auto;padding-bottom:1rem;padding-right:1rem}.resource-image{align-items:center;background:transparent;border:none;cursor:pointer;display:flex;flex:1 1 auto;flex-direction:column;min-height:60%;justify-content:flex-start;padding:1rem;text-transform:uppercase;width:100%}.resource-image span{margin-top:auto;opacity:.7}.resource-image img{align-self:center;max-height:100%;max-width:100%;object-fit:contain;padding:0}.resource-image:hover{background:#0fbb6b1f}.resource-image.is-locked{cursor:default;pointer-events:none}.resource-description{background:transparent;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;display:block;position:relative;padding:.75rem;text-align:left;text-transform:none;width:100%;max-width:100%;font-size:calc(1.15rem * var(--list-font-scale, 1));white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere}.resource-description:before,.resource-description:after{content:"";position:absolute;pointer-events:none}.resource-description:before{left:0;right:0;top:0;height:2px;background:#0fbb6b}.resource-description:after{top:0;bottom:auto;right:0;width:2px;height:2rem;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 35%,#0fbb6b59 65%,#0fbb6b00)}.resource-description:hover{background:#0fbb6b14}.resource-description.is-locked{cursor:default;pointer-events:none}@media(max-width:720px),(max-height:560px){.inventory-actions{gap:.35rem}.resource-add,.resource-edit,.resource-drop{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.resource-move{flex:0 0 1.6rem;height:2.1rem}}\n'],dependencies:[{kind:"component",type:j,selector:"pip-boy-stat-entry-modal",inputs:["open","title","name","itemNames","sourceItems","autofillEnabled","autofillValue","description","value","valueLabel","valueMin","valueMax","showValue","imageUrl"],outputs:["closeResult","save"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:G,decorators:[{type:a,args:[{selector:"pip-boy-stats-layout",standalone:!0,imports:[j],template:'<div class="resource-layout">\n <div class="resource-list">\n <ul class="resource-list-items">\n @for (item of items(); track item.id) {\n <li>\n <button\n type="button"\n class="resource-list-item"\n [class.is-selected]="selectedId() === item.id"\n (click)="selectItem(item.id)"\n >\n <span class="resource-list-item-name">{{ item.name }}</span>\n @if (showValue()) {\n <span class="resource-list-item-value">{{ item.value }}</span>\n }\n </button>\n </li>\n } @empty {\n <li class="is-empty">No entries available.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="inventory-actions">\n <button type="button" class="resource-add" (click)="openAddModal()">\n + Add\n </button>\n @if (selectedId() !== null) {\n <button type="button" class="resource-edit" (click)="openEditModal()">\n Edit\n </button>\n <button type="button" class="resource-drop" (click)="dropSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n <div class="resources-detail">\n @if (selectedItem()) {\n <button\n type="button"\n class="resource-image"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openEditModal()"\n [attr.aria-label]="\n selectedItem()?.imageId ? \'Edit image\' : \'Select image\'\n "\n >\n @if (selectedItem()?.imageId) {\n <img\n [src]="imageStore.getImageUrl(selectedItem()?.imageId)"\n alt="Selected entry"\n />\n }\n </button>\n <button\n type="button"\n class="resource-description"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openEditModal()"\n [innerHTML]="selectedItem()?.description || \'Add description.\'"\n ></button>\n }\n </div>\n</div>\n<pip-boy-stat-entry-modal\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n [open]="showEditModal()"\n [title]="editModalTitle()"\n [name]="modalName()"\n [itemNames]="itemNames()"\n [sourceItems]="sourceItems()"\n [autofillEnabled]="autofillEnabled()"\n [autofillValue]="autofillValue()"\n [description]="modalDescription()"\n [value]="modalValue()"\n [valueLabel]="valueLabel"\n [valueMin]="valueMin"\n [valueMax]="valueMax"\n [showValue]="showValue()"\n [imageUrl]="modalImage()"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{width:100%;height:100%;display:block;font-size:inherit}.resource-layout{box-sizing:border-box;display:flex;gap:1.5rem;height:100%;min-height:0}.resource-list{display:flex;flex:1 1 55%;flex-direction:column;gap:.5rem;min-height:0}.resource-list-items{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.resource-list-items li{margin:0;padding:0;font-size:inherit}.resource-list-items .is-empty{opacity:.6}.resource-list-item{align-items:center;background:transparent;border:none;color:#0fbb6b;cursor:pointer;display:flex;font-size:inherit;padding:.25rem .35rem .25rem 1.2rem;position:relative;text-align:left;justify-content:space-between;gap:.75rem;width:100%}.resource-list-item:hover{background:#0fbb6b1f}.resource-list-item.is-selected{background:#0fbb6b2e}.resource-list-item.is-selected:before{content:"";position:absolute;left:.35rem;top:50%;transform:translateY(-50%);width:.45rem;height:.45rem;background:#0fbb6b}.resource-list-item-name{flex:1 1 auto}.resource-list-item-value{flex:0 0 auto;min-width:2.5rem;text-align:right}.inventory-actions{display:flex;gap:.5rem}.resource-add{background:#0fbb6b14;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-add:hover{background:#0fbb6b2e}.resource-edit{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-edit:hover{background:#0fbb6b1f}.resource-drop{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-drop:hover{background:#0fbb6b1f}.resource-move{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.resource-move:hover{background:#0fbb6b1f}.resources-detail{display:flex;flex:1 1 45%;flex-direction:column;gap:1rem;height:100%;min-height:0;overflow:auto;padding-bottom:1rem;padding-right:1rem}.resource-image{align-items:center;background:transparent;border:none;cursor:pointer;display:flex;flex:1 1 auto;flex-direction:column;min-height:60%;justify-content:flex-start;padding:1rem;text-transform:uppercase;width:100%}.resource-image span{margin-top:auto;opacity:.7}.resource-image img{align-self:center;max-height:100%;max-width:100%;object-fit:contain;padding:0}.resource-image:hover{background:#0fbb6b1f}.resource-image.is-locked{cursor:default;pointer-events:none}.resource-description{background:transparent;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;display:block;position:relative;padding:.75rem;text-align:left;text-transform:none;width:100%;max-width:100%;font-size:calc(1.15rem * var(--list-font-scale, 1));white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere}.resource-description:before,.resource-description:after{content:"";position:absolute;pointer-events:none}.resource-description:before{left:0;right:0;top:0;height:2px;background:#0fbb6b}.resource-description:after{top:0;bottom:auto;right:0;width:2px;height:2rem;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 35%,#0fbb6b59 65%,#0fbb6b00)}.resource-description:hover{background:#0fbb6b14}.resource-description.is-locked{cursor:default;pointer-events:none}@media(max-width:720px),(max-height:560px){.inventory-actions{gap:.35rem}.resource-add,.resource-edit,.resource-drop{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.resource-move{flex:0 0 1.6rem;height:2.1rem}}\n']}]}],ctorParameters:()=>[],propDecorators:{category:[{type:p}],valueLabel:[{type:p}],valueMin:[{type:p}],valueMax:[{type:p}]}});class Y{open=!1;title="Confirm";message="This action cannot be undone. Are you sure you want to continue?";confirmLabel="Confirm";cancelLabel="Cancel";confirm=new c;closeResult=new c;closeModal(){this.closeResult.emit()}confirmReset(){this.confirm.emit()}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:Y,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"21.0.8",type:Y,isStandalone:!0,selector:"pip-boy-reset-confirm-modal",inputs:{open:"open",title:"title",message:"message",confirmLabel:"confirmLabel",cancelLabel:"cancelLabel"},outputs:{confirm:"confirm",closeResult:"closeResult"},ngImport:e,template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <div class="reset-modal-body">\n <p>{{ message }}</p>\n </div>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">{{ cancelLabel }}</button>\n <button type="button" (click)="confirmReset()">\n {{ confirmLabel }}\n </button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.reset-modal-body p{margin:0;line-height:1.35;color:#0fbb6bd9}:host{font-size:inherit}\n"],dependencies:[{kind:"ngmodule",type:f},{kind:"component",type:B,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:Y,decorators:[{type:a,args:[{selector:"pip-boy-reset-confirm-modal",standalone:!0,imports:[f,B],template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <div class="reset-modal-body">\n <p>{{ message }}</p>\n </div>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">{{ cancelLabel }}</button>\n <button type="button" (click)="confirmReset()">\n {{ confirmLabel }}\n </button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.reset-modal-body p{margin:0;line-height:1.35;color:#0fbb6bd9}:host{font-size:inherit}\n"]}]}],propDecorators:{open:[{type:p}],title:[{type:p}],message:[{type:p}],confirmLabel:[{type:p}],cancelLabel:[{type:p}],confirm:[{type:m}],closeResult:[{type:m}]}});class Q{constructor(){r(()=>{this.open()&&this.draft.set(this.value())})}open=t(!1,...ngDevMode?[{debugName:"open"}]:[]);title=t("Edit Name",...ngDevMode?[{debugName:"title"}]:[]);value=t("",...ngDevMode?[{debugName:"value"}]:[]);placeholder=t("Name",...ngDevMode?[{debugName:"placeholder"}]:[]);allowEmpty=t(!1,...ngDevMode?[{debugName:"allowEmpty"}]:[]);inputType=t("text",...ngDevMode?[{debugName:"inputType"}]:[]);inputMin=t(null,...ngDevMode?[{debugName:"inputMin"}]:[]);inputStep=t(null,...ngDevMode?[{debugName:"inputStep"}]:[]);showNumberControls=t(!1,...ngDevMode?[{debugName:"showNumberControls"}]:[]);closeResult=d();save=d();draft=o("",...ngDevMode?[{debugName:"draft"}]:[]);updateDraft(e){this.draft.set(e.target.value)}closeModal(){this.closeResult.emit()}submit(){const e=this.draft().trim();(e||this.allowEmpty())&&this.save.emit(e),this.closeResult.emit()}adjustValue(e){const t=this.inputStep()??1,n=Number(this.draft());let a=(Number.isFinite(n)?n:this.inputMin()??0)+e*t;const o=this.inputMin();"number"==typeof o&&(a=Math.max(o,a)),this.draft.set(String(a))}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:Q,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:Q,isStandalone:!0,selector:"pip-boy-name-edit-modal",inputs:{open:{classPropertyName:"open",publicName:"open",isSignal:!0,isRequired:!1,transformFunction:null},title:{classPropertyName:"title",publicName:"title",isSignal:!0,isRequired:!1,transformFunction:null},value:{classPropertyName:"value",publicName:"value",isSignal:!0,isRequired:!1,transformFunction:null},placeholder:{classPropertyName:"placeholder",publicName:"placeholder",isSignal:!0,isRequired:!1,transformFunction:null},allowEmpty:{classPropertyName:"allowEmpty",publicName:"allowEmpty",isSignal:!0,isRequired:!1,transformFunction:null},inputType:{classPropertyName:"inputType",publicName:"inputType",isSignal:!0,isRequired:!1,transformFunction:null},inputMin:{classPropertyName:"inputMin",publicName:"inputMin",isSignal:!0,isRequired:!1,transformFunction:null},inputStep:{classPropertyName:"inputStep",publicName:"inputStep",isSignal:!0,isRequired:!1,transformFunction:null},showNumberControls:{classPropertyName:"showNumberControls",publicName:"showNumberControls",isSignal:!0,isRequired:!1,transformFunction:null}},outputs:{closeResult:"closeResult",save:"save"},ngImport:e,template:'<pip-boy-dialog [open]="open()" [title]="title()" (closeResult)="closeModal()">\n <div class="name-modal-body">\n <label class="name-modal-field">\n <span>{{ placeholder() }}</span>\n <div class="number-input-row">\n <input\n [type]="inputType()"\n [attr.min]="inputMin() ?? null"\n [attr.step]="inputStep() ?? null"\n [value]="draft()"\n (input)="updateDraft($event)"\n (keydown.enter)="submit()"\n />\n @if (showNumberControls() && inputType() === \'number\') {\n <div class="number-input-controls">\n <button\n type="button"\n class="number-input-control"\n (click)="adjustValue(1)"\n >\n &#8593;\n </button>\n <button\n type="button"\n class="number-input-control"\n (click)="adjustValue(-1)"\n >\n &#8595;\n </button>\n </div>\n }\n </div>\n </label>\n </div>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="button" (click)="submit()">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.name-modal-body{display:flex;flex-direction:column;gap:.5rem}.name-modal-field{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1.5rem}.name-modal-field span{font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);opacity:.8}.name-modal-field input{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;padding:.5rem .75rem;font:inherit;width:100%}.name-modal-field input:focus{outline:none;border-color:#0fbb6b}.number-input-row{display:flex;align-items:stretch;gap:.5rem}.number-input-row input[type=number]{flex:1 1 auto}.number-input-row input[type=number]::-webkit-outer-spin-button,.number-input-row input[type=number]::-webkit-inner-spin-button{appearance:none;margin:0}.number-input-controls{display:flex;flex-direction:column;gap:.35rem}.number-input-control{flex:1 1 auto;background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.4rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);padding:.2rem .5rem;text-transform:uppercase}.number-input-control:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"],dependencies:[{kind:"component",type:B,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:Q,decorators:[{type:a,args:[{selector:"pip-boy-name-edit-modal",standalone:!0,imports:[B],template:'<pip-boy-dialog [open]="open()" [title]="title()" (closeResult)="closeModal()">\n <div class="name-modal-body">\n <label class="name-modal-field">\n <span>{{ placeholder() }}</span>\n <div class="number-input-row">\n <input\n [type]="inputType()"\n [attr.min]="inputMin() ?? null"\n [attr.step]="inputStep() ?? null"\n [value]="draft()"\n (input)="updateDraft($event)"\n (keydown.enter)="submit()"\n />\n @if (showNumberControls() && inputType() === \'number\') {\n <div class="number-input-controls">\n <button\n type="button"\n class="number-input-control"\n (click)="adjustValue(1)"\n >\n &#8593;\n </button>\n <button\n type="button"\n class="number-input-control"\n (click)="adjustValue(-1)"\n >\n &#8595;\n </button>\n </div>\n }\n </div>\n </label>\n </div>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="button" (click)="submit()">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.name-modal-body{display:flex;flex-direction:column;gap:.5rem}.name-modal-field{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1.5rem}.name-modal-field span{font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);opacity:.8}.name-modal-field input{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;padding:.5rem .75rem;font:inherit;width:100%}.name-modal-field input:focus{outline:none;border-color:#0fbb6b}.number-input-row{display:flex;align-items:stretch;gap:.5rem}.number-input-row input[type=number]{flex:1 1 auto}.number-input-row input[type=number]::-webkit-outer-spin-button,.number-input-row input[type=number]::-webkit-inner-spin-button{appearance:none;margin:0}.number-input-controls{display:flex;flex-direction:column;gap:.35rem}.number-input-control{flex:1 1 auto;background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.4rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);padding:.2rem .5rem;text-transform:uppercase}.number-input-control:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"]}]}],ctorParameters:()=>[],propDecorators:{open:[{type:e.Input,args:[{isSignal:!0,alias:"open",required:!1}]}],title:[{type:e.Input,args:[{isSignal:!0,alias:"title",required:!1}]}],value:[{type:e.Input,args:[{isSignal:!0,alias:"value",required:!1}]}],placeholder:[{type:e.Input,args:[{isSignal:!0,alias:"placeholder",required:!1}]}],allowEmpty:[{type:e.Input,args:[{isSignal:!0,alias:"allowEmpty",required:!1}]}],inputType:[{type:e.Input,args:[{isSignal:!0,alias:"inputType",required:!1}]}],inputMin:[{type:e.Input,args:[{isSignal:!0,alias:"inputMin",required:!1}]}],inputStep:[{type:e.Input,args:[{isSignal:!0,alias:"inputStep",required:!1}]}],showNumberControls:[{type:e.Input,args:[{isSignal:!0,alias:"showNumberControls",required:!1}]}],closeResult:[{type:e.Output,args:["closeResult"]}],save:[{type:e.Output,args:["save"]}]}});class K{settings=l(P);imageStore=l(x);soundStore=l(_);nameDraft=o("",...ngDevMode?[{debugName:"nameDraft"}]:[]);showNameModal=o(!1,...ngDevMode?[{debugName:"showNameModal"}]:[]);showVaultBoyDeleteModal=o(!1,...ngDevMode?[{debugName:"showVaultBoyDeleteModal"}]:[]);extraOptionModal=o(null,...ngDevMode?[{debugName:"extraOptionModal"}]:[]);extraOptionTitle=u(()=>{switch(this.extraOptionModal()){case"STIMPAK":case"LIMBS":return"Edit Text";default:return""}},...ngDevMode?[{debugName:"extraOptionTitle"}]:[]);extraOptionValue=u(()=>{const e=this.extraOptionModal();return"STIMPAK"===e?this.settings.stimpakLabel():"LIMBS"===e?this.settings.limbLabel():""},...ngDevMode?[{debugName:"extraOptionValue"}]:[]);selectVaultBoySlot(e){this.settings.selectedVaultBoyImageIndex.set(e),this.playClickSound()}addVaultBoySlot(){if(this.settings.editLockEnabled())return;if(this.settings.vaultBoyImages().length>=10)return;const e=this.settings.vaultBoyImages().length;this.settings.vaultBoyImages.update(e=>[...e,null]),this.settings.selectedVaultBoyImageIndex.set(e)}async onVaultBoyImageSelected(e){if(this.settings.editLockEnabled())return;const t=e.target,n=t.files?.[0]??null;if(!n)return;const a=await this.imageStore.saveFile(n),o=this.settings.selectedVaultBoyImageIndex();this.settings.vaultBoyImages.update(e=>e.map((e,t)=>t===o?a.id:e)),t.value=""}startNameEdit(){this.settings.editLockEnabled()||(this.nameDraft.set(this.settings.userName()),this.showNameModal.set(!0),this.playClickSound())}closeNameModal(){this.showNameModal.set(!1)}saveNameEdit(e){e.trim()&&this.settings.userName.set(e.trim()),this.closeNameModal()}openVaultBoyDeleteModal(){if(this.settings.editLockEnabled())return;const e=this.settings.vaultBoyImages();if(0===e.length)return;e[this.settings.selectedVaultBoyImageIndex()]?this.showVaultBoyDeleteModal.set(!0):this.confirmVaultBoyDelete()}closeVaultBoyDeleteModal(){this.showVaultBoyDeleteModal.set(!1)}confirmVaultBoyDelete(){if(this.settings.editLockEnabled())return;const e=this.settings.selectedVaultBoyImageIndex();this.settings.vaultBoyImages.update(t=>t.filter((t,n)=>n!==e));const t=this.settings.vaultBoyImages().length,n=0===t?0:Math.min(e,t-1);this.settings.selectedVaultBoyImageIndex.set(n),this.closeVaultBoyDeleteModal()}openExtraOptionModal(e){this.settings.editLockEnabled()||this.extraOptionModal.set(e)}closeExtraOptionModal(){this.extraOptionModal.set(null)}saveExtraOptionModal(e){const t=this.extraOptionModal();"STIMPAK"===t?this.settings.stimpakLabel.set(e):"LIMBS"===t&&this.settings.limbLabel.set(e),this.closeExtraOptionModal()}playClickSound(){this.soundStore.playSound(this.settings.clickSoundId())}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:K,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:K,isStandalone:!0,selector:"pip-boy-cnd-status",ngImport:e,template:'<div class="status-panel">\n <label\n class="status-uploader"\n [class.is-locked]="settings.editLockEnabled()"\n for="status-image-input"\n >\n @if (settings.vaultBoyImages()[settings.selectedVaultBoyImageIndex()]) {\n <img\n [src]="\n imageStore.getImageUrl(\n settings.vaultBoyImages()[settings.selectedVaultBoyImageIndex()]\n )\n "\n alt="Vault Boy"\n />\n } @else if (settings.vaultBoyImages().length > 0) {\n <span>\n {{\n settings.editLockEnabled() ? \'NO IMAGE\' : \'Click to upload an Image\'\n }}\n </span>\n }\n </label>\n <input\n #vaultBoyImageInput\n id="status-image-input"\n type="file"\n accept="image/*"\n [disabled]="settings.editLockEnabled()"\n (change)="onVaultBoyImageSelected($event)"\n />\n <div class="status-slots">\n @for (slot of settings.vaultBoyImages(); track $index) {\n <button\n type="button"\n class="status-slot"\n [class.is-active]="settings.selectedVaultBoyImageIndex() === $index"\n [attr.aria-label]="\'Select action-buttonimage slot \' + ($index + 1)"\n (click)="selectVaultBoySlot($index)"\n ></button>\n }\n @if (!settings.editLockEnabled()) {\n <button\n type="button"\n class="status-slot status-slot--add"\n (click)="addVaultBoySlot()"\n [disabled]="settings.vaultBoyImages().length >= 10"\n >\n +\n </button>\n <button\n type="button"\n class="status-slot status-slot--delete"\n (click)="openVaultBoyDeleteModal()"\n [disabled]="settings.vaultBoyImages().length === 0"\n >\n -\n </button>\n }\n </div>\n <button\n type="button"\n class="user-name"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="startNameEdit()"\n >\n {{ settings.userName() }} - Level {{ settings.userLevel() }}\n </button>\n</div>\n<div class="extra-options">\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'STIMPAK\')"\n >\n {{ settings.stimpakLabel() }}\n </button>\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'LIMBS\')"\n >\n {{ settings.limbLabel() }}\n </button>\n <pip-boy-reset-confirm-modal\n [open]="showVaultBoyDeleteModal()"\n title="Delete image"\n message="This will remove the selected slot. Continue?"\n confirmLabel="Delete"\n (closeResult)="closeVaultBoyDeleteModal()"\n (confirm)="confirmVaultBoyDelete()"\n />\n <pip-boy-name-edit-modal\n [open]="showNameModal()"\n [value]="nameDraft()"\n title="Edit Name"\n placeholder="Name"\n (closeResult)="closeNameModal()"\n (save)="saveNameEdit($event)"\n />\n <pip-boy-name-edit-modal\n [open]="extraOptionModal() !== null"\n [value]="extraOptionValue()"\n [title]="extraOptionTitle()"\n placeholder="Value"\n [allowEmpty]="true"\n (closeResult)="closeExtraOptionModal()"\n (save)="saveExtraOptionModal($event)"\n />\n</div>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:flex;flex:1;gap:1rem;min-height:0;font-size:inherit}.status-panel{align-items:stretch;box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;gap:.75rem;justify-content:flex-start;margin:0 1rem 1rem;min-height:0;overflow:hidden}.status-uploader{align-items:center;cursor:pointer;display:flex;flex:1 1 auto;justify-content:center;min-height:0;overflow:hidden;text-transform:uppercase;width:100%}.status-uploader span{opacity:.7;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.status-uploader img{max-height:100%;max-width:100%;object-fit:contain;padding:.5rem}.status-uploader.is-locked{cursor:default;pointer-events:none}#status-image-input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.status-slots{display:flex;gap:.5rem;flex-wrap:wrap;justify-content:center}.status-slot{background:transparent;border:1px solid rgba(15,187,107,.5);color:#0fbb6b;cursor:pointer;height:2rem;padding:0;width:2rem}.status-slot.is-active{background:#0fbb6b33;border-color:#0fbb6b}.status-slot:disabled{cursor:not-allowed;opacity:.4}.status-slot--add,.status-slot--delete{border-style:dashed}.user-name{align-items:center;background:transparent;border:none;color:#0fbb6b;cursor:pointer;display:inline-flex;justify-content:center;padding:.35rem .75rem;text-align:center;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));width:100%}.user-name:hover{background:#0fbb6b1f}.user-name.is-locked{cursor:default}.extra-options{margin-top:0;display:flex;flex-direction:column;font-family:Roboto Mono,monospace;font-size:calc(clamp(1.05rem,1.05rem + .2rem * (100vw - 360px) / 840px,1.25rem) * var(--list-font-scale, 1));align-items:flex-end;gap:.75rem;white-space:nowrap;position:absolute;top:1rem;right:2rem;z-index:3}.extra-options button{background:transparent;border:none;color:var(--pip-boy-color, #0fbb6b);cursor:pointer;font:inherit;padding:0;white-space:nowrap}.extra-options button:hover{opacity:.8}.extra-options button.is-locked{cursor:default}.extra-options .controller-button{font-size:inherit;white-space:nowrap}.extra-options .controller-button .large-par{display:inline;padding-left:.5rem;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));top:-.15rem;position:relative;white-space:nowrap}\n"],dependencies:[{kind:"component",type:Y,selector:"pip-boy-reset-confirm-modal",inputs:["open","title","message","confirmLabel","cancelLabel"],outputs:["confirm","closeResult"]},{kind:"component",type:Q,selector:"pip-boy-name-edit-modal",inputs:["open","title","value","placeholder","allowEmpty","inputType","inputMin","inputStep","showNumberControls"],outputs:["closeResult","save"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:K,decorators:[{type:a,args:[{selector:"pip-boy-cnd-status",standalone:!0,imports:[Y,Q],template:'<div class="status-panel">\n <label\n class="status-uploader"\n [class.is-locked]="settings.editLockEnabled()"\n for="status-image-input"\n >\n @if (settings.vaultBoyImages()[settings.selectedVaultBoyImageIndex()]) {\n <img\n [src]="\n imageStore.getImageUrl(\n settings.vaultBoyImages()[settings.selectedVaultBoyImageIndex()]\n )\n "\n alt="Vault Boy"\n />\n } @else if (settings.vaultBoyImages().length > 0) {\n <span>\n {{\n settings.editLockEnabled() ? \'NO IMAGE\' : \'Click to upload an Image\'\n }}\n </span>\n }\n </label>\n <input\n #vaultBoyImageInput\n id="status-image-input"\n type="file"\n accept="image/*"\n [disabled]="settings.editLockEnabled()"\n (change)="onVaultBoyImageSelected($event)"\n />\n <div class="status-slots">\n @for (slot of settings.vaultBoyImages(); track $index) {\n <button\n type="button"\n class="status-slot"\n [class.is-active]="settings.selectedVaultBoyImageIndex() === $index"\n [attr.aria-label]="\'Select action-buttonimage slot \' + ($index + 1)"\n (click)="selectVaultBoySlot($index)"\n ></button>\n }\n @if (!settings.editLockEnabled()) {\n <button\n type="button"\n class="status-slot status-slot--add"\n (click)="addVaultBoySlot()"\n [disabled]="settings.vaultBoyImages().length >= 10"\n >\n +\n </button>\n <button\n type="button"\n class="status-slot status-slot--delete"\n (click)="openVaultBoyDeleteModal()"\n [disabled]="settings.vaultBoyImages().length === 0"\n >\n -\n </button>\n }\n </div>\n <button\n type="button"\n class="user-name"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="startNameEdit()"\n >\n {{ settings.userName() }} - Level {{ settings.userLevel() }}\n </button>\n</div>\n<div class="extra-options">\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'STIMPAK\')"\n >\n {{ settings.stimpakLabel() }}\n </button>\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'LIMBS\')"\n >\n {{ settings.limbLabel() }}\n </button>\n <pip-boy-reset-confirm-modal\n [open]="showVaultBoyDeleteModal()"\n title="Delete image"\n message="This will remove the selected slot. Continue?"\n confirmLabel="Delete"\n (closeResult)="closeVaultBoyDeleteModal()"\n (confirm)="confirmVaultBoyDelete()"\n />\n <pip-boy-name-edit-modal\n [open]="showNameModal()"\n [value]="nameDraft()"\n title="Edit Name"\n placeholder="Name"\n (closeResult)="closeNameModal()"\n (save)="saveNameEdit($event)"\n />\n <pip-boy-name-edit-modal\n [open]="extraOptionModal() !== null"\n [value]="extraOptionValue()"\n [title]="extraOptionTitle()"\n placeholder="Value"\n [allowEmpty]="true"\n (closeResult)="closeExtraOptionModal()"\n (save)="saveExtraOptionModal($event)"\n />\n</div>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:flex;flex:1;gap:1rem;min-height:0;font-size:inherit}.status-panel{align-items:stretch;box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;gap:.75rem;justify-content:flex-start;margin:0 1rem 1rem;min-height:0;overflow:hidden}.status-uploader{align-items:center;cursor:pointer;display:flex;flex:1 1 auto;justify-content:center;min-height:0;overflow:hidden;text-transform:uppercase;width:100%}.status-uploader span{opacity:.7;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.status-uploader img{max-height:100%;max-width:100%;object-fit:contain;padding:.5rem}.status-uploader.is-locked{cursor:default;pointer-events:none}#status-image-input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.status-slots{display:flex;gap:.5rem;flex-wrap:wrap;justify-content:center}.status-slot{background:transparent;border:1px solid rgba(15,187,107,.5);color:#0fbb6b;cursor:pointer;height:2rem;padding:0;width:2rem}.status-slot.is-active{background:#0fbb6b33;border-color:#0fbb6b}.status-slot:disabled{cursor:not-allowed;opacity:.4}.status-slot--add,.status-slot--delete{border-style:dashed}.user-name{align-items:center;background:transparent;border:none;color:#0fbb6b;cursor:pointer;display:inline-flex;justify-content:center;padding:.35rem .75rem;text-align:center;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));width:100%}.user-name:hover{background:#0fbb6b1f}.user-name.is-locked{cursor:default}.extra-options{margin-top:0;display:flex;flex-direction:column;font-family:Roboto Mono,monospace;font-size:calc(clamp(1.05rem,1.05rem + .2rem * (100vw - 360px) / 840px,1.25rem) * var(--list-font-scale, 1));align-items:flex-end;gap:.75rem;white-space:nowrap;position:absolute;top:1rem;right:2rem;z-index:3}.extra-options button{background:transparent;border:none;color:var(--pip-boy-color, #0fbb6b);cursor:pointer;font:inherit;padding:0;white-space:nowrap}.extra-options button:hover{opacity:.8}.extra-options button.is-locked{cursor:default}.extra-options .controller-button{font-size:inherit;white-space:nowrap}.extra-options .controller-button .large-par{display:inline;padding-left:.5rem;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));top:-.15rem;position:relative;white-space:nowrap}\n"]}]}]});class Z{options;constructor(e){this.options=e,this.trackSelector=e.trackSelector??".radiation-meter-track",this.indicatorSelector=e.indicatorSelector??".radiation-meter-indicator",this.trackClassName=this.trackSelector.startsWith(".")?this.trackSelector.slice(1):this.trackSelector}isPointerDown=!1;trackSelector;indicatorSelector;trackClassName;startPointer(e){if(0!==e.button)return;this.isPointerDown=!0;const t=this.getCaptureElement(e)??e.currentTarget;t instanceof HTMLElement&&t.setPointerCapture(e.pointerId),this.updateFromPointer(e)}dragPointer(e){this.isPointerDown&&this.updateFromPointer(e)}endPointer(e){if(this.isPointerDown){this.isPointerDown=!1;try{const t=this.getCaptureElement(e)??e.currentTarget;t instanceof HTMLElement&&t.releasePointerCapture(e.pointerId)}catch{}}}updateFromPointer(e){const t=this.getTrackElement(e);if(!t)return;const n=t.getBoundingClientRect();if(!n.width)return;const a=Math.max(0,Math.min(n.width,e.clientX-n.left))/n.width;this.options.onChange(Number(a.toFixed(2)))}getTrackElement(e){const t=e.currentTarget;if(!t)return null;if(t.classList.contains(this.trackClassName))return t;const n=t.closest(".radiation-meter");return n?.querySelector(this.trackSelector)??null}getCaptureElement(e){const t=e.currentTarget;return t?t.classList.contains(this.trackClassName)?t:t.closest(this.indicatorSelector):null}}class X{settings=l(P);pointerHandler=new Z({onChange:e=>this.settings.radMeterLevel.set(e)});showResistModal=o(!1,...ngDevMode?[{debugName:"showResistModal"}]:[]);resistPercent=o(12,...ngDevMode?[{debugName:"resistPercent"}]:[]);ticks=Array.from({length:101},(e,t)=>({large:t%10==0,end:100===t}));getLevelPercent(){return`${Math.round(100*this.settings.radMeterLevel())}%`}getLevelOffsetPercent(){return`${(100*this.settings.radMeterLevel()).toFixed(2)}%`}startPointer(e){this.pointerHandler.startPointer(e)}dragPointer(e){this.pointerHandler.dragPointer(e)}endPointer(e){this.pointerHandler.endPointer(e)}openResistModal(){this.showResistModal.set(!0)}closeResistModal(){this.showResistModal.set(!1)}saveResistModal(e){const t=Number.parseInt(e,10);Number.isFinite(t)&&this.resistPercent.set(Math.max(0,t)),this.closeResistModal()}getResistLabel(){const e=this.resistPercent();return e<=0?"":`RAD RESIST ${e}%`}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:X,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:X,isStandalone:!0,selector:"pip-boy-radiation-meter",ngImport:e,template:'<div class="radiation-panel">\n <div class="radiation-info">\n <button type="button" class="status-resist" (click)="openResistModal()">\n <span class="status-resist-text">{{ getResistLabel() }}</span>\n <span class="status-resist-right">\n <span class="bottom-half-line"></span>\n </span>\n </button>\n </div>\n <div class="radiation-meter">\n <div class="radiation-meter-scale">\n <span class="radiation-meter-scale-mid">500</span>\n <span class="radiation-meter-scale-max">1000</span>\n </div>\n <div class="radiation-meter-grid">\n <div class="status-label">RADS</div>\n <div\n class="radiation-meter-track"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <div class="radiation-meter-labels">\n @for (tick of ticks; track $index) {\n <span\n class="radiation-meter-tick"\n [class.radiation-meter-tick--large]="tick.large"\n [class.radiation-meter-tick--small]="!tick.large"\n [class.radiation-meter-tick--end-triangle]="tick.end"\n ></span>\n }\n </div>\n <div\n class="radiation-meter-fill"\n [style.width]="getLevelPercent()"\n ></div>\n </div>\n <div class="status-right">\n <span class="bottom-half-line"></span>\n </div>\n <div\n class="radiation-meter-indicator"\n aria-hidden="true"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <span\n class="radiation-meter-arrow"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n <span\n class="radiation-meter-handle"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n </div>\n </div>\n </div>\n</div>\n<pip-boy-name-edit-modal\n [open]="showResistModal()"\n title="RAD RESIST"\n [value]="resistPercent().toString()"\n placeholder="Percent"\n inputType="number"\n [inputMin]="0"\n [inputStep]="1"\n [showNumberControls]="true"\n (closeResult)="closeResistModal()"\n (save)="saveResistModal($event)"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:flex;flex:1 1 auto;min-height:0;font-size:inherit;flex-direction:column}.radiation-panel{display:flex;flex-direction:row;align-items:flex-start;gap:0;flex-wrap:nowrap;min-height:0;padding:1rem;width:100%;margin-top:auto;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.radiation-info{display:flex;flex-direction:column;flex:0 0 auto;margin-top:1.7rem}.status-resist{background:transparent;border:none;color:#0fbb6b;cursor:pointer;text-align:left;text-transform:uppercase;font-size:inherit;display:flex;align-items:flex-start;position:relative;margin:0}.status-resist:hover .status-resist-text{background:#ffffff14}.status-resist:hover,.status-resist:focus-visible{background:transparent}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:100%;height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:0;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.status-resist-text{display:flex;align-items:center;align-self:stretch;padding:.5rem .5rem 0;border-top:2px solid #0fbb6b;flex:1 1 auto;min-width:200px;white-space:nowrap}.status-resist-right{width:1.25rem;min-height:1.8rem;position:relative;flex:0 0 auto;align-self:stretch}.status-resist-right .bottom-half-line:before{left:0}.radiation-meter{display:flex;flex-direction:column;gap:.75rem;width:100%;justify-self:stretch;flex:1 1 0;min-width:0;--radiation-triangle-width: 14px}.radiation-meter-scale{position:relative;width:100%;height:1rem;line-height:1rem;text-transform:uppercase;letter-spacing:.08em}.radiation-meter-scale-mid{position:absolute;left:calc(50% + 60px);transform:translate(-50%)}.radiation-meter-scale-max{position:absolute;right:0}.radiation-meter-grid{display:grid;grid-template-columns:auto 1fr auto;grid-template-rows:auto auto;align-items:start;column-gap:0;row-gap:0}.status-label{grid-column:1;grid-row:1;text-transform:uppercase;padding:.5rem 2rem 0 .5rem;border-top:2px solid #0fbb6b;letter-spacing:.08em;white-space:nowrap}.status-right{width:1.25rem;height:100%;position:relative;grid-column:3;grid-row:1;pointer-events:none;border-top:2px solid #0fbb6b}.status-right .bottom-half-line:before{right:0}.radiation-meter-track{grid-column:2;grid-row:1;position:relative;width:100%;height:1.5rem;border-top:2px solid #0fbb6b;overflow:visible;cursor:grab;min-width:0}.radiation-meter-fill{position:absolute;top:0;left:0;height:100%;background:#0fbb6b73;box-shadow:0 0 20px #0fbb6b59}.radiation-meter-labels{position:absolute;top:-1px;left:0;width:100%;height:100%;display:flex;justify-content:space-between;align-items:flex-start;padding:0 .1rem 0 0;pointer-events:none}.radiation-meter-tick{width:2px;background:#0fbb6b99;border-radius:1px}.radiation-meter-tick:first-child{width:var(--radiation-triangle-width);margin-left:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,100% 100%)}.radiation-meter-tick--end-triangle{width:var(--radiation-triangle-width);margin-right:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,0 100%)}.radiation-meter-tick--large{height:65%}.radiation-meter-tick--small{height:35%}.radiation-meter-indicator{grid-column:2;grid-row:2;position:relative;height:2.2rem;width:100%;cursor:grab}.radiation-meter-arrow{position:absolute;top:.1rem;width:0;height:0;border-left:.75rem solid transparent;border-right:.75rem solid transparent;border-bottom:.75rem solid rgba(15,187,107,.7);transform:translate(-50%)}.radiation-meter-handle{position:absolute;top:.8rem;width:4px;height:30px;background:#0fbb6b99;transform:translate(-50%)}.radiation-meter-track:active,.radiation-meter-indicator:active,.radiation-meter-arrow:active,.radiation-meter-handle:active{cursor:grabbing}\n'],dependencies:[{kind:"component",type:Q,selector:"pip-boy-name-edit-modal",inputs:["open","title","value","placeholder","allowEmpty","inputType","inputMin","inputStep","showNumberControls"],outputs:["closeResult","save"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:X,decorators:[{type:a,args:[{selector:"pip-boy-radiation-meter",standalone:!0,imports:[Q],template:'<div class="radiation-panel">\n <div class="radiation-info">\n <button type="button" class="status-resist" (click)="openResistModal()">\n <span class="status-resist-text">{{ getResistLabel() }}</span>\n <span class="status-resist-right">\n <span class="bottom-half-line"></span>\n </span>\n </button>\n </div>\n <div class="radiation-meter">\n <div class="radiation-meter-scale">\n <span class="radiation-meter-scale-mid">500</span>\n <span class="radiation-meter-scale-max">1000</span>\n </div>\n <div class="radiation-meter-grid">\n <div class="status-label">RADS</div>\n <div\n class="radiation-meter-track"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <div class="radiation-meter-labels">\n @for (tick of ticks; track $index) {\n <span\n class="radiation-meter-tick"\n [class.radiation-meter-tick--large]="tick.large"\n [class.radiation-meter-tick--small]="!tick.large"\n [class.radiation-meter-tick--end-triangle]="tick.end"\n ></span>\n }\n </div>\n <div\n class="radiation-meter-fill"\n [style.width]="getLevelPercent()"\n ></div>\n </div>\n <div class="status-right">\n <span class="bottom-half-line"></span>\n </div>\n <div\n class="radiation-meter-indicator"\n aria-hidden="true"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <span\n class="radiation-meter-arrow"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n <span\n class="radiation-meter-handle"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n </div>\n </div>\n </div>\n</div>\n<pip-boy-name-edit-modal\n [open]="showResistModal()"\n title="RAD RESIST"\n [value]="resistPercent().toString()"\n placeholder="Percent"\n inputType="number"\n [inputMin]="0"\n [inputStep]="1"\n [showNumberControls]="true"\n (closeResult)="closeResistModal()"\n (save)="saveResistModal($event)"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:flex;flex:1 1 auto;min-height:0;font-size:inherit;flex-direction:column}.radiation-panel{display:flex;flex-direction:row;align-items:flex-start;gap:0;flex-wrap:nowrap;min-height:0;padding:1rem;width:100%;margin-top:auto;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.radiation-info{display:flex;flex-direction:column;flex:0 0 auto;margin-top:1.7rem}.status-resist{background:transparent;border:none;color:#0fbb6b;cursor:pointer;text-align:left;text-transform:uppercase;font-size:inherit;display:flex;align-items:flex-start;position:relative;margin:0}.status-resist:hover .status-resist-text{background:#ffffff14}.status-resist:hover,.status-resist:focus-visible{background:transparent}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:100%;height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:0;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.status-resist-text{display:flex;align-items:center;align-self:stretch;padding:.5rem .5rem 0;border-top:2px solid #0fbb6b;flex:1 1 auto;min-width:200px;white-space:nowrap}.status-resist-right{width:1.25rem;min-height:1.8rem;position:relative;flex:0 0 auto;align-self:stretch}.status-resist-right .bottom-half-line:before{left:0}.radiation-meter{display:flex;flex-direction:column;gap:.75rem;width:100%;justify-self:stretch;flex:1 1 0;min-width:0;--radiation-triangle-width: 14px}.radiation-meter-scale{position:relative;width:100%;height:1rem;line-height:1rem;text-transform:uppercase;letter-spacing:.08em}.radiation-meter-scale-mid{position:absolute;left:calc(50% + 60px);transform:translate(-50%)}.radiation-meter-scale-max{position:absolute;right:0}.radiation-meter-grid{display:grid;grid-template-columns:auto 1fr auto;grid-template-rows:auto auto;align-items:start;column-gap:0;row-gap:0}.status-label{grid-column:1;grid-row:1;text-transform:uppercase;padding:.5rem 2rem 0 .5rem;border-top:2px solid #0fbb6b;letter-spacing:.08em;white-space:nowrap}.status-right{width:1.25rem;height:100%;position:relative;grid-column:3;grid-row:1;pointer-events:none;border-top:2px solid #0fbb6b}.status-right .bottom-half-line:before{right:0}.radiation-meter-track{grid-column:2;grid-row:1;position:relative;width:100%;height:1.5rem;border-top:2px solid #0fbb6b;overflow:visible;cursor:grab;min-width:0}.radiation-meter-fill{position:absolute;top:0;left:0;height:100%;background:#0fbb6b73;box-shadow:0 0 20px #0fbb6b59}.radiation-meter-labels{position:absolute;top:-1px;left:0;width:100%;height:100%;display:flex;justify-content:space-between;align-items:flex-start;padding:0 .1rem 0 0;pointer-events:none}.radiation-meter-tick{width:2px;background:#0fbb6b99;border-radius:1px}.radiation-meter-tick:first-child{width:var(--radiation-triangle-width);margin-left:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,100% 100%)}.radiation-meter-tick--end-triangle{width:var(--radiation-triangle-width);margin-right:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,0 100%)}.radiation-meter-tick--large{height:65%}.radiation-meter-tick--small{height:35%}.radiation-meter-indicator{grid-column:2;grid-row:2;position:relative;height:2.2rem;width:100%;cursor:grab}.radiation-meter-arrow{position:absolute;top:.1rem;width:0;height:0;border-left:.75rem solid transparent;border-right:.75rem solid transparent;border-bottom:.75rem solid rgba(15,187,107,.7);transform:translate(-50%)}.radiation-meter-handle{position:absolute;top:.8rem;width:4px;height:30px;background:#0fbb6b99;transform:translate(-50%)}.radiation-meter-track:active,.radiation-meter-indicator:active,.radiation-meter-arrow:active,.radiation-meter-handle:active{cursor:grabbing}\n']}]}]});class J{kind=t("H20",...ngDevMode?[{debugName:"kind"}]:[]);settings=l(P);pointerHandler=new Z({onChange:e=>this.setLevel(e)});label=u(()=>this.kind(),...ngDevMode?[{debugName:"label"}]:[]);ticks=Array.from({length:101},(e,t)=>({large:t%10==0,end:100===t}));getLevelPercent(){return`${Math.round(100*this.getLevel())}%`}getLevelOffsetPercent(){return`${(100*this.getLevel()).toFixed(2)}%`}startPointer(e){this.pointerHandler.startPointer(e)}dragPointer(e){this.pointerHandler.dragPointer(e)}endPointer(e){this.pointerHandler.endPointer(e)}getLevel(){switch(this.kind()){case"H20":return this.settings.h20MeterLevel();case"FOD":return this.settings.fodMeterLevel();case"SLP":return this.settings.slpMeterLevel();default:return 0}}setLevel(e){switch(this.kind()){case"H20":this.settings.h20MeterLevel.set(e);break;case"FOD":this.settings.fodMeterLevel.set(e);break;case"SLP":this.settings.slpMeterLevel.set(e)}}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:J,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:J,isStandalone:!0,selector:"pip-boy-status-meter",inputs:{kind:{classPropertyName:"kind",publicName:"kind",isSignal:!0,isRequired:!1,transformFunction:null}},ngImport:e,template:'<div class="radiation-panel">\n <div class="radiation-info">\n <button type="button" class="status-resist" disabled>\n <span class="status-resist-text"></span>\n <span class="status-resist-right">\n <span class="bottom-half-line"></span>\n </span>\n </button>\n </div>\n <div class="radiation-meter">\n <div class="radiation-meter-scale">\n <span class="radiation-meter-scale-mid">500</span>\n <span class="radiation-meter-scale-max">1000</span>\n </div>\n <div class="radiation-meter-grid">\n <div class="status-label">{{ label() }}</div>\n <div\n class="radiation-meter-track"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <div class="radiation-meter-labels">\n @for (tick of ticks; track $index) {\n <span\n class="radiation-meter-tick"\n [class.radiation-meter-tick--large]="tick.large"\n [class.radiation-meter-tick--small]="!tick.large"\n [class.radiation-meter-tick--end-triangle]="tick.end"\n ></span>\n }\n </div>\n <div\n class="radiation-meter-fill"\n [style.width]="getLevelPercent()"\n ></div>\n </div>\n <div class="status-right">\n <span class="bottom-half-line"></span>\n </div>\n <div\n class="radiation-meter-indicator"\n aria-hidden="true"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <span\n class="radiation-meter-arrow"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n <span\n class="radiation-meter-handle"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n </div>\n </div>\n </div>\n</div>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:flex;flex:1 1 auto;min-height:0;font-size:inherit;flex-direction:column}.radiation-panel{display:flex;flex-direction:row;align-items:flex-start;gap:0;flex-wrap:nowrap;min-height:0;padding:1rem;width:100%;margin-top:auto;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.radiation-info{display:flex;flex-direction:column;flex:0 0 auto;margin-top:1.7rem}.status-resist{background:transparent;border:none;color:#0fbb6b;cursor:pointer;text-align:left;text-transform:uppercase;font-size:inherit;display:flex;align-items:flex-start;position:relative;margin:0}.status-resist:hover .status-resist-text{background:#ffffff14}.status-resist:hover,.status-resist:focus-visible{background:transparent}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:100%;height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:0;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.status-resist-text{display:flex;align-items:center;align-self:stretch;padding:.5rem .5rem 0;border-top:2px solid #0fbb6b;flex:1 1 auto;min-width:200px;white-space:nowrap}.status-resist-right{width:1.25rem;min-height:1.8rem;position:relative;flex:0 0 auto;align-self:stretch}.status-resist-right .bottom-half-line:before{left:0}.radiation-meter{display:flex;flex-direction:column;gap:.75rem;width:100%;justify-self:stretch;flex:1 1 0;min-width:0;--radiation-triangle-width: 14px}.radiation-meter-scale{position:relative;width:100%;height:1rem;line-height:1rem;text-transform:uppercase;letter-spacing:.08em}.radiation-meter-scale-mid{position:absolute;left:calc(50% + 60px);transform:translate(-50%)}.radiation-meter-scale-max{position:absolute;right:0}.radiation-meter-grid{display:grid;grid-template-columns:auto 1fr auto;grid-template-rows:auto auto;align-items:start;column-gap:0;row-gap:0}.status-label{grid-column:1;grid-row:1;text-transform:uppercase;padding:.5rem 2rem 0 .5rem;border-top:2px solid #0fbb6b;letter-spacing:.08em;white-space:nowrap}.status-right{width:1.25rem;height:100%;position:relative;grid-column:3;grid-row:1;pointer-events:none;border-top:2px solid #0fbb6b}.status-right .bottom-half-line:before{right:0}.radiation-meter-track{grid-column:2;grid-row:1;position:relative;width:100%;height:1.5rem;border-top:2px solid #0fbb6b;overflow:visible;cursor:grab;min-width:0}.radiation-meter-fill{position:absolute;top:0;left:0;height:100%;background:#0fbb6b73;box-shadow:0 0 20px #0fbb6b59}.radiation-meter-labels{position:absolute;top:-1px;left:0;width:100%;height:100%;display:flex;justify-content:space-between;align-items:flex-start;padding:0 .1rem 0 0;pointer-events:none}.radiation-meter-tick{width:2px;background:#0fbb6b99;border-radius:1px}.radiation-meter-tick:first-child{width:var(--radiation-triangle-width);margin-left:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,100% 100%)}.radiation-meter-tick--end-triangle{width:var(--radiation-triangle-width);margin-right:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,0 100%)}.radiation-meter-tick--large{height:65%}.radiation-meter-tick--small{height:35%}.radiation-meter-indicator{grid-column:2;grid-row:2;position:relative;height:2.2rem;width:100%;cursor:grab}.radiation-meter-arrow{position:absolute;top:.1rem;width:0;height:0;border-left:.75rem solid transparent;border-right:.75rem solid transparent;border-bottom:.75rem solid rgba(15,187,107,.7);transform:translate(-50%)}.radiation-meter-handle{position:absolute;top:.8rem;width:4px;height:30px;background:#0fbb6b99;transform:translate(-50%)}.radiation-meter-track:active,.radiation-meter-indicator:active,.radiation-meter-arrow:active,.radiation-meter-handle:active{cursor:grabbing}\n']})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:J,decorators:[{type:a,args:[{selector:"pip-boy-status-meter",standalone:!0,template:'<div class="radiation-panel">\n <div class="radiation-info">\n <button type="button" class="status-resist" disabled>\n <span class="status-resist-text"></span>\n <span class="status-resist-right">\n <span class="bottom-half-line"></span>\n </span>\n </button>\n </div>\n <div class="radiation-meter">\n <div class="radiation-meter-scale">\n <span class="radiation-meter-scale-mid">500</span>\n <span class="radiation-meter-scale-max">1000</span>\n </div>\n <div class="radiation-meter-grid">\n <div class="status-label">{{ label() }}</div>\n <div\n class="radiation-meter-track"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <div class="radiation-meter-labels">\n @for (tick of ticks; track $index) {\n <span\n class="radiation-meter-tick"\n [class.radiation-meter-tick--large]="tick.large"\n [class.radiation-meter-tick--small]="!tick.large"\n [class.radiation-meter-tick--end-triangle]="tick.end"\n ></span>\n }\n </div>\n <div\n class="radiation-meter-fill"\n [style.width]="getLevelPercent()"\n ></div>\n </div>\n <div class="status-right">\n <span class="bottom-half-line"></span>\n </div>\n <div\n class="radiation-meter-indicator"\n aria-hidden="true"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <span\n class="radiation-meter-arrow"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n <span\n class="radiation-meter-handle"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n </div>\n </div>\n </div>\n</div>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:flex;flex:1 1 auto;min-height:0;font-size:inherit;flex-direction:column}.radiation-panel{display:flex;flex-direction:row;align-items:flex-start;gap:0;flex-wrap:nowrap;min-height:0;padding:1rem;width:100%;margin-top:auto;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.radiation-info{display:flex;flex-direction:column;flex:0 0 auto;margin-top:1.7rem}.status-resist{background:transparent;border:none;color:#0fbb6b;cursor:pointer;text-align:left;text-transform:uppercase;font-size:inherit;display:flex;align-items:flex-start;position:relative;margin:0}.status-resist:hover .status-resist-text{background:#ffffff14}.status-resist:hover,.status-resist:focus-visible{background:transparent}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:100%;height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:0;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.status-resist-text{display:flex;align-items:center;align-self:stretch;padding:.5rem .5rem 0;border-top:2px solid #0fbb6b;flex:1 1 auto;min-width:200px;white-space:nowrap}.status-resist-right{width:1.25rem;min-height:1.8rem;position:relative;flex:0 0 auto;align-self:stretch}.status-resist-right .bottom-half-line:before{left:0}.radiation-meter{display:flex;flex-direction:column;gap:.75rem;width:100%;justify-self:stretch;flex:1 1 0;min-width:0;--radiation-triangle-width: 14px}.radiation-meter-scale{position:relative;width:100%;height:1rem;line-height:1rem;text-transform:uppercase;letter-spacing:.08em}.radiation-meter-scale-mid{position:absolute;left:calc(50% + 60px);transform:translate(-50%)}.radiation-meter-scale-max{position:absolute;right:0}.radiation-meter-grid{display:grid;grid-template-columns:auto 1fr auto;grid-template-rows:auto auto;align-items:start;column-gap:0;row-gap:0}.status-label{grid-column:1;grid-row:1;text-transform:uppercase;padding:.5rem 2rem 0 .5rem;border-top:2px solid #0fbb6b;letter-spacing:.08em;white-space:nowrap}.status-right{width:1.25rem;height:100%;position:relative;grid-column:3;grid-row:1;pointer-events:none;border-top:2px solid #0fbb6b}.status-right .bottom-half-line:before{right:0}.radiation-meter-track{grid-column:2;grid-row:1;position:relative;width:100%;height:1.5rem;border-top:2px solid #0fbb6b;overflow:visible;cursor:grab;min-width:0}.radiation-meter-fill{position:absolute;top:0;left:0;height:100%;background:#0fbb6b73;box-shadow:0 0 20px #0fbb6b59}.radiation-meter-labels{position:absolute;top:-1px;left:0;width:100%;height:100%;display:flex;justify-content:space-between;align-items:flex-start;padding:0 .1rem 0 0;pointer-events:none}.radiation-meter-tick{width:2px;background:#0fbb6b99;border-radius:1px}.radiation-meter-tick:first-child{width:var(--radiation-triangle-width);margin-left:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,100% 100%)}.radiation-meter-tick--end-triangle{width:var(--radiation-triangle-width);margin-right:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,0 100%)}.radiation-meter-tick--large{height:65%}.radiation-meter-tick--small{height:35%}.radiation-meter-indicator{grid-column:2;grid-row:2;position:relative;height:2.2rem;width:100%;cursor:grab}.radiation-meter-arrow{position:absolute;top:.1rem;width:0;height:0;border-left:.75rem solid transparent;border-right:.75rem solid transparent;border-bottom:.75rem solid rgba(15,187,107,.7);transform:translate(-50%)}.radiation-meter-handle{position:absolute;top:.8rem;width:4px;height:30px;background:#0fbb6b99;transform:translate(-50%)}.radiation-meter-track:active,.radiation-meter-indicator:active,.radiation-meter-arrow:active,.radiation-meter-handle:active{cursor:grabbing}\n']}]}],propDecorators:{kind:[{type:e.Input,args:[{isSignal:!0,alias:"kind",required:!1}]}]}});class ee{open=!1;title="Edit Effect";name="";description="";closeResult=new c;save=new c;draftName=o("",...ngDevMode?[{debugName:"draftName"}]:[]);draftDescription=o("",...ngDevMode?[{debugName:"draftDescription"}]:[]);ngOnChanges(e){if(e.open&&this.open)return this.draftName.set(this.name??""),void this.draftDescription.set(this.description??"");e.name&&this.draftName.set(this.name??""),e.description&&this.draftDescription.set(this.description??"")}updateName(e){this.draftName.set(e)}updateDescription(e){this.draftDescription.set(e)}closeModal(){this.closeResult.emit()}submit(e){e.preventDefault();const t=this.draftName().trim();t&&this.save.emit({name:t,description:this.draftDescription().trim()})}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:ee,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"21.0.8",type:ee,isStandalone:!0,selector:"pip-boy-effect-edit-modal",inputs:{open:"open",title:"title",name:"name",description:"description"},outputs:{closeResult:"closeResult",save:"save"},usesOnChanges:!0,ngImport:e,template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <form id="effect-edit-form" (submit)="submit($event)">\n <div class="effect-modal-body">\n <label class="effect-modal-field">\n <span>Name</span>\n <input\n type="text"\n name="effect-name"\n [value]="draftName()"\n (input)="updateName($any($event.target).value)"\n />\n </label>\n <label class="effect-modal-field">\n <span>Description</span>\n <textarea\n name="effect-description"\n rows="5"\n [value]="draftDescription()"\n (input)="updateDescription($any($event.target).value)"\n ></textarea>\n </label>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="effect-edit-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.effect-modal-body{display:flex;flex-direction:column;gap:1rem}.effect-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.effect-modal-field input,.effect-modal-field textarea{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.effect-modal-field input:focus,.effect-modal-field textarea:focus{outline:none;border-color:#0fbb6b}.effect-modal-field textarea{resize:vertical;text-transform:none}:host{font-size:inherit}\n"],dependencies:[{kind:"component",type:B,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:ee,decorators:[{type:a,args:[{selector:"pip-boy-effect-edit-modal",standalone:!0,imports:[B],template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <form id="effect-edit-form" (submit)="submit($event)">\n <div class="effect-modal-body">\n <label class="effect-modal-field">\n <span>Name</span>\n <input\n type="text"\n name="effect-name"\n [value]="draftName()"\n (input)="updateName($any($event.target).value)"\n />\n </label>\n <label class="effect-modal-field">\n <span>Description</span>\n <textarea\n name="effect-description"\n rows="5"\n [value]="draftDescription()"\n (input)="updateDescription($any($event.target).value)"\n ></textarea>\n </label>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="effect-edit-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.effect-modal-body{display:flex;flex-direction:column;gap:1rem}.effect-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.effect-modal-field input,.effect-modal-field textarea{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.effect-modal-field input:focus,.effect-modal-field textarea:focus{outline:none;border-color:#0fbb6b}.effect-modal-field textarea{resize:vertical;text-transform:none}:host{font-size:inherit}\n"]}]}],propDecorators:{open:[{type:p}],title:[{type:p}],name:[{type:p}],description:[{type:p}],closeResult:[{type:m}],save:[{type:m}]}});class te{settings=l(P);selectedId=o(null,...ngDevMode?[{debugName:"selectedId"}]:[]);showEditModal=o(!1,...ngDevMode?[{debugName:"showEditModal"}]:[]);editMode=o("ADD",...ngDevMode?[{debugName:"editMode"}]:[]);modalName=o("",...ngDevMode?[{debugName:"modalName"}]:[]);modalDescription=o("",...ngDevMode?[{debugName:"modalDescription"}]:[]);items=u(()=>this.settings.effectItems(),...ngDevMode?[{debugName:"items"}]:[]);selectedItem=u(()=>{const e=this.selectedId();return null===e?null:this.items().find(t=>t.id===e)??null},...ngDevMode?[{debugName:"selectedItem"}]:[]);openAddModal(){this.settings.editLockEnabled()||(this.editMode.set("ADD"),this.modalName.set(""),this.modalDescription.set(""),this.showEditModal.set(!0))}openEditModal(){if(this.settings.editLockEnabled())return;const e=this.selectedItem();e&&(this.editMode.set("EDIT"),this.modalName.set(e.name),this.modalDescription.set(e.description),this.showEditModal.set(!0))}closeEditModal(){this.showEditModal.set(!1)}saveEditModal(e){if(this.settings.editLockEnabled())return;const t=e.name.trim(),n=e.description.trim();if(!t)return;if("ADD"===this.editMode()){const e=this.getNextItemId();return this.settings.effectItems.update(a=>[...a,{id:e,name:t,description:n}]),this.selectedId.set(e),void this.closeEditModal()}const a=this.selectedId();null!==a&&(this.settings.effectItems.update(e=>e.map(e=>e.id===a?{...e,name:t,description:n}:e)),this.closeEditModal())}selectItem(e){this.selectedId.set(this.selectedId()===e?null:e)}deleteSelected(){if(this.settings.editLockEnabled())return;const e=this.selectedId();null!==e&&(this.settings.effectItems.update(t=>t.filter(t=>t.id!==e)),this.selectedId.set(null))}moveSelected(e){if(this.settings.editLockEnabled())return;const t=this.selectedId();null!==t&&this.settings.effectItems.update(n=>{const a=n.findIndex(e=>e.id===t);if(-1===a)return n;const o=a+e;if(o<0||o>=n.length)return n;const i=n.slice(),[s]=i.splice(a,1);return i.splice(o,0,s),i})}getNextItemId(){return this.items().reduce((e,t)=>Math.max(e,t.id),0)+1}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:te,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:te,isStandalone:!0,selector:"pip-boy-eff-layout",ngImport:e,template:'<div class="eff-layout">\n <ul class="eff-list">\n @for (item of items(); track item.id) {\n <li>\n <button\n type="button"\n class="eff-row"\n [class.is-selected]="selectedId() === item.id"\n (click)="selectItem(item.id)"\n >\n <span class="eff-name">{{ item.name }}</span>\n <span class="eff-description">{{ item.description }}</span>\n </button>\n </li>\n } @empty {\n <li class="eff-empty">No effects added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="eff-actions">\n <button type="button" class="eff-add" (click)="openAddModal()">\n + Add\n </button>\n @if (selectedId() !== null) {\n <button type="button" class="eff-edit" (click)="openEditModal()">\n Edit\n </button>\n <button type="button" class="eff-delete" (click)="deleteSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="eff-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="eff-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n</div>\n<pip-boy-effect-edit-modal\n [open]="showEditModal()"\n [title]="editMode() === \'ADD\' ? \'Add Effect\' : \'Edit Effect\'"\n [name]="modalName()"\n [description]="modalDescription()"\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n/>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:block;width:100%;height:100%;font-size:inherit}.eff-layout{display:flex;flex-direction:column;height:100%;min-height:0}.eff-list{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.75rem 1rem .5rem;display:flex;flex-direction:column;justify-content:center;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.eff-list li{margin:0;padding:0}.eff-row{background:transparent;border:none;border-bottom:2px solid rgba(15,187,107,.6);color:#0fbb6b;cursor:pointer;font-size:inherit;padding:.6rem .2rem;text-align:left;text-transform:none;white-space:normal;width:100%;display:grid;grid-template-columns:1fr 1fr;gap:1rem}.eff-row:hover{background:#0fbb6b1f}.eff-row.is-selected{background:#0fbb6b2e}.eff-list li:last-child .eff-row{border-bottom:none}.eff-name,.eff-description{word-break:break-word;font-size:inherit}.eff-empty{opacity:.6;padding:.4rem .2rem}.eff-actions{display:flex;gap:.5rem;padding:.75rem 1rem 1rem}.eff-add,.eff-edit,.eff-delete{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.eff-add:hover,.eff-edit:hover,.eff-delete:hover{background:#0fbb6b1f}.eff-move{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.eff-move:hover{background:#0fbb6b1f}@media(max-width:720px),(max-height:560px){.eff-actions{gap:.35rem;padding:.75rem .75rem .9rem}.eff-add,.eff-edit,.eff-delete{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.eff-move{flex:0 0 1.6rem;height:2.1rem}}\n"],dependencies:[{kind:"component",type:ee,selector:"pip-boy-effect-edit-modal",inputs:["open","title","name","description"],outputs:["closeResult","save"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:te,decorators:[{type:a,args:[{selector:"pip-boy-eff-layout",standalone:!0,imports:[ee],template:'<div class="eff-layout">\n <ul class="eff-list">\n @for (item of items(); track item.id) {\n <li>\n <button\n type="button"\n class="eff-row"\n [class.is-selected]="selectedId() === item.id"\n (click)="selectItem(item.id)"\n >\n <span class="eff-name">{{ item.name }}</span>\n <span class="eff-description">{{ item.description }}</span>\n </button>\n </li>\n } @empty {\n <li class="eff-empty">No effects added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="eff-actions">\n <button type="button" class="eff-add" (click)="openAddModal()">\n + Add\n </button>\n @if (selectedId() !== null) {\n <button type="button" class="eff-edit" (click)="openEditModal()">\n Edit\n </button>\n <button type="button" class="eff-delete" (click)="deleteSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="eff-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="eff-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n</div>\n<pip-boy-effect-edit-modal\n [open]="showEditModal()"\n [title]="editMode() === \'ADD\' ? \'Add Effect\' : \'Edit Effect\'"\n [name]="modalName()"\n [description]="modalDescription()"\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n/>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:block;width:100%;height:100%;font-size:inherit}.eff-layout{display:flex;flex-direction:column;height:100%;min-height:0}.eff-list{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.75rem 1rem .5rem;display:flex;flex-direction:column;justify-content:center;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.eff-list li{margin:0;padding:0}.eff-row{background:transparent;border:none;border-bottom:2px solid rgba(15,187,107,.6);color:#0fbb6b;cursor:pointer;font-size:inherit;padding:.6rem .2rem;text-align:left;text-transform:none;white-space:normal;width:100%;display:grid;grid-template-columns:1fr 1fr;gap:1rem}.eff-row:hover{background:#0fbb6b1f}.eff-row.is-selected{background:#0fbb6b2e}.eff-list li:last-child .eff-row{border-bottom:none}.eff-name,.eff-description{word-break:break-word;font-size:inherit}.eff-empty{opacity:.6;padding:.4rem .2rem}.eff-actions{display:flex;gap:.5rem;padding:.75rem 1rem 1rem}.eff-add,.eff-edit,.eff-delete{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.eff-add:hover,.eff-edit:hover,.eff-delete:hover{background:#0fbb6b1f}.eff-move{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.eff-move:hover{background:#0fbb6b1f}@media(max-width:720px),(max-height:560px){.eff-actions{gap:.35rem;padding:.75rem .75rem .9rem}.eff-add,.eff-edit,.eff-delete{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.eff-move{flex:0 0 1.6rem;height:2.1rem}}\n"]}]}]});class ne{settings=l(P);soundStore=l(_);selectedQuestId=o(null,...ngDevMode?[{debugName:"selectedQuestId"}]:[]);selectedTaskId=o(null,...ngDevMode?[{debugName:"selectedTaskId"}]:[]);showEditModal=o(!1,...ngDevMode?[{debugName:"showEditModal"}]:[]);editTarget=o("QUEST",...ngDevMode?[{debugName:"editTarget"}]:[]);editMode=o("ADD",...ngDevMode?[{debugName:"editMode"}]:[]);editingTaskId=o(null,...ngDevMode?[{debugName:"editingTaskId"}]:[]);modalName=o("",...ngDevMode?[{debugName:"modalName"}]:[]);quests=u(()=>this.settings.questItems(),...ngDevMode?[{debugName:"quests"}]:[]);selectedQuest=u(()=>{const e=this.selectedQuestId();return null===e?null:this.quests().find(t=>t.id===e)??null},...ngDevMode?[{debugName:"selectedQuest"}]:[]);tasks=u(()=>this.selectedQuest()?.tasks??[],...ngDevMode?[{debugName:"tasks"}]:[]);selectedTask=u(()=>{const e=this.selectedTaskId();return null===e?null:this.tasks().find(t=>t.id===e)??null},...ngDevMode?[{debugName:"selectedTask"}]:[]);modalTitle=u(()=>{const e=this.editTarget(),t=this.editMode();return"TASK"===e?"ADD"===t?"Add Task":"Edit Task":"ADD"===t?"Add Quest":"Edit Quest"},...ngDevMode?[{debugName:"modalTitle"}]:[]);selectQuest(e){const t=this.selectedQuestId()===e?null:e;this.selectedQuestId.set(t),null===t&&this.selectedTaskId.set(null),this.playClickSound()}selectTask(e){this.selectedTaskId.set(this.selectedTaskId()===e?null:e),this.playClickSound()}openAddQuest(){this.settings.editLockEnabled()||(this.editTarget.set("QUEST"),this.editMode.set("ADD"),this.modalName.set(""),this.showEditModal.set(!0))}openEditQuest(e){this.settings.editLockEnabled()||(this.editTarget.set("QUEST"),this.editMode.set("EDIT"),this.modalName.set(e.name),this.selectedQuestId.set(e.id),this.showEditModal.set(!0))}openAddTask(){this.settings.editLockEnabled()||this.selectedQuest()&&(this.editTarget.set("TASK"),this.editMode.set("ADD"),this.editingTaskId.set(null),this.modalName.set(""),this.showEditModal.set(!0))}openEditTask(e){this.settings.editLockEnabled()||(this.editTarget.set("TASK"),this.editMode.set("EDIT"),this.editingTaskId.set(e.id),this.modalName.set(e.name),this.showEditModal.set(!0))}openEditSelectedQuest(){if(this.settings.editLockEnabled())return;const e=this.selectedQuest();e&&(this.playClickSound(),this.openEditQuest(e))}openEditSelectedTask(){if(this.settings.editLockEnabled())return;const e=this.selectedTask();e&&(this.playClickSound(),this.openEditTask(e))}closeEditModal(){this.showEditModal.set(!1)}saveEditModal(e){const t=e.name?.trim()??"";if(!t)return;if("QUEST"===this.editTarget()){if("ADD"===this.editMode()){const e=this.getNextQuestId();this.settings.questItems.update(n=>[...n,{id:e,name:t,completed:!1,tasks:[]}]),this.selectedQuestId.set(e),this.selectedTaskId.set(null)}else{const e=this.selectedQuestId();if(null===e)return;this.settings.questItems.update(n=>n.map(n=>n.id===e?{...n,name:t}:n))}return void this.closeEditModal()}const n=this.selectedQuest();if(n){if("ADD"===this.editMode()){const e=this.getNextTaskId(n);this.settings.questItems.update(a=>a.map(a=>a.id===n.id?{...a,tasks:[...a.tasks,{id:e,name:t,completed:!1}]}:a))}else{const e=this.editingTaskId();if(null===e)return;this.settings.questItems.update(a=>a.map(a=>a.id===n.id?{...a,tasks:a.tasks.map(n=>n.id===e?{...n,name:t}:n)}:a))}this.closeEditModal()}}toggleQuest(e){this.playClickSound(),this.settings.questItems.update(t=>t.map(t=>t.id===e?{...t,completed:!t.completed}:t))}toggleTask(e){const t=this.selectedQuest();t&&(this.playClickSound(),this.settings.questItems.update(n=>n.map(n=>n.id===t.id?{...n,tasks:n.tasks.map(t=>t.id===e?{...t,completed:!t.completed}:t)}:n)))}deleteSelectedQuest(){if(this.settings.editLockEnabled())return;const e=this.selectedQuestId();null!==e&&(this.settings.questItems.update(t=>t.filter(t=>t.id!==e)),this.selectedQuestId.set(null),this.selectedTaskId.set(null))}deleteSelectedTask(){if(this.settings.editLockEnabled())return;const e=this.selectedQuest(),t=this.selectedTaskId();e&&null!==t&&(this.settings.questItems.update(n=>n.map(n=>n.id===e.id?{...n,tasks:n.tasks.filter(e=>e.id!==t)}:n)),this.selectedTaskId.set(null))}moveSelectedQuest(e){if(this.settings.editLockEnabled())return;const t=this.selectedQuestId();null!==t&&this.settings.questItems.update(n=>{const a=n.findIndex(e=>e.id===t);if(-1===a)return n;const o=a+e;if(o<0||o>=n.length)return n;const i=n.slice(),[s]=i.splice(a,1);return i.splice(o,0,s),i})}moveSelectedTask(e){if(this.settings.editLockEnabled())return;const t=this.selectedQuest(),n=this.selectedTaskId();t&&null!==n&&this.settings.questItems.update(a=>a.map(a=>{if(a.id!==t.id)return a;const o=a.tasks.findIndex(e=>e.id===n);if(-1===o)return a;const i=o+e;if(i<0||i>=a.tasks.length)return a;const s=a.tasks.slice(),[r]=s.splice(o,1);return s.splice(i,0,r),{...a,tasks:s}}))}getNextQuestId(){return this.quests().reduce((e,t)=>Math.max(e,t.id),0)+1}getNextTaskId(e){return e.tasks.reduce((e,t)=>Math.max(e,t.id),0)+1}playClickSound(){this.soundStore.playSound(this.settings.clickSoundId())}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:ne,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:ne,isStandalone:!0,selector:"pip-boy-quests-layout",ngImport:e,template:'<div class="quest-layout">\n <div class="quest-column">\n <ul class="quest-list">\n @for (quest of quests(); track quest.id) {\n <li\n class="quest-row"\n [class.is-selected]="selectedQuestId() === quest.id"\n (click)="selectQuest(quest.id)"\n (keyup.enter)="selectQuest(quest.id)"\n tabindex="0"\n >\n <button\n type="button"\n class="quest-toggle"\n [class.is-checked]="quest.completed"\n (click)="toggleQuest(quest.id); $event.stopPropagation()"\n aria-label="Toggle quest"\n ></button>\n <button\n type="button"\n class="quest-name"\n (click)="selectQuest(quest.id); $event.stopPropagation()"\n >\n {{ quest.name }}\n </button>\n </li>\n } @empty {\n <li class="quest-empty">No quests added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="quest-actions">\n <button type="button" class="quest-add" (click)="openAddQuest()">\n + Add\n </button>\n <button\n type="button"\n class="quest-edit"\n [disabled]="!selectedQuest()"\n (click)="openEditSelectedQuest()"\n >\n Edit\n </button>\n <button\n type="button"\n class="quest-delete"\n [disabled]="!selectedQuest()"\n (click)="deleteSelectedQuest()"\n >\n - Delete\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedQuest()"\n (click)="moveSelectedQuest(-1)"\n aria-label="Move quest up"\n >\n ▲\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedQuest()"\n (click)="moveSelectedQuest(1)"\n aria-label="Move quest down"\n >\n ▼\n </button>\n </div>\n }\n </div>\n <div class="quest-column">\n <ul class="quest-list">\n @if (selectedQuest()) {\n @for (task of tasks(); track task.id) {\n <li\n class="quest-row"\n [class.is-selected]="selectedTaskId() === task.id"\n (click)="selectTask(task.id)"\n (keyup.enter)="selectTask(task.id)"\n tabindex="0"\n >\n <button\n type="button"\n class="quest-toggle"\n [class.is-checked]="task.completed"\n (click)="toggleTask(task.id); $event.stopPropagation()"\n aria-label="Toggle task"\n ></button>\n <button\n type="button"\n class="quest-name"\n (click)="selectTask(task.id); $event.stopPropagation()"\n >\n {{ task.name }}\n </button>\n </li>\n } @empty {\n <li class="quest-empty">No tasks added.</li>\n }\n } @else {\n <li class="quest-empty">Select a quest to view tasks.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="quest-actions">\n @if (selectedQuest()) {\n <button type="button" class="quest-add" (click)="openAddTask()">\n + Add\n </button>\n <button\n type="button"\n class="quest-edit"\n [disabled]="!selectedTask()"\n (click)="openEditSelectedTask()"\n >\n Edit\n </button>\n <button\n type="button"\n class="quest-delete"\n [disabled]="!selectedTask()"\n (click)="deleteSelectedTask()"\n >\n - Delete\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedTask()"\n (click)="moveSelectedTask(-1)"\n aria-label="Move task up"\n >\n ▲\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedTask()"\n (click)="moveSelectedTask(1)"\n aria-label="Move task down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n</div>\n<pip-boy-stat-edit-modal\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n [open]="showEditModal()"\n [title]="modalTitle()"\n [name]="modalName()"\n nameLabel="Name"\n [showName]="true"\n [fields]="[]"\n/>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:block;width:100%;height:100%;font-size:inherit}.quest-layout{display:flex;gap:1.5rem;height:100%;min-height:0}.quest-column{display:flex;flex:1 1 50%;flex-direction:column;min-height:0}.quest-list{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.quest-row{align-items:center;display:grid;grid-template-columns:1.5rem 1fr;gap:.6rem;padding:.25rem .35rem .25rem .2rem;font-size:inherit}.quest-row.is-selected{background:#0fbb6b2e}.quest-toggle{background:transparent;border:1px solid rgba(15,187,107,.65);cursor:pointer;height:.9rem;width:.9rem}.quest-toggle.is-checked{background:#0fbb6b}.quest-toggle:disabled{cursor:default;opacity:.6}.quest-name{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font-size:inherit;padding:0;text-align:left}.quest-name:hover{opacity:.8}.quest-empty{opacity:.6;padding:0 .2rem}.quest-actions{display:flex;gap:.5rem;justify-content:flex-end;padding:0}.quest-add{background:#0fbb6b14;border:none;border-left:0;border-right:0;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.quest-add:hover{background:#0fbb6b2e}.quest-edit,.quest-delete{background:#0fbb6b0d;border:none;border-left:0;border-right:0;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.quest-edit:hover,.quest-delete:hover{background:#0fbb6b1f}.quest-edit:disabled,.quest-delete:disabled{cursor:not-allowed;opacity:.5}.quest-move{background:#0fbb6b0d;border:none;border-left:0;border-right:0;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.quest-move:hover{background:#0fbb6b1f}.quest-move:disabled{cursor:not-allowed;opacity:.5}.quest-actions button{flex:1 1 0}.quest-actions .quest-move{flex:0 0 2rem;width:2rem;padding:0}@media(max-width:720px),(max-height:560px){.quest-actions{gap:.35rem}.quest-add,.quest-edit,.quest-delete{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.quest-move,.quest-actions .quest-move{flex:0 0 1.6rem;width:1.6rem;height:2.1rem}}\n"],dependencies:[{kind:"component",type:U,selector:"pip-boy-stat-edit-modal",inputs:["open","title","name","nameLabel","showName","nameOptions","imageUrl","showImage","fields","textFields"],outputs:["closeResult","save","nameChange"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:ne,decorators:[{type:a,args:[{selector:"pip-boy-quests-layout",standalone:!0,imports:[U],template:'<div class="quest-layout">\n <div class="quest-column">\n <ul class="quest-list">\n @for (quest of quests(); track quest.id) {\n <li\n class="quest-row"\n [class.is-selected]="selectedQuestId() === quest.id"\n (click)="selectQuest(quest.id)"\n (keyup.enter)="selectQuest(quest.id)"\n tabindex="0"\n >\n <button\n type="button"\n class="quest-toggle"\n [class.is-checked]="quest.completed"\n (click)="toggleQuest(quest.id); $event.stopPropagation()"\n aria-label="Toggle quest"\n ></button>\n <button\n type="button"\n class="quest-name"\n (click)="selectQuest(quest.id); $event.stopPropagation()"\n >\n {{ quest.name }}\n </button>\n </li>\n } @empty {\n <li class="quest-empty">No quests added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="quest-actions">\n <button type="button" class="quest-add" (click)="openAddQuest()">\n + Add\n </button>\n <button\n type="button"\n class="quest-edit"\n [disabled]="!selectedQuest()"\n (click)="openEditSelectedQuest()"\n >\n Edit\n </button>\n <button\n type="button"\n class="quest-delete"\n [disabled]="!selectedQuest()"\n (click)="deleteSelectedQuest()"\n >\n - Delete\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedQuest()"\n (click)="moveSelectedQuest(-1)"\n aria-label="Move quest up"\n >\n ▲\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedQuest()"\n (click)="moveSelectedQuest(1)"\n aria-label="Move quest down"\n >\n ▼\n </button>\n </div>\n }\n </div>\n <div class="quest-column">\n <ul class="quest-list">\n @if (selectedQuest()) {\n @for (task of tasks(); track task.id) {\n <li\n class="quest-row"\n [class.is-selected]="selectedTaskId() === task.id"\n (click)="selectTask(task.id)"\n (keyup.enter)="selectTask(task.id)"\n tabindex="0"\n >\n <button\n type="button"\n class="quest-toggle"\n [class.is-checked]="task.completed"\n (click)="toggleTask(task.id); $event.stopPropagation()"\n aria-label="Toggle task"\n ></button>\n <button\n type="button"\n class="quest-name"\n (click)="selectTask(task.id); $event.stopPropagation()"\n >\n {{ task.name }}\n </button>\n </li>\n } @empty {\n <li class="quest-empty">No tasks added.</li>\n }\n } @else {\n <li class="quest-empty">Select a quest to view tasks.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="quest-actions">\n @if (selectedQuest()) {\n <button type="button" class="quest-add" (click)="openAddTask()">\n + Add\n </button>\n <button\n type="button"\n class="quest-edit"\n [disabled]="!selectedTask()"\n (click)="openEditSelectedTask()"\n >\n Edit\n </button>\n <button\n type="button"\n class="quest-delete"\n [disabled]="!selectedTask()"\n (click)="deleteSelectedTask()"\n >\n - Delete\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedTask()"\n (click)="moveSelectedTask(-1)"\n aria-label="Move task up"\n >\n ▲\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedTask()"\n (click)="moveSelectedTask(1)"\n aria-label="Move task down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n</div>\n<pip-boy-stat-edit-modal\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n [open]="showEditModal()"\n [title]="modalTitle()"\n [name]="modalName()"\n nameLabel="Name"\n [showName]="true"\n [fields]="[]"\n/>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:block;width:100%;height:100%;font-size:inherit}.quest-layout{display:flex;gap:1.5rem;height:100%;min-height:0}.quest-column{display:flex;flex:1 1 50%;flex-direction:column;min-height:0}.quest-list{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.quest-row{align-items:center;display:grid;grid-template-columns:1.5rem 1fr;gap:.6rem;padding:.25rem .35rem .25rem .2rem;font-size:inherit}.quest-row.is-selected{background:#0fbb6b2e}.quest-toggle{background:transparent;border:1px solid rgba(15,187,107,.65);cursor:pointer;height:.9rem;width:.9rem}.quest-toggle.is-checked{background:#0fbb6b}.quest-toggle:disabled{cursor:default;opacity:.6}.quest-name{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font-size:inherit;padding:0;text-align:left}.quest-name:hover{opacity:.8}.quest-empty{opacity:.6;padding:0 .2rem}.quest-actions{display:flex;gap:.5rem;justify-content:flex-end;padding:0}.quest-add{background:#0fbb6b14;border:none;border-left:0;border-right:0;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.quest-add:hover{background:#0fbb6b2e}.quest-edit,.quest-delete{background:#0fbb6b0d;border:none;border-left:0;border-right:0;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.quest-edit:hover,.quest-delete:hover{background:#0fbb6b1f}.quest-edit:disabled,.quest-delete:disabled{cursor:not-allowed;opacity:.5}.quest-move{background:#0fbb6b0d;border:none;border-left:0;border-right:0;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.quest-move:hover{background:#0fbb6b1f}.quest-move:disabled{cursor:not-allowed;opacity:.5}.quest-actions button{flex:1 1 0}.quest-actions .quest-move{flex:0 0 2rem;width:2rem;padding:0}@media(max-width:720px),(max-height:560px){.quest-actions{gap:.35rem}.quest-add,.quest-edit,.quest-delete{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.quest-move,.quest-actions .quest-move{flex:0 0 1.6rem;width:1.6rem;height:2.1rem}}\n"]}]}]});class ae{soundStore=l(_);audio=null;audioUrl=null;currentChannel=null;currentSoundId=null;volumeByChannel=new Map;endedHandlers=new Map;playingSignals={NOTES:o(!1),RADIO:o(!1)};currentChannelSignal=o(null,...ngDevMode?[{debugName:"currentChannelSignal"}]:[]);currentSoundIdSignal=o(null,...ngDevMode?[{debugName:"currentSoundIdSignal"}]:[]);analyserByChannel=new Map;sourceByChannel=new Map;audioContext=null;setPlaying(e,t){this.playingSignals[e].set(t)}updateEndedHandler(){if(!this.audio||!this.currentChannel)return;const e=this.currentChannel,t=this.endedHandlers.get(e);this.audio.onended=()=>{this.setPlaying(e,!1),t?.()}}getAudioContext(){if(this.audioContext)return this.audioContext;if("undefined"==typeof window)return null;if("undefined"!=typeof AudioContext)this.audioContext=new AudioContext;else{if(void 0===window.webkitAudioContext)return null;this.audioContext=new window.webkitAudioContext}return this.audioContext}attachAnalyser(e,t){this.detachAnalyser(e);const n=this.getAudioContext();if(!n)return;"suspended"===n.state&&n.resume();const a=n.createMediaElementSource(t),o=n.createAnalyser();o.fftSize=256,a.connect(o),o.connect(n.destination),this.analyserByChannel.set(e,o),this.sourceByChannel.set(e,a)}detachAnalyser(e){const t=this.analyserByChannel.get(e);t&&t.disconnect();const n=this.sourceByChannel.get(e);n&&n.disconnect(),this.analyserByChannel.delete(e),this.sourceByChannel.delete(e)}setOnEnded(e,t){this.endedHandlers.set(e,t),this.currentChannel===e&&this.audio&&this.updateEndedHandler()}getCurrentSoundId(e){return this.currentChannelSignal()!==e?null:this.currentSoundIdSignal()}isPlaying(e){return this.playingSignals[e]()}async play(e,t){if(!t)return;if(this.audio&&this.currentChannel===e&&this.currentSoundId===t){try{await this.audio.play(),this.setPlaying(e,!0)}catch{this.setPlaying(e,!1)}return}this.stop();const n=await this.soundStore.getRecord(t);if(!n)return;const a=URL.createObjectURL(n.blob),o=new Audio(a),i=this.volumeByChannel.get(e);"number"==typeof i&&(o.volume=Math.min(1,Math.max(0,i))),this.audio=o,this.audioUrl=a,this.currentChannel=e,this.currentSoundId=t,this.currentChannelSignal.set(e),this.currentSoundIdSignal.set(t),this.attachAnalyser(e,o),this.updateEndedHandler();try{await o.play(),this.setPlaying(e,!0)}catch{this.setPlaying(e,!1)}}async toggle(e,t){if(this.audio&&this.currentChannel===e&&this.currentSoundId===t)if(this.audio.paused)try{await this.audio.play(),this.setPlaying(e,!0)}catch{this.setPlaying(e,!1)}else this.audio.pause(),this.setPlaying(e,!1);else await this.play(e,t)}pause(e){this.audio&&this.currentChannel===e&&(this.audio.pause(),this.setPlaying(e,!1))}stop(e){e&&this.currentChannel!==e||(this.audio&&(this.audio.pause(),this.audio.currentTime=0),this.audioUrl&&URL.revokeObjectURL(this.audioUrl),e?this.detachAnalyser(e):this.currentChannel&&this.detachAnalyser(this.currentChannel),e&&this.setPlaying(e,!1),this.currentChannel&&this.setPlaying(this.currentChannel,!1),this.audio=null,this.audioUrl=null,this.currentChannel=null,this.currentSoundId=null,this.currentChannelSignal.set(null),this.currentSoundIdSignal.set(null))}fillWaveform(e,t){const n=this.analyserByChannel.get(e);return!!n&&(n.getByteTimeDomainData(t),!0)}setVolume(e,t){const n=Math.min(1,Math.max(0,t));this.volumeByChannel.set(e,n),this.audio&&this.currentChannel===e&&(this.audio.volume=n)}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:ae,deps:[],target:e.ɵɵFactoryTarget.Injectable});static"ɵprov"=e.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:ae,providedIn:"root"})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:ae,decorators:[{type:i,args:[{providedIn:"root"}]}]});class oe{openValue=!1;nameValue="";fileLabelValue=null;set open(e){this.openValue=e,e&&(this.draftName.set(this.nameValue??""),this.draftFileLabel.set(this.fileLabelValue),this.draftFile=null)}get open(){return this.openValue}set name(e){this.nameValue=e??"",this.openValue&&this.draftName.set(this.nameValue)}get name(){return this.nameValue}set fileLabel(e){this.fileLabelValue=e,this.openValue&&this.draftFileLabel.set(e)}get fileLabel(){return this.fileLabelValue}title="Edit Audio";nameLabel="Song Name";fileFieldLabel="Song File";selectLabel="Select Song";closeResult=new c;save=new c;draftName=o("",...ngDevMode?[{debugName:"draftName"}]:[]);draftFileLabel=o(null,...ngDevMode?[{debugName:"draftFileLabel"}]:[]);draftFile=null;closeModal(){this.closeResult.emit()}updateName(e){this.draftName.set(e)}onFileSelected(e){const t=e.target,n=t.files?.[0]??null;this.draftFile=n,this.draftFileLabel.set(n?.name??this.fileLabel),t&&(t.value="")}removeFile(){this.draftFile=null,this.draftFileLabel.set(null)}submit(e){e.preventDefault();const t=this.draftName().trim();t&&this.save.emit({name:t,file:this.draftFile})}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:oe,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:oe,isStandalone:!0,selector:"pip-boy-audio-edit-modal",inputs:{open:"open",name:"name",fileLabel:"fileLabel",title:"title",nameLabel:"nameLabel",fileFieldLabel:"fileFieldLabel",selectLabel:"selectLabel"},outputs:{closeResult:"closeResult",save:"save"},ngImport:e,template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <form id="audio-edit-form" (submit)="submit($event)">\n <div class="audio-modal-body">\n <label class="audio-modal-field">\n <span>{{ nameLabel }}</span>\n <input\n type="text"\n [value]="draftName()"\n (input)="updateName($any($event.target).value)"\n />\n </label>\n <div class="audio-modal-field">\n <span>{{ fileFieldLabel }}</span>\n <div class="audio-modal-file-row">\n <button\n type="button"\n class="audio-modal-file-button"\n (click)="audioFileInput.click()"\n >\n {{ draftFileLabel() ?? selectLabel }}\n </button>\n @if (draftFileLabel()) {\n <button\n type="button"\n class="audio-modal-file-remove"\n (click)="removeFile()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #audioFileInput\n type="file"\n accept="audio/*"\n (change)="onFileSelected($event)"\n />\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="audio-edit-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.audio-modal-body{display:flex;flex-direction:column;gap:1rem}.audio-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.audio-modal-field input{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.audio-modal-field input:focus{outline:none;border-color:#0fbb6b}.audio-modal-file-row{display:flex;gap:.5rem;align-items:center}.audio-modal-file-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;flex:1 1 auto;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.audio-modal-file-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.audio-modal-file-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.audio-modal-file-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}:host{font-size:inherit}\n"],dependencies:[{kind:"component",type:B,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:oe,decorators:[{type:a,args:[{selector:"pip-boy-audio-edit-modal",standalone:!0,imports:[B],template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <form id="audio-edit-form" (submit)="submit($event)">\n <div class="audio-modal-body">\n <label class="audio-modal-field">\n <span>{{ nameLabel }}</span>\n <input\n type="text"\n [value]="draftName()"\n (input)="updateName($any($event.target).value)"\n />\n </label>\n <div class="audio-modal-field">\n <span>{{ fileFieldLabel }}</span>\n <div class="audio-modal-file-row">\n <button\n type="button"\n class="audio-modal-file-button"\n (click)="audioFileInput.click()"\n >\n {{ draftFileLabel() ?? selectLabel }}\n </button>\n @if (draftFileLabel()) {\n <button\n type="button"\n class="audio-modal-file-remove"\n (click)="removeFile()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #audioFileInput\n type="file"\n accept="audio/*"\n (change)="onFileSelected($event)"\n />\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="audio-edit-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.audio-modal-body{display:flex;flex-direction:column;gap:1rem}.audio-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.audio-modal-field input{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.audio-modal-field input:focus{outline:none;border-color:#0fbb6b}.audio-modal-file-row{display:flex;gap:.5rem;align-items:center}.audio-modal-file-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;flex:1 1 auto;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.audio-modal-file-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.audio-modal-file-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.audio-modal-file-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}:host{font-size:inherit}\n"]}]}],propDecorators:{open:[{type:p}],name:[{type:p}],fileLabel:[{type:p}],title:[{type:p}],nameLabel:[{type:p}],fileFieldLabel:[{type:p}],selectLabel:[{type:p}],closeResult:[{type:m}],save:[{type:m}]}});class ie{constructor(){r(()=>{const e=this.items(),t=this.selectedId();e.length?null!==t&&e.some(e=>e.id===t)||this.setSelectedId(e[0].id):null!==t&&this.setSelectedId(null)}),r(()=>{this.settings.playbackResetToken(),this.autoplayEnabled.set(!1),this.shuffleEnabled.set(!1),this.currentPlayingId.set(null)}),r(()=>{const e=this.audioPlayer.getCurrentSoundId(this.getChannel());if(!e)return void(null!==this.currentPlayingId()&&this.currentPlayingId.set(null));const t=this.items().find(t=>t.soundId===e);t?this.currentPlayingId()!==t.id&&this.currentPlayingId.set(t.id):null!==this.currentPlayingId()&&this.currentPlayingId.set(null)})}category="NOTES";waveformColorRgb="116, 255, 126";settings=l(P);soundStore=l(_);audioPlayer=l(ae);showEditModal=o(!1,...ngDevMode?[{debugName:"showEditModal"}]:[]);editMode=o("ADD",...ngDevMode?[{debugName:"editMode"}]:[]);modalName=o("",...ngDevMode?[{debugName:"modalName"}]:[]);modalFileLabel=o(null,...ngDevMode?[{debugName:"modalFileLabel"}]:[]);autoplayEnabled=o(!1,...ngDevMode?[{debugName:"autoplayEnabled"}]:[]);shuffleEnabled=o(!1,...ngDevMode?[{debugName:"shuffleEnabled"}]:[]);currentPlayingId=o(null,...ngDevMode?[{debugName:"currentPlayingId"}]:[]);channelPlaying=u(()=>this.audioPlayer.isPlaying(this.getChannel()),...ngDevMode?[{debugName:"channelPlaying"}]:[]);waveformCanvas=b("waveformCanvas",...ngDevMode?[{debugName:"waveformCanvas"}]:[]);animationFrameId=null;animationAngle=0;waveformResizeObserver=null;lastWaveformPixelRatio=1;waveformSamples=new Uint8Array(new ArrayBuffer(256));items=u(()=>this.getItems(),...ngDevMode?[{debugName:"items"}]:[]);selectedItem=u(()=>{const e=this.selectedId();return null===e?null:this.items().find(t=>t.id===e)??null},...ngDevMode?[{debugName:"selectedItem"}]:[]);modalTitle=u(()=>{const e=this.editMode(),t="RADIO"===this.category?"Radio":"Note";return"ADD"===e?`Add ${t}`:`Edit ${t}`},...ngDevMode?[{debugName:"modalTitle"}]:[]);modalLabelPrefix=u(()=>"RADIO"===this.category?"Song":"Note",...ngDevMode?[{debugName:"modalLabelPrefix"}]:[]);currentPlayingName=u(()=>{const e=this.currentPlayingId();return null===e?"":this.items().find(t=>t.id===e)?.name??""},...ngDevMode?[{debugName:"currentPlayingName"}]:[]);ngOnInit(){this.audioPlayer.setOnEnded(this.getChannel(),this.onEndedHandler)}ngAfterViewInit(){this.updateWaveformCanvasSize(),this.attachWaveformResizeObserver(),this.startWaveAnimation()}ngOnDestroy(){"NOTES"===this.category&&this.audioPlayer.stop("NOTES"),this.audioPlayer.setOnEnded(this.getChannel(),null),this.stopWaveAnimation(),this.waveformResizeObserver?.disconnect(),this.waveformResizeObserver=null}onEndedHandler=()=>{this.autoplayEnabled()?this.playNext():this.currentPlayingId.set(null)};openAddModal(){this.settings.editLockEnabled()||(this.editMode.set("ADD"),this.modalName.set(""),this.modalFileLabel.set(null),this.showEditModal.set(!0))}openEditModal(){if(this.settings.editLockEnabled())return;const e=this.selectedItem();e&&(this.editMode.set("EDIT"),this.modalName.set(e.name),this.modalFileLabel.set(this.soundStore.getSoundLabel(e.soundId)),this.showEditModal.set(!0),this.playClickSound())}closeEditModal(){this.showEditModal.set(!1)}selectItem(e){const t=this.selectedId();this.setSelectedId(t===e?null:e),this.playClickSound()}async saveEditModal(e){if(this.settings.editLockEnabled())return;const t=e.name.trim();if(!t)return;if("ADD"===this.editMode()){if(!e.file)return;const n=await this.soundStore.saveFile(e.file),a=this.getNextItemId();return this.updateItems(e=>[...e,{id:a,name:t,soundId:n.id}]),this.setSelectedId(a),void this.closeEditModal()}const n=this.selectedId();if(null!==n){if(e.file){const a=await this.soundStore.saveFile(e.file);this.updateItems(e=>e.map(e=>e.id===n?{...e,name:t,soundId:a.id}:e))}else this.updateItems(e=>e.map(e=>e.id===n?{...e,name:t}:e));this.closeEditModal()}}deleteSelected(){if(this.settings.editLockEnabled())return;const e=this.selectedId();null!==e&&(this.updateItems(t=>t.filter(t=>t.id!==e)),this.setSelectedId(null),this.audioPlayer.stop(this.getChannel()),this.currentPlayingId.set(null))}moveSelected(e){if(this.settings.editLockEnabled())return;const t=this.selectedId();null!==t&&this.updateItems(n=>{const a=n.findIndex(e=>e.id===t);if(-1===a)return n;const o=a+e;if(o<0||o>=n.length)return n;const i=n.slice(),[s]=i.splice(a,1);return i.splice(o,0,s),i})}async playSelected(){const e=this.items();if(!e.length)return;let t=this.selectedItem();t||(t=e[0],this.setSelectedId(t.id)),this.currentPlayingId.set(t.id),this.audioPlayer.setVolume(this.getChannel(),this.getVolumePercent()/100),await this.audioPlayer.play(this.getChannel(),t.soundId)}async playNextManual(){const e=this.items();if(!e.length)return;const t=this.currentPlayingId(),n=this.selectedId(),a=e.findIndex(e=>e.id===(t??n));let o;if(this.shuffleEnabled()&&e.length>1)do{o=Math.floor(Math.random()*e.length)}while(o===a);else o=-1===a?0:(a+1)%e.length;const i=e[o];this.setSelectedId(i.id),this.currentPlayingId.set(i.id),this.audioPlayer.setVolume(this.getChannel(),this.getVolumePercent()/100),await this.audioPlayer.play(this.getChannel(),i.soundId)}async playPreviousManual(){const e=this.items();if(!e.length)return;const t=this.currentPlayingId(),n=this.selectedId(),a=e.findIndex(e=>e.id===(t??n));let o;if(this.shuffleEnabled()&&e.length>1)do{o=Math.floor(Math.random()*e.length)}while(o===a);else o=a<=0?e.length-1:a-1;const i=e[o];this.setSelectedId(i.id),this.currentPlayingId.set(i.id),this.audioPlayer.setVolume(this.getChannel(),this.getVolumePercent()/100),await this.audioPlayer.play(this.getChannel(),i.soundId)}pauseSelected(){this.audioPlayer.pause(this.getChannel())}stopSelected(){this.audioPlayer.stop(this.getChannel()),this.currentPlayingId.set(null),this.autoplayEnabled.set(!1),this.shuffleEnabled.set(!1)}updateVolume(e){const t=Number(e);if(!Number.isFinite(t))return;const n=Math.min(100,Math.max(0,t));this.setVolumePercent(n),this.audioPlayer.setVolume(this.getChannel(),n/100)}toggleAutoplay(){const e=!this.autoplayEnabled();this.autoplayEnabled.set(e),e||this.shuffleEnabled.set(!1)}toggleShuffle(){this.shuffleEnabled.update(e=>!e)}isChannelPlaying(){return this.channelPlaying()}startWaveAnimation(){null===this.animationFrameId&&(this.animationFrameId=requestAnimationFrame(this.animateWaveform))}stopWaveAnimation(){null!==this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}animateWaveform=()=>{this.drawWaveformFrame(),this.animationFrameId=requestAnimationFrame(this.animateWaveform)};drawWaveformFrame(){const e=this.getWaveCanvas();if(!e)return;this.updateWaveformCanvasSize();const t=e.getContext("2d");if(!t)return;const n=this.lastWaveformPixelRatio,a=e.width/n,o=e.height/n;t.setTransform(n,0,0,n,0,0),t.clearRect(0,0,a,o);const i=this.channelPlaying(),s=i?.35*o:.04*o,r=o/2+(i?4*Math.sin(.7*this.animationAngle):0);t.lineJoin="round",t.lineCap="round",t.lineWidth=i?2.4:1,t.strokeStyle=i?this.waveformColor(.95):this.waveformColor(.25),t.shadowBlur=i?8:2,t.shadowColor=i?this.waveformColor(.6):this.waveformColor(.35);const l=this.audioPlayer.fillWaveform(this.getChannel(),this.waveformSamples);if(t.beginPath(),l){let e=0;for(const t of this.waveformSamples){const n=Math.abs(t-128)/128;e=Math.max(e,n)}const n=Math.min(1,1.4*Math.pow(e,.6)),i=o*Math.max(.3,.95*n),s=a/(this.waveformSamples.length-1);for(let e=0;e<this.waveformSamples.length;e+=1){const n=e*s,a=r+(this.waveformSamples[e]-128)/128*i;0===e?t.moveTo(n,a):t.lineTo(n,a)}}else{const e=i?4:1;for(let n=0;n<=a;n+=1){const o=n/a,i=r+Math.sin(this.animationAngle+o*Math.PI*3)*s*(.65+.35*o)+Math.sin(1.4*this.animationAngle+o*Math.PI*4)*e;0===n?t.moveTo(n,i):t.lineTo(n,i)}}t.stroke(),this.drawWaveformTicks(t,a,o),this.drawWaveformBottomTicks(t,a,o),this.animationAngle+=.04}waveformColor(e){return`rgba(${this.waveformColorRgb}, ${e})`}drawWaveformTicks(e,t,n){const a=this.getWaveformTickMetrics(),o=a.spacing,i=a.smallTick,s=a.bigTick,r=a.bottomPadding;e.save(),e.strokeStyle=this.waveformColor(.5),e.lineWidth=1,e.beginPath();const l=this.getWaveformTickCount(t,n,o,r);for(let n=0;n<=l;n+=1){const a=n*o+.5,r=n%5==0?s:i;e.moveTo(t-1,a),e.lineTo(t-1-r,a)}e.stroke(),e.restore()}drawWaveformBottomTicks(e,t,n){e.save(),e.strokeStyle=this.waveformColor(.5),e.lineWidth=1,e.beginPath();const a=Math.floor((t-8)/6);for(let t=0;t<=a;t+=1){const a=6*t+.5,o=t%6==0?12:6;e.moveTo(a,n-1),e.lineTo(a,n-1-o)}e.stroke(),e.restore()}getWaveformTickMetrics(){return{spacing:6,smallTick:6,bigTick:12,bottomPadding:8}}getWaveformTickCount(e,t,n,a){const o=Math.floor((t-a)/n),i=o+1;if(e<=0||t<=0)return o;const s="undefined"==typeof window?e:window.innerWidth;if(!(s>("undefined"==typeof window?t:window.innerHeight)))return o;if(s<=800){const e=Math.max(0,Math.min(800,s)),t=e<=400?0:(e-400)/400,n=Math.round(20+10*t),a=Math.min(Math.max(1,n),i);return Math.max(0,a-1)}return o}getWaveCanvas(){const e=this.waveformCanvas();return e?e.nativeElement:null}attachWaveformResizeObserver(){const e=this.getWaveCanvas();e&&"undefined"!=typeof ResizeObserver&&(this.waveformResizeObserver=new ResizeObserver(()=>{this.updateWaveformCanvasSize()}),this.waveformResizeObserver.observe(e))}updateWaveformCanvasSize(){const e=this.getWaveCanvas();if(!e)return;const t=e.getBoundingClientRect();if(!t.width||!t.height)return;const n=Math.max(1,window.devicePixelRatio||1),a=Math.max(1,Math.floor(t.width*n)),o=Math.max(1,Math.floor(t.height*n));e.width===a&&e.height===o&&this.lastWaveformPixelRatio===n||(this.lastWaveformPixelRatio=n,e.width=a,e.height=o)}async playNext(){const e=this.items();if(!e.length)return;const t=this.currentPlayingId(),n=this.selectedId(),a=e.findIndex(e=>e.id===(t??n));let o;if(this.shuffleEnabled())if(1===e.length)o=0;else do{o=Math.floor(Math.random()*e.length)}while(o===a);else o=-1===a?0:(a+1)%e.length;const i=e[o];this.setSelectedId(i.id),this.currentPlayingId.set(i.id),this.audioPlayer.setVolume(this.getChannel(),this.getVolumePercent()/100),await this.audioPlayer.play(this.getChannel(),i.soundId)}getChannel(){return"RADIO"===this.category?"RADIO":"NOTES"}getVolumePercent(){return"RADIO"===this.category?this.settings.radioVolume():this.settings.notesVolume()}setVolumePercent(e){"RADIO"===this.category?this.settings.radioVolume.set(e):this.settings.notesVolume.set(e)}getItems(){return"RADIO"===this.category?this.settings.radioItems():this.settings.notesItems()}updateItems(e){"RADIO"===this.category?this.settings.radioItems.update(e):this.settings.notesItems.update(e)}selectedId(){return"RADIO"===this.category?this.settings.selectedRadioItemId():this.settings.selectedNotesItemId()}setSelectedId(e){"RADIO"===this.category?this.settings.selectedRadioItemId.set(e):this.settings.selectedNotesItemId.set(e)}getNextItemId(){return this.items().reduce((e,t)=>Math.max(e,t.id),0)+1}playClickSound(){this.soundStore.playSound(this.settings.clickSoundId())}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:ie,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:ie,isStandalone:!0,selector:"pip-boy-music-layout",inputs:{category:"category",waveformColorRgb:"waveformColorRgb"},viewQueries:[{propertyName:"waveformCanvas",first:!0,predicate:["waveformCanvas"],descendants:!0,isSignal:!0}],ngImport:e,template:'<div class="music-layout">\n <div class="music-list">\n <ul class="music-list-items">\n @for (item of items(); track item.id) {\n <li>\n <button\n type="button"\n class="music-list-item"\n [class.is-selected]="selectedId() === item.id"\n (click)="selectItem(item.id)"\n >\n {{ item.name }}\n </button>\n </li>\n } @empty {\n <li class="is-empty">No items added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="music-actions">\n <button type="button" class="music-add" (click)="openAddModal()">\n + Add\n </button>\n @if (selectedId() !== null) {\n <button type="button" class="music-edit" (click)="openEditModal()">\n Edit\n </button>\n <button type="button" class="music-delete" (click)="deleteSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="music-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="music-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n <div class="music-controls">\n <div class="music-controls-inner">\n <div class="music-waveform">\n <canvas #waveformCanvas width="320" height="140"></canvas>\n </div>\n <div class="music-controls-stack">\n <div class="music-controls-row">\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="playSelected()"\n [disabled]="!items().length || isChannelPlaying()"\n aria-label="Play"\n >\n &#9654;\n </button>\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="pauseSelected()"\n [disabled]="!isChannelPlaying()"\n aria-label="Pause"\n >\n &#10074;&#10074;\n </button>\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="stopSelected()"\n [disabled]="!isChannelPlaying()"\n aria-label="Stop"\n >\n &#9632;\n </button>\n </div>\n <div class="music-controls-row">\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="playPreviousManual()"\n [disabled]="!isChannelPlaying() || items().length <= 1"\n aria-label="Previous"\n >\n &#9198;\n </button>\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="playNextManual()"\n [disabled]="!isChannelPlaying() || items().length <= 1"\n aria-label="Next"\n >\n &#9197;\n </button>\n </div>\n <div class="music-control-row">\n <button\n type="button"\n class="music-control music-control--autoplay"\n [class.is-active]="autoplayEnabled()"\n [disabled]="!isChannelPlaying()"\n (click)="toggleAutoplay()"\n >\n Autoplay\n </button>\n <button\n type="button"\n class="music-control music-control--shuffle"\n [class.is-active]="shuffleEnabled()"\n [disabled]="!isChannelPlaying()"\n (click)="toggleShuffle()"\n aria-label="Shuffle"\n >\n Shuffle\n </button>\n </div>\n <div class="music-volume">\n <div\n class="music-now-playing"\n [class.is-disabled]="!isChannelPlaying()"\n >\n <span class="music-now-playing-label">Currently Playing</span>\n <span class="music-now-playing-value">\n <span class="music-now-playing-text">\n {{ currentPlayingName() }}\n </span>\n </span>\n </div>\n <div class="music-volume-row">\n <span class="music-volume-label">VOL</span>\n <input\n type="range"\n min="0"\n max="100"\n step="1"\n [value]="getVolumePercent()"\n [disabled]="!items().length"\n (input)="updateVolume($any($event.target).value)"\n aria-label="Volume"\n />\n <span class="music-volume-value">{{ getVolumePercent() }}%</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n<pip-boy-audio-edit-modal\n [open]="showEditModal()"\n [title]="modalTitle()"\n [name]="modalName()"\n [fileLabel]="modalFileLabel()"\n [nameLabel]="modalLabelPrefix() + \' Name\'"\n [fileFieldLabel]="modalLabelPrefix() + \' File\'"\n [selectLabel]="\'Select \' + modalLabelPrefix()"\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{width:100%;height:100%;display:block;font-size:inherit}.music-layout{box-sizing:border-box;display:flex;gap:1.5rem;height:100%;min-height:0}.music-list{display:flex;flex:1 1 55%;flex-direction:column;gap:.5rem;min-height:0}.music-list-items{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.music-list-items li{margin:0;padding:0;font-size:inherit}.music-list-items .is-empty{opacity:.6}.music-list-item{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font-size:inherit;padding:.25rem .35rem .25rem 1.2rem;position:relative;text-align:left;width:100%}.music-list-item:hover{background:#0fbb6b1f}.music-list-item.is-selected{background:#0fbb6b2e}.music-list-item.is-selected:before{content:"";position:absolute;left:.35rem;top:50%;transform:translateY(-50%);width:.45rem;height:.45rem;background:#0fbb6b}.music-actions{display:flex;gap:.5rem}.music-add{background:#0fbb6b14;border:none;border-left:0;border-right:0;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.music-add:hover{background:#0fbb6b2e}.music-edit,.music-delete{background:#0fbb6b0d;border:none;border-left:0;border-right:0;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.music-edit:hover,.music-delete:hover{background:#0fbb6b1f}.music-move{background:#0fbb6b0d;border:none;border-left:0;border-right:0;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.music-move:hover{background:#0fbb6b1f}.music-controls{display:flex;flex:1 1 45%;min-height:0;align-items:stretch;justify-content:center}.music-controls-inner{display:flex;flex-direction:column;gap:0;width:100%;min-height:0;height:100%;max-height:100%;overflow-y:auto;padding-right:.35rem;box-sizing:content-box}.music-controls-stack{display:flex;flex-direction:column;gap:.6rem;margin-top:auto;width:100%}.music-control-row{display:flex;flex-wrap:wrap;gap:.5rem;width:100%}.music-control-row button{flex:1 1 4rem;text-align:center}.music-waveform{width:100%;display:flex;justify-content:center;flex:1 1 auto;min-height:clamp(96px,22vh,160px);margin-bottom:1rem;padding:0}.music-waveform canvas{width:100%;max-width:none;height:100%;border-radius:0;border:0;border-right:1px solid rgba(15,187,107,.25);border-bottom:1px solid rgba(15,187,107,.25);background:transparent;box-shadow:none}.music-controls-row{display:flex;flex-wrap:wrap;gap:.5rem}.music-control{background:#0fbb6b0d;border:1px solid rgba(15,187,107,.6);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:calc(clamp(.85rem,.85rem + .15rem * (100vw - 360px) / 840px,1rem) * var(--list-font-scale, 1));letter-spacing:.08em;padding:.6rem .75rem;text-transform:uppercase}.music-control:hover,.music-control.is-active{background:#0fbb6b1f;border-color:#0fbb6b}.music-control:disabled{cursor:default;background:#0fbb6b08;border-color:#0fbb6b40;color:#0fbb6b73;opacity:.8}.music-control--icon{flex:1 1 4rem;text-align:center}.music-control--autoplay.is-active,.music-control--shuffle.is-active{background:#0fbb6b33;border-color:#0fbb6b;box-shadow:0 0 .6rem #0fbb6b47}.music-volume{border:1px solid rgba(15,187,107,.35);border-radius:.6rem;box-sizing:border-box;padding:.6rem .75rem;display:flex;flex-direction:column;gap:.5rem;align-items:stretch;background:#0fbb6b0a;min-height:calc(2.6rem * var(--list-font-scale, 1))}.music-now-playing{display:flex;flex-direction:column;gap:.35rem}.music-now-playing.is-disabled .music-now-playing-label,.music-now-playing.is-disabled .music-now-playing-value{color:#0fbb6b73}.music-now-playing.is-disabled .music-now-playing-value{background:#0fbb6b08;border-color:#0fbb6b33}.music-now-playing-label{text-transform:uppercase;letter-spacing:.08em;font-size:calc(clamp(.7rem,.7rem + .1rem * (100vw - 360px) / 840px,.8rem) * var(--list-font-scale, 1));color:#0fbb6bb3}.music-now-playing-value{display:flex;align-items:center;border:1px solid rgba(15,187,107,.4);border-radius:.4rem;padding:.35rem .5rem;font-size:calc(clamp(.8rem,.8rem + .15rem * (100vw - 360px) / 840px,.95rem) * var(--list-font-scale, 1));color:#0fbb6bd9;min-height:calc(1.4rem * var(--list-font-scale, 1));min-width:0}.music-now-playing-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.music-volume-row{display:flex;align-items:center;gap:.75rem;width:100%}.music-volume-row input[type=range]{appearance:none;background:#0fbb6b33;border-radius:999px;cursor:pointer;flex:1 1 0;height:.35rem;min-width:0;outline:none}.music-volume-row input[type=range]::-webkit-slider-thumb{appearance:none;background:#0fbb6b;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.music-volume-row input[type=range]::-moz-range-thumb{background:#0fbb6b;border:none;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.music-volume-label{text-transform:uppercase;letter-spacing:.08em;font-size:calc(clamp(.75rem,.75rem + .1rem * (100vw - 360px) / 840px,.85rem) * var(--list-font-scale, 1));color:#0fbb6bcc;flex:0 0 3.2ch;max-width:3.2ch;min-width:3.2ch;text-align:left;white-space:nowrap}.music-volume-value{font-size:calc(clamp(.75rem,.75rem + .1rem * (100vw - 360px) / 840px,.85rem) * var(--list-font-scale, 1));color:#0fbb6bcc;letter-spacing:.08em;flex:0 0 4.5ch;max-width:4.5ch;min-width:4.5ch;text-align:right;white-space:nowrap}@media(max-width:720px),(max-height:560px){.music-actions{gap:.35rem}.music-add,.music-edit,.music-delete{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.music-move{flex:0 0 1.6rem;height:2.1rem}.music-controls-inner{flex-direction:row;flex-wrap:wrap;gap:.5rem;justify-content:center;padding:.25rem;width:100%}.music-waveform{flex:0 0 auto;height:clamp(96px,22vh,160px);max-height:clamp(96px,22vh,160px);margin-bottom:.5rem}.music-controls-row{width:100%;justify-content:center}.music-control{flex:1 1 calc(50% - .5rem);font-size:calc(clamp(.7rem,.7rem + .15rem * (100vw - 360px) / 840px,.85rem) * var(--list-font-scale, 1));padding:.35rem .5rem;border-radius:.4rem}.music-control--icon{flex:1 1 3rem}.music-volume{width:100%}.music-volume-row{flex-wrap:wrap}.music-volume-label{min-width:auto}}\n'],dependencies:[{kind:"component",type:oe,selector:"pip-boy-audio-edit-modal",inputs:["open","name","fileLabel","title","nameLabel","fileFieldLabel","selectLabel"],outputs:["closeResult","save"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:ie,decorators:[{type:a,args:[{selector:"pip-boy-music-layout",standalone:!0,imports:[oe],template:'<div class="music-layout">\n <div class="music-list">\n <ul class="music-list-items">\n @for (item of items(); track item.id) {\n <li>\n <button\n type="button"\n class="music-list-item"\n [class.is-selected]="selectedId() === item.id"\n (click)="selectItem(item.id)"\n >\n {{ item.name }}\n </button>\n </li>\n } @empty {\n <li class="is-empty">No items added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="music-actions">\n <button type="button" class="music-add" (click)="openAddModal()">\n + Add\n </button>\n @if (selectedId() !== null) {\n <button type="button" class="music-edit" (click)="openEditModal()">\n Edit\n </button>\n <button type="button" class="music-delete" (click)="deleteSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="music-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="music-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n <div class="music-controls">\n <div class="music-controls-inner">\n <div class="music-waveform">\n <canvas #waveformCanvas width="320" height="140"></canvas>\n </div>\n <div class="music-controls-stack">\n <div class="music-controls-row">\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="playSelected()"\n [disabled]="!items().length || isChannelPlaying()"\n aria-label="Play"\n >\n &#9654;\n </button>\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="pauseSelected()"\n [disabled]="!isChannelPlaying()"\n aria-label="Pause"\n >\n &#10074;&#10074;\n </button>\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="stopSelected()"\n [disabled]="!isChannelPlaying()"\n aria-label="Stop"\n >\n &#9632;\n </button>\n </div>\n <div class="music-controls-row">\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="playPreviousManual()"\n [disabled]="!isChannelPlaying() || items().length <= 1"\n aria-label="Previous"\n >\n &#9198;\n </button>\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="playNextManual()"\n [disabled]="!isChannelPlaying() || items().length <= 1"\n aria-label="Next"\n >\n &#9197;\n </button>\n </div>\n <div class="music-control-row">\n <button\n type="button"\n class="music-control music-control--autoplay"\n [class.is-active]="autoplayEnabled()"\n [disabled]="!isChannelPlaying()"\n (click)="toggleAutoplay()"\n >\n Autoplay\n </button>\n <button\n type="button"\n class="music-control music-control--shuffle"\n [class.is-active]="shuffleEnabled()"\n [disabled]="!isChannelPlaying()"\n (click)="toggleShuffle()"\n aria-label="Shuffle"\n >\n Shuffle\n </button>\n </div>\n <div class="music-volume">\n <div\n class="music-now-playing"\n [class.is-disabled]="!isChannelPlaying()"\n >\n <span class="music-now-playing-label">Currently Playing</span>\n <span class="music-now-playing-value">\n <span class="music-now-playing-text">\n {{ currentPlayingName() }}\n </span>\n </span>\n </div>\n <div class="music-volume-row">\n <span class="music-volume-label">VOL</span>\n <input\n type="range"\n min="0"\n max="100"\n step="1"\n [value]="getVolumePercent()"\n [disabled]="!items().length"\n (input)="updateVolume($any($event.target).value)"\n aria-label="Volume"\n />\n <span class="music-volume-value">{{ getVolumePercent() }}%</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n<pip-boy-audio-edit-modal\n [open]="showEditModal()"\n [title]="modalTitle()"\n [name]="modalName()"\n [fileLabel]="modalFileLabel()"\n [nameLabel]="modalLabelPrefix() + \' Name\'"\n [fileFieldLabel]="modalLabelPrefix() + \' File\'"\n [selectLabel]="\'Select \' + modalLabelPrefix()"\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{width:100%;height:100%;display:block;font-size:inherit}.music-layout{box-sizing:border-box;display:flex;gap:1.5rem;height:100%;min-height:0}.music-list{display:flex;flex:1 1 55%;flex-direction:column;gap:.5rem;min-height:0}.music-list-items{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.music-list-items li{margin:0;padding:0;font-size:inherit}.music-list-items .is-empty{opacity:.6}.music-list-item{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font-size:inherit;padding:.25rem .35rem .25rem 1.2rem;position:relative;text-align:left;width:100%}.music-list-item:hover{background:#0fbb6b1f}.music-list-item.is-selected{background:#0fbb6b2e}.music-list-item.is-selected:before{content:"";position:absolute;left:.35rem;top:50%;transform:translateY(-50%);width:.45rem;height:.45rem;background:#0fbb6b}.music-actions{display:flex;gap:.5rem}.music-add{background:#0fbb6b14;border:none;border-left:0;border-right:0;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.music-add:hover{background:#0fbb6b2e}.music-edit,.music-delete{background:#0fbb6b0d;border:none;border-left:0;border-right:0;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.music-edit:hover,.music-delete:hover{background:#0fbb6b1f}.music-move{background:#0fbb6b0d;border:none;border-left:0;border-right:0;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.music-move:hover{background:#0fbb6b1f}.music-controls{display:flex;flex:1 1 45%;min-height:0;align-items:stretch;justify-content:center}.music-controls-inner{display:flex;flex-direction:column;gap:0;width:100%;min-height:0;height:100%;max-height:100%;overflow-y:auto;padding-right:.35rem;box-sizing:content-box}.music-controls-stack{display:flex;flex-direction:column;gap:.6rem;margin-top:auto;width:100%}.music-control-row{display:flex;flex-wrap:wrap;gap:.5rem;width:100%}.music-control-row button{flex:1 1 4rem;text-align:center}.music-waveform{width:100%;display:flex;justify-content:center;flex:1 1 auto;min-height:clamp(96px,22vh,160px);margin-bottom:1rem;padding:0}.music-waveform canvas{width:100%;max-width:none;height:100%;border-radius:0;border:0;border-right:1px solid rgba(15,187,107,.25);border-bottom:1px solid rgba(15,187,107,.25);background:transparent;box-shadow:none}.music-controls-row{display:flex;flex-wrap:wrap;gap:.5rem}.music-control{background:#0fbb6b0d;border:1px solid rgba(15,187,107,.6);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:calc(clamp(.85rem,.85rem + .15rem * (100vw - 360px) / 840px,1rem) * var(--list-font-scale, 1));letter-spacing:.08em;padding:.6rem .75rem;text-transform:uppercase}.music-control:hover,.music-control.is-active{background:#0fbb6b1f;border-color:#0fbb6b}.music-control:disabled{cursor:default;background:#0fbb6b08;border-color:#0fbb6b40;color:#0fbb6b73;opacity:.8}.music-control--icon{flex:1 1 4rem;text-align:center}.music-control--autoplay.is-active,.music-control--shuffle.is-active{background:#0fbb6b33;border-color:#0fbb6b;box-shadow:0 0 .6rem #0fbb6b47}.music-volume{border:1px solid rgba(15,187,107,.35);border-radius:.6rem;box-sizing:border-box;padding:.6rem .75rem;display:flex;flex-direction:column;gap:.5rem;align-items:stretch;background:#0fbb6b0a;min-height:calc(2.6rem * var(--list-font-scale, 1))}.music-now-playing{display:flex;flex-direction:column;gap:.35rem}.music-now-playing.is-disabled .music-now-playing-label,.music-now-playing.is-disabled .music-now-playing-value{color:#0fbb6b73}.music-now-playing.is-disabled .music-now-playing-value{background:#0fbb6b08;border-color:#0fbb6b33}.music-now-playing-label{text-transform:uppercase;letter-spacing:.08em;font-size:calc(clamp(.7rem,.7rem + .1rem * (100vw - 360px) / 840px,.8rem) * var(--list-font-scale, 1));color:#0fbb6bb3}.music-now-playing-value{display:flex;align-items:center;border:1px solid rgba(15,187,107,.4);border-radius:.4rem;padding:.35rem .5rem;font-size:calc(clamp(.8rem,.8rem + .15rem * (100vw - 360px) / 840px,.95rem) * var(--list-font-scale, 1));color:#0fbb6bd9;min-height:calc(1.4rem * var(--list-font-scale, 1));min-width:0}.music-now-playing-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.music-volume-row{display:flex;align-items:center;gap:.75rem;width:100%}.music-volume-row input[type=range]{appearance:none;background:#0fbb6b33;border-radius:999px;cursor:pointer;flex:1 1 0;height:.35rem;min-width:0;outline:none}.music-volume-row input[type=range]::-webkit-slider-thumb{appearance:none;background:#0fbb6b;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.music-volume-row input[type=range]::-moz-range-thumb{background:#0fbb6b;border:none;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.music-volume-label{text-transform:uppercase;letter-spacing:.08em;font-size:calc(clamp(.75rem,.75rem + .1rem * (100vw - 360px) / 840px,.85rem) * var(--list-font-scale, 1));color:#0fbb6bcc;flex:0 0 3.2ch;max-width:3.2ch;min-width:3.2ch;text-align:left;white-space:nowrap}.music-volume-value{font-size:calc(clamp(.75rem,.75rem + .1rem * (100vw - 360px) / 840px,.85rem) * var(--list-font-scale, 1));color:#0fbb6bcc;letter-spacing:.08em;flex:0 0 4.5ch;max-width:4.5ch;min-width:4.5ch;text-align:right;white-space:nowrap}@media(max-width:720px),(max-height:560px){.music-actions{gap:.35rem}.music-add,.music-edit,.music-delete{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.music-move{flex:0 0 1.6rem;height:2.1rem}.music-controls-inner{flex-direction:row;flex-wrap:wrap;gap:.5rem;justify-content:center;padding:.25rem;width:100%}.music-waveform{flex:0 0 auto;height:clamp(96px,22vh,160px);max-height:clamp(96px,22vh,160px);margin-bottom:.5rem}.music-controls-row{width:100%;justify-content:center}.music-control{flex:1 1 calc(50% - .5rem);font-size:calc(clamp(.7rem,.7rem + .15rem * (100vw - 360px) / 840px,.85rem) * var(--list-font-scale, 1));padding:.35rem .5rem;border-radius:.4rem}.music-control--icon{flex:1 1 3rem}.music-volume{width:100%}.music-volume-row{flex-wrap:wrap}.music-volume-label{min-width:auto}}\n']}]}],ctorParameters:()=>[],propDecorators:{category:[{type:p}],waveformColorRgb:[{type:p}],waveformCanvas:[{type:e.ViewChild,args:["waveformCanvas",{isSignal:!0}]}]}});class se{open=!1;listFontScale=1.25;closeResult=new c;previewListFontScale=new c;appVersion=A;updateListFontScale(e){const t=Number(e);if(!Number.isFinite(t))return;const n=Math.min(150,Math.max(50,t))/100*1.25;this.listFontScale=n,this.previewListFontScale.emit(n)}listFontScalePercent(){return Math.round(this.listFontScale/1.25*100)}closeModal(){this.closeResult.emit()}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:se,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"21.0.8",type:se,isStandalone:!0,selector:"pip-boy-welcome-modal",inputs:{open:"open",listFontScale:"listFontScale"},outputs:{closeResult:"closeResult",previewListFontScale:"previewListFontScale"},ngImport:e,template:'<pip-boy-dialog\n [open]="open"\n title="Welcome to Pip UI"\n subtitle="Fan made Pip-Boy inspired simulators from the Fallout universe."\n (closeResult)="closeModal()"\n>\n <span dialog-title-extra class="welcome__version">v{{ appVersion }}</span>\n\n <div class="welcome__body">\n <section class="welcome__section" aria-labelledby="welcomeFontTitle">\n <div class="welcome__section-head">\n <div class="welcome__section-title" id="welcomeFontTitle">\n Global Font Size\n </div>\n <p class="welcome__section-text">\n Adjusts key UI font sizes to match your device.\n </p>\n </div>\n\n <div class="welcome__slider">\n <input\n class="welcome__range"\n type="range"\n min="50"\n max="150"\n step="1"\n [value]="listFontScalePercent()"\n (input)="updateListFontScale($any($event.target).value)"\n aria-label="Global font size"\n />\n <span class="welcome__value">{{ listFontScalePercent() }}%</span>\n </div>\n\n <p class="welcome__hint">\n You can adjust this any time later in the settings menu.\n </p>\n </section>\n\n <div class="welcome__divider" aria-hidden="true"></div>\n\n <section class="welcome__section" aria-labelledby="welcomeNpmTitle">\n <div class="welcome__section-head">\n <div class="welcome__section-title" id="welcomeNpmTitle">Npm</div>\n <p class="welcome__section-text">\n Use this package for free in your own projects.\n </p>\n </div>\n\n <dl class="welcome__meta" aria-label="Install information">\n <div class="welcome__row">\n <dt class="welcome__label">Package</dt>\n <dd class="welcome__data"><code>@vault-tec/pip-boy</code></dd>\n </div>\n\n <div class="welcome__row">\n <dt class="welcome__label">Install</dt>\n <dd class="welcome__data">\n <code>npm install @vault-tec/pip-boy</code>\n </dd>\n </div>\n\n <div class="welcome__row">\n <dt class="welcome__label">NPM</dt>\n <dd class="welcome__data">\n <a\n href="https://www.npmjs.com/package/@vault-tec/pip-boy"\n target="_blank"\n rel="noreferrer"\n >\n npmjs.com/package/@vault-tec/pip-boy\n </a>\n </dd>\n </div>\n </dl>\n\n <p class="welcome__disclaimer">\n Please note that this is an unofficial fan project. No official game\n assets are included. Not affiliated with or endorsed by Bethesda\n Softworks or ZeniMax Media.\n </p>\n </section>\n </div>\n\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Close</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.welcome__version{color:#0fbb6bc7;font-size:clamp(.8rem,.8rem + (.9rem - .8rem) * (100vw - 360px) / (1200px - 360px),.9rem);letter-spacing:.1em}.welcome__body{display:flex;flex-direction:column;gap:.9rem}.welcome__body p{margin:0}.welcome__divider{border-top:1px solid rgba(15,187,107,.22);margin:.15rem 0}.welcome__section{border:1px solid rgba(15,187,107,.2);border-radius:.75rem;padding:.9rem .95rem;background:#0fbb6b0a;display:flex;flex-direction:column;gap:.75rem}.welcome__section:last-child{margin-bottom:1rem}.welcome__section-head{display:flex;flex-direction:column;gap:.35rem}.welcome__section-title{text-transform:uppercase;letter-spacing:.08em;color:#0fbb6bd1;font-size:clamp(.8rem,.8rem + (.95rem - .8rem) * (100vw - 360px) / (1200px - 360px),.95rem)}.welcome__section-text{color:#0fbb6bc7;font-size:clamp(.85rem,.85rem + (.95rem - .85rem) * (100vw - 360px) / (1200px - 360px),.95rem);line-height:1.35}.welcome__slider{align-items:center;display:flex;gap:.8rem}.welcome__range{appearance:none;background:#0fbb6b33;border-radius:999px;cursor:pointer;flex:1 1 auto;height:.35rem;outline:none}.welcome__range::-webkit-slider-thumb{appearance:none;background:#0fbb6b;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.welcome__range::-moz-range-thumb{background:#0fbb6b;border:none;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.welcome__value{font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);color:#0fbb6bd1;letter-spacing:.08em;min-width:3.25rem;text-align:right}.welcome__hint{color:#0fbb6bbf;font-size:clamp(.5rem,.5rem + (.7rem - .5rem) * (100vw - 360px) / (1200px - 360px),.7rem);line-height:1.35}.welcome__meta{display:grid;gap:.6rem;margin:0}.welcome__row{display:grid;grid-template-columns:5.25rem 1fr;align-items:start;gap:.75rem}.welcome__label{color:#0fbb6bbd;text-transform:uppercase;letter-spacing:.08em;font-size:.75rem;line-height:1.25;padding-top:.15rem}.welcome__data{margin:0}.welcome__data code{background:#0fbb6b14;border:1px solid rgba(15,187,107,.22);border-radius:.45rem;color:#0fbb6b;display:inline-block;padding:.25rem .55rem;max-width:100%;overflow-wrap:anywhere}.welcome__data a{color:#0fbb6b;text-decoration:none;overflow-wrap:anywhere}.welcome__data a:hover{text-decoration:underline}.welcome__disclaimer{color:#0fbb6bc2;font-size:clamp(.5rem,.5rem + (.7rem - .5rem) * (100vw - 360px) / (1200px - 360px),.7rem);line-height:1.35}:host{font-size:inherit}\n"],dependencies:[{kind:"ngmodule",type:f},{kind:"component",type:B,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:se,decorators:[{type:a,args:[{selector:"pip-boy-welcome-modal",standalone:!0,imports:[f,B],template:'<pip-boy-dialog\n [open]="open"\n title="Welcome to Pip UI"\n subtitle="Fan made Pip-Boy inspired simulators from the Fallout universe."\n (closeResult)="closeModal()"\n>\n <span dialog-title-extra class="welcome__version">v{{ appVersion }}</span>\n\n <div class="welcome__body">\n <section class="welcome__section" aria-labelledby="welcomeFontTitle">\n <div class="welcome__section-head">\n <div class="welcome__section-title" id="welcomeFontTitle">\n Global Font Size\n </div>\n <p class="welcome__section-text">\n Adjusts key UI font sizes to match your device.\n </p>\n </div>\n\n <div class="welcome__slider">\n <input\n class="welcome__range"\n type="range"\n min="50"\n max="150"\n step="1"\n [value]="listFontScalePercent()"\n (input)="updateListFontScale($any($event.target).value)"\n aria-label="Global font size"\n />\n <span class="welcome__value">{{ listFontScalePercent() }}%</span>\n </div>\n\n <p class="welcome__hint">\n You can adjust this any time later in the settings menu.\n </p>\n </section>\n\n <div class="welcome__divider" aria-hidden="true"></div>\n\n <section class="welcome__section" aria-labelledby="welcomeNpmTitle">\n <div class="welcome__section-head">\n <div class="welcome__section-title" id="welcomeNpmTitle">Npm</div>\n <p class="welcome__section-text">\n Use this package for free in your own projects.\n </p>\n </div>\n\n <dl class="welcome__meta" aria-label="Install information">\n <div class="welcome__row">\n <dt class="welcome__label">Package</dt>\n <dd class="welcome__data"><code>@vault-tec/pip-boy</code></dd>\n </div>\n\n <div class="welcome__row">\n <dt class="welcome__label">Install</dt>\n <dd class="welcome__data">\n <code>npm install @vault-tec/pip-boy</code>\n </dd>\n </div>\n\n <div class="welcome__row">\n <dt class="welcome__label">NPM</dt>\n <dd class="welcome__data">\n <a\n href="https://www.npmjs.com/package/@vault-tec/pip-boy"\n target="_blank"\n rel="noreferrer"\n >\n npmjs.com/package/@vault-tec/pip-boy\n </a>\n </dd>\n </div>\n </dl>\n\n <p class="welcome__disclaimer">\n Please note that this is an unofficial fan project. No official game\n assets are included. Not affiliated with or endorsed by Bethesda\n Softworks or ZeniMax Media.\n </p>\n </section>\n </div>\n\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Close</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.welcome__version{color:#0fbb6bc7;font-size:clamp(.8rem,.8rem + (.9rem - .8rem) * (100vw - 360px) / (1200px - 360px),.9rem);letter-spacing:.1em}.welcome__body{display:flex;flex-direction:column;gap:.9rem}.welcome__body p{margin:0}.welcome__divider{border-top:1px solid rgba(15,187,107,.22);margin:.15rem 0}.welcome__section{border:1px solid rgba(15,187,107,.2);border-radius:.75rem;padding:.9rem .95rem;background:#0fbb6b0a;display:flex;flex-direction:column;gap:.75rem}.welcome__section:last-child{margin-bottom:1rem}.welcome__section-head{display:flex;flex-direction:column;gap:.35rem}.welcome__section-title{text-transform:uppercase;letter-spacing:.08em;color:#0fbb6bd1;font-size:clamp(.8rem,.8rem + (.95rem - .8rem) * (100vw - 360px) / (1200px - 360px),.95rem)}.welcome__section-text{color:#0fbb6bc7;font-size:clamp(.85rem,.85rem + (.95rem - .85rem) * (100vw - 360px) / (1200px - 360px),.95rem);line-height:1.35}.welcome__slider{align-items:center;display:flex;gap:.8rem}.welcome__range{appearance:none;background:#0fbb6b33;border-radius:999px;cursor:pointer;flex:1 1 auto;height:.35rem;outline:none}.welcome__range::-webkit-slider-thumb{appearance:none;background:#0fbb6b;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.welcome__range::-moz-range-thumb{background:#0fbb6b;border:none;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.welcome__value{font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);color:#0fbb6bd1;letter-spacing:.08em;min-width:3.25rem;text-align:right}.welcome__hint{color:#0fbb6bbf;font-size:clamp(.5rem,.5rem + (.7rem - .5rem) * (100vw - 360px) / (1200px - 360px),.7rem);line-height:1.35}.welcome__meta{display:grid;gap:.6rem;margin:0}.welcome__row{display:grid;grid-template-columns:5.25rem 1fr;align-items:start;gap:.75rem}.welcome__label{color:#0fbb6bbd;text-transform:uppercase;letter-spacing:.08em;font-size:.75rem;line-height:1.25;padding-top:.15rem}.welcome__data{margin:0}.welcome__data code{background:#0fbb6b14;border:1px solid rgba(15,187,107,.22);border-radius:.45rem;color:#0fbb6b;display:inline-block;padding:.25rem .55rem;max-width:100%;overflow-wrap:anywhere}.welcome__data a{color:#0fbb6b;text-decoration:none;overflow-wrap:anywhere}.welcome__data a:hover{text-decoration:underline}.welcome__disclaimer{color:#0fbb6bc2;font-size:clamp(.5rem,.5rem + (.7rem - .5rem) * (100vw - 360px) / (1200px - 360px),.7rem);line-height:1.35}:host{font-size:inherit}\n"]}]}],propDecorators:{open:[{type:p}],listFontScale:[{type:p}],closeResult:[{type:m}],previewListFontScale:[{type:m}]}});class re{open=!1;scanLinesEnabled=!0;rememberTabOnRefreshEnabled=!1;editLockEnabled=!1;listFontScale=1.25;secondaryTabSoundLabel=null;mainTabSoundLabel=null;clickSoundLabel=null;closeResult=new c;save=new c;previewListFontScale=new c;draftScanLines=o(!0,...ngDevMode?[{debugName:"draftScanLines"}]:[]);draftRememberTabOnRefresh=o(!1,...ngDevMode?[{debugName:"draftRememberTabOnRefresh"}]:[]);draftEditLock=o(!1,...ngDevMode?[{debugName:"draftEditLock"}]:[]);draftListFontScale=o(1.25,...ngDevMode?[{debugName:"draftListFontScale"}]:[]);secondarySoundName=o(null,...ngDevMode?[{debugName:"secondarySoundName"}]:[]);mainSoundName=o(null,...ngDevMode?[{debugName:"mainSoundName"}]:[]);clickSoundName=o(null,...ngDevMode?[{debugName:"clickSoundName"}]:[]);secondarySoundFile=null;mainSoundFile=null;clickSoundFile=null;removeSecondary=!1;removeMain=!1;removeClick=!1;ngOnChanges(e){e.scanLinesEnabled&&this.draftScanLines.set(this.scanLinesEnabled),e.rememberTabOnRefreshEnabled&&this.draftRememberTabOnRefresh.set(this.rememberTabOnRefreshEnabled),e.editLockEnabled&&this.draftEditLock.set(this.editLockEnabled),e.listFontScale&&this.draftListFontScale.set(this.listFontScale),e.secondaryTabSoundLabel&&this.secondarySoundName.set(this.secondaryTabSoundLabel),e.mainTabSoundLabel&&this.mainSoundName.set(this.mainTabSoundLabel),e.clickSoundLabel&&this.clickSoundName.set(this.clickSoundLabel),e.open&&this.open&&(this.secondarySoundFile=null,this.mainSoundFile=null,this.clickSoundFile=null,this.removeSecondary=!1,this.removeMain=!1,this.removeClick=!1)}closeModal(){this.closeResult.emit()}toggleScanLines(){this.draftScanLines.update(e=>!e)}toggleRememberTabOnRefresh(){this.draftRememberTabOnRefresh.update(e=>!e)}toggleEditLock(){this.draftEditLock.update(e=>!e)}updateListFontScale(e){const t=Number(e);if(!Number.isFinite(t))return;const n=Math.min(150,Math.max(50,t))/100*1.25;this.draftListFontScale.set(n),this.previewListFontScale.emit(n)}resetListFontScale(){this.draftListFontScale.set(1.25),this.previewListFontScale.emit(1.25)}listFontScalePercent(){return Math.round(this.draftListFontScale()/1.25*100)}onSecondarySoundSelected(e){const t=e.target,n=t.files?.[0]??null;this.secondarySoundFile=n,this.removeSecondary=!1,this.secondarySoundName.set(n?.name??this.secondaryTabSoundLabel),t&&(t.value="")}onMainSoundSelected(e){const t=e.target,n=t.files?.[0]??null;this.mainSoundFile=n,this.removeMain=!1,this.mainSoundName.set(n?.name??this.mainTabSoundLabel),t&&(t.value="")}onClickSoundSelected(e){const t=e.target,n=t.files?.[0]??null;this.clickSoundFile=n,this.removeClick=!1,this.clickSoundName.set(n?.name??this.clickSoundLabel),t&&(t.value="")}removeSecondarySound(){this.secondarySoundFile=null,this.removeSecondary=!0,this.secondarySoundName.set(null)}removeMainSound(){this.mainSoundFile=null,this.removeMain=!0,this.mainSoundName.set(null)}removeClickSound(){this.clickSoundFile=null,this.removeClick=!0,this.clickSoundName.set(null)}submit(e){e.preventDefault(),this.save.emit({scanLinesEnabled:this.draftScanLines(),rememberTabOnRefreshEnabled:this.draftRememberTabOnRefresh(),editLockEnabled:this.draftEditLock(),listFontScale:this.draftListFontScale(),secondaryTabSoundFile:this.secondarySoundFile,mainTabSoundFile:this.mainSoundFile,clickSoundFile:this.clickSoundFile,removeSecondaryTabSound:this.removeSecondary,removeMainTabSound:this.removeMain,removeClickSound:this.removeClick})}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:re,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:re,isStandalone:!0,selector:"pip-boy-settings-modal",inputs:{open:"open",scanLinesEnabled:"scanLinesEnabled",rememberTabOnRefreshEnabled:"rememberTabOnRefreshEnabled",editLockEnabled:"editLockEnabled",listFontScale:"listFontScale",secondaryTabSoundLabel:"secondaryTabSoundLabel",mainTabSoundLabel:"mainTabSoundLabel",clickSoundLabel:"clickSoundLabel"},outputs:{closeResult:"closeResult",save:"save",previewListFontScale:"previewListFontScale"},usesOnChanges:!0,ngImport:e,template:'<pip-boy-dialog [open]="open" title="Settings" (closeResult)="closeModal()">\n <form id="settings-form" (submit)="submit($event)">\n <div class="settings-modal-body">\n <label class="settings-modal-field settings-modal-toggle">\n <span>Screen Line Effect</span>\n <input\n type="checkbox"\n [checked]="draftScanLines()"\n (change)="toggleScanLines()"\n hidden\n />\n <button\n type="button"\n class="settings-toggle"\n [class.is-on]="draftScanLines()"\n (click)="toggleScanLines()"\n >\n {{ draftScanLines() ? \'On\' : \'Off\' }}\n </button>\n </label>\n <label class="settings-modal-field settings-modal-toggle">\n <span>Remember Tab on Refresh</span>\n <input\n type="checkbox"\n [checked]="draftRememberTabOnRefresh()"\n (change)="toggleRememberTabOnRefresh()"\n hidden\n />\n <button\n type="button"\n class="settings-toggle"\n [class.is-on]="draftRememberTabOnRefresh()"\n (click)="toggleRememberTabOnRefresh()"\n >\n {{ draftRememberTabOnRefresh() ? \'On\' : \'Off\' }}\n </button>\n </label>\n <label class="settings-modal-field settings-modal-toggle">\n <span>Edit Lock</span>\n <input\n type="checkbox"\n [checked]="draftEditLock()"\n (change)="toggleEditLock()"\n hidden\n />\n <button\n type="button"\n class="settings-toggle"\n [class.is-on]="draftEditLock()"\n (click)="toggleEditLock()"\n >\n {{ draftEditLock() ? \'Locked\' : \'Unlocked\' }}\n </button>\n </label>\n <div class="settings-divider"></div>\n <label class="settings-modal-field settings-modal-slider">\n <div class="settings-slider-head">\n <span>Content Font Size</span>\n <button\n type="button"\n class="settings-reset"\n [disabled]="listFontScalePercent() === 100"\n (click)="resetListFontScale()"\n >\n Reset\n </button>\n </div>\n <div class="settings-slider-row">\n <input\n type="range"\n min="50"\n max="150"\n step="1"\n [value]="listFontScalePercent()"\n (input)="updateListFontScale($any($event.target).value)"\n />\n <span class="settings-slider-value">\n {{ listFontScalePercent() }}%\n </span>\n </div>\n </label>\n <div class="settings-divider"></div>\n <div class="settings-modal-field">\n <span>Secondary Tab Sound</span>\n <div class="settings-sound-actions">\n <button\n type="button"\n class="settings-sound-button"\n (click)="secondarySoundInput.click()"\n >\n {{ secondarySoundName() ?? \'Select Sound\' }}\n </button>\n @if (secondarySoundName()) {\n <button\n type="button"\n class="settings-sound-remove"\n (click)="removeSecondarySound()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #secondarySoundInput\n type="file"\n accept="audio/*"\n (change)="onSecondarySoundSelected($event)"\n />\n </div>\n <div class="settings-modal-field">\n <span>Main Tab Sound</span>\n <div class="settings-sound-actions">\n <button\n type="button"\n class="settings-sound-button"\n (click)="mainSoundInput.click()"\n >\n {{ mainSoundName() ?? \'Select Sound\' }}\n </button>\n @if (mainSoundName()) {\n <button\n type="button"\n class="settings-sound-remove"\n (click)="removeMainSound()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #mainSoundInput\n type="file"\n accept="audio/*"\n (change)="onMainSoundSelected($event)"\n />\n </div>\n <div class="settings-modal-field">\n <span>Click Sound</span>\n <div class="settings-sound-actions">\n <button\n type="button"\n class="settings-sound-button"\n (click)="clickSoundInput.click()"\n >\n {{ clickSoundName() ?? \'Select Sound\' }}\n </button>\n @if (clickSoundName()) {\n <button\n type="button"\n class="settings-sound-remove"\n (click)="removeClickSound()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #clickSoundInput\n type="file"\n accept="audio/*"\n (change)="onClickSoundSelected($event)"\n />\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="settings-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.settings-modal-body{display:flex;flex-direction:column;gap:1rem}.settings-modal-field{display:flex;flex-direction:column;gap:.5rem}.settings-modal-slider{gap:.65rem}.settings-slider-head{display:flex;align-items:center;justify-content:space-between;gap:.75rem;flex-wrap:wrap}.settings-slider-row{align-items:center;display:flex;gap:.75rem}.settings-slider-row input[type=range]{appearance:none;background:#0fbb6b33;border-radius:999px;cursor:pointer;flex:1 1 auto;height:.35rem;outline:none}.settings-slider-row input[type=range]::-webkit-slider-thumb{appearance:none;background:#0fbb6b;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.settings-slider-row input[type=range]::-moz-range-thumb{background:#0fbb6b;border:none;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.settings-slider-value{font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);color:#0fbb6bcc;letter-spacing:.08em;min-width:3.25rem;text-align:right}.settings-reset{background:transparent;border:1px solid rgba(15,187,107,.45);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.4rem .75rem;text-transform:uppercase;width:auto}.settings-reset:hover{background:#0fbb6b1f;border-color:#0fbb6b}.settings-reset:disabled{cursor:default;opacity:.55}.settings-modal-toggle{align-items:center;flex-direction:row;justify-content:space-between}.settings-divider{border-top:1px solid rgba(15,187,107,.2);margin:.5rem 0}.settings-sound-actions{display:flex;gap:.5rem;align-items:center}.settings-sound-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;flex:1 1 auto;padding:.5rem .75rem;text-align:left;text-transform:uppercase}.settings-sound-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.settings-sound-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.4rem .7rem;text-transform:uppercase}.settings-sound-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.settings-toggle{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:999px;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.35rem .9rem;text-transform:uppercase}.settings-toggle.is-on{background:#0fbb6b33;border-color:#0fbb6b}.settings-toggle:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"],dependencies:[{kind:"component",type:B,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:re,decorators:[{type:a,args:[{selector:"pip-boy-settings-modal",standalone:!0,imports:[B],template:'<pip-boy-dialog [open]="open" title="Settings" (closeResult)="closeModal()">\n <form id="settings-form" (submit)="submit($event)">\n <div class="settings-modal-body">\n <label class="settings-modal-field settings-modal-toggle">\n <span>Screen Line Effect</span>\n <input\n type="checkbox"\n [checked]="draftScanLines()"\n (change)="toggleScanLines()"\n hidden\n />\n <button\n type="button"\n class="settings-toggle"\n [class.is-on]="draftScanLines()"\n (click)="toggleScanLines()"\n >\n {{ draftScanLines() ? \'On\' : \'Off\' }}\n </button>\n </label>\n <label class="settings-modal-field settings-modal-toggle">\n <span>Remember Tab on Refresh</span>\n <input\n type="checkbox"\n [checked]="draftRememberTabOnRefresh()"\n (change)="toggleRememberTabOnRefresh()"\n hidden\n />\n <button\n type="button"\n class="settings-toggle"\n [class.is-on]="draftRememberTabOnRefresh()"\n (click)="toggleRememberTabOnRefresh()"\n >\n {{ draftRememberTabOnRefresh() ? \'On\' : \'Off\' }}\n </button>\n </label>\n <label class="settings-modal-field settings-modal-toggle">\n <span>Edit Lock</span>\n <input\n type="checkbox"\n [checked]="draftEditLock()"\n (change)="toggleEditLock()"\n hidden\n />\n <button\n type="button"\n class="settings-toggle"\n [class.is-on]="draftEditLock()"\n (click)="toggleEditLock()"\n >\n {{ draftEditLock() ? \'Locked\' : \'Unlocked\' }}\n </button>\n </label>\n <div class="settings-divider"></div>\n <label class="settings-modal-field settings-modal-slider">\n <div class="settings-slider-head">\n <span>Content Font Size</span>\n <button\n type="button"\n class="settings-reset"\n [disabled]="listFontScalePercent() === 100"\n (click)="resetListFontScale()"\n >\n Reset\n </button>\n </div>\n <div class="settings-slider-row">\n <input\n type="range"\n min="50"\n max="150"\n step="1"\n [value]="listFontScalePercent()"\n (input)="updateListFontScale($any($event.target).value)"\n />\n <span class="settings-slider-value">\n {{ listFontScalePercent() }}%\n </span>\n </div>\n </label>\n <div class="settings-divider"></div>\n <div class="settings-modal-field">\n <span>Secondary Tab Sound</span>\n <div class="settings-sound-actions">\n <button\n type="button"\n class="settings-sound-button"\n (click)="secondarySoundInput.click()"\n >\n {{ secondarySoundName() ?? \'Select Sound\' }}\n </button>\n @if (secondarySoundName()) {\n <button\n type="button"\n class="settings-sound-remove"\n (click)="removeSecondarySound()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #secondarySoundInput\n type="file"\n accept="audio/*"\n (change)="onSecondarySoundSelected($event)"\n />\n </div>\n <div class="settings-modal-field">\n <span>Main Tab Sound</span>\n <div class="settings-sound-actions">\n <button\n type="button"\n class="settings-sound-button"\n (click)="mainSoundInput.click()"\n >\n {{ mainSoundName() ?? \'Select Sound\' }}\n </button>\n @if (mainSoundName()) {\n <button\n type="button"\n class="settings-sound-remove"\n (click)="removeMainSound()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #mainSoundInput\n type="file"\n accept="audio/*"\n (change)="onMainSoundSelected($event)"\n />\n </div>\n <div class="settings-modal-field">\n <span>Click Sound</span>\n <div class="settings-sound-actions">\n <button\n type="button"\n class="settings-sound-button"\n (click)="clickSoundInput.click()"\n >\n {{ clickSoundName() ?? \'Select Sound\' }}\n </button>\n @if (clickSoundName()) {\n <button\n type="button"\n class="settings-sound-remove"\n (click)="removeClickSound()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #clickSoundInput\n type="file"\n accept="audio/*"\n (change)="onClickSoundSelected($event)"\n />\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="settings-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.settings-modal-body{display:flex;flex-direction:column;gap:1rem}.settings-modal-field{display:flex;flex-direction:column;gap:.5rem}.settings-modal-slider{gap:.65rem}.settings-slider-head{display:flex;align-items:center;justify-content:space-between;gap:.75rem;flex-wrap:wrap}.settings-slider-row{align-items:center;display:flex;gap:.75rem}.settings-slider-row input[type=range]{appearance:none;background:#0fbb6b33;border-radius:999px;cursor:pointer;flex:1 1 auto;height:.35rem;outline:none}.settings-slider-row input[type=range]::-webkit-slider-thumb{appearance:none;background:#0fbb6b;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.settings-slider-row input[type=range]::-moz-range-thumb{background:#0fbb6b;border:none;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.settings-slider-value{font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);color:#0fbb6bcc;letter-spacing:.08em;min-width:3.25rem;text-align:right}.settings-reset{background:transparent;border:1px solid rgba(15,187,107,.45);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.4rem .75rem;text-transform:uppercase;width:auto}.settings-reset:hover{background:#0fbb6b1f;border-color:#0fbb6b}.settings-reset:disabled{cursor:default;opacity:.55}.settings-modal-toggle{align-items:center;flex-direction:row;justify-content:space-between}.settings-divider{border-top:1px solid rgba(15,187,107,.2);margin:.5rem 0}.settings-sound-actions{display:flex;gap:.5rem;align-items:center}.settings-sound-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;flex:1 1 auto;padding:.5rem .75rem;text-align:left;text-transform:uppercase}.settings-sound-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.settings-sound-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.4rem .7rem;text-transform:uppercase}.settings-sound-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.settings-toggle{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:999px;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.35rem .9rem;text-transform:uppercase}.settings-toggle.is-on{background:#0fbb6b33;border-color:#0fbb6b}.settings-toggle:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"]}]}],propDecorators:{open:[{type:p}],scanLinesEnabled:[{type:p}],rememberTabOnRefreshEnabled:[{type:p}],editLockEnabled:[{type:p}],listFontScale:[{type:p}],secondaryTabSoundLabel:[{type:p}],mainTabSoundLabel:[{type:p}],clickSoundLabel:[{type:p}],closeResult:[{type:m}],save:[{type:m}],previewListFontScale:[{type:m}]}});class le{constructor(){r(()=>{this.open()&&(this.draftImageUrl.set(this.imageUrl()),this.draftImageName.set(null),this.draftImageFile.set(null),this.removedImage.set(!1),this.clearPreviewUrl())})}open=t(!1,...ngDevMode?[{debugName:"open"}]:[]);title=t("Map Image",...ngDevMode?[{debugName:"title"}]:[]);imageUrl=t(null,...ngDevMode?[{debugName:"imageUrl"}]:[]);closeResult=d();save=d();draftImageName=o(null,...ngDevMode?[{debugName:"draftImageName"}]:[]);draftImageUrl=o(null,...ngDevMode?[{debugName:"draftImageUrl"}]:[]);draftImageFile=o(null,...ngDevMode?[{debugName:"draftImageFile"}]:[]);removedImage=o(!1,...ngDevMode?[{debugName:"removedImage"}]:[]);previewUrl=null;closeModal(){this.clearPreviewUrl(),this.closeResult.emit()}onImageSelected(e){const t=e.target,n=t.files?.[0]??null;this.draftImageName.set(n?n.name:null),n&&(this.removedImage.set(!1),this.draftImageFile.set(n),this.setPreviewUrl(URL.createObjectURL(n)),t.value="")}removeImage(){this.draftImageName.set(null),this.draftImageUrl.set(null),this.draftImageFile.set(null),this.removedImage.set(!0),this.clearPreviewUrl()}submit(e){e?.preventDefault(),this.save.emit({imageFile:this.draftImageFile(),removeImage:this.removedImage()}),this.clearPreviewUrl(),this.closeResult.emit()}setPreviewUrl(e){this.clearPreviewUrl(),this.previewUrl=e,this.draftImageUrl.set(e)}clearPreviewUrl(){this.previewUrl&&(URL.revokeObjectURL(this.previewUrl),this.previewUrl=null)}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:le,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:le,isStandalone:!0,selector:"pip-boy-map-image-modal",inputs:{open:{classPropertyName:"open",publicName:"open",isSignal:!0,isRequired:!1,transformFunction:null},title:{classPropertyName:"title",publicName:"title",isSignal:!0,isRequired:!1,transformFunction:null},imageUrl:{classPropertyName:"imageUrl",publicName:"imageUrl",isSignal:!0,isRequired:!1,transformFunction:null}},outputs:{closeResult:"closeResult",save:"save"},ngImport:e,template:'<pip-boy-dialog [open]="open()" [title]="title()" (closeResult)="closeModal()">\n <form id="map-image-form" (submit)="submit($event)">\n <div class="map-image-modal-body">\n <div class="map-image-modal-image">\n <button\n type="button"\n class="map-image-modal-image-button"\n (click)="modalImageInput.click()"\n >\n {{ draftImageName() ? draftImageName() : \'Select Image\' }}\n </button>\n @if (draftImageUrl()) {\n <button\n type="button"\n class="map-image-modal-image-remove"\n (click)="removeImage()"\n >\n Remove Image\n </button>\n }\n <input\n #modalImageInput\n type="file"\n accept="image/*"\n (change)="onImageSelected($event)"\n />\n @if (draftImageUrl()) {\n <img [src]="draftImageUrl()" alt="Map preview" />\n }\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="map-image-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.map-image-modal-body{display:flex;flex-direction:column;gap:1rem}.map-image-modal-image{display:flex;flex-direction:column;gap:.75rem}.map-image-modal-image input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.map-image-modal-image img{border:1px solid rgba(15,187,107,.35);max-height:12rem;object-fit:contain;padding:.5rem}.map-image-modal-image-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.map-image-modal-image-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.map-image-modal-image-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.map-image-modal-image-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"],dependencies:[{kind:"component",type:B,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:le,decorators:[{type:a,args:[{selector:"pip-boy-map-image-modal",standalone:!0,imports:[B],template:'<pip-boy-dialog [open]="open()" [title]="title()" (closeResult)="closeModal()">\n <form id="map-image-form" (submit)="submit($event)">\n <div class="map-image-modal-body">\n <div class="map-image-modal-image">\n <button\n type="button"\n class="map-image-modal-image-button"\n (click)="modalImageInput.click()"\n >\n {{ draftImageName() ? draftImageName() : \'Select Image\' }}\n </button>\n @if (draftImageUrl()) {\n <button\n type="button"\n class="map-image-modal-image-remove"\n (click)="removeImage()"\n >\n Remove Image\n </button>\n }\n <input\n #modalImageInput\n type="file"\n accept="image/*"\n (change)="onImageSelected($event)"\n />\n @if (draftImageUrl()) {\n <img [src]="draftImageUrl()" alt="Map preview" />\n }\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="map-image-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.map-image-modal-body{display:flex;flex-direction:column;gap:1rem}.map-image-modal-image{display:flex;flex-direction:column;gap:.75rem}.map-image-modal-image input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.map-image-modal-image img{border:1px solid rgba(15,187,107,.35);max-height:12rem;object-fit:contain;padding:.5rem}.map-image-modal-image-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.map-image-modal-image-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.map-image-modal-image-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.map-image-modal-image-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"]}]}],ctorParameters:()=>[],propDecorators:{open:[{type:e.Input,args:[{isSignal:!0,alias:"open",required:!1}]}],title:[{type:e.Input,args:[{isSignal:!0,alias:"title",required:!1}]}],imageUrl:[{type:e.Input,args:[{isSignal:!0,alias:"imageUrl",required:!1}]}],closeResult:[{type:e.Output,args:["closeResult"]}],save:[{type:e.Output,args:["save"]}]}});const de=[],ce=[],me=[],pe=[],ue=[],be=[],ge=[],he=[],fe=[],ve=[],ye=[],we=[],xe=[],ke=[],Se=[];class Me{returnToUrl=t("https://www.pip-boy.com",...ngDevMode?[{debugName:"returnToUrl"}]:[]);state=l(W);settings=l(P);imageStore=l(x);soundStore=l(_);audioPlayer=l(ae);appVersion=A;tabsOpen=o(!1,...ngDevMode?[{debugName:"tabsOpen"}]:[]);showResetModal=o(!1,...ngDevMode?[{debugName:"showResetModal"}]:[]);showExitModal=o(!1,...ngDevMode?[{debugName:"showExitModal"}]:[]);showBugModal=o(!1,...ngDevMode?[{debugName:"showBugModal"}]:[]);showSettingsModal=o(!1,...ngDevMode?[{debugName:"showSettingsModal"}]:[]);settingsListFontScaleSnapshot=o(null,...ngDevMode?[{debugName:"settingsListFontScaleSnapshot"}]:[]);showWelcomeModal=o(!0,...ngDevMode?[{debugName:"showWelcomeModal"}]:[]);mapImageModal=o(null,...ngDevMode?[{debugName:"mapImageModal"}]:[]);localMapImage=b("localMapImage",...ngDevMode?[{debugName:"localMapImage"}]:[]);worldMapImage=b("worldMapImage",...ngDevMode?[{debugName:"worldMapImage"}]:[]);localMapView=b("localMapView",...ngDevMode?[{debugName:"localMapView"}]:[]);worldMapView=b("worldMapView",...ngDevMode?[{debugName:"worldMapView"}]:[]);extraOptionModal=o(null,...ngDevMode?[{debugName:"extraOptionModal"}]:[]);tabsActionsLeftOpen=o(!1,...ngDevMode?[{debugName:"tabsActionsLeftOpen"}]:[]);tabsActionsRightOpen=o(!1,...ngDevMode?[{debugName:"tabsActionsRightOpen"}]:[]);isMapDragging=o(!1,...ngDevMode?[{debugName:"isMapDragging"}]:[]);viewportWidth=o("undefined"==typeof window?0:window.innerWidth,...ngDevMode?[{debugName:"viewportWidth"}]:[]);mapImageModalTitle=u(()=>"WORLD"===this.mapImageModal()?"World Map":"Local Map",...ngDevMode?[{debugName:"mapImageModalTitle"}]:[]);mapImageModalImage=u(()=>{const e="WORLD"===this.mapImageModal()?this.settings.worldMapImage():this.settings.localMapImage();return this.imageStore.getImageUrl(e)},...ngDevMode?[{debugName:"mapImageModalImage"}]:[]);secondaryTabSoundLabel=u(()=>this.soundStore.getSoundLabel(this.settings.secondaryTabSoundId()),...ngDevMode?[{debugName:"secondaryTabSoundLabel"}]:[]);mainTabSoundLabel=u(()=>this.soundStore.getSoundLabel(this.settings.mainTabSoundId()),...ngDevMode?[{debugName:"mainTabSoundLabel"}]:[]);clickSoundLabel=u(()=>this.soundStore.getSoundLabel(this.settings.clickSoundId()),...ngDevMode?[{debugName:"clickSoundLabel"}]:[]);mapDragState={target:null,startX:0,startY:0,scrollLeft:0,scrollTop:0,moved:!1};suppressMapClick=!1;isScreenTooSmall=u(()=>this.viewportWidth()<650,...ngDevMode?[{debugName:"isScreenTooSmall"}]:[]);extraOptionTitle=u(()=>{switch(this.extraOptionModal()){case"RADAWAY":case"RADX":return"Edit Text";default:return""}},...ngDevMode?[{debugName:"extraOptionTitle"}]:[]);extraOptionValue=u(()=>{const e=this.extraOptionModal();return"STIMPAK"===e?this.settings.stimpakLabel():"LIMBS"===e?this.settings.limbLabel():"RADAWAY"===e?this.settings.radAwayLabel():"RADX"===e?this.settings.radXLabel():""},...ngDevMode?[{debugName:"extraOptionValue"}]:[]);toggleTabs(){this.tabsOpen.update(e=>!e)}toggleTabsActions(e){"left"===e?(this.tabsActionsLeftOpen.update(e=>!e),this.tabsActionsRightOpen.set(!1)):(this.tabsActionsRightOpen.update(e=>!e),this.tabsActionsLeftOpen.set(!1))}onResize(){this.viewportWidth.set(window.innerWidth)}async saveSettingsToFile(){const e=this.settings.exportSettingsSnapshot(),t=this.collectImageIds(e),n=this.collectSoundIds(e),a=[],o=[],i=new v;for(const e of t){const t=await this.imageStore.getRecord(e);if(!t)continue;const n=this.getExtension(t.fileName,t.mime);i.file(`images/${e}${n}`,t.blob),a.push({id:e,fileName:t.fileName,mime:t.mime})}for(const e of n){const t=await this.soundStore.getRecord(e);if(!t)continue;const n=this.getSoundExtension(t.fileName,t.mime);i.file(`sounds/${e}${n}`,t.blob),o.push({id:e,fileName:t.fileName,mime:t.mime})}const s={version:1,images:a,sounds:o,pipBoy3000Settings:e};i.file("settings.json",JSON.stringify(s));const r=await i.generateAsync({type:"blob"}),l=URL.createObjectURL(r),d=document.createElement("a");d.href=l,d.download="pip-boy-3000a.zip",d.click(),URL.revokeObjectURL(l)}openResetModal(){this.showResetModal.set(!0)}closeResetModal(){this.showResetModal.set(!1)}confirmReset(){this.stopAllSounds(),this.settings.resetToDefaults(),this.closeResetModal(),this.showWelcomeModal.set(!0)}openExitModal(){this.showExitModal.set(!0)}closeExitModal(){this.showExitModal.set(!1)}confirmExit(){window.location.href=this.returnToUrl()}openBugModal(){this.showBugModal.set(!0)}closeBugModal(){this.showBugModal.set(!1)}confirmBugReport(){window.open("https://github.com/CodyTolene/pip-terminal/issues","_blank"),this.closeBugModal()}openSettingsModal(){this.settingsListFontScaleSnapshot.set(this.settings.listFontScale()),this.showSettingsModal.set(!0)}closeSettingsModal(){this.showSettingsModal.set(!1)}cancelSettingsModal(){const e=this.settingsListFontScaleSnapshot();null!==e&&this.settings.listFontScale.set(e),this.settingsListFontScaleSnapshot.set(null),this.showSettingsModal.set(!1)}closeWelcomeModal(){this.showWelcomeModal.set(!1)}saveSettingsModal(e){this.settings.scanLinesEnabled.set(e.scanLinesEnabled),this.settings.rememberTabOnRefresh.set(e.rememberTabOnRefreshEnabled),this.settings.editLockEnabled.set(e.editLockEnabled),this.settings.listFontScale.set(e.listFontScale),this.settingsListFontScaleSnapshot.set(null),e.removeSecondaryTabSound&&this.settings.secondaryTabSoundId.set(null),e.removeMainTabSound&&this.settings.mainTabSoundId.set(null),e.removeClickSound&&this.settings.clickSoundId.set(null),e.secondaryTabSoundFile&&this.soundStore.saveFile(e.secondaryTabSoundFile).then(e=>this.settings.secondaryTabSoundId.set(e.id)),e.mainTabSoundFile&&this.soundStore.saveFile(e.mainTabSoundFile).then(e=>this.settings.mainTabSoundId.set(e.id)),e.clickSoundFile&&this.soundStore.saveFile(e.clickSoundFile).then(e=>this.settings.clickSoundId.set(e.id)),this.closeSettingsModal()}previewListFontScale(e){this.settings.listFontScale.set(e)}openGithubProfile(){window.open("https://github.com/CodyTolene","_blank")}selectPrimary(e){this.soundStore.playSound(this.settings.mainTabSoundId()),this.state.selectPrimary(e)}selectSecondary(e){this.soundStore.playSound(this.settings.secondaryTabSoundId()),this.state.selectSecondary(e)}openExtraOptionModal(e){this.settings.editLockEnabled()||this.extraOptionModal.set(e)}closeExtraOptionModal(){this.extraOptionModal.set(null)}saveExtraOptionModal(e){const t=this.extraOptionModal();"STIMPAK"===t?this.settings.stimpakLabel.set(e):"LIMBS"===t?this.settings.limbLabel.set(e):"RADAWAY"===t?this.settings.radAwayLabel.set(e):"RADX"===t&&this.settings.radXLabel.set(e),this.closeExtraOptionModal()}async loadSettingsFromFile(e){const t=e.target,n=t.files?.[0]??null;if(!n)return;this.stopAllSounds();const a=await v.loadAsync(n),o=a.file("settings.json");if(!o)return void(t.value="");const i=await o.async("string"),s=JSON.parse(i),r=s.pipBoy3000Settings??s;if(Array.isArray(s.images))for(const e of s.images){const t=this.getExtension(e.fileName,e.mime),n=a.file(`images/${e.id}${t}`)??a.file(new RegExp(`^images/${e.id}\\.`))?.[0];if(!n)continue;const o=await n.async("blob");await this.imageStore.saveBlobWithId(e.id,o,e.fileName,e.mime)}if(Array.isArray(s.sounds))for(const e of s.sounds){const t=this.getSoundExtension(e.fileName,e.mime),n=a.file(`sounds/${e.id}${t}`)??a.file(new RegExp(`^sounds/${e.id}\\.`))?.[0];if(!n)continue;const o=await n.async("blob");await this.soundStore.saveBlobWithId(e.id,o,e.fileName,e.mime)}this.settings.importSettingsSnapshot(r),t.value=""}stopAllSounds(){this.audioPlayer.stop(),this.soundStore.stopAll()}collectImageIds(e){const t=new Set,n=e=>{e&&t.add(e)};return e.weaponItems.forEach(e=>n(e.imageId)),e.apparelItems.forEach(e=>n(e.imageId)),e.aidItems.forEach(e=>n(e.imageId)),e.miscItems.forEach(e=>n(e.imageId)),e.ammoItems.forEach(e=>n(e.imageId)),e.specialItems.forEach(e=>n(e.imageId)),e.skillItems.forEach(e=>n(e.imageId)),e.perkItems.forEach(e=>n(e.imageId)),e.vaultBoyImages.forEach(e=>n(e)),n(e.localMapImage),n(e.worldMapImage),Array.from(t)}collectSoundIds(e){const t=new Set,n=e=>{e&&t.add(e)};return n(e.secondaryTabSoundId),n(e.mainTabSoundId),n(e.clickSoundId),e.notesItems.forEach(e=>n(e.soundId)),e.radioItems.forEach(e=>n(e.soundId)),Array.from(t)}getExtension(e,t){const n=e.match(/\.[a-z0-9]+$/i);return n?n[0]:this.imageStore.extensionFromMime(t)}getSoundExtension(e,t){const n=e.match(/\.[a-z0-9]+$/i);return n?n[0]:this.soundStore.extensionFromMime(t)}openMapImageModal(e){this.settings.editLockEnabled()||(this.suppressMapClick?this.suppressMapClick=!1:this.mapImageModal.set(e))}closeMapImageModal(){this.mapImageModal.set(null)}zoomMap(e,t){const n="WORLD"===e?this.settings.worldMapZoom:this.settings.localMapZoom,a=Math.min(3,Math.max(.5,n()+t));n.set(Number(a.toFixed(2)))}resetMapZoom(e){"WORLD"===e?this.settings.worldMapZoom.set(1):this.settings.localMapZoom.set(1)}startMapDrag(e){if(0!==e.button)return;const t=e.currentTarget;t&&t.querySelector("img")&&(this.mapDragState={target:t,startX:e.clientX,startY:e.clientY,scrollLeft:t.scrollLeft,scrollTop:t.scrollTop,moved:!1},this.isMapDragging.set(!0),e.preventDefault())}onMapDrag(e){const t=this.mapDragState.target;if(!t)return;const n=e.clientX-this.mapDragState.startX,a=e.clientY-this.mapDragState.startY;if(!this.mapDragState.moved){if(Math.abs(n)<3&&Math.abs(a)<3)return;this.mapDragState.moved=!0}t.scrollLeft=this.mapDragState.scrollLeft-n,t.scrollTop=this.mapDragState.scrollTop-a,e.preventDefault()}endMapDrag(){this.mapDragState.target&&(this.mapDragState.moved&&(this.suppressMapClick=!0),this.mapDragState={target:null,startX:0,startY:0,scrollLeft:0,scrollTop:0,moved:!1},this.isMapDragging.set(!1))}fitMapZoom(e){const t="WORLD"===e?this.worldMapView():this.localMapView(),n="WORLD"===e?this.worldMapImage():this.localMapImage();if(!t||!n)return;const a=t.nativeElement.clientWidth,o=n.nativeElement.naturalWidth;if(!a||!o)return;const i=Math.min(3,Math.max(.5,a/o));("WORLD"===e?this.settings.worldMapZoom:this.settings.localMapZoom).set(Number(i.toFixed(2)))}isMapFit(e){const t="WORLD"===e?this.worldMapView():this.localMapView(),n="WORLD"===e?this.worldMapImage():this.localMapImage();if(!t||!n)return!1;const a=t.nativeElement.clientWidth,o=n.nativeElement.naturalWidth;if(!a||!o)return!1;const i=Math.min(3,Math.max(.5,a/o)),s="WORLD"===e?this.settings.worldMapZoom():this.settings.localMapZoom();return Math.abs(s-Number(i.toFixed(2)))<.01}async saveMapImageModal(e){const t=this.mapImageModal();if(t){if(e.removeImage)return"WORLD"===t?this.settings.worldMapImage.set(null):this.settings.localMapImage.set(null),void this.closeMapImageModal();if(e.imageFile){const n=await this.imageStore.saveFile(e.imageFile);"WORLD"===t?this.settings.worldMapImage.set(n.id):this.settings.localMapImage.set(n.id)}this.closeMapImageModal()}}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:Me,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:Me,isStandalone:!0,selector:"pip-boy-3000a",inputs:{returnToUrl:{classPropertyName:"returnToUrl",publicName:"returnToUrl",isSignal:!0,isRequired:!1,transformFunction:null}},host:{listeners:{"window:resize":"onResize()"},classAttribute:"pip-boy-3000a-theme"},providers:[W,P,{provide:N,useValue:{storageKey:"pipBoy3000aSettings",skillDefaults:ye,perkDefaults:we,weaponDefaults:de,apparelDefaults:ce,aidDefaults:me,miscDefaults:pe,ammoDefaults:ue,statSourceItems:{special:xe,skills:ke,perks:Se},inventorySourceItems:{weapons:be,apparel:ge,aid:he,misc:fe,ammo:ve}}}],viewQueries:[{propertyName:"localMapImage",first:!0,predicate:["localMapImage"],descendants:!0,isSignal:!0},{propertyName:"worldMapImage",first:!0,predicate:["worldMapImage"],descendants:!0,isSignal:!0},{propertyName:"localMapView",first:!0,predicate:["localMapView"],descendants:!0,isSignal:!0},{propertyName:"worldMapView",first:!0,predicate:["worldMapView"],descendants:!0,isSignal:!0}],ngImport:e,template:'<main\n #screen\n class="screen"\n [style.--list-font-scale]="settings.listFontScale()"\n>\n @if (settings.scanLinesEnabled()) {\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="300"\n [scanColorRgb]="\'255, 159, 28\'"\n />\n }\n @if (isScreenTooSmall()) {\n <div class="screen-size-overlay" role="alert" aria-live="assertive">\n Screen is too small.<br />Please rotate to landscape.\n </div>\n }\n \x3c!-- HEADER --\x3e\n <pip-boy-3000-header />\n \x3c!-- CONTENT --\x3e\n <section class="content">\n @if (state.primary() === \'STATS\') {\n @if (state.secondary() === \'STATUS\') {\n <div class="status-content">\n <nav class="column sub-content" aria-label="Status tabs">\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'CND\'"\n (click)="state.selectTertiary(\'CND\')"\n >\n CND\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'RAD\'"\n (click)="state.selectTertiary(\'RAD\')"\n >\n RAD\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'EFF\'"\n (click)="state.selectTertiary(\'EFF\')"\n >\n EFF\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'H20\'"\n (click)="state.selectTertiary(\'H20\')"\n >\n H20\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'FOD\'"\n (click)="state.selectTertiary(\'FOD\')"\n >\n FOD\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'SLP\'"\n (click)="state.selectTertiary(\'SLP\')"\n >\n SLP\n </button>\n </nav>\n @if (state.tertiary() === \'CND\') {\n <pip-boy-cnd-status />\n } @else if (state.tertiary() === \'RAD\') {\n <pip-boy-radiation-meter />\n <div class="extra-options">\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADAWAY\')"\n >\n {{ settings.radAwayLabel() }}\n </button>\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADX\')"\n >\n {{ settings.radXLabel() }}\n </button>\n </div>\n } @else if (state.tertiary() === \'EFF\') {\n <pip-boy-eff-layout />\n } @else if (state.tertiary() === \'H20\') {\n <pip-boy-status-meter kind="H20" />\n } @else if (state.tertiary() === \'FOD\') {\n <pip-boy-status-meter kind="FOD" />\n } @else if (state.tertiary() === \'SLP\') {\n <pip-boy-status-meter kind="SLP" />\n }\n </div>\n } @else if (state.secondary() === \'S.P.E.C.I.A.L.\') {\n <pip-boy-stats-layout\n category="SPECIAL"\n valueLabel="Rating"\n [valueMin]="1"\n [valueMax]="10"\n />\n } @else if (state.secondary() === \'SKILLS\') {\n <pip-boy-stats-layout\n category="SKILLS"\n valueLabel="Skill"\n [valueMin]="0"\n [valueMax]="100"\n />\n } @else if (state.secondary() === \'PERKS\') {\n <pip-boy-stats-layout\n category="PERKS"\n valueLabel="Rank"\n [valueMin]="0"\n />\n } @else if (state.secondary() === \'GENERAL\') {\n <pip-boy-stats-layout category="GENERAL" valueLabel="Value" />\n }\n } @else if (state.primary() === \'ITEMS\') {\n @if (state.secondary() === \'WEAPONS\') {\n <pip-boy-inventory-layout category="WEAPONS" />\n } @else if (state.secondary() === \'APPAREL\') {\n <pip-boy-inventory-layout category="APPAREL" />\n } @else if (state.secondary() === \'AID\') {\n <pip-boy-inventory-layout category="AID" />\n } @else if (state.secondary() === \'MISC\') {\n <pip-boy-inventory-layout category="MISC" />\n } @else if (state.secondary() === \'AMMO\') {\n <pip-boy-inventory-layout category="AMMO" />\n }\n } @else if (state.primary() === \'DATA\') {\n @if (state.secondary() === \'LOCAL MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #localMapView\n [class.is-draggable]="settings.localMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'LOCAL\')"\n >\n @if (settings.localMapImage()) {\n <img\n #localMapImage\n [src]="imageStore.getImageUrl(settings.localMapImage())"\n alt="Local map"\n [style.zoom]="settings.localMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.localMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.localMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'LOCAL\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'LOCAL\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'LOCAL\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'WORLD MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #worldMapView\n [class.is-draggable]="settings.worldMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'WORLD\')"\n >\n @if (settings.worldMapImage()) {\n <img\n #worldMapImage\n [src]="imageStore.getImageUrl(settings.worldMapImage())"\n alt="World map"\n [style.zoom]="settings.worldMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.worldMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.worldMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'WORLD\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'WORLD\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'WORLD\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'QUESTS\') {\n <pip-boy-quests-layout />\n } @else if (state.secondary() === \'NOTES\') {\n <pip-boy-stats-layout category="GENERAL" valueLabel="Value" />\n } @else if (state.secondary() === \'RADIO\') {\n <pip-boy-music-layout\n category="RADIO"\n [waveformColorRgb]="\'255, 159, 28\'"\n />\n }\n }\n </section>\n \x3c!-- SUB TABS --\x3e\n <section class="sub-tabs">\n @if (state.primary() === \'STATS\') {\n <nav aria-label="Stats tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'STATUS\'"\n (click)="selectSecondary(\'STATUS\')"\n >\n Status\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'S.P.E.C.I.A.L.\'"\n (click)="selectSecondary(\'S.P.E.C.I.A.L.\')"\n >\n S.P.E.C.I.A.L.\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'SKILLS\'"\n (click)="selectSecondary(\'SKILLS\')"\n >\n Skills\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'PERKS\'"\n (click)="selectSecondary(\'PERKS\')"\n >\n Perks\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'GENERAL\'"\n (click)="selectSecondary(\'GENERAL\')"\n >\n General\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'ITEMS\') {\n <nav aria-label="Items tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WEAPONS\'"\n (click)="selectSecondary(\'WEAPONS\')"\n >\n Weapons\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'APPAREL\'"\n (click)="selectSecondary(\'APPAREL\')"\n >\n Apparel\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AID\'"\n (click)="selectSecondary(\'AID\')"\n >\n Aid\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'MISC\'"\n (click)="selectSecondary(\'MISC\')"\n >\n Misc\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AMMO\'"\n (click)="selectSecondary(\'AMMO\')"\n >\n Ammo\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'DATA\') {\n <nav aria-label="Data tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'LOCAL MAP\'"\n (click)="selectSecondary(\'LOCAL MAP\')"\n >\n Local Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WORLD MAP\'"\n (click)="selectSecondary(\'WORLD MAP\')"\n >\n World Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'QUESTS\'"\n (click)="selectSecondary(\'QUESTS\')"\n >\n Quests\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'NOTES\'"\n (click)="selectSecondary(\'NOTES\')"\n >\n Misc\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'RADIO\'"\n (click)="selectSecondary(\'RADIO\')"\n >\n Radio\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n }\n </section>\n \x3c!-- MAIN TABS --\x3e\n <section class="tabs" [class.is-collapsed]="!tabsOpen()">\n <button\n type="button"\n class="tabs-toggle"\n aria-label="Toggle main tabs"\n [attr.aria-expanded]="tabsOpen()"\n aria-controls="main-tabs"\n (click)="toggleTabs()"\n >\n <span class="tabs-toggle-label tabs-toggle-label--state">\n {{ tabsOpen() ? \'CLOSE\' : \'OPEN\' }}\n </span>\n <span class="caret" aria-hidden="true"></span>\n <span class="tabs-toggle-label tabs-toggle-label--menu">MENU</span>\n </button>\n <nav id="main-tabs" aria-label="Main tabs">\n <div\n class="tabs-actions tabs-actions--left"\n [class.is-open]="tabsActionsLeftOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open settings actions"\n (click)="toggleTabsActions(\'left\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Save settings"\n title="Save settings"\n (click)="saveSettingsToFile()"\n >\n Save\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Load settings"\n title="Load settings"\n (click)="loadSettingsInputRight.click()"\n >\n Load\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Reset settings"\n title="Reset settings"\n (click)="openResetModal()"\n >\n Reset\n </button>\n <input\n #loadSettingsInputRight\n type="file"\n accept=".zip,application/zip"\n (change)="loadSettingsFromFile($event)"\n />\n </div>\n </div>\n <button\n type="button"\n [class.is-active]="state.primary() === \'STATS\'"\n (click)="selectPrimary(\'STATS\')"\n >\n <span>STATS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'ITEMS\'"\n (click)="selectPrimary(\'ITEMS\')"\n >\n <span>ITEMS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'DATA\'"\n (click)="selectPrimary(\'DATA\')"\n >\n <span>DATA</span>\n </button>\n <div\n class="tabs-actions tabs-actions--right"\n [class.is-open]="tabsActionsRightOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open utility actions"\n (click)="toggleTabsActions(\'right\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Open GitHub profile"\n title="Open GitHub profile"\n (click)="openGithubProfile()"\n >\n ❤\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Open settings"\n title="Settings"\n (click)="openSettingsModal()"\n >\n Settings\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Report a bug"\n title="Report a bug"\n (click)="openBugModal()"\n >\n Bug\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Exit"\n title="Exit"\n (click)="openExitModal()"\n >\n Exit\n </button>\n </div>\n </div>\n @if (tabsOpen()) {\n <div class="tabs-version">v{{ appVersion }}</div>\n }\n </nav>\n </section>\n <pip-boy-welcome-modal\n [open]="showWelcomeModal()"\n [listFontScale]="settings.listFontScale()"\n (previewListFontScale)="previewListFontScale($event)"\n (closeResult)="closeWelcomeModal()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showResetModal()"\n title="Reset Settings"\n message="This will reset all values back to defaults. This cannot be undone."\n confirmLabel="Reset"\n (closeResult)="closeResetModal()"\n (confirm)="confirmReset()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showExitModal()"\n title="Exit"\n message="Are you sure you want to leave this screen?"\n confirmLabel="Exit"\n (closeResult)="closeExitModal()"\n (confirm)="confirmExit()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showBugModal()"\n title="Report a bug"\n message="Would you like to report a bug?"\n confirmLabel="Yes"\n cancelLabel="No"\n (closeResult)="closeBugModal()"\n (confirm)="confirmBugReport()"\n />\n <pip-boy-map-image-modal\n [open]="mapImageModal() !== null"\n [title]="mapImageModalTitle()"\n [imageUrl]="mapImageModalImage()"\n (closeResult)="closeMapImageModal()"\n (save)="saveMapImageModal($event)"\n />\n <pip-boy-settings-modal\n [open]="showSettingsModal()"\n [scanLinesEnabled]="settings.scanLinesEnabled()"\n [rememberTabOnRefreshEnabled]="settings.rememberTabOnRefresh()"\n [editLockEnabled]="settings.editLockEnabled()"\n [listFontScale]="settings.listFontScale()"\n [secondaryTabSoundLabel]="secondaryTabSoundLabel()"\n [mainTabSoundLabel]="mainTabSoundLabel()"\n [clickSoundLabel]="clickSoundLabel()"\n (closeResult)="cancelSettingsModal()"\n (previewListFontScale)="previewListFontScale($event)"\n (save)="saveSettingsModal($event)"\n />\n <pip-boy-name-edit-modal\n [open]="extraOptionModal() !== null"\n [value]="extraOptionValue()"\n [title]="extraOptionTitle()"\n placeholder="Value"\n [allowEmpty]="true"\n (closeResult)="closeExtraOptionModal()"\n (save)="saveExtraOptionModal($event)"\n />\n</main>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.content{box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;height:100%;overflow:auto;padding:1rem 2rem;position:relative;width:100%}.content .status-content{box-sizing:border-box;display:flex;flex-direction:row;height:100%;gap:1rem}.content .column{box-sizing:border-box;display:flex;flex:1;flex-direction:column}.content .sub-content{max-width:max-content}.content .sub-content button{width:auto;max-width:10rem;height:2.5rem;background:transparent;color:#ff9f1c;display:flex;align-items:center;justify-content:center;text-align:center;text-transform:uppercase;border:none;border-left:2px solid transparent;border-right:2px solid transparent;cursor:pointer;padding:0 1rem;margin-bottom:1rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1) * 1.25)}.content .sub-content button.is-active{background:#ff9f1c14;border-left:2px solid #ff9f1c;border-right:2px solid #ff9f1c}.content .sub-content button:hover{background:#ff9f1c26}.content .radiation-status,.content .effects-status{box-sizing:border-box;display:flex;align-items:center;justify-content:center}.content .actions{box-sizing:border-box;display:flex;align-items:flex-end;max-width:max-content}:host{font-size:inherit}\n",":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.sub-tabs{flex:0 0 auto;min-height:0;margin-bottom:.5rem;padding:0 1rem;position:relative;z-index:1}.sub-tabs>nav{box-sizing:border-box;display:flex;align-items:center;width:100%;height:2.25rem;gap:0}.sub-tabs>nav .center-line{flex:1 1 auto;height:100%;min-width:1.5rem}.sub-tabs>nav>.center-line:last-child .top-half-line:before{left:auto;right:0}.sub-tabs>nav button{background:transparent;border:2px solid transparent;color:#ff9f1c;cursor:pointer;font-size:clamp(1.25rem,1.25rem + (1.5rem - 1.25rem) * (100vw - 360px) / (1200px - 360px),1.5rem);padding:.5rem}.sub-tabs>nav button.is-active{background:#ff9f1c14;border:2px solid #ff9f1c}.sub-tabs>nav button:hover{background:#ff9f1c26}@media(max-width:700px)and (orientation:landscape){.sub-tabs>nav .center-line{min-width:.5rem}}:host{font-size:inherit}\n",':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.tabs{align-items:center;box-sizing:border-box;display:flex;flex-direction:column;flex:0 0 auto;gap:.5rem;max-height:12rem;overflow:hidden;padding:0;position:relative;z-index:5;transition:max-height .35s ease-in-out,padding .35s ease-in-out,gap .35s ease-in-out;width:100%}.tabs.is-collapsed{gap:0;max-height:2rem}.tabs.is-collapsed>nav{opacity:0;pointer-events:none;transform:translateY(100%)}.tabs.is-collapsed .tabs-toggle .caret{transform:translateY(2px) rotate(-135deg)}.tabs .tabs-toggle{align-items:center;background:transparent;border:none;box-sizing:border-box;color:#ff9f1c;cursor:pointer;display:inline-flex;height:2rem;justify-content:center;line-height:0;max-height:2rem;min-height:2rem;overflow:hidden;padding:0 1rem;transition:border-color .2s ease;width:100%}.tabs .tabs-toggle:hover{background-color:#ff9f1c1f}.tabs .tabs-toggle .caret{border:solid #ff9f1c;border-width:0 2px 2px 0;box-sizing:border-box;display:inline-block;height:.6rem;margin:0 .5rem;padding:0;transform:translateY(-4px) rotate(45deg);transform-origin:center;transition:transform .35s ease;width:.6rem}.tabs .tabs-toggle .tabs-toggle-label{font-size:clamp(.7rem,.7rem + (.85rem - .7rem) * (100vw - 360px) / (1200px - 360px),.85rem);letter-spacing:.1em;line-height:1;text-transform:uppercase;white-space:nowrap}.tabs>nav{display:flex;justify-content:center;opacity:1;padding-bottom:.5rem;transform:translateY(0);transition:transform .35s ease-in-out,opacity .35s ease-in-out;transform-origin:bottom;will-change:transform,opacity;width:100%;position:relative}.tabs .tabs-version{bottom:14px;color:#ff9f1cbf;font-size:10px;letter-spacing:.08em;position:absolute;right:22px}.tabs .tabs-actions{align-items:center;display:flex;gap:.5rem;left:1rem;position:absolute;top:50%;transform:translateY(-50%)}.tabs .tabs-actions.right,.tabs .tabs-actions.tabs-actions--right{left:auto;right:1rem}.tabs .tabs-actions .tabs-actions-toggle{align-items:center;background:transparent;border:1px solid rgba(255,159,28,.6);border-radius:9999px;color:#ff9f1c;cursor:pointer;display:none;height:2.1rem;justify-content:center;padding:0 .6rem;text-transform:uppercase;width:2.4rem}.tabs .tabs-actions .tabs-actions-toggle:hover{background:#ff9f1c1f;border-color:#ff9f1c}.tabs .tabs-actions .tabs-actions-icon{background:#ff9f1c;border-radius:9999px;display:block;height:2px;position:relative;width:1.1rem}.tabs .tabs-actions .tabs-actions-icon:before,.tabs .tabs-actions .tabs-actions-icon:after{content:"";background:#ff9f1c;border-radius:9999px;height:2px;left:0;position:absolute;width:100%}.tabs .tabs-actions .tabs-actions-icon:before{top:-5px}.tabs .tabs-actions .tabs-actions-icon:after{top:5px}.tabs .tabs-actions .tabs-actions-menu{display:flex;gap:.5rem;align-items:center}.tabs .tabs-actions .action-button{background:transparent;border:1px solid rgba(255,159,28,.7);color:#ff9f1cb3;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.25rem .35rem;text-align:left;width:100%;border-radius:1rem;text-align:center}.tabs .tabs-actions .action-button:hover{background:#ff9f1c1f;border-color:#ff9f1c}.tabs .tabs-actions input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.tabs .tabs-action{align-items:center;background:#ff9f1c1a;border:2px solid rgba(255,159,28,.6);border-radius:.4rem;color:#ff9f1c;cursor:pointer;display:inline-flex;font-size:clamp(.65rem,.65rem + (.75rem - .65rem) * (100vw - 360px) / (1200px - 360px),.75rem);height:2.5rem;justify-content:center;letter-spacing:.08em;padding:0 .85rem;text-transform:uppercase;transition:background .2s ease,border-color .2s ease;width:auto}.tabs .tabs-action:hover{background:#ff9f1c2e;border-color:#ff9f1c}.tabs>nav>button{align-items:center;background:transparent;border-radius:9999px;border:2px solid rgba(255,159,28,.35);box-sizing:border-box;color:#ff9f1c;cursor:pointer;display:inline-flex;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);height:5rem;justify-content:center;line-height:1;margin:0 1rem;padding:0;text-transform:uppercase;width:5rem}.tabs>nav>button>span{align-items:center;display:inline-flex;justify-content:center;line-height:1;white-space:nowrap;width:100%;height:100%;border-radius:9999px;padding:0}.tabs>nav>button:hover{border-color:#ff9f1ca6}.tabs>nav>button:hover>span{background:#ff9f1c1f}.tabs>nav>button.is-active{border-color:#ff9f1c}.tabs>nav>button.is-active>span{background:#ff9f1c29}@media(max-width:750px){.tabs .tabs-actions{z-index:5}.tabs .tabs-actions .tabs-actions-toggle{display:inline-flex}.tabs .tabs-actions .tabs-actions-menu{display:none}.tabs .tabs-actions.is-open .tabs-actions-menu{background:#1f1002f2;border:1px solid rgba(255,159,28,.35);border-radius:.5rem;display:flex;flex-direction:column;gap:.35rem;padding:.5rem;position:absolute;bottom:2.6rem;z-index:1000}.tabs .tabs-actions.tabs-actions--left.is-open .tabs-actions-menu{left:0}.tabs .tabs-actions.tabs-actions--right.is-open .tabs-actions-menu{right:0}.tabs .tabs-actions .action-button{width:100%}}@media(max-width:750px){.tabs{overflow:visible}}:host{font-size:inherit}\n',':host{--pip-boy-color: #ff9f1c;--pip-boy-color-rgb: 255, 159, 28;--pip-boy-bg-dark: #1f1002;--pip-boy-bg-darker: #3d2104}:host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host.pip-boy-3000a-theme ::ng-deep{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep button{color:#ff9f1c;border-color:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep button:hover{background:#ff9f1c1f;border-color:#ff9f1ca6}:host.pip-boy-3000a-theme ::ng-deep button.is-active{border-color:#ff9f1c;background:#ff9f1c29;border-left-color:#ff9f1c;border-right-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep input,:host.pip-boy-3000a-theme ::ng-deep select,:host.pip-boy-3000a-theme ::ng-deep textarea{color:#ff9f1c;border-color:#ff9f1c99;background:#1f10024d}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout,:host.pip-boy-3000a-theme ::ng-deep .stats-layout,:host.pip-boy-3000a-theme ::ng-deep .quests-layout,:host.pip-boy-3000a-theme ::ng-deep .music-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header *,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout *,:host.pip-boy-3000a-theme ::ng-deep .stats-layout *,:host.pip-boy-3000a-theme ::ng-deep .quests-layout *,:host.pip-boy-3000a-theme ::ng-deep .music-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal *{color:#ff9f1c;border-color:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header button,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout button,:host.pip-boy-3000a-theme ::ng-deep .stats-layout button,:host.pip-boy-3000a-theme ::ng-deep .quests-layout button,:host.pip-boy-3000a-theme ::ng-deep .music-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal button{color:#ff9f1c;border-color:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header button:hover,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep .stats-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep .quests-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep .music-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal button:hover{background:#ff9f1c1f;border-color:#ff9f1ca6}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header button.is-active,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep .stats-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep .quests-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep .music-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal button.is-active{border-color:#ff9f1c;background:#ff9f1c29}:host.pip-boy-3000a-theme ::ng-deep [role=dialog],:host.pip-boy-3000a-theme ::ng-deep .dialog,:host.pip-boy-3000a-theme ::ng-deep .modal,:host.pip-boy-3000a-theme ::ng-deep .pip-boy-dialog{background:#1f1002fa;border-color:#ff9f1c99;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep [role=dialog] *,:host.pip-boy-3000a-theme ::ng-deep .dialog *,:host.pip-boy-3000a-theme ::ng-deep .modal *,:host.pip-boy-3000a-theme ::ng-deep .pip-boy-dialog *{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .center-line:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .bottom-half-line:before{background:linear-gradient(to bottom,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}:host.pip-boy-3000a-theme ::ng-deep .top-half-line:before{background:linear-gradient(to top,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}:host.pip-boy-3000a-theme ::ng-deep .main-title-left-line .bottom-half-line:before{left:0}:host.pip-boy-3000a-theme ::ng-deep .main-title-right-line .bottom-half-line:before{right:0}:host.pip-boy-3000a-theme ::ng-deep .hp-title-line .bottom-half-line:before,:host.pip-boy-3000a-theme ::ng-deep .ap-title-line .bottom-half-line:before,:host.pip-boy-3000a-theme ::ng-deep .xp-title-line .bottom-half-line:before{right:0}:host.pip-boy-3000a-theme ::ng-deep ::-webkit-scrollbar-thumb{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep ::-webkit-scrollbar-track{background:#1f100299}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-tick{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-tick:first-child,:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-tick--end-triangle{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-arrow{border-left-color:transparent;border-right-color:transparent;border-bottom-color:#ff9f1cb3}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-handle{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-fill{background:#ff9f1c73;box-shadow:0 0 20px #ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-track,:host.pip-boy-3000a-theme ::ng-deep .status-label,:host.pip-boy-3000a-theme ::ng-deep .status-right,:host.pip-boy-3000a-theme ::ng-deep .status-resist-text{border-top-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .status-resist:hover,:host.pip-boy-3000a-theme ::ng-deep .status-resist:focus-visible{background:transparent;border-color:transparent}:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-add,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-edit,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-delete,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-move{background:#ff9f1c0d;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-add:hover,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-delete:hover,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .quest-toggle{border-color:#ff9f1ca6}:host.pip-boy-3000a-theme ::ng-deep .quest-toggle.is-checked{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .quest-add{background:#ff9f1c14;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .quest-edit,:host.pip-boy-3000a-theme ::ng-deep .quest-delete,:host.pip-boy-3000a-theme ::ng-deep .quest-move{background:#ff9f1c0d;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .quest-add:hover{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .quest-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .quest-delete:hover,:host.pip-boy-3000a-theme ::ng-deep .quest-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .music-add{background:#ff9f1c14;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-edit,:host.pip-boy-3000a-theme ::ng-deep .music-delete,:host.pip-boy-3000a-theme ::ng-deep .music-move{background:#ff9f1c0d;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-add:hover{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .music-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .music-delete:hover,:host.pip-boy-3000a-theme ::ng-deep .music-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .music-waveform canvas{border-right-color:#ff9f1c40;border-bottom-color:#ff9f1c40}:host.pip-boy-3000a-theme ::ng-deep .music-list-item.is-selected{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .music-list-item.is-selected:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-control{background:#ff9f1c0d;border-color:#ff9f1c99;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-control:hover,:host.pip-boy-3000a-theme ::ng-deep .music-control.is-active{background:#ff9f1c1f;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-control--autoplay.is-active,:host.pip-boy-3000a-theme ::ng-deep .music-control--shuffle.is-active{background:#ff9f1c33;border-color:#ff9f1c;box-shadow:0 0 .6rem #ff9f1c47}:host.pip-boy-3000a-theme ::ng-deep .music-volume{border-color:#ff9f1c59;background:#ff9f1c0a}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing-label{color:#ff9f1cb3}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing-value{border-color:#ff9f1c66;color:#ff9f1cd9}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing.is-disabled .music-now-playing-label,:host.pip-boy-3000a-theme ::ng-deep .music-now-playing.is-disabled .music-now-playing-value{color:#ff9f1c73}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing.is-disabled .music-now-playing-value{background:#ff9f1c08;border-color:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep .music-volume-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep .music-volume-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-volume-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-volume-label,:host.pip-boy-3000a-theme ::ng-deep .music-volume-value{color:#ff9f1ccc}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-value{color:#ff9f1ccc}:host.pip-boy-3000a-theme ::ng-deep .settings-toggle.is-on{background:#ff9f1c33;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .map-control-button:hover{background:#1f1002e6;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .welcome__range{background:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .welcome__range::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .welcome__range::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-list-item.is-selected{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .resource-list-item.is-selected:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-add,:host.pip-boy-3000a-theme ::ng-deep .resource-edit,:host.pip-boy-3000a-theme ::ng-deep .resource-drop,:host.pip-boy-3000a-theme ::ng-deep .resource-move{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-add{background:#ff9f1c14}:host.pip-boy-3000a-theme ::ng-deep .resource-add:hover{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .resource-edit,:host.pip-boy-3000a-theme ::ng-deep .resource-drop,:host.pip-boy-3000a-theme ::ng-deep .resource-move{background:#ff9f1c0d}:host.pip-boy-3000a-theme ::ng-deep .resource-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .resource-drop:hover,:host.pip-boy-3000a-theme ::ng-deep .resource-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .resource-description:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-description:after{background:linear-gradient(to bottom,#ff9f1c,#ff9f1ca6 35%,#ff9f1c59 65%,#ff9f1c00)}:host.pip-boy-3000a-theme ::ng-deep .resource-stat{border:none}:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field textarea{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal .settings-slider-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal .settings-slider-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal .settings-slider-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__data{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__data code{background:#ff9f1c14;border-color:#ff9f1c38;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__data a{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__section{background:#ff9f1c0a;border-color:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal .reset-modal-body{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal .reset-modal-body p{color:#ff9f1cd9}:host.pip-boy-3000a-theme ::ng-deep pip-boy-audio-edit-modal .audio-modal-field input{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-audio-edit-modal .audio-modal-field input:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .stat-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .number-input-row input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .number-input-row input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field textarea,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal .number-input-row input{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .stat-modal-field input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .number-input-row input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .number-input-row input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field textarea:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal .number-input-row input:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep input:focus,:host.pip-boy-3000a-theme ::ng-deep select:focus,:host.pip-boy-3000a-theme ::ng-deep textarea:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field textarea{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field textarea:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep #text-field-effects{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep #text-field-effects:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control{background:#ff9f1c0d;border-color:#ff9f1c99;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control.is-active{background:#ff9f1c1f;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control--autoplay.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control--shuffle.is-active{background:#ff9f1c33;border-color:#ff9f1c;box-shadow:0 0 .6rem #ff9f1c47}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control:disabled{background:#ff9f1c05;border-color:#ff9f1c33;color:#ff9f1c59;opacity:.8}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing-label{color:#ff9f1cb3}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing-value{border-color:#ff9f1c66;color:#ff9f1cd9}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing.is-disabled .music-now-playing-label,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing.is-disabled .music-now-playing-value{color:#ff9f1c73}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing.is-disabled .music-now-playing-value{background:#ff9f1c08;border-color:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-volume-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-volume-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-volume-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host{font-family:Roboto Condensed,sans-serif;font-size:clamp(.95rem,.95rem + (1.15rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.15rem);scrollbar-color:rgba(255,159,28,.6) rgba(31,16,2,.6);scrollbar-width:thin;background-color:#1f1002;background-image:repeating-linear-gradient(to bottom,#ffffff0a 0 1px,#0000 4px);background-size:100% 6px;animation:scan-lines 6s linear infinite;box-shadow:inset 0 0 24px #0009,inset 0 0 90px #00000073;box-sizing:border-box;color:#ff9f1c;display:block;height:100%;overflow:hidden;position:relative;width:100%;font-size:inherit}:host ::-webkit-scrollbar{width:6px;height:6px}:host ::-webkit-scrollbar-track{background:#1f100299}:host ::-webkit-scrollbar-thumb{background:#ff9f1c99;border-radius:9999px}:host:before{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,#1f100200 55%,#00000040 70%,#0009);mix-blend-mode:multiply}@keyframes scan-lines{0%{background-position:0 0}to{background-position:0 60px}}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:0;position:relative;width:100%;display:flex;flex-direction:column;min-height:0}.screen-size-overlay{position:absolute;inset:0;background:#000000d9;color:#ff9f1c;display:flex;align-items:center;justify-content:center;text-align:center;padding:2rem;text-transform:uppercase;font-size:clamp(1.1rem,1.1rem + (1.35rem - 1.1rem) * (100vw - 360px) / (1200px - 360px),1.35rem);z-index:200}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:2px;background:#ff9f1c}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:50%;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}.top-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.top-half-line:before{content:"";position:absolute;bottom:50%;top:-1.25rem;width:2px;z-index:2;left:0;background:linear-gradient(to top,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}.extra-options{margin-top:0;display:flex;flex-direction:column;font-family:Roboto Mono,monospace;font-size:calc(clamp(1.05rem,1.05rem + .2rem * (100vw - 360px) / 840px,1.25rem) * var(--list-font-scale, 1));align-items:flex-end;gap:.75rem;white-space:nowrap;position:absolute;top:1rem;right:2rem;z-index:3}.extra-options button{background:transparent;border:none;color:#ff9f1c;cursor:pointer;font:inherit;padding:0;white-space:nowrap}.extra-options button:hover{opacity:.8}.extra-options button:disabled,.extra-options button.is-locked{cursor:default}.extra-options .controller-button{font-size:inherit;white-space:nowrap}.extra-options .controller-button .large-par{display:inline;padding-left:.5rem;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));top:-.15rem;position:relative;white-space:nowrap}.map-panel{display:flex;flex:1 1 auto;min-height:0;position:relative;width:100%}.map-view{align-items:flex-start;background:transparent;border:none;color:#ff9f1c;cursor:pointer;display:flex;flex:1 1 auto;justify-content:flex-start;min-height:0;overflow:auto;padding:0;width:100%}.map-view span{letter-spacing:.1em;margin:auto;text-transform:uppercase;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.map-view img{display:block;max-width:none;max-height:none}.map-view.is-locked,.map-view:disabled{cursor:default}.map-view.is-draggable{cursor:grab}.map-view.is-dragging{cursor:grabbing}.map-zoom{display:flex;gap:.5rem;position:absolute;right:1.5rem;top:.5rem;z-index:2}.map-zoom .map-zoom-button{padding:0;width:calc(2rem * var(--list-font-scale, 1))}.map-fit{position:absolute;right:1.5rem;bottom:.5rem;z-index:2}.map-control-button{align-items:center;background:#1f1002f2;border:1px solid rgba(255,159,28,.65);border-radius:.5rem;color:#ff9f1c;cursor:pointer;display:inline-flex;font-size:calc(clamp(.75rem,.75rem + .15rem * (100vw - 360px) / 840px,.9rem) * var(--list-font-scale, 1));justify-content:center;text-transform:uppercase;height:calc(2rem * var(--list-font-scale, 1));padding:0 calc(.6rem * var(--list-font-scale, 1))}.map-control-button:hover{border-color:#ff9f1c;background:#1f1002e6}\n'],dependencies:[{kind:"component",type:y,selector:"pip-boy-screen-scan-lines",inputs:["replayTimeoutSeconds","screen","scanSpeedSeconds","tailLengthPx","scanColorRgb"]},{kind:"component",type:H,selector:"pip-boy-3000-header"},{kind:"component",type:$,selector:"pip-boy-inventory-layout",inputs:["category"]},{kind:"component",type:G,selector:"pip-boy-stats-layout",inputs:["category","valueLabel","valueMin","valueMax"]},{kind:"component",type:Y,selector:"pip-boy-reset-confirm-modal",inputs:["open","title","message","confirmLabel","cancelLabel"],outputs:["confirm","closeResult"]},{kind:"component",type:Q,selector:"pip-boy-name-edit-modal",inputs:["open","title","value","placeholder","allowEmpty","inputType","inputMin","inputStep","showNumberControls"],outputs:["closeResult","save"]},{kind:"component",type:K,selector:"pip-boy-cnd-status"},{kind:"component",type:X,selector:"pip-boy-radiation-meter"},{kind:"component",type:J,selector:"pip-boy-status-meter",inputs:["kind"]},{kind:"component",type:te,selector:"pip-boy-eff-layout"},{kind:"component",type:le,selector:"pip-boy-map-image-modal",inputs:["open","title","imageUrl"],outputs:["closeResult","save"]},{kind:"component",type:ne,selector:"pip-boy-quests-layout"},{kind:"component",type:re,selector:"pip-boy-settings-modal",inputs:["open","scanLinesEnabled","rememberTabOnRefreshEnabled","editLockEnabled","listFontScale","secondaryTabSoundLabel","mainTabSoundLabel","clickSoundLabel"],outputs:["closeResult","save","previewListFontScale"]},{kind:"component",type:ie,selector:"pip-boy-music-layout",inputs:["category","waveformColorRgb"]},{kind:"component",type:se,selector:"pip-boy-welcome-modal",inputs:["open","listFontScale"],outputs:["closeResult","previewListFontScale"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:Me,decorators:[{type:a,args:[{selector:"pip-boy-3000a",standalone:!0,host:{class:"pip-boy-3000a-theme"},imports:[y,H,$,G,Y,Q,K,X,J,te,le,ne,re,ie,se],providers:[W,P,{provide:N,useValue:{storageKey:"pipBoy3000aSettings",skillDefaults:ye,perkDefaults:we,weaponDefaults:de,apparelDefaults:ce,aidDefaults:me,miscDefaults:pe,ammoDefaults:ue,statSourceItems:{special:xe,skills:ke,perks:Se},inventorySourceItems:{weapons:be,apparel:ge,aid:he,misc:fe,ammo:ve}}}],template:'<main\n #screen\n class="screen"\n [style.--list-font-scale]="settings.listFontScale()"\n>\n @if (settings.scanLinesEnabled()) {\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="300"\n [scanColorRgb]="\'255, 159, 28\'"\n />\n }\n @if (isScreenTooSmall()) {\n <div class="screen-size-overlay" role="alert" aria-live="assertive">\n Screen is too small.<br />Please rotate to landscape.\n </div>\n }\n \x3c!-- HEADER --\x3e\n <pip-boy-3000-header />\n \x3c!-- CONTENT --\x3e\n <section class="content">\n @if (state.primary() === \'STATS\') {\n @if (state.secondary() === \'STATUS\') {\n <div class="status-content">\n <nav class="column sub-content" aria-label="Status tabs">\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'CND\'"\n (click)="state.selectTertiary(\'CND\')"\n >\n CND\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'RAD\'"\n (click)="state.selectTertiary(\'RAD\')"\n >\n RAD\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'EFF\'"\n (click)="state.selectTertiary(\'EFF\')"\n >\n EFF\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'H20\'"\n (click)="state.selectTertiary(\'H20\')"\n >\n H20\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'FOD\'"\n (click)="state.selectTertiary(\'FOD\')"\n >\n FOD\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'SLP\'"\n (click)="state.selectTertiary(\'SLP\')"\n >\n SLP\n </button>\n </nav>\n @if (state.tertiary() === \'CND\') {\n <pip-boy-cnd-status />\n } @else if (state.tertiary() === \'RAD\') {\n <pip-boy-radiation-meter />\n <div class="extra-options">\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADAWAY\')"\n >\n {{ settings.radAwayLabel() }}\n </button>\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADX\')"\n >\n {{ settings.radXLabel() }}\n </button>\n </div>\n } @else if (state.tertiary() === \'EFF\') {\n <pip-boy-eff-layout />\n } @else if (state.tertiary() === \'H20\') {\n <pip-boy-status-meter kind="H20" />\n } @else if (state.tertiary() === \'FOD\') {\n <pip-boy-status-meter kind="FOD" />\n } @else if (state.tertiary() === \'SLP\') {\n <pip-boy-status-meter kind="SLP" />\n }\n </div>\n } @else if (state.secondary() === \'S.P.E.C.I.A.L.\') {\n <pip-boy-stats-layout\n category="SPECIAL"\n valueLabel="Rating"\n [valueMin]="1"\n [valueMax]="10"\n />\n } @else if (state.secondary() === \'SKILLS\') {\n <pip-boy-stats-layout\n category="SKILLS"\n valueLabel="Skill"\n [valueMin]="0"\n [valueMax]="100"\n />\n } @else if (state.secondary() === \'PERKS\') {\n <pip-boy-stats-layout\n category="PERKS"\n valueLabel="Rank"\n [valueMin]="0"\n />\n } @else if (state.secondary() === \'GENERAL\') {\n <pip-boy-stats-layout category="GENERAL" valueLabel="Value" />\n }\n } @else if (state.primary() === \'ITEMS\') {\n @if (state.secondary() === \'WEAPONS\') {\n <pip-boy-inventory-layout category="WEAPONS" />\n } @else if (state.secondary() === \'APPAREL\') {\n <pip-boy-inventory-layout category="APPAREL" />\n } @else if (state.secondary() === \'AID\') {\n <pip-boy-inventory-layout category="AID" />\n } @else if (state.secondary() === \'MISC\') {\n <pip-boy-inventory-layout category="MISC" />\n } @else if (state.secondary() === \'AMMO\') {\n <pip-boy-inventory-layout category="AMMO" />\n }\n } @else if (state.primary() === \'DATA\') {\n @if (state.secondary() === \'LOCAL MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #localMapView\n [class.is-draggable]="settings.localMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'LOCAL\')"\n >\n @if (settings.localMapImage()) {\n <img\n #localMapImage\n [src]="imageStore.getImageUrl(settings.localMapImage())"\n alt="Local map"\n [style.zoom]="settings.localMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.localMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.localMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'LOCAL\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'LOCAL\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'LOCAL\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'WORLD MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #worldMapView\n [class.is-draggable]="settings.worldMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'WORLD\')"\n >\n @if (settings.worldMapImage()) {\n <img\n #worldMapImage\n [src]="imageStore.getImageUrl(settings.worldMapImage())"\n alt="World map"\n [style.zoom]="settings.worldMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.worldMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.worldMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'WORLD\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'WORLD\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'WORLD\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'QUESTS\') {\n <pip-boy-quests-layout />\n } @else if (state.secondary() === \'NOTES\') {\n <pip-boy-stats-layout category="GENERAL" valueLabel="Value" />\n } @else if (state.secondary() === \'RADIO\') {\n <pip-boy-music-layout\n category="RADIO"\n [waveformColorRgb]="\'255, 159, 28\'"\n />\n }\n }\n </section>\n \x3c!-- SUB TABS --\x3e\n <section class="sub-tabs">\n @if (state.primary() === \'STATS\') {\n <nav aria-label="Stats tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'STATUS\'"\n (click)="selectSecondary(\'STATUS\')"\n >\n Status\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'S.P.E.C.I.A.L.\'"\n (click)="selectSecondary(\'S.P.E.C.I.A.L.\')"\n >\n S.P.E.C.I.A.L.\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'SKILLS\'"\n (click)="selectSecondary(\'SKILLS\')"\n >\n Skills\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'PERKS\'"\n (click)="selectSecondary(\'PERKS\')"\n >\n Perks\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'GENERAL\'"\n (click)="selectSecondary(\'GENERAL\')"\n >\n General\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'ITEMS\') {\n <nav aria-label="Items tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WEAPONS\'"\n (click)="selectSecondary(\'WEAPONS\')"\n >\n Weapons\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'APPAREL\'"\n (click)="selectSecondary(\'APPAREL\')"\n >\n Apparel\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AID\'"\n (click)="selectSecondary(\'AID\')"\n >\n Aid\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'MISC\'"\n (click)="selectSecondary(\'MISC\')"\n >\n Misc\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AMMO\'"\n (click)="selectSecondary(\'AMMO\')"\n >\n Ammo\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'DATA\') {\n <nav aria-label="Data tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'LOCAL MAP\'"\n (click)="selectSecondary(\'LOCAL MAP\')"\n >\n Local Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WORLD MAP\'"\n (click)="selectSecondary(\'WORLD MAP\')"\n >\n World Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'QUESTS\'"\n (click)="selectSecondary(\'QUESTS\')"\n >\n Quests\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'NOTES\'"\n (click)="selectSecondary(\'NOTES\')"\n >\n Misc\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'RADIO\'"\n (click)="selectSecondary(\'RADIO\')"\n >\n Radio\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n }\n </section>\n \x3c!-- MAIN TABS --\x3e\n <section class="tabs" [class.is-collapsed]="!tabsOpen()">\n <button\n type="button"\n class="tabs-toggle"\n aria-label="Toggle main tabs"\n [attr.aria-expanded]="tabsOpen()"\n aria-controls="main-tabs"\n (click)="toggleTabs()"\n >\n <span class="tabs-toggle-label tabs-toggle-label--state">\n {{ tabsOpen() ? \'CLOSE\' : \'OPEN\' }}\n </span>\n <span class="caret" aria-hidden="true"></span>\n <span class="tabs-toggle-label tabs-toggle-label--menu">MENU</span>\n </button>\n <nav id="main-tabs" aria-label="Main tabs">\n <div\n class="tabs-actions tabs-actions--left"\n [class.is-open]="tabsActionsLeftOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open settings actions"\n (click)="toggleTabsActions(\'left\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Save settings"\n title="Save settings"\n (click)="saveSettingsToFile()"\n >\n Save\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Load settings"\n title="Load settings"\n (click)="loadSettingsInputRight.click()"\n >\n Load\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Reset settings"\n title="Reset settings"\n (click)="openResetModal()"\n >\n Reset\n </button>\n <input\n #loadSettingsInputRight\n type="file"\n accept=".zip,application/zip"\n (change)="loadSettingsFromFile($event)"\n />\n </div>\n </div>\n <button\n type="button"\n [class.is-active]="state.primary() === \'STATS\'"\n (click)="selectPrimary(\'STATS\')"\n >\n <span>STATS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'ITEMS\'"\n (click)="selectPrimary(\'ITEMS\')"\n >\n <span>ITEMS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'DATA\'"\n (click)="selectPrimary(\'DATA\')"\n >\n <span>DATA</span>\n </button>\n <div\n class="tabs-actions tabs-actions--right"\n [class.is-open]="tabsActionsRightOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open utility actions"\n (click)="toggleTabsActions(\'right\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Open GitHub profile"\n title="Open GitHub profile"\n (click)="openGithubProfile()"\n >\n ❤\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Open settings"\n title="Settings"\n (click)="openSettingsModal()"\n >\n Settings\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Report a bug"\n title="Report a bug"\n (click)="openBugModal()"\n >\n Bug\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Exit"\n title="Exit"\n (click)="openExitModal()"\n >\n Exit\n </button>\n </div>\n </div>\n @if (tabsOpen()) {\n <div class="tabs-version">v{{ appVersion }}</div>\n }\n </nav>\n </section>\n <pip-boy-welcome-modal\n [open]="showWelcomeModal()"\n [listFontScale]="settings.listFontScale()"\n (previewListFontScale)="previewListFontScale($event)"\n (closeResult)="closeWelcomeModal()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showResetModal()"\n title="Reset Settings"\n message="This will reset all values back to defaults. This cannot be undone."\n confirmLabel="Reset"\n (closeResult)="closeResetModal()"\n (confirm)="confirmReset()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showExitModal()"\n title="Exit"\n message="Are you sure you want to leave this screen?"\n confirmLabel="Exit"\n (closeResult)="closeExitModal()"\n (confirm)="confirmExit()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showBugModal()"\n title="Report a bug"\n message="Would you like to report a bug?"\n confirmLabel="Yes"\n cancelLabel="No"\n (closeResult)="closeBugModal()"\n (confirm)="confirmBugReport()"\n />\n <pip-boy-map-image-modal\n [open]="mapImageModal() !== null"\n [title]="mapImageModalTitle()"\n [imageUrl]="mapImageModalImage()"\n (closeResult)="closeMapImageModal()"\n (save)="saveMapImageModal($event)"\n />\n <pip-boy-settings-modal\n [open]="showSettingsModal()"\n [scanLinesEnabled]="settings.scanLinesEnabled()"\n [rememberTabOnRefreshEnabled]="settings.rememberTabOnRefresh()"\n [editLockEnabled]="settings.editLockEnabled()"\n [listFontScale]="settings.listFontScale()"\n [secondaryTabSoundLabel]="secondaryTabSoundLabel()"\n [mainTabSoundLabel]="mainTabSoundLabel()"\n [clickSoundLabel]="clickSoundLabel()"\n (closeResult)="cancelSettingsModal()"\n (previewListFontScale)="previewListFontScale($event)"\n (save)="saveSettingsModal($event)"\n />\n <pip-boy-name-edit-modal\n [open]="extraOptionModal() !== null"\n [value]="extraOptionValue()"\n [title]="extraOptionTitle()"\n placeholder="Value"\n [allowEmpty]="true"\n (closeResult)="closeExtraOptionModal()"\n (save)="saveExtraOptionModal($event)"\n />\n</main>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.content{box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;height:100%;overflow:auto;padding:1rem 2rem;position:relative;width:100%}.content .status-content{box-sizing:border-box;display:flex;flex-direction:row;height:100%;gap:1rem}.content .column{box-sizing:border-box;display:flex;flex:1;flex-direction:column}.content .sub-content{max-width:max-content}.content .sub-content button{width:auto;max-width:10rem;height:2.5rem;background:transparent;color:#ff9f1c;display:flex;align-items:center;justify-content:center;text-align:center;text-transform:uppercase;border:none;border-left:2px solid transparent;border-right:2px solid transparent;cursor:pointer;padding:0 1rem;margin-bottom:1rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1) * 1.25)}.content .sub-content button.is-active{background:#ff9f1c14;border-left:2px solid #ff9f1c;border-right:2px solid #ff9f1c}.content .sub-content button:hover{background:#ff9f1c26}.content .radiation-status,.content .effects-status{box-sizing:border-box;display:flex;align-items:center;justify-content:center}.content .actions{box-sizing:border-box;display:flex;align-items:flex-end;max-width:max-content}:host{font-size:inherit}\n",":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.sub-tabs{flex:0 0 auto;min-height:0;margin-bottom:.5rem;padding:0 1rem;position:relative;z-index:1}.sub-tabs>nav{box-sizing:border-box;display:flex;align-items:center;width:100%;height:2.25rem;gap:0}.sub-tabs>nav .center-line{flex:1 1 auto;height:100%;min-width:1.5rem}.sub-tabs>nav>.center-line:last-child .top-half-line:before{left:auto;right:0}.sub-tabs>nav button{background:transparent;border:2px solid transparent;color:#ff9f1c;cursor:pointer;font-size:clamp(1.25rem,1.25rem + (1.5rem - 1.25rem) * (100vw - 360px) / (1200px - 360px),1.5rem);padding:.5rem}.sub-tabs>nav button.is-active{background:#ff9f1c14;border:2px solid #ff9f1c}.sub-tabs>nav button:hover{background:#ff9f1c26}@media(max-width:700px)and (orientation:landscape){.sub-tabs>nav .center-line{min-width:.5rem}}:host{font-size:inherit}\n",':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.tabs{align-items:center;box-sizing:border-box;display:flex;flex-direction:column;flex:0 0 auto;gap:.5rem;max-height:12rem;overflow:hidden;padding:0;position:relative;z-index:5;transition:max-height .35s ease-in-out,padding .35s ease-in-out,gap .35s ease-in-out;width:100%}.tabs.is-collapsed{gap:0;max-height:2rem}.tabs.is-collapsed>nav{opacity:0;pointer-events:none;transform:translateY(100%)}.tabs.is-collapsed .tabs-toggle .caret{transform:translateY(2px) rotate(-135deg)}.tabs .tabs-toggle{align-items:center;background:transparent;border:none;box-sizing:border-box;color:#ff9f1c;cursor:pointer;display:inline-flex;height:2rem;justify-content:center;line-height:0;max-height:2rem;min-height:2rem;overflow:hidden;padding:0 1rem;transition:border-color .2s ease;width:100%}.tabs .tabs-toggle:hover{background-color:#ff9f1c1f}.tabs .tabs-toggle .caret{border:solid #ff9f1c;border-width:0 2px 2px 0;box-sizing:border-box;display:inline-block;height:.6rem;margin:0 .5rem;padding:0;transform:translateY(-4px) rotate(45deg);transform-origin:center;transition:transform .35s ease;width:.6rem}.tabs .tabs-toggle .tabs-toggle-label{font-size:clamp(.7rem,.7rem + (.85rem - .7rem) * (100vw - 360px) / (1200px - 360px),.85rem);letter-spacing:.1em;line-height:1;text-transform:uppercase;white-space:nowrap}.tabs>nav{display:flex;justify-content:center;opacity:1;padding-bottom:.5rem;transform:translateY(0);transition:transform .35s ease-in-out,opacity .35s ease-in-out;transform-origin:bottom;will-change:transform,opacity;width:100%;position:relative}.tabs .tabs-version{bottom:14px;color:#ff9f1cbf;font-size:10px;letter-spacing:.08em;position:absolute;right:22px}.tabs .tabs-actions{align-items:center;display:flex;gap:.5rem;left:1rem;position:absolute;top:50%;transform:translateY(-50%)}.tabs .tabs-actions.right,.tabs .tabs-actions.tabs-actions--right{left:auto;right:1rem}.tabs .tabs-actions .tabs-actions-toggle{align-items:center;background:transparent;border:1px solid rgba(255,159,28,.6);border-radius:9999px;color:#ff9f1c;cursor:pointer;display:none;height:2.1rem;justify-content:center;padding:0 .6rem;text-transform:uppercase;width:2.4rem}.tabs .tabs-actions .tabs-actions-toggle:hover{background:#ff9f1c1f;border-color:#ff9f1c}.tabs .tabs-actions .tabs-actions-icon{background:#ff9f1c;border-radius:9999px;display:block;height:2px;position:relative;width:1.1rem}.tabs .tabs-actions .tabs-actions-icon:before,.tabs .tabs-actions .tabs-actions-icon:after{content:"";background:#ff9f1c;border-radius:9999px;height:2px;left:0;position:absolute;width:100%}.tabs .tabs-actions .tabs-actions-icon:before{top:-5px}.tabs .tabs-actions .tabs-actions-icon:after{top:5px}.tabs .tabs-actions .tabs-actions-menu{display:flex;gap:.5rem;align-items:center}.tabs .tabs-actions .action-button{background:transparent;border:1px solid rgba(255,159,28,.7);color:#ff9f1cb3;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.25rem .35rem;text-align:left;width:100%;border-radius:1rem;text-align:center}.tabs .tabs-actions .action-button:hover{background:#ff9f1c1f;border-color:#ff9f1c}.tabs .tabs-actions input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.tabs .tabs-action{align-items:center;background:#ff9f1c1a;border:2px solid rgba(255,159,28,.6);border-radius:.4rem;color:#ff9f1c;cursor:pointer;display:inline-flex;font-size:clamp(.65rem,.65rem + (.75rem - .65rem) * (100vw - 360px) / (1200px - 360px),.75rem);height:2.5rem;justify-content:center;letter-spacing:.08em;padding:0 .85rem;text-transform:uppercase;transition:background .2s ease,border-color .2s ease;width:auto}.tabs .tabs-action:hover{background:#ff9f1c2e;border-color:#ff9f1c}.tabs>nav>button{align-items:center;background:transparent;border-radius:9999px;border:2px solid rgba(255,159,28,.35);box-sizing:border-box;color:#ff9f1c;cursor:pointer;display:inline-flex;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);height:5rem;justify-content:center;line-height:1;margin:0 1rem;padding:0;text-transform:uppercase;width:5rem}.tabs>nav>button>span{align-items:center;display:inline-flex;justify-content:center;line-height:1;white-space:nowrap;width:100%;height:100%;border-radius:9999px;padding:0}.tabs>nav>button:hover{border-color:#ff9f1ca6}.tabs>nav>button:hover>span{background:#ff9f1c1f}.tabs>nav>button.is-active{border-color:#ff9f1c}.tabs>nav>button.is-active>span{background:#ff9f1c29}@media(max-width:750px){.tabs .tabs-actions{z-index:5}.tabs .tabs-actions .tabs-actions-toggle{display:inline-flex}.tabs .tabs-actions .tabs-actions-menu{display:none}.tabs .tabs-actions.is-open .tabs-actions-menu{background:#1f1002f2;border:1px solid rgba(255,159,28,.35);border-radius:.5rem;display:flex;flex-direction:column;gap:.35rem;padding:.5rem;position:absolute;bottom:2.6rem;z-index:1000}.tabs .tabs-actions.tabs-actions--left.is-open .tabs-actions-menu{left:0}.tabs .tabs-actions.tabs-actions--right.is-open .tabs-actions-menu{right:0}.tabs .tabs-actions .action-button{width:100%}}@media(max-width:750px){.tabs{overflow:visible}}:host{font-size:inherit}\n',':host{--pip-boy-color: #ff9f1c;--pip-boy-color-rgb: 255, 159, 28;--pip-boy-bg-dark: #1f1002;--pip-boy-bg-darker: #3d2104}:host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host.pip-boy-3000a-theme ::ng-deep{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep button{color:#ff9f1c;border-color:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep button:hover{background:#ff9f1c1f;border-color:#ff9f1ca6}:host.pip-boy-3000a-theme ::ng-deep button.is-active{border-color:#ff9f1c;background:#ff9f1c29;border-left-color:#ff9f1c;border-right-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep input,:host.pip-boy-3000a-theme ::ng-deep select,:host.pip-boy-3000a-theme ::ng-deep textarea{color:#ff9f1c;border-color:#ff9f1c99;background:#1f10024d}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout,:host.pip-boy-3000a-theme ::ng-deep .stats-layout,:host.pip-boy-3000a-theme ::ng-deep .quests-layout,:host.pip-boy-3000a-theme ::ng-deep .music-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header *,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout *,:host.pip-boy-3000a-theme ::ng-deep .stats-layout *,:host.pip-boy-3000a-theme ::ng-deep .quests-layout *,:host.pip-boy-3000a-theme ::ng-deep .music-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal *{color:#ff9f1c;border-color:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header button,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout button,:host.pip-boy-3000a-theme ::ng-deep .stats-layout button,:host.pip-boy-3000a-theme ::ng-deep .quests-layout button,:host.pip-boy-3000a-theme ::ng-deep .music-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal button{color:#ff9f1c;border-color:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header button:hover,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep .stats-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep .quests-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep .music-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal button:hover{background:#ff9f1c1f;border-color:#ff9f1ca6}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header button.is-active,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep .stats-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep .quests-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep .music-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal button.is-active{border-color:#ff9f1c;background:#ff9f1c29}:host.pip-boy-3000a-theme ::ng-deep [role=dialog],:host.pip-boy-3000a-theme ::ng-deep .dialog,:host.pip-boy-3000a-theme ::ng-deep .modal,:host.pip-boy-3000a-theme ::ng-deep .pip-boy-dialog{background:#1f1002fa;border-color:#ff9f1c99;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep [role=dialog] *,:host.pip-boy-3000a-theme ::ng-deep .dialog *,:host.pip-boy-3000a-theme ::ng-deep .modal *,:host.pip-boy-3000a-theme ::ng-deep .pip-boy-dialog *{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .center-line:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .bottom-half-line:before{background:linear-gradient(to bottom,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}:host.pip-boy-3000a-theme ::ng-deep .top-half-line:before{background:linear-gradient(to top,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}:host.pip-boy-3000a-theme ::ng-deep .main-title-left-line .bottom-half-line:before{left:0}:host.pip-boy-3000a-theme ::ng-deep .main-title-right-line .bottom-half-line:before{right:0}:host.pip-boy-3000a-theme ::ng-deep .hp-title-line .bottom-half-line:before,:host.pip-boy-3000a-theme ::ng-deep .ap-title-line .bottom-half-line:before,:host.pip-boy-3000a-theme ::ng-deep .xp-title-line .bottom-half-line:before{right:0}:host.pip-boy-3000a-theme ::ng-deep ::-webkit-scrollbar-thumb{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep ::-webkit-scrollbar-track{background:#1f100299}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-tick{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-tick:first-child,:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-tick--end-triangle{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-arrow{border-left-color:transparent;border-right-color:transparent;border-bottom-color:#ff9f1cb3}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-handle{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-fill{background:#ff9f1c73;box-shadow:0 0 20px #ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-track,:host.pip-boy-3000a-theme ::ng-deep .status-label,:host.pip-boy-3000a-theme ::ng-deep .status-right,:host.pip-boy-3000a-theme ::ng-deep .status-resist-text{border-top-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .status-resist:hover,:host.pip-boy-3000a-theme ::ng-deep .status-resist:focus-visible{background:transparent;border-color:transparent}:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-add,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-edit,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-delete,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-move{background:#ff9f1c0d;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-add:hover,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-delete:hover,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .quest-toggle{border-color:#ff9f1ca6}:host.pip-boy-3000a-theme ::ng-deep .quest-toggle.is-checked{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .quest-add{background:#ff9f1c14;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .quest-edit,:host.pip-boy-3000a-theme ::ng-deep .quest-delete,:host.pip-boy-3000a-theme ::ng-deep .quest-move{background:#ff9f1c0d;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .quest-add:hover{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .quest-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .quest-delete:hover,:host.pip-boy-3000a-theme ::ng-deep .quest-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .music-add{background:#ff9f1c14;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-edit,:host.pip-boy-3000a-theme ::ng-deep .music-delete,:host.pip-boy-3000a-theme ::ng-deep .music-move{background:#ff9f1c0d;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-add:hover{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .music-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .music-delete:hover,:host.pip-boy-3000a-theme ::ng-deep .music-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .music-waveform canvas{border-right-color:#ff9f1c40;border-bottom-color:#ff9f1c40}:host.pip-boy-3000a-theme ::ng-deep .music-list-item.is-selected{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .music-list-item.is-selected:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-control{background:#ff9f1c0d;border-color:#ff9f1c99;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-control:hover,:host.pip-boy-3000a-theme ::ng-deep .music-control.is-active{background:#ff9f1c1f;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-control--autoplay.is-active,:host.pip-boy-3000a-theme ::ng-deep .music-control--shuffle.is-active{background:#ff9f1c33;border-color:#ff9f1c;box-shadow:0 0 .6rem #ff9f1c47}:host.pip-boy-3000a-theme ::ng-deep .music-volume{border-color:#ff9f1c59;background:#ff9f1c0a}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing-label{color:#ff9f1cb3}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing-value{border-color:#ff9f1c66;color:#ff9f1cd9}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing.is-disabled .music-now-playing-label,:host.pip-boy-3000a-theme ::ng-deep .music-now-playing.is-disabled .music-now-playing-value{color:#ff9f1c73}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing.is-disabled .music-now-playing-value{background:#ff9f1c08;border-color:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep .music-volume-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep .music-volume-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-volume-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-volume-label,:host.pip-boy-3000a-theme ::ng-deep .music-volume-value{color:#ff9f1ccc}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-value{color:#ff9f1ccc}:host.pip-boy-3000a-theme ::ng-deep .settings-toggle.is-on{background:#ff9f1c33;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .map-control-button:hover{background:#1f1002e6;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .welcome__range{background:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .welcome__range::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .welcome__range::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-list-item.is-selected{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .resource-list-item.is-selected:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-add,:host.pip-boy-3000a-theme ::ng-deep .resource-edit,:host.pip-boy-3000a-theme ::ng-deep .resource-drop,:host.pip-boy-3000a-theme ::ng-deep .resource-move{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-add{background:#ff9f1c14}:host.pip-boy-3000a-theme ::ng-deep .resource-add:hover{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .resource-edit,:host.pip-boy-3000a-theme ::ng-deep .resource-drop,:host.pip-boy-3000a-theme ::ng-deep .resource-move{background:#ff9f1c0d}:host.pip-boy-3000a-theme ::ng-deep .resource-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .resource-drop:hover,:host.pip-boy-3000a-theme ::ng-deep .resource-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .resource-description:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-description:after{background:linear-gradient(to bottom,#ff9f1c,#ff9f1ca6 35%,#ff9f1c59 65%,#ff9f1c00)}:host.pip-boy-3000a-theme ::ng-deep .resource-stat{border:none}:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field textarea{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal .settings-slider-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal .settings-slider-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal .settings-slider-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__data{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__data code{background:#ff9f1c14;border-color:#ff9f1c38;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__data a{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__section{background:#ff9f1c0a;border-color:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal .reset-modal-body{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal .reset-modal-body p{color:#ff9f1cd9}:host.pip-boy-3000a-theme ::ng-deep pip-boy-audio-edit-modal .audio-modal-field input{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-audio-edit-modal .audio-modal-field input:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .stat-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .number-input-row input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .number-input-row input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field textarea,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal .number-input-row input{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .stat-modal-field input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .number-input-row input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .number-input-row input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field textarea:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal .number-input-row input:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep input:focus,:host.pip-boy-3000a-theme ::ng-deep select:focus,:host.pip-boy-3000a-theme ::ng-deep textarea:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field textarea{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field textarea:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep #text-field-effects{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep #text-field-effects:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control{background:#ff9f1c0d;border-color:#ff9f1c99;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control.is-active{background:#ff9f1c1f;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control--autoplay.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control--shuffle.is-active{background:#ff9f1c33;border-color:#ff9f1c;box-shadow:0 0 .6rem #ff9f1c47}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control:disabled{background:#ff9f1c05;border-color:#ff9f1c33;color:#ff9f1c59;opacity:.8}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing-label{color:#ff9f1cb3}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing-value{border-color:#ff9f1c66;color:#ff9f1cd9}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing.is-disabled .music-now-playing-label,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing.is-disabled .music-now-playing-value{color:#ff9f1c73}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing.is-disabled .music-now-playing-value{background:#ff9f1c08;border-color:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-volume-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-volume-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-volume-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host{font-family:Roboto Condensed,sans-serif;font-size:clamp(.95rem,.95rem + (1.15rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.15rem);scrollbar-color:rgba(255,159,28,.6) rgba(31,16,2,.6);scrollbar-width:thin;background-color:#1f1002;background-image:repeating-linear-gradient(to bottom,#ffffff0a 0 1px,#0000 4px);background-size:100% 6px;animation:scan-lines 6s linear infinite;box-shadow:inset 0 0 24px #0009,inset 0 0 90px #00000073;box-sizing:border-box;color:#ff9f1c;display:block;height:100%;overflow:hidden;position:relative;width:100%;font-size:inherit}:host ::-webkit-scrollbar{width:6px;height:6px}:host ::-webkit-scrollbar-track{background:#1f100299}:host ::-webkit-scrollbar-thumb{background:#ff9f1c99;border-radius:9999px}:host:before{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,#1f100200 55%,#00000040 70%,#0009);mix-blend-mode:multiply}@keyframes scan-lines{0%{background-position:0 0}to{background-position:0 60px}}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:0;position:relative;width:100%;display:flex;flex-direction:column;min-height:0}.screen-size-overlay{position:absolute;inset:0;background:#000000d9;color:#ff9f1c;display:flex;align-items:center;justify-content:center;text-align:center;padding:2rem;text-transform:uppercase;font-size:clamp(1.1rem,1.1rem + (1.35rem - 1.1rem) * (100vw - 360px) / (1200px - 360px),1.35rem);z-index:200}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:2px;background:#ff9f1c}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:50%;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}.top-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.top-half-line:before{content:"";position:absolute;bottom:50%;top:-1.25rem;width:2px;z-index:2;left:0;background:linear-gradient(to top,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}.extra-options{margin-top:0;display:flex;flex-direction:column;font-family:Roboto Mono,monospace;font-size:calc(clamp(1.05rem,1.05rem + .2rem * (100vw - 360px) / 840px,1.25rem) * var(--list-font-scale, 1));align-items:flex-end;gap:.75rem;white-space:nowrap;position:absolute;top:1rem;right:2rem;z-index:3}.extra-options button{background:transparent;border:none;color:#ff9f1c;cursor:pointer;font:inherit;padding:0;white-space:nowrap}.extra-options button:hover{opacity:.8}.extra-options button:disabled,.extra-options button.is-locked{cursor:default}.extra-options .controller-button{font-size:inherit;white-space:nowrap}.extra-options .controller-button .large-par{display:inline;padding-left:.5rem;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));top:-.15rem;position:relative;white-space:nowrap}.map-panel{display:flex;flex:1 1 auto;min-height:0;position:relative;width:100%}.map-view{align-items:flex-start;background:transparent;border:none;color:#ff9f1c;cursor:pointer;display:flex;flex:1 1 auto;justify-content:flex-start;min-height:0;overflow:auto;padding:0;width:100%}.map-view span{letter-spacing:.1em;margin:auto;text-transform:uppercase;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.map-view img{display:block;max-width:none;max-height:none}.map-view.is-locked,.map-view:disabled{cursor:default}.map-view.is-draggable{cursor:grab}.map-view.is-dragging{cursor:grabbing}.map-zoom{display:flex;gap:.5rem;position:absolute;right:1.5rem;top:.5rem;z-index:2}.map-zoom .map-zoom-button{padding:0;width:calc(2rem * var(--list-font-scale, 1))}.map-fit{position:absolute;right:1.5rem;bottom:.5rem;z-index:2}.map-control-button{align-items:center;background:#1f1002f2;border:1px solid rgba(255,159,28,.65);border-radius:.5rem;color:#ff9f1c;cursor:pointer;display:inline-flex;font-size:calc(clamp(.75rem,.75rem + .15rem * (100vw - 360px) / 840px,.9rem) * var(--list-font-scale, 1));justify-content:center;text-transform:uppercase;height:calc(2rem * var(--list-font-scale, 1));padding:0 calc(.6rem * var(--list-font-scale, 1))}.map-control-button:hover{border-color:#ff9f1c;background:#1f1002e6}\n']}]}],propDecorators:{returnToUrl:[{type:e.Input,args:[{isSignal:!0,alias:"returnToUrl",required:!1}]}],localMapImage:[{type:e.ViewChild,args:["localMapImage",{isSignal:!0}]}],worldMapImage:[{type:e.ViewChild,args:["worldMapImage",{isSignal:!0}]}],localMapView:[{type:e.ViewChild,args:["localMapView",{isSignal:!0}]}],worldMapView:[{type:e.ViewChild,args:["worldMapView",{isSignal:!0}]}],onResize:[{type:g,args:["window:resize"]}]}});class Ie{static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:Ie,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"21.0.8",type:Ie,isStandalone:!0,selector:"pip-boy-3000-mk-iv",ngImport:e,template:'<section #screen class="screen">\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="200"\n />\n</section>\n',styles:[":host{background:#030703;box-sizing:border-box;color:#3ad03a;display:block;height:100%;width:100%}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:1rem;position:relative;width:100%}\n"],dependencies:[{kind:"component",type:y,selector:"pip-boy-screen-scan-lines",inputs:["replayTimeoutSeconds","screen","scanSpeedSeconds","tailLengthPx","scanColorRgb"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:Ie,decorators:[{type:a,args:[{selector:"pip-boy-3000-mk-iv",standalone:!0,imports:[y],template:'<section #screen class="screen">\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="200"\n />\n</section>\n',styles:[":host{background:#030703;box-sizing:border-box;color:#3ad03a;display:block;height:100%;width:100%}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:1rem;position:relative;width:100%}\n"]}]}]});class Re{returnToUrl=t("https://www.pip-boy.com",...ngDevMode?[{debugName:"returnToUrl"}]:[]);state=l(W);settings=l(P);imageStore=l(x);soundStore=l(_);audioPlayer=l(ae);appVersion=A;tabsOpen=o(!1,...ngDevMode?[{debugName:"tabsOpen"}]:[]);showResetModal=o(!1,...ngDevMode?[{debugName:"showResetModal"}]:[]);showExitModal=o(!1,...ngDevMode?[{debugName:"showExitModal"}]:[]);showBugModal=o(!1,...ngDevMode?[{debugName:"showBugModal"}]:[]);showSettingsModal=o(!1,...ngDevMode?[{debugName:"showSettingsModal"}]:[]);settingsListFontScaleSnapshot=o(null,...ngDevMode?[{debugName:"settingsListFontScaleSnapshot"}]:[]);showWelcomeModal=o(!0,...ngDevMode?[{debugName:"showWelcomeModal"}]:[]);mapImageModal=o(null,...ngDevMode?[{debugName:"mapImageModal"}]:[]);localMapImage=b("localMapImage",...ngDevMode?[{debugName:"localMapImage"}]:[]);worldMapImage=b("worldMapImage",...ngDevMode?[{debugName:"worldMapImage"}]:[]);localMapView=b("localMapView",...ngDevMode?[{debugName:"localMapView"}]:[]);worldMapView=b("worldMapView",...ngDevMode?[{debugName:"worldMapView"}]:[]);extraOptionModal=o(null,...ngDevMode?[{debugName:"extraOptionModal"}]:[]);tabsActionsLeftOpen=o(!1,...ngDevMode?[{debugName:"tabsActionsLeftOpen"}]:[]);tabsActionsRightOpen=o(!1,...ngDevMode?[{debugName:"tabsActionsRightOpen"}]:[]);isMapDragging=o(!1,...ngDevMode?[{debugName:"isMapDragging"}]:[]);viewportWidth=o("undefined"==typeof window?0:window.innerWidth,...ngDevMode?[{debugName:"viewportWidth"}]:[]);mapImageModalTitle=u(()=>"WORLD"===this.mapImageModal()?"World Map":"Local Map",...ngDevMode?[{debugName:"mapImageModalTitle"}]:[]);mapImageModalImage=u(()=>{const e="WORLD"===this.mapImageModal()?this.settings.worldMapImage():this.settings.localMapImage();return this.imageStore.getImageUrl(e)},...ngDevMode?[{debugName:"mapImageModalImage"}]:[]);secondaryTabSoundLabel=u(()=>this.soundStore.getSoundLabel(this.settings.secondaryTabSoundId()),...ngDevMode?[{debugName:"secondaryTabSoundLabel"}]:[]);mainTabSoundLabel=u(()=>this.soundStore.getSoundLabel(this.settings.mainTabSoundId()),...ngDevMode?[{debugName:"mainTabSoundLabel"}]:[]);clickSoundLabel=u(()=>this.soundStore.getSoundLabel(this.settings.clickSoundId()),...ngDevMode?[{debugName:"clickSoundLabel"}]:[]);mapDragState={target:null,startX:0,startY:0,scrollLeft:0,scrollTop:0,moved:!1};suppressMapClick=!1;isScreenTooSmall=u(()=>this.viewportWidth()<650,...ngDevMode?[{debugName:"isScreenTooSmall"}]:[]);extraOptionTitle=u(()=>{switch(this.extraOptionModal()){case"RADAWAY":case"RADX":return"Edit Text";default:return""}},...ngDevMode?[{debugName:"extraOptionTitle"}]:[]);extraOptionValue=u(()=>{const e=this.extraOptionModal();return"STIMPAK"===e?this.settings.stimpakLabel():"LIMBS"===e?this.settings.limbLabel():"RADAWAY"===e?this.settings.radAwayLabel():"RADX"===e?this.settings.radXLabel():""},...ngDevMode?[{debugName:"extraOptionValue"}]:[]);toggleTabs(){this.tabsOpen.update(e=>!e)}toggleTabsActions(e){"left"===e?(this.tabsActionsLeftOpen.update(e=>!e),this.tabsActionsRightOpen.set(!1)):(this.tabsActionsRightOpen.update(e=>!e),this.tabsActionsLeftOpen.set(!1))}onResize(){this.viewportWidth.set(window.innerWidth)}async saveSettingsToFile(){const e=this.settings.exportSettingsSnapshot(),t=this.collectImageIds(e),n=this.collectSoundIds(e),a=[],o=[],i=new v;for(const e of t){const t=await this.imageStore.getRecord(e);if(!t)continue;const n=this.getExtension(t.fileName,t.mime);i.file(`images/${e}${n}`,t.blob),a.push({id:e,fileName:t.fileName,mime:t.mime})}for(const e of n){const t=await this.soundStore.getRecord(e);if(!t)continue;const n=this.getSoundExtension(t.fileName,t.mime);i.file(`sounds/${e}${n}`,t.blob),o.push({id:e,fileName:t.fileName,mime:t.mime})}const s={version:1,images:a,sounds:o,pipBoy3000Settings:e};i.file("settings.json",JSON.stringify(s));const r=await i.generateAsync({type:"blob"}),l=URL.createObjectURL(r),d=document.createElement("a");d.href=l,d.download="pip-boy-3000.zip",d.click(),URL.revokeObjectURL(l)}openResetModal(){this.showResetModal.set(!0)}closeResetModal(){this.showResetModal.set(!1)}confirmReset(){this.stopAllSounds(),this.settings.resetToDefaults(),this.closeResetModal(),this.showWelcomeModal.set(!0)}openExitModal(){this.showExitModal.set(!0)}closeExitModal(){this.showExitModal.set(!1)}confirmExit(){window.location.href=this.returnToUrl()}openBugModal(){this.showBugModal.set(!0)}closeBugModal(){this.showBugModal.set(!1)}confirmBugReport(){window.open("https://github.com/CodyTolene/pip-terminal/issues","_blank"),this.closeBugModal()}openSettingsModal(){this.settingsListFontScaleSnapshot.set(this.settings.listFontScale()),this.showSettingsModal.set(!0)}closeSettingsModal(){this.showSettingsModal.set(!1)}cancelSettingsModal(){const e=this.settingsListFontScaleSnapshot();null!==e&&this.settings.listFontScale.set(e),this.settingsListFontScaleSnapshot.set(null),this.showSettingsModal.set(!1)}closeWelcomeModal(){this.showWelcomeModal.set(!1)}saveSettingsModal(e){this.settings.scanLinesEnabled.set(e.scanLinesEnabled),this.settings.rememberTabOnRefresh.set(e.rememberTabOnRefreshEnabled),this.settings.editLockEnabled.set(e.editLockEnabled),this.settings.listFontScale.set(e.listFontScale),this.settingsListFontScaleSnapshot.set(null),e.removeSecondaryTabSound&&this.settings.secondaryTabSoundId.set(null),e.removeMainTabSound&&this.settings.mainTabSoundId.set(null),e.removeClickSound&&this.settings.clickSoundId.set(null),e.secondaryTabSoundFile&&this.soundStore.saveFile(e.secondaryTabSoundFile).then(e=>this.settings.secondaryTabSoundId.set(e.id)),e.mainTabSoundFile&&this.soundStore.saveFile(e.mainTabSoundFile).then(e=>this.settings.mainTabSoundId.set(e.id)),e.clickSoundFile&&this.soundStore.saveFile(e.clickSoundFile).then(e=>this.settings.clickSoundId.set(e.id)),this.closeSettingsModal()}previewListFontScale(e){this.settings.listFontScale.set(e)}openGithubProfile(){window.open("https://github.com/CodyTolene","_blank")}selectPrimary(e){this.soundStore.playSound(this.settings.mainTabSoundId()),this.state.selectPrimary(e)}selectSecondary(e){this.soundStore.playSound(this.settings.secondaryTabSoundId()),this.state.selectSecondary(e)}openExtraOptionModal(e){this.settings.editLockEnabled()||this.extraOptionModal.set(e)}closeExtraOptionModal(){this.extraOptionModal.set(null)}saveExtraOptionModal(e){const t=this.extraOptionModal();"STIMPAK"===t?this.settings.stimpakLabel.set(e):"LIMBS"===t?this.settings.limbLabel.set(e):"RADAWAY"===t?this.settings.radAwayLabel.set(e):"RADX"===t&&this.settings.radXLabel.set(e),this.closeExtraOptionModal()}async loadSettingsFromFile(e){const t=e.target,n=t.files?.[0]??null;if(!n)return;this.stopAllSounds();const a=await v.loadAsync(n),o=a.file("settings.json");if(!o)return void(t.value="");const i=await o.async("string"),s=JSON.parse(i),r=s.pipBoy3000Settings??s;if(Array.isArray(s.images))for(const e of s.images){const t=this.getExtension(e.fileName,e.mime),n=a.file(`images/${e.id}${t}`)??a.file(new RegExp(`^images/${e.id}\\.`))?.[0];if(!n)continue;const o=await n.async("blob");await this.imageStore.saveBlobWithId(e.id,o,e.fileName,e.mime)}if(Array.isArray(s.sounds))for(const e of s.sounds){const t=this.getSoundExtension(e.fileName,e.mime),n=a.file(`sounds/${e.id}${t}`)??a.file(new RegExp(`^sounds/${e.id}\\.`))?.[0];if(!n)continue;const o=await n.async("blob");await this.soundStore.saveBlobWithId(e.id,o,e.fileName,e.mime)}this.settings.importSettingsSnapshot(r),t.value=""}stopAllSounds(){this.audioPlayer.stop(),this.soundStore.stopAll()}collectImageIds(e){const t=new Set,n=e=>{e&&t.add(e)};return e.weaponItems.forEach(e=>n(e.imageId)),e.apparelItems.forEach(e=>n(e.imageId)),e.aidItems.forEach(e=>n(e.imageId)),e.miscItems.forEach(e=>n(e.imageId)),e.ammoItems.forEach(e=>n(e.imageId)),e.specialItems.forEach(e=>n(e.imageId)),e.skillItems.forEach(e=>n(e.imageId)),e.perkItems.forEach(e=>n(e.imageId)),e.vaultBoyImages.forEach(e=>n(e)),n(e.localMapImage),n(e.worldMapImage),Array.from(t)}collectSoundIds(e){const t=new Set,n=e=>{e&&t.add(e)};return n(e.secondaryTabSoundId),n(e.mainTabSoundId),n(e.clickSoundId),e.notesItems.forEach(e=>n(e.soundId)),e.radioItems.forEach(e=>n(e.soundId)),Array.from(t)}getExtension(e,t){const n=e.match(/\.[a-z0-9]+$/i);return n?n[0]:this.imageStore.extensionFromMime(t)}getSoundExtension(e,t){const n=e.match(/\.[a-z0-9]+$/i);return n?n[0]:this.soundStore.extensionFromMime(t)}openMapImageModal(e){this.settings.editLockEnabled()||(this.suppressMapClick?this.suppressMapClick=!1:this.mapImageModal.set(e))}closeMapImageModal(){this.mapImageModal.set(null)}zoomMap(e,t){const n="WORLD"===e?this.settings.worldMapZoom:this.settings.localMapZoom,a=Math.min(3,Math.max(.5,n()+t));n.set(Number(a.toFixed(2)))}resetMapZoom(e){"WORLD"===e?this.settings.worldMapZoom.set(1):this.settings.localMapZoom.set(1)}startMapDrag(e){if(0!==e.button)return;const t=e.currentTarget;t&&t.querySelector("img")&&(this.mapDragState={target:t,startX:e.clientX,startY:e.clientY,scrollLeft:t.scrollLeft,scrollTop:t.scrollTop,moved:!1},this.isMapDragging.set(!0),e.preventDefault())}onMapDrag(e){const t=this.mapDragState.target;if(!t)return;const n=e.clientX-this.mapDragState.startX,a=e.clientY-this.mapDragState.startY;if(!this.mapDragState.moved){if(Math.abs(n)<3&&Math.abs(a)<3)return;this.mapDragState.moved=!0}t.scrollLeft=this.mapDragState.scrollLeft-n,t.scrollTop=this.mapDragState.scrollTop-a,e.preventDefault()}endMapDrag(){this.mapDragState.target&&(this.mapDragState.moved&&(this.suppressMapClick=!0),this.mapDragState={target:null,startX:0,startY:0,scrollLeft:0,scrollTop:0,moved:!1},this.isMapDragging.set(!1))}fitMapZoom(e){const t="WORLD"===e?this.worldMapView():this.localMapView(),n="WORLD"===e?this.worldMapImage():this.localMapImage();if(!t||!n)return;const a=t.nativeElement.clientWidth,o=n.nativeElement.naturalWidth;if(!a||!o)return;const i=Math.min(3,Math.max(.5,a/o));("WORLD"===e?this.settings.worldMapZoom:this.settings.localMapZoom).set(Number(i.toFixed(2)))}isMapFit(e){const t="WORLD"===e?this.worldMapView():this.localMapView(),n="WORLD"===e?this.worldMapImage():this.localMapImage();if(!t||!n)return!1;const a=t.nativeElement.clientWidth,o=n.nativeElement.naturalWidth;if(!a||!o)return!1;const i=Math.min(3,Math.max(.5,a/o)),s="WORLD"===e?this.settings.worldMapZoom():this.settings.localMapZoom();return Math.abs(s-Number(i.toFixed(2)))<.01}async saveMapImageModal(e){const t=this.mapImageModal();if(t){if(e.removeImage)return"WORLD"===t?this.settings.worldMapImage.set(null):this.settings.localMapImage.set(null),void this.closeMapImageModal();if(e.imageFile){const n=await this.imageStore.saveFile(e.imageFile);"WORLD"===t?this.settings.worldMapImage.set(n.id):this.settings.localMapImage.set(n.id)}this.closeMapImageModal()}}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:Re,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.0.8",type:Re,isStandalone:!0,selector:"pip-boy-3000",inputs:{returnToUrl:{classPropertyName:"returnToUrl",publicName:"returnToUrl",isSignal:!0,isRequired:!1,transformFunction:null}},host:{listeners:{"window:resize":"onResize()"}},providers:[W],viewQueries:[{propertyName:"localMapImage",first:!0,predicate:["localMapImage"],descendants:!0,isSignal:!0},{propertyName:"worldMapImage",first:!0,predicate:["worldMapImage"],descendants:!0,isSignal:!0},{propertyName:"localMapView",first:!0,predicate:["localMapView"],descendants:!0,isSignal:!0},{propertyName:"worldMapView",first:!0,predicate:["worldMapView"],descendants:!0,isSignal:!0}],ngImport:e,template:'<main\n #screen\n class="screen"\n [style.--list-font-scale]="settings.listFontScale()"\n>\n @if (settings.scanLinesEnabled()) {\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="300"\n />\n }\n @if (isScreenTooSmall()) {\n <div class="screen-size-overlay" role="alert" aria-live="assertive">\n Screen is too small.<br />Please rotate to landscape.\n </div>\n }\n \x3c!-- HEADER --\x3e\n <pip-boy-3000-header />\n \x3c!-- CONTENT --\x3e\n <section class="content">\n @if (state.primary() === \'STATS\') {\n @if (state.secondary() === \'STATUS\') {\n <div class="status-content">\n <nav class="column sub-content" aria-label="Status tabs">\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'CND\'"\n (click)="state.selectTertiary(\'CND\')"\n >\n CND\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'RAD\'"\n (click)="state.selectTertiary(\'RAD\')"\n >\n RAD\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'EFF\'"\n (click)="state.selectTertiary(\'EFF\')"\n >\n EFF\n </button>\n </nav>\n @if (state.tertiary() === \'CND\') {\n <pip-boy-cnd-status />\n } @else if (state.tertiary() === \'RAD\') {\n <pip-boy-radiation-meter />\n <div class="extra-options">\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADAWAY\')"\n >\n {{ settings.radAwayLabel() }}\n </button>\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADX\')"\n >\n {{ settings.radXLabel() }}\n </button>\n </div>\n } @else if (state.tertiary() === \'EFF\') {\n <pip-boy-eff-layout />\n }\n </div>\n } @else if (state.secondary() === \'S.P.E.C.I.A.L.\') {\n <pip-boy-stats-layout\n category="SPECIAL"\n valueLabel="Rating"\n [valueMin]="1"\n [valueMax]="10"\n />\n } @else if (state.secondary() === \'SKILLS\') {\n <pip-boy-stats-layout\n category="SKILLS"\n valueLabel="Skill"\n [valueMin]="0"\n [valueMax]="100"\n />\n } @else if (state.secondary() === \'PERKS\') {\n <pip-boy-stats-layout\n category="PERKS"\n valueLabel="Rank"\n [valueMin]="0"\n />\n } @else if (state.secondary() === \'GENERAL\') {\n <pip-boy-stats-layout category="GENERAL" valueLabel="Value" />\n }\n } @else if (state.primary() === \'ITEMS\') {\n @if (state.secondary() === \'WEAPONS\') {\n <pip-boy-inventory-layout category="WEAPONS" />\n } @else if (state.secondary() === \'APPAREL\') {\n <pip-boy-inventory-layout category="APPAREL" />\n } @else if (state.secondary() === \'AID\') {\n <pip-boy-inventory-layout category="AID" />\n } @else if (state.secondary() === \'MISC\') {\n <pip-boy-inventory-layout category="MISC" />\n } @else if (state.secondary() === \'AMMO\') {\n <pip-boy-inventory-layout category="AMMO" />\n }\n } @else if (state.primary() === \'DATA\') {\n @if (state.secondary() === \'LOCAL MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #localMapView\n [class.is-draggable]="settings.localMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'LOCAL\')"\n >\n @if (settings.localMapImage()) {\n <img\n #localMapImage\n [src]="imageStore.getImageUrl(settings.localMapImage())"\n alt="Local map"\n [style.zoom]="settings.localMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.localMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.localMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'LOCAL\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'LOCAL\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'LOCAL\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'WORLD MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #worldMapView\n [class.is-draggable]="settings.worldMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'WORLD\')"\n >\n @if (settings.worldMapImage()) {\n <img\n #worldMapImage\n [src]="imageStore.getImageUrl(settings.worldMapImage())"\n alt="World map"\n [style.zoom]="settings.worldMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.worldMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.worldMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'WORLD\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'WORLD\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'WORLD\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'QUESTS\') {\n <pip-boy-quests-layout />\n } @else if (state.secondary() === \'NOTES\') {\n <pip-boy-music-layout category="NOTES" />\n } @else if (state.secondary() === \'RADIO\') {\n <pip-boy-music-layout category="RADIO" />\n }\n }\n </section>\n \x3c!-- SUB TABS --\x3e\n <section class="sub-tabs">\n @if (state.primary() === \'STATS\') {\n <nav aria-label="Stats tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'STATUS\'"\n (click)="selectSecondary(\'STATUS\')"\n >\n Status\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'S.P.E.C.I.A.L.\'"\n (click)="selectSecondary(\'S.P.E.C.I.A.L.\')"\n >\n S.P.E.C.I.A.L.\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'SKILLS\'"\n (click)="selectSecondary(\'SKILLS\')"\n >\n Skills\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'PERKS\'"\n (click)="selectSecondary(\'PERKS\')"\n >\n Perks\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'GENERAL\'"\n (click)="selectSecondary(\'GENERAL\')"\n >\n General\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'ITEMS\') {\n <nav aria-label="Items tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WEAPONS\'"\n (click)="selectSecondary(\'WEAPONS\')"\n >\n Weapons\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'APPAREL\'"\n (click)="selectSecondary(\'APPAREL\')"\n >\n Apparel\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AID\'"\n (click)="selectSecondary(\'AID\')"\n >\n Aid\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'MISC\'"\n (click)="selectSecondary(\'MISC\')"\n >\n Misc\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AMMO\'"\n (click)="selectSecondary(\'AMMO\')"\n >\n Ammo\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'DATA\') {\n <nav aria-label="Data tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'LOCAL MAP\'"\n (click)="selectSecondary(\'LOCAL MAP\')"\n >\n Local Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WORLD MAP\'"\n (click)="selectSecondary(\'WORLD MAP\')"\n >\n World Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'QUESTS\'"\n (click)="selectSecondary(\'QUESTS\')"\n >\n Quests\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'NOTES\'"\n (click)="selectSecondary(\'NOTES\')"\n >\n Notes\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'RADIO\'"\n (click)="selectSecondary(\'RADIO\')"\n >\n Radio\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n }\n </section>\n \x3c!-- MAIN TABS --\x3e\n <section class="tabs" [class.is-collapsed]="!tabsOpen()">\n <button\n type="button"\n class="tabs-toggle"\n aria-label="Toggle main tabs"\n [attr.aria-expanded]="tabsOpen()"\n aria-controls="main-tabs"\n (click)="toggleTabs()"\n >\n <span class="tabs-toggle-label tabs-toggle-label--state">\n {{ tabsOpen() ? \'CLOSE\' : \'OPEN\' }}\n </span>\n <span class="caret" aria-hidden="true"></span>\n <span class="tabs-toggle-label tabs-toggle-label--menu">MENU</span>\n </button>\n <nav id="main-tabs" aria-label="Main tabs">\n <div\n class="tabs-actions tabs-actions--left"\n [class.is-open]="tabsActionsLeftOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open settings actions"\n (click)="toggleTabsActions(\'left\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Save settings"\n title="Save settings"\n (click)="saveSettingsToFile()"\n >\n Save\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Load settings"\n title="Load settings"\n (click)="loadSettingsInput.click()"\n >\n Load\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Reset settings"\n title="Reset settings"\n (click)="openResetModal()"\n >\n Reset\n </button>\n <input\n #loadSettingsInput\n type="file"\n accept=".zip,application/zip"\n (change)="loadSettingsFromFile($event)"\n />\n </div>\n </div>\n <button\n type="button"\n [class.is-active]="state.primary() === \'STATS\'"\n (click)="selectPrimary(\'STATS\')"\n >\n <span>STATS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'ITEMS\'"\n (click)="selectPrimary(\'ITEMS\')"\n >\n <span>ITEMS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'DATA\'"\n (click)="selectPrimary(\'DATA\')"\n >\n <span>DATA</span>\n </button>\n <div\n class="tabs-actions tabs-actions--right"\n [class.is-open]="tabsActionsRightOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open utility actions"\n (click)="toggleTabsActions(\'right\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Open GitHub profile"\n title="Open GitHub profile"\n (click)="openGithubProfile()"\n >\n ❤\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Open settings"\n title="Settings"\n (click)="openSettingsModal()"\n >\n Settings\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Report a bug"\n title="Report a bug"\n (click)="openBugModal()"\n >\n Bug\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Exit"\n title="Exit"\n (click)="openExitModal()"\n >\n Exit\n </button>\n </div>\n </div>\n @if (tabsOpen()) {\n <div class="tabs-version">v{{ appVersion }}</div>\n }\n </nav>\n </section>\n <pip-boy-welcome-modal\n [open]="showWelcomeModal()"\n [listFontScale]="settings.listFontScale()"\n (previewListFontScale)="previewListFontScale($event)"\n (closeResult)="closeWelcomeModal()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showResetModal()"\n title="Reset Settings"\n message="This will reset all values back to defaults. This cannot be undone."\n confirmLabel="Reset"\n (closeResult)="closeResetModal()"\n (confirm)="confirmReset()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showExitModal()"\n title="Exit"\n message="Are you sure you want to leave this screen?"\n confirmLabel="Exit"\n (closeResult)="closeExitModal()"\n (confirm)="confirmExit()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showBugModal()"\n title="Report a bug"\n message="Would you like to report a bug?"\n confirmLabel="Yes"\n cancelLabel="No"\n (closeResult)="closeBugModal()"\n (confirm)="confirmBugReport()"\n />\n <pip-boy-map-image-modal\n [open]="mapImageModal() !== null"\n [title]="mapImageModalTitle()"\n [imageUrl]="mapImageModalImage()"\n (closeResult)="closeMapImageModal()"\n (save)="saveMapImageModal($event)"\n />\n <pip-boy-settings-modal\n [open]="showSettingsModal()"\n [scanLinesEnabled]="settings.scanLinesEnabled()"\n [rememberTabOnRefreshEnabled]="settings.rememberTabOnRefresh()"\n [editLockEnabled]="settings.editLockEnabled()"\n [listFontScale]="settings.listFontScale()"\n [secondaryTabSoundLabel]="secondaryTabSoundLabel()"\n [mainTabSoundLabel]="mainTabSoundLabel()"\n [clickSoundLabel]="clickSoundLabel()"\n (closeResult)="cancelSettingsModal()"\n (previewListFontScale)="previewListFontScale($event)"\n (save)="saveSettingsModal($event)"\n />\n <pip-boy-name-edit-modal\n [open]="extraOptionModal() !== null"\n [value]="extraOptionValue()"\n [title]="extraOptionTitle()"\n placeholder="Value"\n [allowEmpty]="true"\n (closeResult)="closeExtraOptionModal()"\n (save)="saveExtraOptionModal($event)"\n />\n</main>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.content{box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;height:100%;overflow:auto;padding:1rem 2rem;position:relative;width:100%}.content .status-content{box-sizing:border-box;display:flex;flex-direction:row;height:100%;gap:1rem}.content .column{box-sizing:border-box;display:flex;flex:1;flex-direction:column}.content .sub-content{max-width:max-content}.content .sub-content button{width:auto;max-width:10rem;height:2.5rem;background:transparent;color:#0fbb6b;display:flex;align-items:center;justify-content:center;text-align:center;text-transform:uppercase;border:none;border-left:2px solid transparent;border-right:2px solid transparent;cursor:pointer;padding:0 1rem;margin-bottom:1rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1) * 1.25)}.content .sub-content button.is-active{background:#0fbb6b14;border-left:2px solid #0fbb6b;border-right:2px solid #0fbb6b}.content .sub-content button:hover{background:#0fbb6b26}.content .radiation-status,.content .effects-status{box-sizing:border-box;display:flex;align-items:center;justify-content:center}.content .actions{box-sizing:border-box;display:flex;align-items:flex-end;max-width:max-content}:host{font-size:inherit}\n",":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.sub-tabs{flex:0 0 auto;min-height:0;margin-bottom:.5rem;padding:0 1rem;position:relative;z-index:1}.sub-tabs>nav{box-sizing:border-box;display:flex;align-items:center;width:100%;height:2.25rem;gap:0}.sub-tabs>nav .center-line{flex:1 1 auto;height:100%;min-width:1.5rem}.sub-tabs>nav>.center-line:last-child .top-half-line:before{left:auto;right:0}.sub-tabs>nav button{background:transparent;border:2px solid transparent;color:#0fbb6b;cursor:pointer;font-size:clamp(1.25rem,1.25rem + (1.5rem - 1.25rem) * (100vw - 360px) / (1200px - 360px),1.5rem);padding:.5rem}.sub-tabs>nav button.is-active{background:#0fbb6b14;border:2px solid #0fbb6b}.sub-tabs>nav button:hover{background:#0fbb6b26}@media(max-width:700px)and (orientation:landscape){.sub-tabs>nav .center-line{min-width:.5rem}}:host{font-size:inherit}\n",':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.tabs{align-items:center;box-sizing:border-box;display:flex;flex-direction:column;flex:0 0 auto;gap:.5rem;max-height:12rem;overflow:hidden;padding:0;position:relative;z-index:5;transition:max-height .35s ease-in-out,padding .35s ease-in-out,gap .35s ease-in-out;width:100%}.tabs.is-collapsed{gap:0;max-height:2rem}.tabs.is-collapsed>nav{opacity:0;pointer-events:none;transform:translateY(100%)}.tabs.is-collapsed .tabs-toggle .caret{transform:translateY(2px) rotate(-135deg)}.tabs .tabs-toggle{align-items:center;background:transparent;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;display:inline-flex;height:2rem;justify-content:center;line-height:0;max-height:2rem;min-height:2rem;overflow:hidden;padding:0 1rem;transition:border-color .2s ease;width:100%}.tabs .tabs-toggle:hover{background-color:#0fbb6b1f}.tabs .tabs-toggle .caret{border:solid #0fbb6b;border-width:0 2px 2px 0;box-sizing:border-box;display:inline-block;height:.6rem;margin:0 .5rem;padding:0;transform:translateY(-4px) rotate(45deg);transform-origin:center;transition:transform .35s ease;width:.6rem}.tabs .tabs-toggle .tabs-toggle-label{font-size:clamp(.7rem,.7rem + (.85rem - .7rem) * (100vw - 360px) / (1200px - 360px),.85rem);letter-spacing:.1em;line-height:1;text-transform:uppercase;white-space:nowrap}.tabs>nav{display:flex;justify-content:center;opacity:1;padding-bottom:.5rem;transform:translateY(0);transition:transform .35s ease-in-out,opacity .35s ease-in-out;transform-origin:bottom;will-change:transform,opacity;width:100%;position:relative}.tabs .tabs-version{bottom:14px;color:#0fbb6bbf;font-size:10px;letter-spacing:.08em;position:absolute;right:22px}.tabs .tabs-actions{align-items:center;display:flex;gap:.5rem;left:1rem;position:absolute;top:50%;transform:translateY(-50%)}.tabs .tabs-actions.right,.tabs .tabs-actions.tabs-actions--right{left:auto;right:1rem}.tabs .tabs-actions .tabs-actions-toggle{align-items:center;background:transparent;border:1px solid rgba(15,187,107,.6);border-radius:9999px;color:#0fbb6b;cursor:pointer;display:none;height:2.1rem;justify-content:center;padding:0 .6rem;text-transform:uppercase;width:2.4rem}.tabs .tabs-actions .tabs-actions-toggle:hover{background:#0fbb6b1f;border-color:#0fbb6b}.tabs .tabs-actions .tabs-actions-icon{background:#0fbb6b;border-radius:9999px;display:block;height:2px;position:relative;width:1.1rem}.tabs .tabs-actions .tabs-actions-icon:before,.tabs .tabs-actions .tabs-actions-icon:after{content:"";background:#0fbb6b;border-radius:9999px;height:2px;left:0;position:absolute;width:100%}.tabs .tabs-actions .tabs-actions-icon:before{top:-5px}.tabs .tabs-actions .tabs-actions-icon:after{top:5px}.tabs .tabs-actions .tabs-actions-menu{display:flex;gap:.5rem;align-items:center}.tabs .tabs-actions .action-button{background:transparent;border:1px solid rgba(15,187,107,.7);color:#0fbb6bb3;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.25rem .35rem;width:100%;border-radius:1rem;text-align:center}.tabs .tabs-actions .action-button:hover{background:#0fbb6b1f;border-color:#0fbb6b}.tabs .tabs-actions input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.tabs .tabs-action{align-items:center;background:#0fbb6b1a;border:2px solid rgba(15,187,107,.6);border-radius:.4rem;color:#0fbb6b;cursor:pointer;display:inline-flex;font-size:clamp(.65rem,.65rem + (.75rem - .65rem) * (100vw - 360px) / (1200px - 360px),.75rem);height:2.5rem;justify-content:center;letter-spacing:.08em;padding:0 .85rem;text-transform:uppercase;transition:background .2s ease,border-color .2s ease;width:auto}.tabs .tabs-action:hover{background:#0fbb6b2e;border-color:#0fbb6b}.tabs>nav>button{align-items:center;background:transparent;border-radius:9999px;border:2px solid rgba(15,187,107,.35);box-sizing:border-box;color:#0fbb6b;cursor:pointer;display:inline-flex;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);height:5rem;justify-content:center;line-height:1;margin:0 1rem;padding:0;text-transform:uppercase;width:5rem}.tabs>nav>button>span{align-items:center;display:inline-flex;justify-content:center;line-height:1;white-space:nowrap;width:100%;height:100%;border-radius:9999px;padding:0}.tabs>nav>button:hover{border-color:#0fbb6ba6}.tabs>nav>button:hover>span{background:#0fbb6b1f}.tabs>nav>button.is-active{border-color:#0fbb6b}.tabs>nav>button.is-active>span{background:#0fbb6b29}@media(max-width:750px){.tabs .tabs-actions{z-index:5}.tabs .tabs-actions .tabs-actions-toggle{display:inline-flex}.tabs .tabs-actions .tabs-actions-menu{display:none}.tabs .tabs-actions.is-open .tabs-actions-menu{background:#062114f2;border:1px solid rgba(15,187,107,.35);border-radius:.5rem;display:flex;flex-direction:column;gap:.35rem;padding:.5rem;position:absolute;bottom:2.6rem;z-index:1000}.tabs .tabs-actions.tabs-actions--left.is-open .tabs-actions-menu{left:0}.tabs .tabs-actions.tabs-actions--right.is-open .tabs-actions-menu{right:0}.tabs .tabs-actions .action-button{width:100%}}@media(max-width:750px){.tabs{overflow:visible}}:host{font-size:inherit}\n',':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{font-family:Roboto Condensed,sans-serif;font-size:clamp(.95rem,.95rem + (1.15rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.15rem);scrollbar-color:rgba(107,255,153,.6) rgba(6,33,20,.6);scrollbar-width:thin;background-color:#062114;background-image:repeating-linear-gradient(to bottom,#ffffff0a 0 1px,#0000 4px);background-size:100% 6px;animation:scan-lines 6s linear infinite;box-shadow:inset 0 0 24px #0009,inset 0 0 90px #00000073;box-sizing:border-box;color:#0fbb6b;display:block;height:100%;overflow:hidden;position:relative;width:100%;font-size:inherit}:host ::-webkit-scrollbar{width:6px;height:6px}:host ::-webkit-scrollbar-track{background:#06211499}:host ::-webkit-scrollbar-thumb{background:#6bff9999;border-radius:9999px}:host:before{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,#06211400 55%,#00000040 70%,#0009);mix-blend-mode:multiply}@keyframes scan-lines{0%{background-position:0 0}to{background-position:0 60px}}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:0;position:relative;width:100%;display:flex;flex-direction:column;min-height:0}.screen-size-overlay{position:absolute;inset:0;background:#000000d9;color:#0fbb6b;display:flex;align-items:center;justify-content:center;text-align:center;padding:2rem;text-transform:uppercase;font-size:clamp(1.1rem,1.1rem + (1.35rem - 1.1rem) * (100vw - 360px) / (1200px - 360px),1.35rem);z-index:200}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:50%;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.top-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.top-half-line:before{content:"";position:absolute;bottom:50%;top:-1.25rem;width:2px;z-index:2;left:0;background:linear-gradient(to top,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.extra-options{margin-top:0;display:flex;flex-direction:column;font-family:Roboto Mono,monospace;font-size:calc(clamp(1.05rem,1.05rem + .2rem * (100vw - 360px) / 840px,1.25rem) * var(--list-font-scale, 1));align-items:flex-end;gap:.75rem;white-space:nowrap;position:absolute;top:1rem;right:2rem;z-index:3}.extra-options button{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font:inherit;padding:0;white-space:nowrap}.extra-options button:hover{opacity:.8}.extra-options button:disabled,.extra-options button.is-locked{cursor:default}.extra-options .controller-button{font-size:inherit;white-space:nowrap}.extra-options .controller-button .large-par{display:inline;padding-left:.5rem;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));top:-.15rem;position:relative;white-space:nowrap}.map-panel{display:flex;flex:1 1 auto;min-height:0;position:relative;width:100%}.map-view{align-items:flex-start;background:transparent;border:none;color:#0fbb6b;cursor:pointer;display:flex;flex:1 1 auto;justify-content:flex-start;min-height:0;overflow:auto;padding:0;width:100%}.map-view span{letter-spacing:.1em;margin:auto;text-transform:uppercase;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.map-view img{display:block;max-width:none;max-height:none}.map-view.is-locked,.map-view:disabled{cursor:default}.map-view.is-draggable{cursor:grab}.map-view.is-dragging{cursor:grabbing}.map-zoom{display:flex;gap:.5rem;position:absolute;right:1.5rem;top:.5rem;z-index:2}.map-zoom .map-zoom-button{padding:0;width:calc(2rem * var(--list-font-scale, 1))}.map-fit{position:absolute;right:1.5rem;bottom:.5rem;z-index:2}.map-control-button{align-items:center;background:#062114f2;border:1px solid rgba(15,187,107,.65);border-radius:.5rem;color:#0fbb6b;cursor:pointer;display:inline-flex;font-size:calc(clamp(.75rem,.75rem + .15rem * (100vw - 360px) / 840px,.9rem) * var(--list-font-scale, 1));justify-content:center;text-transform:uppercase;height:calc(2rem * var(--list-font-scale, 1));padding:0 calc(.6rem * var(--list-font-scale, 1))}.map-control-button:hover{border-color:#0fbb6b;background:#062114e6}\n'],dependencies:[{kind:"component",type:K,selector:"pip-boy-cnd-status"},{kind:"component",type:te,selector:"pip-boy-eff-layout"},{kind:"component",type:$,selector:"pip-boy-inventory-layout",inputs:["category"]},{kind:"component",type:le,selector:"pip-boy-map-image-modal",inputs:["open","title","imageUrl"],outputs:["closeResult","save"]},{kind:"component",type:ie,selector:"pip-boy-music-layout",inputs:["category","waveformColorRgb"]},{kind:"component",type:Q,selector:"pip-boy-name-edit-modal",inputs:["open","title","value","placeholder","allowEmpty","inputType","inputMin","inputStep","showNumberControls"],outputs:["closeResult","save"]},{kind:"component",type:H,selector:"pip-boy-3000-header"},{kind:"component",type:ne,selector:"pip-boy-quests-layout"},{kind:"component",type:X,selector:"pip-boy-radiation-meter"},{kind:"component",type:Y,selector:"pip-boy-reset-confirm-modal",inputs:["open","title","message","confirmLabel","cancelLabel"],outputs:["confirm","closeResult"]},{kind:"component",type:y,selector:"pip-boy-screen-scan-lines",inputs:["replayTimeoutSeconds","screen","scanSpeedSeconds","tailLengthPx","scanColorRgb"]},{kind:"component",type:re,selector:"pip-boy-settings-modal",inputs:["open","scanLinesEnabled","rememberTabOnRefreshEnabled","editLockEnabled","listFontScale","secondaryTabSoundLabel","mainTabSoundLabel","clickSoundLabel"],outputs:["closeResult","save","previewListFontScale"]},{kind:"component",type:G,selector:"pip-boy-stats-layout",inputs:["category","valueLabel","valueMin","valueMax"]},{kind:"component",type:se,selector:"pip-boy-welcome-modal",inputs:["open","listFontScale"],outputs:["closeResult","previewListFontScale"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.0.8",ngImport:e,type:Re,decorators:[{type:a,args:[{selector:"pip-boy-3000",standalone:!0,imports:[K,te,$,le,ie,Q,H,ne,X,Y,y,re,G,se],providers:[W],template:'<main\n #screen\n class="screen"\n [style.--list-font-scale]="settings.listFontScale()"\n>\n @if (settings.scanLinesEnabled()) {\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="300"\n />\n }\n @if (isScreenTooSmall()) {\n <div class="screen-size-overlay" role="alert" aria-live="assertive">\n Screen is too small.<br />Please rotate to landscape.\n </div>\n }\n \x3c!-- HEADER --\x3e\n <pip-boy-3000-header />\n \x3c!-- CONTENT --\x3e\n <section class="content">\n @if (state.primary() === \'STATS\') {\n @if (state.secondary() === \'STATUS\') {\n <div class="status-content">\n <nav class="column sub-content" aria-label="Status tabs">\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'CND\'"\n (click)="state.selectTertiary(\'CND\')"\n >\n CND\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'RAD\'"\n (click)="state.selectTertiary(\'RAD\')"\n >\n RAD\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'EFF\'"\n (click)="state.selectTertiary(\'EFF\')"\n >\n EFF\n </button>\n </nav>\n @if (state.tertiary() === \'CND\') {\n <pip-boy-cnd-status />\n } @else if (state.tertiary() === \'RAD\') {\n <pip-boy-radiation-meter />\n <div class="extra-options">\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADAWAY\')"\n >\n {{ settings.radAwayLabel() }}\n </button>\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADX\')"\n >\n {{ settings.radXLabel() }}\n </button>\n </div>\n } @else if (state.tertiary() === \'EFF\') {\n <pip-boy-eff-layout />\n }\n </div>\n } @else if (state.secondary() === \'S.P.E.C.I.A.L.\') {\n <pip-boy-stats-layout\n category="SPECIAL"\n valueLabel="Rating"\n [valueMin]="1"\n [valueMax]="10"\n />\n } @else if (state.secondary() === \'SKILLS\') {\n <pip-boy-stats-layout\n category="SKILLS"\n valueLabel="Skill"\n [valueMin]="0"\n [valueMax]="100"\n />\n } @else if (state.secondary() === \'PERKS\') {\n <pip-boy-stats-layout\n category="PERKS"\n valueLabel="Rank"\n [valueMin]="0"\n />\n } @else if (state.secondary() === \'GENERAL\') {\n <pip-boy-stats-layout category="GENERAL" valueLabel="Value" />\n }\n } @else if (state.primary() === \'ITEMS\') {\n @if (state.secondary() === \'WEAPONS\') {\n <pip-boy-inventory-layout category="WEAPONS" />\n } @else if (state.secondary() === \'APPAREL\') {\n <pip-boy-inventory-layout category="APPAREL" />\n } @else if (state.secondary() === \'AID\') {\n <pip-boy-inventory-layout category="AID" />\n } @else if (state.secondary() === \'MISC\') {\n <pip-boy-inventory-layout category="MISC" />\n } @else if (state.secondary() === \'AMMO\') {\n <pip-boy-inventory-layout category="AMMO" />\n }\n } @else if (state.primary() === \'DATA\') {\n @if (state.secondary() === \'LOCAL MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #localMapView\n [class.is-draggable]="settings.localMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'LOCAL\')"\n >\n @if (settings.localMapImage()) {\n <img\n #localMapImage\n [src]="imageStore.getImageUrl(settings.localMapImage())"\n alt="Local map"\n [style.zoom]="settings.localMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.localMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.localMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'LOCAL\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'LOCAL\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'LOCAL\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'WORLD MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #worldMapView\n [class.is-draggable]="settings.worldMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'WORLD\')"\n >\n @if (settings.worldMapImage()) {\n <img\n #worldMapImage\n [src]="imageStore.getImageUrl(settings.worldMapImage())"\n alt="World map"\n [style.zoom]="settings.worldMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.worldMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.worldMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'WORLD\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'WORLD\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'WORLD\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'QUESTS\') {\n <pip-boy-quests-layout />\n } @else if (state.secondary() === \'NOTES\') {\n <pip-boy-music-layout category="NOTES" />\n } @else if (state.secondary() === \'RADIO\') {\n <pip-boy-music-layout category="RADIO" />\n }\n }\n </section>\n \x3c!-- SUB TABS --\x3e\n <section class="sub-tabs">\n @if (state.primary() === \'STATS\') {\n <nav aria-label="Stats tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'STATUS\'"\n (click)="selectSecondary(\'STATUS\')"\n >\n Status\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'S.P.E.C.I.A.L.\'"\n (click)="selectSecondary(\'S.P.E.C.I.A.L.\')"\n >\n S.P.E.C.I.A.L.\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'SKILLS\'"\n (click)="selectSecondary(\'SKILLS\')"\n >\n Skills\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'PERKS\'"\n (click)="selectSecondary(\'PERKS\')"\n >\n Perks\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'GENERAL\'"\n (click)="selectSecondary(\'GENERAL\')"\n >\n General\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'ITEMS\') {\n <nav aria-label="Items tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WEAPONS\'"\n (click)="selectSecondary(\'WEAPONS\')"\n >\n Weapons\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'APPAREL\'"\n (click)="selectSecondary(\'APPAREL\')"\n >\n Apparel\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AID\'"\n (click)="selectSecondary(\'AID\')"\n >\n Aid\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'MISC\'"\n (click)="selectSecondary(\'MISC\')"\n >\n Misc\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AMMO\'"\n (click)="selectSecondary(\'AMMO\')"\n >\n Ammo\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'DATA\') {\n <nav aria-label="Data tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'LOCAL MAP\'"\n (click)="selectSecondary(\'LOCAL MAP\')"\n >\n Local Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WORLD MAP\'"\n (click)="selectSecondary(\'WORLD MAP\')"\n >\n World Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'QUESTS\'"\n (click)="selectSecondary(\'QUESTS\')"\n >\n Quests\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'NOTES\'"\n (click)="selectSecondary(\'NOTES\')"\n >\n Notes\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'RADIO\'"\n (click)="selectSecondary(\'RADIO\')"\n >\n Radio\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n }\n </section>\n \x3c!-- MAIN TABS --\x3e\n <section class="tabs" [class.is-collapsed]="!tabsOpen()">\n <button\n type="button"\n class="tabs-toggle"\n aria-label="Toggle main tabs"\n [attr.aria-expanded]="tabsOpen()"\n aria-controls="main-tabs"\n (click)="toggleTabs()"\n >\n <span class="tabs-toggle-label tabs-toggle-label--state">\n {{ tabsOpen() ? \'CLOSE\' : \'OPEN\' }}\n </span>\n <span class="caret" aria-hidden="true"></span>\n <span class="tabs-toggle-label tabs-toggle-label--menu">MENU</span>\n </button>\n <nav id="main-tabs" aria-label="Main tabs">\n <div\n class="tabs-actions tabs-actions--left"\n [class.is-open]="tabsActionsLeftOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open settings actions"\n (click)="toggleTabsActions(\'left\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Save settings"\n title="Save settings"\n (click)="saveSettingsToFile()"\n >\n Save\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Load settings"\n title="Load settings"\n (click)="loadSettingsInput.click()"\n >\n Load\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Reset settings"\n title="Reset settings"\n (click)="openResetModal()"\n >\n Reset\n </button>\n <input\n #loadSettingsInput\n type="file"\n accept=".zip,application/zip"\n (change)="loadSettingsFromFile($event)"\n />\n </div>\n </div>\n <button\n type="button"\n [class.is-active]="state.primary() === \'STATS\'"\n (click)="selectPrimary(\'STATS\')"\n >\n <span>STATS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'ITEMS\'"\n (click)="selectPrimary(\'ITEMS\')"\n >\n <span>ITEMS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'DATA\'"\n (click)="selectPrimary(\'DATA\')"\n >\n <span>DATA</span>\n </button>\n <div\n class="tabs-actions tabs-actions--right"\n [class.is-open]="tabsActionsRightOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open utility actions"\n (click)="toggleTabsActions(\'right\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Open GitHub profile"\n title="Open GitHub profile"\n (click)="openGithubProfile()"\n >\n ❤\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Open settings"\n title="Settings"\n (click)="openSettingsModal()"\n >\n Settings\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Report a bug"\n title="Report a bug"\n (click)="openBugModal()"\n >\n Bug\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Exit"\n title="Exit"\n (click)="openExitModal()"\n >\n Exit\n </button>\n </div>\n </div>\n @if (tabsOpen()) {\n <div class="tabs-version">v{{ appVersion }}</div>\n }\n </nav>\n </section>\n <pip-boy-welcome-modal\n [open]="showWelcomeModal()"\n [listFontScale]="settings.listFontScale()"\n (previewListFontScale)="previewListFontScale($event)"\n (closeResult)="closeWelcomeModal()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showResetModal()"\n title="Reset Settings"\n message="This will reset all values back to defaults. This cannot be undone."\n confirmLabel="Reset"\n (closeResult)="closeResetModal()"\n (confirm)="confirmReset()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showExitModal()"\n title="Exit"\n message="Are you sure you want to leave this screen?"\n confirmLabel="Exit"\n (closeResult)="closeExitModal()"\n (confirm)="confirmExit()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showBugModal()"\n title="Report a bug"\n message="Would you like to report a bug?"\n confirmLabel="Yes"\n cancelLabel="No"\n (closeResult)="closeBugModal()"\n (confirm)="confirmBugReport()"\n />\n <pip-boy-map-image-modal\n [open]="mapImageModal() !== null"\n [title]="mapImageModalTitle()"\n [imageUrl]="mapImageModalImage()"\n (closeResult)="closeMapImageModal()"\n (save)="saveMapImageModal($event)"\n />\n <pip-boy-settings-modal\n [open]="showSettingsModal()"\n [scanLinesEnabled]="settings.scanLinesEnabled()"\n [rememberTabOnRefreshEnabled]="settings.rememberTabOnRefresh()"\n [editLockEnabled]="settings.editLockEnabled()"\n [listFontScale]="settings.listFontScale()"\n [secondaryTabSoundLabel]="secondaryTabSoundLabel()"\n [mainTabSoundLabel]="mainTabSoundLabel()"\n [clickSoundLabel]="clickSoundLabel()"\n (closeResult)="cancelSettingsModal()"\n (previewListFontScale)="previewListFontScale($event)"\n (save)="saveSettingsModal($event)"\n />\n <pip-boy-name-edit-modal\n [open]="extraOptionModal() !== null"\n [value]="extraOptionValue()"\n [title]="extraOptionTitle()"\n placeholder="Value"\n [allowEmpty]="true"\n (closeResult)="closeExtraOptionModal()"\n (save)="saveExtraOptionModal($event)"\n />\n</main>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.content{box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;height:100%;overflow:auto;padding:1rem 2rem;position:relative;width:100%}.content .status-content{box-sizing:border-box;display:flex;flex-direction:row;height:100%;gap:1rem}.content .column{box-sizing:border-box;display:flex;flex:1;flex-direction:column}.content .sub-content{max-width:max-content}.content .sub-content button{width:auto;max-width:10rem;height:2.5rem;background:transparent;color:#0fbb6b;display:flex;align-items:center;justify-content:center;text-align:center;text-transform:uppercase;border:none;border-left:2px solid transparent;border-right:2px solid transparent;cursor:pointer;padding:0 1rem;margin-bottom:1rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1) * 1.25)}.content .sub-content button.is-active{background:#0fbb6b14;border-left:2px solid #0fbb6b;border-right:2px solid #0fbb6b}.content .sub-content button:hover{background:#0fbb6b26}.content .radiation-status,.content .effects-status{box-sizing:border-box;display:flex;align-items:center;justify-content:center}.content .actions{box-sizing:border-box;display:flex;align-items:flex-end;max-width:max-content}:host{font-size:inherit}\n",":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.sub-tabs{flex:0 0 auto;min-height:0;margin-bottom:.5rem;padding:0 1rem;position:relative;z-index:1}.sub-tabs>nav{box-sizing:border-box;display:flex;align-items:center;width:100%;height:2.25rem;gap:0}.sub-tabs>nav .center-line{flex:1 1 auto;height:100%;min-width:1.5rem}.sub-tabs>nav>.center-line:last-child .top-half-line:before{left:auto;right:0}.sub-tabs>nav button{background:transparent;border:2px solid transparent;color:#0fbb6b;cursor:pointer;font-size:clamp(1.25rem,1.25rem + (1.5rem - 1.25rem) * (100vw - 360px) / (1200px - 360px),1.5rem);padding:.5rem}.sub-tabs>nav button.is-active{background:#0fbb6b14;border:2px solid #0fbb6b}.sub-tabs>nav button:hover{background:#0fbb6b26}@media(max-width:700px)and (orientation:landscape){.sub-tabs>nav .center-line{min-width:.5rem}}:host{font-size:inherit}\n",':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.tabs{align-items:center;box-sizing:border-box;display:flex;flex-direction:column;flex:0 0 auto;gap:.5rem;max-height:12rem;overflow:hidden;padding:0;position:relative;z-index:5;transition:max-height .35s ease-in-out,padding .35s ease-in-out,gap .35s ease-in-out;width:100%}.tabs.is-collapsed{gap:0;max-height:2rem}.tabs.is-collapsed>nav{opacity:0;pointer-events:none;transform:translateY(100%)}.tabs.is-collapsed .tabs-toggle .caret{transform:translateY(2px) rotate(-135deg)}.tabs .tabs-toggle{align-items:center;background:transparent;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;display:inline-flex;height:2rem;justify-content:center;line-height:0;max-height:2rem;min-height:2rem;overflow:hidden;padding:0 1rem;transition:border-color .2s ease;width:100%}.tabs .tabs-toggle:hover{background-color:#0fbb6b1f}.tabs .tabs-toggle .caret{border:solid #0fbb6b;border-width:0 2px 2px 0;box-sizing:border-box;display:inline-block;height:.6rem;margin:0 .5rem;padding:0;transform:translateY(-4px) rotate(45deg);transform-origin:center;transition:transform .35s ease;width:.6rem}.tabs .tabs-toggle .tabs-toggle-label{font-size:clamp(.7rem,.7rem + (.85rem - .7rem) * (100vw - 360px) / (1200px - 360px),.85rem);letter-spacing:.1em;line-height:1;text-transform:uppercase;white-space:nowrap}.tabs>nav{display:flex;justify-content:center;opacity:1;padding-bottom:.5rem;transform:translateY(0);transition:transform .35s ease-in-out,opacity .35s ease-in-out;transform-origin:bottom;will-change:transform,opacity;width:100%;position:relative}.tabs .tabs-version{bottom:14px;color:#0fbb6bbf;font-size:10px;letter-spacing:.08em;position:absolute;right:22px}.tabs .tabs-actions{align-items:center;display:flex;gap:.5rem;left:1rem;position:absolute;top:50%;transform:translateY(-50%)}.tabs .tabs-actions.right,.tabs .tabs-actions.tabs-actions--right{left:auto;right:1rem}.tabs .tabs-actions .tabs-actions-toggle{align-items:center;background:transparent;border:1px solid rgba(15,187,107,.6);border-radius:9999px;color:#0fbb6b;cursor:pointer;display:none;height:2.1rem;justify-content:center;padding:0 .6rem;text-transform:uppercase;width:2.4rem}.tabs .tabs-actions .tabs-actions-toggle:hover{background:#0fbb6b1f;border-color:#0fbb6b}.tabs .tabs-actions .tabs-actions-icon{background:#0fbb6b;border-radius:9999px;display:block;height:2px;position:relative;width:1.1rem}.tabs .tabs-actions .tabs-actions-icon:before,.tabs .tabs-actions .tabs-actions-icon:after{content:"";background:#0fbb6b;border-radius:9999px;height:2px;left:0;position:absolute;width:100%}.tabs .tabs-actions .tabs-actions-icon:before{top:-5px}.tabs .tabs-actions .tabs-actions-icon:after{top:5px}.tabs .tabs-actions .tabs-actions-menu{display:flex;gap:.5rem;align-items:center}.tabs .tabs-actions .action-button{background:transparent;border:1px solid rgba(15,187,107,.7);color:#0fbb6bb3;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.25rem .35rem;width:100%;border-radius:1rem;text-align:center}.tabs .tabs-actions .action-button:hover{background:#0fbb6b1f;border-color:#0fbb6b}.tabs .tabs-actions input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.tabs .tabs-action{align-items:center;background:#0fbb6b1a;border:2px solid rgba(15,187,107,.6);border-radius:.4rem;color:#0fbb6b;cursor:pointer;display:inline-flex;font-size:clamp(.65rem,.65rem + (.75rem - .65rem) * (100vw - 360px) / (1200px - 360px),.75rem);height:2.5rem;justify-content:center;letter-spacing:.08em;padding:0 .85rem;text-transform:uppercase;transition:background .2s ease,border-color .2s ease;width:auto}.tabs .tabs-action:hover{background:#0fbb6b2e;border-color:#0fbb6b}.tabs>nav>button{align-items:center;background:transparent;border-radius:9999px;border:2px solid rgba(15,187,107,.35);box-sizing:border-box;color:#0fbb6b;cursor:pointer;display:inline-flex;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);height:5rem;justify-content:center;line-height:1;margin:0 1rem;padding:0;text-transform:uppercase;width:5rem}.tabs>nav>button>span{align-items:center;display:inline-flex;justify-content:center;line-height:1;white-space:nowrap;width:100%;height:100%;border-radius:9999px;padding:0}.tabs>nav>button:hover{border-color:#0fbb6ba6}.tabs>nav>button:hover>span{background:#0fbb6b1f}.tabs>nav>button.is-active{border-color:#0fbb6b}.tabs>nav>button.is-active>span{background:#0fbb6b29}@media(max-width:750px){.tabs .tabs-actions{z-index:5}.tabs .tabs-actions .tabs-actions-toggle{display:inline-flex}.tabs .tabs-actions .tabs-actions-menu{display:none}.tabs .tabs-actions.is-open .tabs-actions-menu{background:#062114f2;border:1px solid rgba(15,187,107,.35);border-radius:.5rem;display:flex;flex-direction:column;gap:.35rem;padding:.5rem;position:absolute;bottom:2.6rem;z-index:1000}.tabs .tabs-actions.tabs-actions--left.is-open .tabs-actions-menu{left:0}.tabs .tabs-actions.tabs-actions--right.is-open .tabs-actions-menu{right:0}.tabs .tabs-actions .action-button{width:100%}}@media(max-width:750px){.tabs{overflow:visible}}:host{font-size:inherit}\n',':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{font-family:Roboto Condensed,sans-serif;font-size:clamp(.95rem,.95rem + (1.15rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.15rem);scrollbar-color:rgba(107,255,153,.6) rgba(6,33,20,.6);scrollbar-width:thin;background-color:#062114;background-image:repeating-linear-gradient(to bottom,#ffffff0a 0 1px,#0000 4px);background-size:100% 6px;animation:scan-lines 6s linear infinite;box-shadow:inset 0 0 24px #0009,inset 0 0 90px #00000073;box-sizing:border-box;color:#0fbb6b;display:block;height:100%;overflow:hidden;position:relative;width:100%;font-size:inherit}:host ::-webkit-scrollbar{width:6px;height:6px}:host ::-webkit-scrollbar-track{background:#06211499}:host ::-webkit-scrollbar-thumb{background:#6bff9999;border-radius:9999px}:host:before{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,#06211400 55%,#00000040 70%,#0009);mix-blend-mode:multiply}@keyframes scan-lines{0%{background-position:0 0}to{background-position:0 60px}}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:0;position:relative;width:100%;display:flex;flex-direction:column;min-height:0}.screen-size-overlay{position:absolute;inset:0;background:#000000d9;color:#0fbb6b;display:flex;align-items:center;justify-content:center;text-align:center;padding:2rem;text-transform:uppercase;font-size:clamp(1.1rem,1.1rem + (1.35rem - 1.1rem) * (100vw - 360px) / (1200px - 360px),1.35rem);z-index:200}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:50%;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.top-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.top-half-line:before{content:"";position:absolute;bottom:50%;top:-1.25rem;width:2px;z-index:2;left:0;background:linear-gradient(to top,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.extra-options{margin-top:0;display:flex;flex-direction:column;font-family:Roboto Mono,monospace;font-size:calc(clamp(1.05rem,1.05rem + .2rem * (100vw - 360px) / 840px,1.25rem) * var(--list-font-scale, 1));align-items:flex-end;gap:.75rem;white-space:nowrap;position:absolute;top:1rem;right:2rem;z-index:3}.extra-options button{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font:inherit;padding:0;white-space:nowrap}.extra-options button:hover{opacity:.8}.extra-options button:disabled,.extra-options button.is-locked{cursor:default}.extra-options .controller-button{font-size:inherit;white-space:nowrap}.extra-options .controller-button .large-par{display:inline;padding-left:.5rem;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));top:-.15rem;position:relative;white-space:nowrap}.map-panel{display:flex;flex:1 1 auto;min-height:0;position:relative;width:100%}.map-view{align-items:flex-start;background:transparent;border:none;color:#0fbb6b;cursor:pointer;display:flex;flex:1 1 auto;justify-content:flex-start;min-height:0;overflow:auto;padding:0;width:100%}.map-view span{letter-spacing:.1em;margin:auto;text-transform:uppercase;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.map-view img{display:block;max-width:none;max-height:none}.map-view.is-locked,.map-view:disabled{cursor:default}.map-view.is-draggable{cursor:grab}.map-view.is-dragging{cursor:grabbing}.map-zoom{display:flex;gap:.5rem;position:absolute;right:1.5rem;top:.5rem;z-index:2}.map-zoom .map-zoom-button{padding:0;width:calc(2rem * var(--list-font-scale, 1))}.map-fit{position:absolute;right:1.5rem;bottom:.5rem;z-index:2}.map-control-button{align-items:center;background:#062114f2;border:1px solid rgba(15,187,107,.65);border-radius:.5rem;color:#0fbb6b;cursor:pointer;display:inline-flex;font-size:calc(clamp(.75rem,.75rem + .15rem * (100vw - 360px) / 840px,.9rem) * var(--list-font-scale, 1));justify-content:center;text-transform:uppercase;height:calc(2rem * var(--list-font-scale, 1));padding:0 calc(.6rem * var(--list-font-scale, 1))}.map-control-button:hover{border-color:#0fbb6b;background:#062114e6}\n']}]}],propDecorators:{returnToUrl:[{type:e.Input,args:[{isSignal:!0,alias:"returnToUrl",required:!1}]}],localMapImage:[{type:e.ViewChild,args:["localMapImage",{isSignal:!0}]}],worldMapImage:[{type:e.ViewChild,args:["worldMapImage",{isSignal:!0}]}],localMapView:[{type:e.ViewChild,args:["localMapView",{isSignal:!0}]}],worldMapView:[{type:e.ViewChild,args:["worldMapView",{isSignal:!0}]}],onResize:[{type:g,args:["window:resize"]}]}});export{w as PipBoy2000MkVI,Re as PipBoy3000,Ie as PipBoy3000MkIV,W as PipBoy3000State,Me as PipBoy3000a};
1
+ import*as e from"@angular/core";import{input as t,ViewChild as n,Component as a,signal as o,Injectable as i,InjectionToken as s,effect as r,inject as l,output as d,EventEmitter as c,Output as p,Input as m,computed as u,viewChild as b,ElementRef as g,HostListener as h}from"@angular/core";import f from"gsap";import{CommonModule as v}from"@angular/common";import y from"jszip";class w{replayTimeoutSeconds=t(8,...ngDevMode?[{debugName:"replayTimeoutSeconds"}]:[]);screen=t.required(...ngDevMode?[{debugName:"screen"}]:[]);scanSpeedSeconds=t(5,...ngDevMode?[{debugName:"scanSpeedSeconds"}]:[]);tailLengthPx=t(300,...ngDevMode?[{debugName:"tailLengthPx"}]:[]);scanColorRgb=t("58, 208, 58",...ngDevMode?[{debugName:"scanColorRgb"}]:[]);scanlineRef;scanTween=null;resizeObserver=null;ngAfterViewInit(){if(window.matchMedia("(prefers-reduced-motion: reduce)").matches)return;const e=this.scanlineRef.nativeElement,t=this.screen(),n=()=>{e.style.height=`${this.tailLengthPx()}px`;const n=t.clientHeight,a=e.offsetHeight;if(n<=0||a<=0)return;const o=-a,i=n+a;this.scanTween&&(this.scanTween.kill(),this.scanTween=null),f.set(e,{y:o});const s=this.replayTimeoutSeconds(),r=s>0?Math.random()*s:0;this.scanTween=f.to(e,{y:i,duration:this.scanSpeedSeconds(),ease:"none",repeat:-1,repeatDelay:s,delay:r})};n(),this.resizeObserver=new ResizeObserver(()=>{n()}),this.resizeObserver.observe(t)}ngOnDestroy(){this.scanTween&&(this.scanTween.kill(),this.scanTween=null),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null)}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:w,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.1.0",version:"21.1.1",type:w,isStandalone:!0,selector:"pip-boy-screen-scan-lines",inputs:{replayTimeoutSeconds:{classPropertyName:"replayTimeoutSeconds",publicName:"replayTimeoutSeconds",isSignal:!0,isRequired:!1,transformFunction:null},screen:{classPropertyName:"screen",publicName:"screen",isSignal:!0,isRequired:!0,transformFunction:null},scanSpeedSeconds:{classPropertyName:"scanSpeedSeconds",publicName:"scanSpeedSeconds",isSignal:!0,isRequired:!1,transformFunction:null},tailLengthPx:{classPropertyName:"tailLengthPx",publicName:"tailLengthPx",isSignal:!0,isRequired:!1,transformFunction:null},scanColorRgb:{classPropertyName:"scanColorRgb",publicName:"scanColorRgb",isSignal:!0,isRequired:!1,transformFunction:null}},viewQueries:[{propertyName:"scanlineRef",first:!0,predicate:["scanline"],descendants:!0,static:!0}],ngImport:e,template:'<div\n #scanline\n class="screen-scanline"\n [style.--scanline-color-rgb]="scanColorRgb()"\n aria-hidden="true"\n></div>\n',styles:['.screen>:not(.screen-scanline){position:relative;z-index:1}.screen-scanline{position:absolute;left:0;right:0;top:0;height:140px;z-index:0;pointer-events:none;background:linear-gradient(to bottom,rgba(var(--scanline-color-rgb, 58, 208, 58),0),rgba(var(--scanline-color-rgb, 58, 208, 58),.04) 35%,rgba(var(--scanline-color-rgb, 58, 208, 58),.12) 65%,rgba(var(--scanline-color-rgb, 58, 208, 58),.16) 85%);mix-blend-mode:screen;opacity:.5;filter:blur(5px)}.screen-scanline:after{content:"";position:absolute;left:0;right:0;bottom:8px;height:2px;background:rgba(var(--scanline-color-rgb, 58, 208, 58),.3)}\n']})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:w,decorators:[{type:a,args:[{selector:"pip-boy-screen-scan-lines",template:'<div\n #scanline\n class="screen-scanline"\n [style.--scanline-color-rgb]="scanColorRgb()"\n aria-hidden="true"\n></div>\n',styles:['.screen>:not(.screen-scanline){position:relative;z-index:1}.screen-scanline{position:absolute;left:0;right:0;top:0;height:140px;z-index:0;pointer-events:none;background:linear-gradient(to bottom,rgba(var(--scanline-color-rgb, 58, 208, 58),0),rgba(var(--scanline-color-rgb, 58, 208, 58),.04) 35%,rgba(var(--scanline-color-rgb, 58, 208, 58),.12) 65%,rgba(var(--scanline-color-rgb, 58, 208, 58),.16) 85%);mix-blend-mode:screen;opacity:.5;filter:blur(5px)}.screen-scanline:after{content:"";position:absolute;left:0;right:0;bottom:8px;height:2px;background:rgba(var(--scanline-color-rgb, 58, 208, 58),.3)}\n']}]}],propDecorators:{replayTimeoutSeconds:[{type:e.Input,args:[{isSignal:!0,alias:"replayTimeoutSeconds",required:!1}]}],screen:[{type:e.Input,args:[{isSignal:!0,alias:"screen",required:!0}]}],scanSpeedSeconds:[{type:e.Input,args:[{isSignal:!0,alias:"scanSpeedSeconds",required:!1}]}],tailLengthPx:[{type:e.Input,args:[{isSignal:!0,alias:"tailLengthPx",required:!1}]}],scanColorRgb:[{type:e.Input,args:[{isSignal:!0,alias:"scanColorRgb",required:!1}]}],scanlineRef:[{type:n,args:["scanline",{static:!0}]}]}});class x{static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:x,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"21.1.1",type:x,isStandalone:!0,selector:"pip-boy-2000-mk-vi",ngImport:e,template:'<section #screen class="screen">\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="200"\n />\n</section>\n',styles:[":host{background:#030703;box-sizing:border-box;color:#3ad03a;display:block;height:100%;width:100%}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:1rem;position:relative;width:100%}\n"],dependencies:[{kind:"component",type:w,selector:"pip-boy-screen-scan-lines",inputs:["replayTimeoutSeconds","screen","scanSpeedSeconds","tailLengthPx","scanColorRgb"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:x,decorators:[{type:a,args:[{selector:"pip-boy-2000-mk-vi",standalone:!0,imports:[w],template:'<section #screen class="screen">\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="200"\n />\n</section>\n',styles:[":host{background:#030703;box-sizing:border-box;color:#3ad03a;display:block;height:100%;width:100%}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:1rem;position:relative;width:100%}\n"]}]}]});class k{dbPromise=this.openDb();imageUrls=o({},...ngDevMode?[{debugName:"imageUrls"}]:[]);loading=new Set;getImageUrl(e){if(!e)return null;const t=this.imageUrls()[e];return t||(this.loadImageUrl(e),null)}async saveFile(e){const t=this.createId(),n={id:t,fileName:e.name,mime:e.type||"application/octet-stream"};return await this.putRecord({...n,blob:e}),this.cacheUrl(t,URL.createObjectURL(e)),n}async saveBlobWithId(e,t,n,a){await this.putRecord({id:e,blob:t,fileName:n,mime:a}),this.cacheUrl(e,URL.createObjectURL(t))}async saveDataUrlWithId(e,t){const n=await fetch(t),a=await n.blob(),o=a.type||"application/octet-stream",i=`image-${e}${this.extensionFromMime(o)}`;await this.saveBlobWithId(e,a,i,o)}async getRecord(e){const t=await this.dbPromise;return new Promise((n,a)=>{const o=t.transaction("images","readonly").objectStore("images").get(e);o.onsuccess=()=>{n(o.result??null)},o.onerror=()=>a(o.error)})}async getBlob(e){const t=await this.getRecord(e);return t?.blob??null}extensionFromMime(e){switch(e){case"image/png":return".png";case"image/jpeg":return".jpg";case"image/webp":return".webp";case"image/gif":return".gif";case"image/svg+xml":return".svg";default:return""}}generateId(){return this.createId()}cacheUrl(e,t){this.imageUrls.update(n=>({...n,[e]:t}))}async loadImageUrl(e){if(!this.loading.has(e)){this.loading.add(e);try{const t=await this.getBlob(e);if(!t)return;this.cacheUrl(e,URL.createObjectURL(t))}finally{this.loading.delete(e)}}}async putRecord(e){const t=await this.dbPromise;return new Promise((n,a)=>{const o=t.transaction("images","readwrite").objectStore("images").put(e);o.onsuccess=()=>n(),o.onerror=()=>a(o.error)})}openDb(){return new Promise((e,t)=>{const n=indexedDB.open("pipBoy3000Images",1);n.onupgradeneeded=()=>{const e=n.result;e.objectStoreNames.contains("images")||e.createObjectStore("images",{keyPath:"id"})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}createId(){return"undefined"!=typeof crypto&&"randomUUID"in crypto?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:k,deps:[],target:e.ɵɵFactoryTarget.Injectable});static"ɵprov"=e.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:k,providedIn:"root"})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:k,decorators:[{type:i,args:[{providedIn:"root"}]}]});const S=[{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Ant Meat",val:4,wg:1},{effects:"INT +2,CHA +2,STR +4,Usage Monitor Effect 20",name:"Ant Nectar",val:20,wg:.25},{effects:"CHA +3,INT +3,PER +3",name:"Ant Queen Pheromones",val:75,wg:1},{effects:"INT +1,STR +1,CHA +1",name:"Beer",val:2,wg:1},{effects:"INT +5",name:"Berry Mentats",val:20,wg:0},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Blamco Mac and Cheese",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Bloatfly Meat",val:4,wg:1},{effects:"Restore Health 19,Restore Health 1",name:"Blood Pack",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Brahmin Steak",val:5,wg:1},{effects:"Restore Health 1,Restore Health 1,Damage Rads 1",name:"Bubblegum",val:1,wg:1},{name:"Buffout",wg:0,val:20,effects:"STR +2,END +3,Increased Health - Buffout 60,Usage Monitor Effect 30"},{effects:"Restore Health 5,Restore Rads 10",name:"Cave Fungus",val:50,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Cram",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Crispy Squirrel Bits",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Crunchy Mutfruit",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Dandy Boy Apples",val:5,wg:1},{effects:"Restore Health 10,Restore Health 2,Damage Rads 6",name:"Dirty Water",val:10,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Dog Meat",val:4,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Fancy Lads Snack Cakes",val:5,wg:1},{effects:"AGL +4,INT +3,Increased Fire Resistance 25",name:"Fire Ant Nectar",val:20,wg:1},{effects:"Restore Health 10",name:"Fresh Apple",val:5,wg:1},{effects:"Restore Health 10",name:"Fresh Carrot",val:5,wg:1},{effects:"Restore Health 10",name:"Fresh Pear",val:5,wg:1},{effects:"Restore Health 10",name:"Fresh Potato",val:5,wg:1},{effects:"CHA +5",name:"Grape Mentats",val:20,wg:0},{effects:"Restore Health 1,Damage Rads 1,Restore Health 1",name:"Gum Drops",val:2,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Hatchling Mirelurk Meat",val:4,wg:1},{effects:"Restore Health 25,Restore Health 5,Damage Rads 10",name:"Human Flesh",val:0,wg:1},{name:"Ice Cold Nuka-Cola",wg:1,val:20,effects:"Restore Health 20,Nuka-Cola Add Cap Effect,Restore Health 4,Damage Rads 3"},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Iguana Bits",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Iguana on a Stick",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"InstaMash",val:5,wg:1},{effects:"Increase Action Points - Jet 30,Usage Monitor Effect 30",name:"Jet",val:20,wg:0},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Junk Food",val:5,wg:1},{effects:"Increase Damage Resistance - Psycho 25,Usage Monitor Effect 30",name:"Med-X",val:20,wg:0},{effects:"INT +5,PER +5,Usage Monitor Effect 30",name:"Mentats",val:20,wg:0},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Mirelurk Cakes",val:5,wg:1},{effects:"Restore Health 20,Restore Health 4,Damage Rads 3",name:"Mirelurk Meat",val:20,wg:1},{effects:"STR +1,INT +1,Increased Action Points 20,Damage Rads 5",name:"Miss. Quantum Pie",val:20,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Mole Rat Meat",val:4,wg:1},{effects:"Restore Health 20,Restore Health 4,Damage Rads 3",name:"Mole Rat Wonder Meat",val:20,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Mutfruit",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Noodles",val:5,wg:1},{name:"Nuka-Cola Quantum",wg:1,val:30,effects:"Nuka-Cola Add Cap Effect,Increased Action Points 20,Damage Rads 10,Usage Monitor Effect 12"},{name:"Nuka-Cola",wg:1,val:20,effects:"Restore Health 10,Nuka-Cola Add Cap Effect,Restore Health 2,Damage Rads 3"},{name:"NukaLurk Meat",wg:1,val:7,effects:"Restore Health 20,Restore Health 4,Increased Action Points 10,Damage Rads 5"},{effects:"PER +5",name:"Orange Mentats",val:20,wg:0},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Pork N' Beans",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Potato Crisps",val:5,wg:1},{effects:"Damage +25%,Usage Monitor Effect 30",name:"Psycho",val:20,wg:0},{effects:"Restore Health 20",name:"Purified Water",val:20,wg:1},{effects:"Restore Rads 50",name:"RadAway",val:20,wg:0},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Radroach Meat",val:4,wg:1},{effects:"Increased Radiation Resistance 25",name:"Rad-X",val:20,wg:0},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Salisbury Steak",val:5,wg:1},{effects:"STR +1,INT +1,CHA +1",name:"Scotch",val:10,wg:1},{effects:"Restore Health 30,Restore Health 6,Damage Rads 3",name:"Softshell Mirelurk Meat",val:30,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Squirrel on a Stick",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Squirrel Stew",val:5,wg:1},{effects:"Stealth Field 75,Increased Sneak 100,Stealth Field Stop Combat",name:"Stealth Boy",val:100,wg:1},{effects:"Restore Health & Conditions 30,Restore Health & Conditions 36",name:"Stimpak",val:25,wg:0},{effects:"Restore Health 5,Damage Rads 3,Restore Health 1",name:"Strange Meat Pie",val:2,wg:1},{effects:"Restore Health 5,Damage Rads 3,Restore Health 1",name:"Strange Meat",val:2,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"Sugar Bombs",val:5,wg:1},{effects:"Restore Health 5,Restore Health 1",name:"Sweetroll",val:5,wg:1},{effects:"Increase Action Points - Jet 40,Usage Monitor Effect 12",name:"Ultrajet",val:50,wg:0},{effects:"STR +1,INT +1,CHA +1",name:"Vodka",val:20,wg:1},{effects:"STR +1,INT +1,CHA +1",name:"Whiskey",val:10,wg:1},{effects:"STR +1,INT +1,CHA +1",name:"Wine",val:10,wg:1},{effects:"Restore Health 10,Restore Health 2,Damage Rads 10,Damage +10%",name:"Yao Guai Meat",val:30,wg:1},{effects:"Restore Health 5,Restore Health 1,Damage Rads 3",name:"YumYum Deviled Eggs",val:5,wg:1}],M=[{name:".308 Caliber Round",val:3,wg:0},{name:".32 Caliber Round",val:1,wg:0},{name:".44 Round, Magnum",val:2,wg:0},{name:"10mm Round",val:1,wg:0},{name:"5.56mm Round",val:1,wg:0},{name:"5.56mm Round",val:0,wg:0},{name:"5mm Round",val:1,wg:0},{name:"5mm Round",val:1,wg:0},{name:"Alien Power Cell",val:10,wg:0},{name:"BB",val:1,wg:0},{name:"Dart",val:1,wg:0},{name:"Dart",val:1,wg:0},{name:"Electron Charge Pack",val:1,wg:0},{name:"Electron Charge Pack",val:1,wg:0},{name:"Energy Cell",val:2,wg:0},{name:"Energy Cell",val:0,wg:0},{name:"Flamer Fuel",val:1,wg:0},{name:"Flamer Fuel",val:0,wg:0},{name:"Mesmetron Power Cell",val:10,wg:0},{name:"Microfusion Cell",val:3,wg:0},{name:"Microfusion Cell",val:0,wg:0},{name:"Mini Nuke",val:250,wg:0},{name:"Missile",val:50,wg:0},{name:"Missile",val:1,wg:0},{name:"Missile",val:50,wg:0},{name:"Missile",val:1,wg:0},{name:"Railway Spikes",val:2,wg:0},{name:"Shotgun Shell",val:2,wg:0},{name:"Shotgun Shell",val:2,wg:0},{name:"Sonic Energy",val:10,wg:0}],I=[{cnd:3e3,dr:40,name:'"Robo-Thor" Armor',val:820,wg:45},{cnd:125,dr:8,name:'"Robo-Thor" Helmet',val:120,wg:5},{cnd:25,dr:8,name:"Advanced Radiation Suit",val:100,wg:7},{cnd:100,dr:3,name:"All-Purpose Science Suit",val:8,wg:2},{cnd:1200,dr:36,name:"Apocalypse Gladiator Armor",val:460,wg:30},{cnd:75,dr:5,name:"Apocalypse Gladiator Helmet",val:70,wg:3},{cnd:100,dr:12,name:"Armored Vault 101 Jumpsuit",val:180,wg:15},{cnd:100,dr:12,name:"Armored Vault 101 Jumpsuit",val:180,wg:15},{cnd:1e3,dr:40,name:"Army Power Armor",val:740,wg:45},{cnd:100,dr:2,name:"Athlete of the Wastes Outfit",val:30,wg:2},{cnd:10,dr:1,name:"Ballcap with Glasses",val:6,wg:1},{cnd:10,dr:2,name:"Bandana",val:6,wg:1},{cnd:10,dr:1,name:"Biker Goggles",val:6,wg:1},{cnd:100,dr:0,name:"BirthSkirt",val:0,wg:0},{cnd:100,dr:1,name:"Blast Off Helmet",val:30,wg:1},{cnd:100,dr:2,name:"Blast Off Pajamas",val:30,wg:2},{cnd:100,dr:8,name:"Boogeyman's Hood",val:110,wg:3},{cnd:100,dr:2,name:"Brahmin-Skin Outfit",val:6,wg:2},{cnd:1e3,dr:40,name:"Brotherhood Power Armor",val:740,wg:45},{cnd:75,dr:8,name:"Brotherhood Power Helmet",val:110,wg:5},{cnd:100,dr:2,name:"Brotherhood Scribe Robe",val:6,wg:2},{cnd:100,dr:1,name:"Button's Wig",val:20,wg:1},{cnd:100,dr:0,name:"",val:30,wg:1},{cnd:25,dr:0,name:"ChildBlastoffHelmet",val:0,wg:0},{cnd:15,dr:1,name:"Chinese Commando Hat",val:6,wg:1},{cnd:100,dr:6,name:"Chinese Jumpsuit",val:10,wg:2},{cnd:100,dr:10,name:"Colonel Autumn's Uniform",val:12,wg:3},{cnd:400,dr:32,name:"Combat Armor",val:390,wg:25},{cnd:50,dr:5,name:"Combat Helmet",val:50,wg:3},{cnd:150,dr:24,name:"Commando Armor",val:160,wg:15},{cnd:600,dr:28,name:"Composite Recon Armor",val:180,wg:20},{cnd:70,dr:4,name:"Composite Recon Helmet",val:40,wg:3},{cnd:25,dr:5,name:"Crow's Eyebot Helmet",val:20,wg:10},{cnd:100,dr:2,name:"Dad's Wasteland Outfit",val:6,wg:20},{cnd:150,dr:24,name:"Defender Armor",val:160,wg:15},{cnd:50,dr:6,name:"Dirty Chinese Jumpsuit",val:6,wg:2},{cnd:50,dr:6,name:"Dirty Chinese Jumpsuit",val:6,wg:2},{cnd:100,dr:3,name:"Dirty Pre-War Businesswear",val:8,wg:2},{cnd:100,dr:3,name:"Dirty Pre-War Casualwear",val:6,wg:2},{cnd:100,dr:2,name:"Dirty Pre-War Kid's Outfit",val:30,wg:2},{cnd:100,dr:3,name:"Dirty Pre-War Parkstroller Outfit",val:5,wg:10},{cnd:100,dr:3,name:"Dirty Pre-War Relaxedwear",val:6,wg:5},{cnd:100,dr:3,name:"Dirty Pre-War Spring Outfit",val:5,wg:2},{cnd:100,dr:4,name:"Dirty Pre-War Spring Outfit",val:40,wg:2},{cnd:100,dr:1,name:"Doctor Li's Glasses",val:6,wg:0},{cnd:100,dr:3,name:"Doctor Li's Outfit",val:8,wg:2},{cnd:100,dr:3,name:"Elder Lyons' Robe",val:8,wg:2},{cnd:15,dr:1,name:"Enclave Officer Hat",val:6,wg:1},{cnd:100,dr:5,name:"Enclave Officer Uniform",val:8,wg:3},{cnd:1200,dr:40,name:"Enclave Power Armor",val:780,wg:45},{cnd:1200,dr:40,name:"Enclave Power Armor",val:780,wg:45},{cnd:75,dr:9,name:"Enclave Power Helmet",val:110,wg:5},{cnd:100,dr:3,name:"Enclave Scientist Outfit",val:8,wg:2},{cnd:1500,dr:40,name:"Enclave Shocktrooper Armor",val:900,wg:45},{cnd:125,dr:7,name:"Enclave Shocktrooper Helmet",val:150,wg:5},{cnd:25,dr:6,name:"Environment Suit",val:100,wg:5},{cnd:15,dr:1,name:"Eulogy Jones' Hat",val:6,wg:1},{cnd:100,dr:2,name:"Eulogy Jones' Suit",val:6,wg:3},{cnd:100,dr:12,name:"Explorer's Gear",val:50,wg:3},{cnd:25,dr:5,name:"Eyebot Helmet",val:20,wg:3},{cnd:150,dr:1,name:"Eyeglasses",val:8,wg:0},{cnd:100,dr:3,name:"Ghoul Mask",val:50,wg:1},{cnd:150,dr:0,name:"GlassesReadingChild",val:12,wg:0},{cnd:100,dr:3,name:"Grimy Pre-War Businesswear",val:6,wg:2},{cnd:100,dr:15,name:"Hand-Me-Down Raider Armor",val:180,wg:15},{cnd:100,dr:2,name:"Handyman Jumpsuit",val:6,wg:1},{cnd:20,dr:1,name:"Hat of the People",val:30,wg:1},{cnd:10,dr:1,name:"Head Wrap",val:0,wg:0},{cnd:10,dr:1,name:"Head Wrap",val:0,wg:0},{cnd:10,dr:1,name:"Head Wrap",val:0,wg:0},{cnd:10,dr:1,name:"Head Wrap",val:0,wg:0},{cnd:100,dr:15,name:"Highway Scar Armor",val:180,wg:15},{cnd:15,dr:3,name:"Hockey Mask",val:10,wg:1},{cnd:100,dr:2,name:"Junior Officer Outfit",val:30,wg:2},{cnd:100,dr:1,name:"Kid's Ballcap with Glasses",val:30,wg:1},{cnd:150,dr:1,name:"Kid's Baseball Cap",val:40,wg:1},{cnd:100,dr:2,name:"Kid's Cave Rat Outfit",val:30,wg:2},{cnd:100,dr:2,name:"Kid's Murray the Mole Hat",val:30,wg:1},{cnd:10,dr:1,name:"Kid's Party Hat",val:5,wg:1},{cnd:150,dr:1,name:"Kid's Police Hat",val:40,wg:1},{cnd:100,dr:3,name:"Lab Technician Outfit",val:8,wg:2},{cnd:150,dr:24,name:"Leather Armor",val:160,wg:15},{cnd:150,dr:24,name:"Leather Armor",val:160,wg:15},{cnd:150,dr:24,name:"Leather Armor",val:160,wg:15},{cnd:150,dr:24,name:"Leather Armor",val:160,wg:15},{cnd:25,dr:4,name:"Ledoux's Hockey Mask",val:100,wg:1},{cnd:200,dr:5,name:"Lesko's Lab Coat",val:150,wg:1},{cnd:50,dr:1,name:"Lincoln's Hat",val:40,wg:1},{cnd:1e3,dr:40,name:"Linden's Outcast Power Armor",val:740,wg:45},{cnd:150,dr:1,name:"Lucky Shades",val:40,wg:1},{cnd:1e3,dr:40,name:"Lyons' Pride Power Armor",val:740,wg:45},{cnd:15,dr:6,name:"MacCready's Helmet",val:60,wg:1},{cnd:25,dr:3,name:"Makeshift Gas Mask",val:40,wg:2},{cnd:150,dr:15,name:"Maple's Garb",val:200,wg:2},{cnd:100,dr:2,name:"Mayor MacCready's Outfit",val:30,wg:2},{cnd:100,dr:12,name:"Merc Adventurer Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Adventurer Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Charmer Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Charmer Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Cruiser Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Cruiser Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Grunt Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Grunt Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Troublemaker Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Troublemaker Outfit",val:50,wg:8},{cnd:100,dr:12,name:"Merc Veteran Outfit",val:50,wg:8},{cnd:500,dr:36,name:"Metal Armor",val:460,wg:30},{cnd:50,dr:5,name:"Metal Helmet",val:70,wg:3},{cnd:100,dr:1,name:"Modified Utility Jumpsuit",val:30,wg:2},{cnd:10,dr:5,name:"Motorcycle Helmet",val:6,wg:1},{cnd:100,dr:2,name:"Mysterious Stranger Hat",val:30,wg:1},{cnd:100,dr:5,name:"Mysterious Stranger Outfit",val:40,wg:3},{cnd:100,dr:1,name:"Naughty Nightwear",val:200,wg:1},{cnd:10,dr:2,name:"Oasis Druid Hood",val:6,wg:1},{cnd:10,dr:2,name:"Oasis Exile Hood",val:30,wg:1},{cnd:100,dr:4,name:"Oasis Robe",val:30,wg:3},{cnd:100,dr:4,name:"Oasis Villager Robe",val:6,wg:2},{cnd:1e3,dr:40,name:"Outcast Power Armor",val:740,wg:45},{cnd:75,dr:8,name:"Outcast Power Helmet",val:110,wg:5},{cnd:400,dr:28,name:"Outcast Recon Armor",val:180,wg:20},{cnd:40,dr:4,name:"Outcast Recon Helmet",val:40,wg:3},{cnd:10,dr:1,name:"Party Hat",val:5,wg:1},{cnd:10,dr:0,name:"Party HatStanley",val:5,wg:1},{cnd:150,dr:6,name:"Pint-Sized Slasher Mask",val:60,wg:1},{cnd:1e5,dr:0,name:"Pip-Boy 3000",val:0,wg:0},{cnd:1e5,dr:0,name:"Pip-Boy 3000",val:0,wg:0},{cnd:1e5,dr:0,name:"Pip-Boy Glove",val:30,wg:0},{cnd:150,dr:1,name:"Police Hat",val:8,wg:1},{cnd:50,dr:2,name:"Poplar's Hood",val:100,wg:1},{cnd:1e3,dr:40,name:"Power Armor",val:740,wg:45},{cnd:1e3,dr:40,name:"Power Armor",val:510,wg:45},{cnd:1500,dr:40,name:"Power Armor",val:740,wg:45},{cnd:75,dr:8,name:"Power Helmet",val:110,wg:5},{cnd:100,dr:3,name:"Power-Suit Armor",val:12,wg:2},{cnd:15,dr:1,name:"Pre-War Baseball Cap",val:8,wg:1},{cnd:15,dr:1,name:"Pre-War Bonnet",val:8,wg:1},{cnd:100,dr:3,name:"Pre-War Casualwear",val:8,wg:2},{cnd:100,dr:3,name:"Pre-War Casualwear",val:12,wg:2},{cnd:15,dr:1,name:"Pre-War Hat",val:8,wg:1},{cnd:100,dr:1,name:"Pre-War Kid's Outfit",val:30,wg:2},{cnd:100,dr:2,name:"Pre-War Outfit and Watch",val:30,wg:2},{cnd:100,dr:2,name:"Pre-War Outfit and Watch",val:6,wg:2},{cnd:100,dr:3,name:"Pre-War Parkstroller Outfit",val:6,wg:2},{cnd:100,dr:3,name:"Pre-War Parkstroller Outfit",val:10,wg:2},{cnd:100,dr:3,name:"Pre-War Relaxedwear",val:8,wg:2},{cnd:100,dr:3,name:"Pre-War Spring Outfit",val:8,wg:2},{cnd:1e3,dr:40,name:"Prototype Medic Power Armor",val:1e3,wg:45},{cnd:15,dr:3,name:"Pyro Helmet",val:20,wg:3},{cnd:15,dr:6,name:"Radiation Suit",val:60,wg:5},{cnd:100,dr:2,name:"Ragamuffin Outfit",val:30,wg:2},{cnd:100,dr:1,name:"Ragamuffin Tophat",val:30,wg:1},{cnd:15,dr:3,name:"Raider Arclight Helmet",val:20,wg:3},{cnd:100,dr:16,name:"Raider Badlands Armor",val:180,wg:15},{cnd:100,dr:16,name:"Raider Blastmaster Armor",val:180,wg:15},{cnd:15,dr:3,name:"Raider Blastmaster Helmet",val:20,wg:3},{cnd:100,dr:16,name:"Raider Painspike Armor",val:180,wg:15},{cnd:15,dr:3,name:"Raider Psycho-Tic Helmet",val:20,wg:3},{cnd:100,dr:16,name:"Raider Sadist Armor",val:180,wg:15},{cnd:15,dr:3,name:"Raider Wastehound Helmet",val:20,wg:3},{cnd:1100,dr:39,name:"Ranger Battle Armor",val:430,wg:27},{cnd:50,dr:6,name:"Ranger Battle Helmet",val:60,wg:5},{cnd:150,dr:1,name:"Reading Glasses",val:12,wg:0},{cnd:40,dr:4,name:"Recon Armor Helmet",val:40,wg:3},{cnd:400,dr:28,name:"Recon Armor",val:180,wg:20},{cnd:100,dr:2,name:"Red Racer Jumpsuit",val:6,wg:1},{cnd:10,dr:2,name:"Red's Bandana",val:30,wg:1},{cnd:100,dr:3,name:"Red's Jumpsuit",val:40,wg:1},{cnd:150,dr:10,name:"Regulator Duster",val:70,wg:3},{cnd:25,dr:4,name:"Rivet City Security Helmet",val:50,wg:3},{cnd:100,dr:24,name:"Rivet City Security Uniform",val:330,wg:20},{cnd:150,dr:24,name:"Road Rascal Leather Armor",val:160,wg:15},{cnd:100,dr:2,name:"RobCo Jumpsuit",val:6,wg:1},{cnd:10,dr:1,name:"Roving Trader Hat",val:6,wg:1},{cnd:100,dr:2,name:"Roving Trader Outfit",val:6,wg:2},{cnd:100,dr:3,name:"Scientist Outfit",val:8,wg:2},{cnd:100,dr:1,name:"Sexy Sleepwear",val:6,wg:1},{cnd:50,dr:1,name:"Shady Hat",val:40,wg:1},{cnd:100,dr:15,name:"Sharp-Dressed Raider's Armor",val:180,wg:15},{cnd:400,dr:32,name:"Shellshocked Combat Armor",val:390,wg:25},{cnd:50,dr:5,name:"Shellshocked Combat Helmet",val:50,wg:3},{cnd:150,dr:5,name:"Sheriff's Duster",val:35,wg:3},{cnd:40,dr:1,name:"Sheriff's Hat",val:35,wg:1},{cnd:150,dr:3,name:"Slave Collar",val:50,wg:5},{cnd:400,dr:4,name:"Slave Collar",val:100,wg:5},{cnd:100,dr:1,name:"Sleepwear",val:10,wg:1},{cnd:10,dr:1,name:"Stormchaser Hat",val:6,wg:1},{cnd:150,dr:1,name:"Sunglasses",val:8,wg:0},{cnd:10,dr:1,name:"Surgical Mask",val:6,wg:1},{cnd:2e3,dr:50,name:"T-51b Power Armor",val:1e3,wg:40},{cnd:100,dr:10,name:"T-51b Power Helmet",val:120,wg:4},{cnd:15,dr:1,name:"Takoma Park Little Leaguer Cap",val:60,wg:1},{cnd:300,dr:28,name:"Talon Combat Armor",val:275,wg:25},{cnd:1e3,dr:32,name:"Talon Combat Armor",val:390,wg:25},{cnd:40,dr:4,name:"Talon Combat Helmet",val:60,wg:3},{cnd:50,dr:5,name:"Talon Combat Helmet",val:60,wg:3},{cnd:25,dr:4,name:"Tenpenny Security Helmet",val:50,wg:1},{cnd:100,dr:24,name:"Tenpenny Security Uniform",val:180,wg:20},{cnd:100,dr:2,name:"Tenpenny's Suit",val:8,wg:2},{cnd:1500,dr:43,name:"Tesla Armor",val:820,wg:45},{cnd:1500,dr:40,name:"Tesla Armor",val:820,wg:45},{cnd:100,dr:9,name:"Tesla Helmet",val:120,wg:5},{cnd:100,dr:20,name:"The AntAgonizer's Costume",val:120,wg:15},{cnd:50,dr:6,name:"The AntAgonizer's Helmet",val:60,wg:5},{cnd:15,dr:3,name:"The Devil's Pigtails",val:20,wg:3},{cnd:100,dr:20,name:"The Mechanist's Costume",val:30,wg:15},{cnd:50,dr:6,name:"The Mechanist's Helmet",val:60,wg:5},{cnd:100,dr:2,name:"The Surgeon's Lab Coat",val:30,wg:1},{cnd:150,dr:1,name:"Three Dog's Glasses",val:12,wg:0},{cnd:15,dr:2,name:"Three Dog's Head Wrap",val:200,wg:0},{cnd:150,dr:1,name:"Tinted Reading Glasses",val:12,wg:0},{cnd:15,dr:2,name:"Torcher's Mask",val:20,wg:3},{cnd:150,dr:1,name:"Tortiseshell Glasses",val:8,wg:0},{cnd:100,dr:4,name:"Tunnel Snake Outfit",val:8,wg:2},{cnd:100,dr:4,name:"Tunnel Snake Outfit",val:40,wg:3},{cnd:100,dr:0,name:"Underwear",val:2,wg:1},{cnd:100,dr:10,name:"Vance's Longcoat Outfit",val:100,wg:4},{cnd:100,dr:1,name:"Vault 101 Child's Jumpsuit",val:5,wg:2},{cnd:100,dr:1,name:"Vault 101 Jumpsuit",val:8,wg:1},{cnd:100,dr:12,name:"Vault 101 Security Armor",val:70,wg:15},{cnd:25,dr:3,name:"Vault 101 Security Helmet",val:30,wg:3},{cnd:100,dr:1,name:"Vault 101 Utility Jumpsuit",val:10,wg:1},{cnd:100,dr:1,name:"Vault 106 Jumpsuit",val:6,wg:1},{cnd:100,dr:1,name:"Vault 108 Jumpsuit",val:6,wg:1},{cnd:100,dr:1,name:"Vault 112 Jumpsuit",val:6,wg:1},{cnd:100,dr:1,name:"Vault 77 Jumpsuit",val:6,wg:1},{cnd:100,dr:1,name:"Vault 87 Jumpsuit",val:6,wg:1},{cnd:100,dr:1,name:"Vault 92 Jumpsuit",val:6,wg:1},{cnd:100,dr:2,name:"Vault Lab Uniform",val:6,wg:1},{cnd:150,dr:24,name:"Wanderer's Leather Armor",val:160,wg:15},{cnd:100,dr:2,name:"Wasteland Doctor Fatigues",val:6,wg:2},{cnd:100,dr:12,name:"Wasteland Legend Outfit",val:50,wg:8},{cnd:100,dr:1,name:"Wasteland Scout Hat",val:30,wg:1},{cnd:100,dr:2,name:"Wasteland Scout Uniform",val:30,wg:2},{cnd:100,dr:2,name:"Wasteland Settler Outfit",val:6,wg:2},{cnd:100,dr:2,name:"Wasteland Surgeon Outfit",val:6,wg:2},{cnd:100,dr:2,name:"Wasteland Wanderer Outfit",val:6,wg:2},{cnd:100,dr:12,name:"Wastelander's Gear",val:50,wg:2}],L=[{name:"10 Ball",val:2,wg:1},{name:"13 Ball",val:2,wg:1},{name:"2 Ball",val:2,wg:1},{name:"5 Ball",val:2,wg:1},{name:"8 Ball",val:2,wg:1},{name:"Abraxo Cleaner",val:5,wg:1},{name:"Action Abe Action Figure",val:5,wg:1},{name:"Android Component",val:0,wg:0},{name:"Ant Resin",val:3,wg:1},{name:"Antique Lincoln Coin Collection",val:5,wg:1},{name:"Archives Prize Voucher",val:0,wg:1},{name:"Ashtray",val:1,wg:1},{name:"Baseball Glove",val:4,wg:1},{name:"Baseball",val:2,wg:1},{name:"Basketball",val:1,wg:1},{name:"Bent Tin Can",val:1,wg:1},{name:"Big Spoon",val:1,wg:1},{name:"Bill of Rights",val:0,wg:1},{name:"Birch's Sap",val:0,wg:1},{name:"Blue Pass Card",val:1,wg:0},{name:"Bobblehead - Agility",val:0,wg:0},{name:"Bobblehead - Barter",val:0,wg:0},{name:"Bobblehead - Big Guns",val:0,wg:0},{name:"Bobblehead - Charisma",val:0,wg:0},{name:"Bobblehead - Endurance",val:0,wg:0},{name:"Bobblehead - Energy Weapons",val:0,wg:0},{name:"Bobblehead - Explosives",val:0,wg:0},{name:"Bobblehead - Intelligence",val:0,wg:0},{name:"Bobblehead - Lockpick",val:0,wg:0},{name:"Bobblehead - Luck",val:0,wg:0},{name:"Bobblehead - Medicine",val:0,wg:0},{name:"Bobblehead - Melee Weapons",val:0,wg:0},{name:"Bobblehead - Perception",val:0,wg:0},{name:"Bobblehead - Repair",val:0,wg:0},{name:"Bobblehead - Science",val:0,wg:0},{name:"Bobblehead - Small Guns",val:0,wg:0},{name:"Bobblehead - Sneak",val:0,wg:0},{name:"Bobblehead - Speech",val:0,wg:0},{name:"Bobblehead - Strength",val:0,wg:0},{name:"Bobblehead - Unarmed",val:0,wg:0},{name:"Bobby Pin",val:1,wg:0},{name:"Bonesaw",val:5,wg:2},{name:"Bottle Cap",val:1,wg:0},{name:"Box of Detergent",val:1,wg:1},{name:"Brahmin Skull",val:1,wg:2},{name:"Brotherhood of Steel Holotag",val:1,wg:0},{name:"Butter Knife",val:1,wg:1},{name:"Butter Knife",val:1,wg:1},{name:"Camera",val:5,wg:1},{name:"Card Catalog Holotape",val:0,wg:0},{name:"Carton of Cigarettes",val:50,wg:2},{name:"Ceramic Dinner Plate",val:1,wg:1},{name:"",val:1,wg:1},{name:"",val:1,wg:1},{name:"",val:1,wg:1},{name:"",val:1,wg:1},{name:"Chandelier",val:2,wg:14},{name:"Charon's Employment Contract",val:1,wg:0},{name:"Cherry Bomb",val:5,wg:0},{name:"Chessboard",val:1,wg:1},{name:"Cigarette",val:1,wg:0},{name:"Civil War Draft Poster",val:5,wg:1},{name:"Clipboard",val:1,wg:1},{name:"Coffee Mug",val:1,wg:1},{name:"Coffee Pot",val:1,wg:1},{name:"Computer Password Module",val:0,wg:0},{name:"Conductor",val:30,wg:5},{name:"Constitution of the United States",val:1,wg:1},{name:"Control Collar",val:1,wg:5},{name:"Crumpled Note",val:1,wg:1},{name:"Crutch",val:5,wg:2},{name:"Cue Ball",val:3,wg:1},{name:"Cup",val:1,wg:1},{name:"Cutting Board",val:1,wg:1},{name:"Damaged Garden Gnome",val:1,wg:4},{name:"Danielle's Book",val:1,wg:1},{name:"Deathclaw Hand",val:25,wg:1},{name:"Declaration of Independence",val:0,wg:1},{name:"Dinner Plate",val:1,wg:1},{name:"Dog Bowl",val:1,wg:1},{name:"Donovan's Wrench",val:75,wg:0},{name:"Door Component",val:1,wg:1},{name:"Drinking Glass",val:1,wg:1},{name:"Ear",val:1,wg:0},{name:"Earnings Clipboard",val:1,wg:1},{name:"Emancipation Proclamation",val:1,wg:1},{name:"Empty Nuka-Cola Bottle",val:2,wg:1},{name:"Empty Sap Container",val:0,wg:1},{name:"Empty Soda Bottle",val:1,wg:1},{name:"Empty Syringe",val:5,wg:1},{name:"Empty Whisky Bottle",val:1,wg:1},{name:"Experimental Rho ID",val:1,wg:0},{name:"Factory Employee ID",val:1,wg:0},{name:"Finance Clipboard",val:1,wg:1},{name:"Finger",val:1,wg:0},{name:"Firehose Nozzle",val:5,wg:1},{name:"Fission Battery",val:75,wg:10},{name:"Flour",val:2,wg:1},{name:"Food Sanitizer",val:150,wg:7},{name:"Forceps",val:5,wg:1},{name:"Forged Declaration",val:0,wg:1},{name:"Fork",val:1,wg:.5},{name:"Fuse",val:0,wg:0},{name:"Fusion Pulse Charge",val:1,wg:0},{name:"G.E.C.K.",val:0,wg:5},{name:"Garden Gnome",val:1,wg:5},{name:"Geomapper Module",val:20,wg:1},{name:"Gettysburg Address",val:1,wg:1},{name:"Glass Pitcher",val:1,wg:1},{name:"Green Plate",val:1,wg:1},{name:"Hammer",val:3,wg:2},{name:"Harmonica",val:2,wg:1},{name:"Holotape",val:0,wg:0},{name:"Hot Plate",val:5,wg:2},{name:"House: Explorer Theme",val:1e3,wg:0},{name:"House: Jukebox",val:500,wg:0},{name:"House: Love Machine Theme",val:1e3,wg:0},{name:"House: My First Infirmary",val:1200,wg:0},{name:"House: My First Laboratory",val:1200,wg:0},{name:"House: Nuka-Cola Machine",val:500,wg:0},{name:"House: Pre-War Theme",val:1e3,wg:0},{name:"House: Raider Theme",val:1e3,wg:0},{name:"House: Scientist Theme",val:1e3,wg:0},{name:"House: Vault Theme",val:1e3,wg:0},{name:"House: Workbench",val:500,wg:0},{name:"Ink Container",val:0,wg:0},{name:"Intact Garden Gnome",val:1,wg:5},{name:"Iron",val:2,wg:5},{name:"John Wilkes Booth Wanted Poster",val:5,wg:1},{name:"Junders Plunkett's Finger",val:1,wg:0},{name:"Lacy Underwear",val:3,wg:0},{name:"Large Burned Book",val:1,wg:1},{name:"Large Destroyed Book",val:1,wg:1},{name:"Large Ruined Book",val:1,wg:1},{name:"Large Scorched Book",val:1,wg:1},{name:"Large Whiskey Bottle",val:5,wg:2},{name:"Laurel's Liniment",val:0,wg:1},{name:"Lawn Mower Blade",val:10,wg:2},{name:"Leaf Blower",val:15,wg:2},{name:"Leather Belt",val:5,wg:1},{name:"Lincoln Memorial Poster",val:0,wg:1},{name:"Lincoln's Diary",val:5,wg:1},{name:"Lincoln's Voice",val:5,wg:2},{name:"Lucky 8 Ball",val:4,wg:1},{name:"Lucy's Sealed Envelope",val:0,wg:0},{name:"Lunchbox",val:3,wg:1},{name:"Magna Carta",val:0,wg:1},{name:"Media Archives Holotape",val:0,wg:0},{name:"Medical Brace",val:10,wg:2},{name:"Medical Brace",val:1,wg:2},{name:"Medical Clipboard",val:1,wg:1},{name:"Metal Cooking Pan",val:5,wg:1},{name:"Metal Cooking Pot",val:1,wg:1},{name:"Metal Spoon",val:1,wg:.5},{name:"Metro Ticket",val:1,wg:0},{name:"Military ID",val:1,wg:0},{name:"Military School Brochure",val:0,wg:0},{name:"Milk Bottle",val:1,wg:1},{name:"Modified FEV Virus",val:0,wg:1},{name:"Monroe Doctrine",val:1,wg:1},{name:"Motorcycle Gas Tank",val:25,wg:5},{name:"Motorcycle Handbrake",val:15,wg:1},{name:"Museum Token",val:1,wg:0},{name:"Mutilated Arm",val:0,wg:2},{name:"Mutilated Leg",val:0,wg:2},{name:"Mutilated Organs",val:0,wg:2},{name:"Mutilated Skull",val:0,wg:2},{name:"Mutilated Torso",val:0,wg:2},{name:"Nuka-Cola Clear Formula",val:150,wg:1},{name:"Nuka-Cola Truck",val:5,wg:2},{name:"Observer",val:0,wg:1},{name:"Office Employee ID",val:1,wg:0},{name:"Opthalmoscope",val:4,wg:1},{name:"Pack of Cigarettes",val:10,wg:.5},{name:"Paint Gun",val:15,wg:5},{name:"Paperweight",val:1,wg:1},{name:"Pencil",val:1,wg:0},{name:"Pilot Light",val:14,wg:1},{name:"Plunger",val:1,wg:1},{name:"Pool Ball",val:2,wg:1},{name:"Pot",val:0,wg:2},{name:"Pressure Cooker",val:15,wg:5},{name:"Pre-War Book",val:5,wg:1},{name:"Pre-War Book",val:1,wg:1},{name:"Pre-war Money",val:10,wg:0},{name:"Radscorpion Poison Gland",val:30,wg:1},{name:"Rake",val:1,wg:2},{name:"Red Pass Card",val:1,wg:0},{name:"Red Plate",val:1,wg:1},{name:"Rivet City Historical Record",val:0,wg:1},{name:"RobCo Processor Widget",val:0,wg:1},{name:"Rollerskate",val:4,wg:1},{name:"Scalpel",val:5,wg:1},{name:"Schematics - Bottlecap Mine",val:300,wg:0},{name:"Schematics - Dart Gun",val:500,wg:0},{name:"Schematics - Deathclaw Gauntlet",val:800,wg:0},{name:"Schematics - Nuka-Grenade",val:300,wg:0},{name:"Schematics - Railway Rifle",val:800,wg:0},{name:"Schematics - Rock-It Launcher",val:800,wg:0},{name:"Schematics - Shishkebab",val:500,wg:0},{name:"Scissors",val:3,wg:1},{name:"Scrap Metal",val:1,wg:1},{name:"Sensor Module",val:30,wg:2},{name:"Sheet Music Book",val:100,wg:1},{name:"Shot glass",val:1,wg:1},{name:"Slave Collar",val:0,wg:1},{name:"Small Burned Book",val:1,wg:1},{name:"Small Destroyed Book",val:1,wg:1},{name:"Small Ruined Book",val:1,wg:1},{name:"Small Scorched Book",val:1,wg:1},{name:"Soil Stradivarius",val:0,wg:3},{name:"Spatula",val:1,wg:1},{name:"Spork",val:1,wg:.5},{name:"Steam Gauge Assembly",val:25,wg:10},{name:"Surgical Tubing",val:10,wg:1},{name:"Teddy Bear",val:3,wg:1},{name:"Tin Can",val:1,wg:1},{name:"Tin Plate",val:1,wg:1},{name:"Toaster",val:5,wg:3},{name:"Toaster",val:5,wg:3},{name:"Toy Car",val:5,wg:1},{name:"Triangle",val:1,wg:1},{name:"Turpentine",val:10,wg:2},{name:"Tweezers",val:3,wg:1},{name:"U.S. Declaration of War on China",val:1,wg:1},{name:"U.S. Declaration of War on Germany",val:1,wg:1},{name:"Utility Worker ID",val:1,wg:0},{name:"Vacuum Cleaner",val:20,wg:10},{name:"Vance's Proposal",val:0,wg:0},{name:"Virgo II Dish",val:0,wg:1},{name:"Wasteland Survival Guide",val:1,wg:2},{name:"Whet Stone",val:1,wg:2},{name:"White Plate",val:1,wg:1},{name:"Wonderglue",val:10,wg:1},{name:"Wood Chipper",val:25,wg:50},{name:"Wrench",val:1,wg:1},{name:"Yew's Bear Charm",val:50,wg:1}],R=[{description:"With the Action Boy perk, you gain an additional 25 Action Points to use in V.A.T.S.",id:1,maxRanks:1,name:"Action Boy",value:0},{description:"With the Action Girl perk, you gain an additional 25 Action Points to use in V.A.T.S.",id:2,maxRanks:1,name:"Action Girl",value:0},{description:"With the Adamantium Skeleton perk, your limbs only receive 50% of the damage they normally would.",id:3,maxRanks:1,name:"Adamantium Skeleton",value:0},{description:"At the first rank of this perk, animals simply won't attack. At the second rank, they will actually come to your aid in combat, but never against another animal. This perk affects the Dog, Yao Guai, Mole Rat, and Brahmin. ",id:4,maxRanks:2,name:"Animal Friend",value:0},{description:"Your body has been genetically enhanced with the strength and flame resistance of the Grayditch Fire Ants! Your Strength has increased by 1 and you are now 25% resistant to fire.",id:5,maxRanks:1,name:"Ant Might",value:0},{description:"Your body has been genetically enhanced with the perception and flame resistance of the Grayditch Fire Ants! Your Perception has increased by 1 and you are now 25% resistant to fire.",id:6,maxRanks:1,name:"Ant Sight",value:0},{description:"You've been exposed to Harold's mutation and your skin is now as hard as tree bark. As a result, you've gained a permanent +5% to Damage Resistance.",id:7,maxRanks:1,name:"Barkskin",value:0},{description:"With the Better Criticals perk, you gain a 50% damage bonus every time a critical hit is scored on an opponent.",id:8,maxRanks:1,name:"Better Criticals",value:0},{description:"In combat, you do +10% damage against male opponents. Outside of combat, you'll sometimes have access to unique dialogue options when dealing with the opposite sex. ",id:9,maxRanks:1,name:"Black Widow",value:0},{description:"With the Bloody Mess perk, characters and creatures you kill will often explode into a red, gut-ridden, eyeball-strewn paste. Fun! Oh, and you'll do 5% extra damage with all weapons.",id:10,maxRanks:1,name:"Bloody Mess",value:0},{description:"With the Cannibal perk, when you're in Sneak mode, you gain the option to eat a corpse to regain Health. But every time you feed, you lose Karma, and if the act is witnessed, it is considered a crime against nature.",id:11,maxRanks:1,name:"Cannibal",value:0},{description:"Having the Chem Resistant perk means you're 50% less likely to develop an addiction to chems, like Psycho or Jet.",id:12,maxRanks:1,name:"Chem Resistant",value:0},{description:"With the Chemist perk, any chems you take last twice as long.",id:13,maxRanks:1,name:"Chemist",value:0},{description:"The Child at Heart perk greatly improves your interactions with children, usually in the form of unique dialogue choices.",id:14,maxRanks:1,name:"Child at Heart",value:0},{description:"While using a rifle (or similar two-handed weapon), your accuracy in V.A.T.S. is significantly increased.",id:15,maxRanks:1,name:"Commando",value:0},{description:"With the Comprehension perk, you gain one additional skill point whenever a skill book is read.",id:16,maxRanks:1,name:"Comprehension",value:0},{description:"Fail a hack attempt and get locked out of a computer? Not if you're a Computer Whiz! With this perk, you can attempt to re-hack any computer you were previously locked out of.",id:17,maxRanks:1,name:"Computer Whiz",value:0},{description:"With Concentrated Fire, your accuracy to hit any body part in V.A.T.S. increases slightly with each subsequent hit on that body part.",id:18,maxRanks:1,name:"Concentrated Fire",value:0},{description:"Once you have the Contract Killer perk, any good character you kill will have an ear on their corpse. This ear can then be sold to a certain person (whose identity is disclosed when you take the perk) for caps and negative Karma. ",id:19,maxRanks:1,name:"Contract Killer",value:0},{description:"You've made permanent enhancements to your body! The Cyborg perk instantly adds +10% to your Damage, Poison, and Radiation Resistances, and 10 points to the Energy Weapons skill.",id:20,maxRanks:1,name:"Cyborg",value:0},{description:"Just like dear old Dad, you've devoted your time to intellectual pursuits. You gain an additional 5 points to both the Science and Medicine skills.",id:21,maxRanks:3,name:"Daddy's Boy",value:0},{description:"Just like dear old Dad, you've devoted your time to intellectual pursuits. You gain an additional 5 points to both the Science and Medicine skills.",id:22,maxRanks:3,name:"Daddy's Girl",value:0},{description:"With each rank of this perk, all of your explosive weapons do an additional 20% damage. ",id:23,maxRanks:3,name:"Demolition Expert",value:0},{description:"Something about your presence dampens others' desires to exceed. Any enemy's chance of getting critical hits on you is reduced by 50%. ",id:24,maxRanks:1,name:"Dream Crusher",value:0},{description:"With the Educated perk, you gain three more skill points every time you advance in level. This perk is best taken early on, to maximize its effectiveness.",id:25,maxRanks:1,name:"Educated",value:0},{description:"With the Entomologist perk, you do an additional +50% damage every time you attack a mutated insect, like the Radroach, Giant Ant, or Radscorpion.",id:26,maxRanks:1,name:"Entomologist",value:0},{description:"When you choose the Explorer perk, every location in the world is revealed on your map. So get out there and explore!",id:27,maxRanks:1,name:"Explorer",value:0},{description:"With the Fast Metabolism perk, you gain a 20% Health bonus when using Stimpaks.",id:28,maxRanks:1,name:"Fast Metabolism",value:0},{description:"With the Finesse perk, you have a higher chance to score a critical hit on an opponent in combat, equivalent to 5 extra points of Luck.",id:29,maxRanks:1,name:"Finesse",value:0},{description:"With the Fortune Finder perk, you'll find considerably more Nuka-Cola caps in containers than you normally would. ",id:30,maxRanks:1,name:"Fortune Finder",value:0},{description:"If you kill a target in V.A.T.S., all your Action Points are restored upon exiting V.A.T.S.",id:31,maxRanks:1,name:"Grim Reaper's Sprint",value:0},{description:"You're obsessed with using and maintaining a wide variety of conventional firearms. With each rank of the Gun Nut perk, you gain an additional 5 points to the Small Guns and Repair skills.",id:32,maxRanks:3,name:"Gun Nut",value:0},{description:"While using a pistol (or similar one-handed weapon), your accuracy in V.A.T.S. is significantly increased.",id:33,maxRanks:1,name:"Gunslinger",value:0},{description:"This perk allows you to regain health by consuming Bloodpacks.",id:34,maxRanks:1,name:"Hematophage",value:0},{description:"The Here and Now perk immediately grants an additional experience level, complete with all the advantages that brings.",id:35,maxRanks:1,name:"Here and Now",value:0},{description:"With the Impartial Mediation perk, you gain an extra 30 points to Speech... so long as you maintain a Neutral Karma level.",id:36,maxRanks:1,name:"Impartial Mediation",value:0},{description:'With Infiltrator, if a lock is broken, and can\'t normally be picked again, you can attempt to pick it again one more time. This includes locks previously broken by a "Force Lock" attempt.',id:37,maxRanks:1,name:"Infiltrator",value:0},{description:"With the Intense Training perk, you can put a single point into any of your S.P.E.C.I.A.L. attributes.",id:38,maxRanks:10,name:"Intense Training",value:0},{description:"With the Iron Fist perk, you do an additional 5 points of Unarmed damage per rank.",id:39,maxRanks:3,name:"Iron Fist",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you're still alive to tell the tale. You've gained +2% bonus to Poison Resistance and Radiation Resistance, and +5 points to maximum Health.",id:40,maxRanks:1,name:"Junior Survivor",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you're still alive to tell the tale. You've gained +2% bonus to Poison Resistance and Radiation Resistance, and 2 points to both the Medicine and Science skills.",id:41,maxRanks:1,name:"Junior Survivor",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you're still alive to tell the tale. You've gained +2% bonus to Poison Resistance, Radiation Resistance and Damage Resistance.",id:42,maxRanks:1,name:"Junior Survivor",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you're still alive to tell the tale. You've gained +2% bonus to Poison Resistance & Radiation Resistance, and 2 points to both the Speech and Sneak skills.",id:43,maxRanks:1,name:"Junior Survivor",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you're still alive to tell the tale. You've gained +2% bonus to Poison Resistance and Radiation Resistance, and a +1% bonus to Critical Chance.",id:44,maxRanks:1,name:"Junior Survivor",value:0},{description:"In combat, you do +10% damage against female opponents. Outside of combat, you'll sometimes have access to unique dialogue options when dealing with the opposite sex. ",id:45,maxRanks:1,name:"Lady Killer",value:0},{description:"Once you have the Lawbringer perk, any evil character you kill will have a finger on their corpse. This finger can then be sold to a certain person (whose identity is disclosed when you take the perk) for caps and positive Karma. ",id:46,maxRanks:1,name:"Lawbringer",value:0},{description:"With the Lead Belly perk, you take 50% less radiation every time you drink from an irradiated water source.",id:47,maxRanks:1,name:"Lead Belly",value:0},{description:"With the Life Giver perk, you gain an additional 30 Hit Points.",id:48,maxRanks:1,name:"Life Giver",value:0},{description:"With the Light Step perk, you'll never set off an enemy's mines or floor-based traps.",id:49,maxRanks:1,name:"Light Step",value:0},{description:"Years as the Vault little league MVP have honed your hitting and throwing. With every rank, you gain 5 points of Melee Weapons skill and 5 points of Explosives skill.",id:50,maxRanks:3,name:"Little Leaguer",value:0},{description:"When you take the Master Trader perk, the price of every item you buy from a vendor is reduced by 25%.",id:51,maxRanks:1,name:"Master Trader",value:0},{description:"With the Mister Sandman perk, when you're in Sneak mode, you gain the option to silently kill any human or Ghoul while they're sleeping. And, all Mister Sandman kills earn bonus XP.",id:52,maxRanks:1,name:"Mister Sandman",value:0},{description:"You've gained your own personal guardian angel... armed with a fully loaded .44 Magnum. With this perk, the Mysterious Stranger will appear occasionally in V.A.T.S. mode to lend a hand, with deadly efficiency.",id:53,maxRanks:1,name:"Mysterious Stranger",value:0},{description:"You've been pushed around long enough! With the Nerd Rage! perk, your Strength is raised to 10 and you gain 50% to damage resistance whenever your Health drops to 20% or below.",id:54,maxRanks:1,name:"Nerd Rage!",value:0},{description:'When the sun is down, a Night Person gains +2 to both Intelligence and Perception (up to a maximum of 10). This perk directly affects your "internal clock," and remains active both inside and outside.',id:55,maxRanks:1,name:"Night Person",value:0},{description:"The Ninja perk grants you the power of the fabled shadow warriors. When attacking with either Melee or Unarmed, you gain a +15% critical chance on every strike. Sneak attack criticals do 25% more damage than normal.",id:56,maxRanks:1,name:"Ninja",value:0},{description:"With Paralyzing Palm, you will sometimes perform a special V.A.T.S. palm strike that paralyzes your opponent for 30 seconds. Note that in order to perform the Paralyzing Palm, you must be completely unarmed.",id:57,maxRanks:1,name:"Paralyzing Palm",value:0},{description:"You have received the specialized training needed to move in any form of Power Armor.",id:58,maxRanks:1,name:"Power Armor Training",value:0},{description:"",id:59,maxRanks:1,name:"",value:0},{description:"With the Pyromaniac perk, you do +50% damage with fire-based weapons, like the Flamer and Shishkebab.",id:60,maxRanks:1,name:"Pyromaniac",value:0},{description:"After an experimental treatment, intense radiation keeps your body operating at peak performance regardless of crippling injuries... right up until death. When you suffer from Advanced Radiation Poisoning, crippled limbs automatically regenerate.",id:61,maxRanks:1,name:"Rad Regeneration",value:0},{description:"Rad Resistance allows you to -- what else? -- resist radiation. This perk grants an additional 25% to Radiation Resistance.",id:62,maxRanks:1,name:"Rad Resistance",value:0},{description:"With the Robotics perk, you do an additional 25% damage to any robot. But, even better, sneaking up on a hostile robot undetected and activating it will put that robot into a permanent shutdown state.",id:63,maxRanks:1,name:"Robotics Expert",value:0},{description:"Take the Scoundrel perk, and you can use your wily charms to influence people -- each rank raises your Speech and Barter skills by 5 points.",id:64,maxRanks:3,name:"Scoundrel",value:0},{description:"With the Scrounger perk, you'll find considerably more ammunition in containers than you normally would. ",id:65,maxRanks:1,name:"Scrounger",value:0},{description:"With the Silent Running perk, you gain an additional 10 points to Sneak, and running no longer factors into a successful sneak attempt.",id:66,maxRanks:1,name:"Silent Running",value:0},{description:"You're obsessed with really big weapons. With each rank of this perk, you gain an additional 15 points to the Big Guns skill.",id:67,maxRanks:3,name:"Size Matters",value:0},{description:"With the Sniper perk, your chance to hit an opponent's head in V.A.T.S. is significantly increased.",id:68,maxRanks:1,name:"Sniper",value:0},{description:"With the Solar Powered perk, you gain an additional 2 points to Strength when in direct sunlight, and slowly regenerate lost Health.",id:69,maxRanks:1,name:"Solar Powered",value:0},{description:"With the Strong Back perk, you can carry 50 more pounds of equipment.",id:70,maxRanks:1,name:"Strong Back",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you've not only survived - you've learned a few things. You've gained +4% bonus to Poison Resistance and Radiation Resistance, and +10 points to maximum Health.",id:71,maxRanks:1,name:"Survival Expert",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you've not only survived - you've learned a few things. You've gained +4% bonus to Poison Resistance and Radiation Resistance, and 4 points to both the Medicine and Science skills.",id:72,maxRanks:1,name:"Survival Expert",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you've not only survived - you've learned a few things. You've gained +4% bonus to Poison Resistance, Radiation Resistance and Damage Resistance.",id:73,maxRanks:1,name:"Survival Expert",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you've not only survived - you've learned a few things. You've gained +4% bonus to Poison Resistance & Radiation Resistance, and 4 points to both the Speech and Sneak skills.",id:74,maxRanks:1,name:"Survival Expert",value:0},{description:"You've been tested in some of the most dangerous parts of the wastes, and you've not only survived - you've learned a few things. You've gained +4% bonus to Poison Resistance and Radiation Resistance, and a +2% bonus to Critical Chance.",id:75,maxRanks:1,name:"Survival Expert",value:0},{description:"You wrote the book on how to survive in the Wasteland, and have shared your secrets with humanity. You've gained +6% bonus to Poison Resistance and Radiation Resistance, and +15 points to maximum Health.",id:76,maxRanks:1,name:"Survival Guru",value:0},{description:"You wrote the book on how to survive in the Wasteland, and have shared your secrets with humanity. You've gained +6% bonus to Poison Resistance and Radiation Resistance, and 6 points to both the Medicine and Science skills.",id:77,maxRanks:1,name:"Survival Guru",value:0},{description:"You wrote the book on how to survive in the Wasteland, and have shared your secrets with humanity. You've gained +6% bonus to Poison Resistance, Radiation Resistance and Damage Resistance.",id:78,maxRanks:1,name:"Survival Guru",value:0},{description:"You wrote the book on how to survive in the Wasteland, and have shared your secrets with humanity. You've gained +6% bonus to Poison Resistance & Radiation Resistance, and 6 points to both the Speech and Sneak skills.",id:79,maxRanks:1,name:"Survival Guru",value:0},{description:"You wrote the book on how to survive in the Wasteland, and have shared your secrets with humanity. You've gained +6% bonus to Poison Resistance & Radiation Resistance, and +3% bonus to Critical Chance.",id:80,maxRanks:1,name:"Survival Guru",value:0},{description:"With each rank in the Swift Learner perk, you gain an additional 10% to total Experience Points whenever Experience Points are earned.",id:81,maxRanks:3,name:"Swift Learner",value:0},{description:"The Tag! perk allows you to select a fourth Skill to be a Tag skill, which instantly raises it by 15 points.",id:82,maxRanks:1,name:"Tag!",value:0},{description:"With each rank of the Thief perk, you gain an immediate bonus of 5 points to both the Sneak and Lockpick skills.",id:83,maxRanks:3,name:"Thief",value:0},{description:"With the Toughness perk, you gain +10% to overall Damage Resistance, up to the maximum of 85%. ",id:84,maxRanks:1,name:"Toughness",value:0},{description:"After sleeping in a safe bed, you will wake well rested. You earn 10% more experience points for several hours.",id:85,maxRanks:1,name:"Well Rested",value:0},{description:"Advanced technology from the Commonwealth has increased your reaction speed, giving you a higher chance to hit in V.A.T.S.",id:86,maxRanks:1,name:"Wired Reflexes",value:0},{description:"",id:87,maxRanks:1,name:"",value:0}],D=[{description:"Improves buying and selling prices.",id:1,name:"Barter",value:0},{description:"Accuracy and damage with heavy weapons.",id:2,name:"Big Guns",value:0},{description:"Accuracy and damage with energy weapons.",id:3,name:"Energy Weapons",value:0},{description:"Damage with explosives and ability to disarm traps.",id:4,name:"Explosives",value:0},{description:"Ability to pick locks.",id:5,name:"Lockpick",value:0},{description:"Effectiveness of Stimpaks and healing.",id:6,name:"Medicine",value:0},{description:"Damage with melee weapons.",id:7,name:"Melee Weapons",value:0},{description:"Ability to maintain and repair items.",id:8,name:"Repair",value:0},{description:"Ability to hack terminals and use tech.",id:9,name:"Science",value:0},{description:"Accuracy and damage with small firearms.",id:10,name:"Small Guns",value:0},{description:"Ability to remain undetected.",id:11,name:"Sneak",value:0},{description:"Effectiveness in dialogue and persuasion.",id:12,name:"Speech",value:0},{description:"Damage with fists and unarmed weapons.",id:13,name:"Unarmed",value:0}],A=[{description:"Affects how much you can carry and the damage you do with melee attacks.",id:7,name:"Strength",short:"STR",value:5},{description:"Affects your ability to notice things and your accuracy in VATS.",id:6,name:"Perception",short:"PER",value:5},{description:"Affects your total Health and resistance to physical punishment over time.",id:3,name:"Endurance",short:"END",value:5},{description:"Affects your speech skills and how people react to you in conversation.",id:2,name:"Charisma",short:"CHA",value:5},{description:"Affects how many skill points you gain when leveling up.",id:4,name:"Intelligence",short:"INT",value:5},{description:"Affects your Action Points and your ability to sneak and avoid detection.",id:1,name:"Agility",short:"AGI",value:5},{description:"Affects many things in small ways, and helps you succeed at random chances.",id:5,name:"Luck",short:"LCK",value:5}],E=[{damage:6,health:100,name:".32 Pistol",value:110,weight:2},{damage:9e3,health:1e3,name:".44 Magnum",value:0,weight:3},{damage:9,health:150,name:"10mm Pistol",value:225,weight:3},{damage:9,health:150,name:"10mm Pistol",value:30,weight:2},{damage:100,health:150,name:"10mm Pistol",value:43590,weight:2},{damage:7,health:250,name:"10mm Submachine Gun",value:330,weight:5},{damage:50,health:1200,name:"A3-21's Plasma Rifle",value:2200,weight:8},{damage:40,health:100,name:"Acid Spit",value:80,weight:1},{damage:70,health:100,name:"Acid Spit",value:130,weight:1},{damage:100,health:500,name:"Alien Blaster",value:500,weight:2},{damage:4,health:250,name:"Ant's Sting",value:30,weight:1},{damage:8,health:300,name:"Assault Rifle",value:300,weight:7},{damage:9,health:400,name:"Baseball Bat",value:55,weight:3},{damage:6,health:5,name:"Baseball",value:10,weight:4},{damage:4,health:50,name:"BB Gun",value:36,weight:2},{damage:4,health:1e3,name:"BB Gun",value:36,weight:2},{damage:8,health:100,name:"Black Bart's Bane",value:60,weight:2},{damage:55,health:360,name:"Blackhawk",value:500,weight:4},{damage:5,health:100,name:"",value:20,weight:1},{damage:12,health:150,name:"Board of Education",value:60,weight:4},{damage:1,health:5,name:"Bottlecap Mine",value:75,weight:.5},{damage:6,health:200,name:"Brass Knuckles",value:20,weight:1},{damage:12,health:150,name:"Breaker",value:30,weight:4},{damage:24,health:200,name:"Burnmaster",value:500,weight:15},{damage:10,health:150,name:"Butch's Toothpick",value:50,weight:1},{damage:20,health:100,name:"Buzzsaw",value:250,weight:1},{damage:11,health:400,name:"Chinese Assault Rifle",value:500,weight:7},{damage:11,health:200,name:"Chinese Assault Rifle",value:340,weight:7},{damage:10,health:500,name:"Chinese Officer's Sword",value:75,weight:3},{damage:10,health:500,name:"Chinese Officer's Sword",value:75,weight:3},{damage:4,health:150,name:"Chinese Pistol",value:190,weight:2},{damage:15,health:500,name:"Clover's Cleaver",value:100,weight:3},{damage:13,health:225,name:"Col. Autumn's 10mm Pistol",value:325,weight:3},{damage:10,health:500,name:"Col. Autumn's Laser Pistol",value:420,weight:2},{damage:7,health:450,name:"Combat Knife",value:50,weight:1},{damage:7,health:450,name:"Combat Knife",value:50,weight:1},{damage:55,health:240,name:"Combat Shotgun",value:200,weight:7},{damage:20,health:150,name:"Combat Shotgun",value:90,weight:10},{damage:55,health:150,name:"Combat Shotgun",value:70,weight:10},{damage:13,health:600,name:"Curse Breaker",value:75,weight:3},{damage:6,health:150,name:"Dart Gun",value:500,weight:3},{damage:20,health:600,name:"Deathclaw Gauntlet",value:150,weight:10},{damage:5,health:100,name:"Electrical Zap",value:110,weight:1},{damage:7,health:1500,name:"Eugene",value:1500,weight:18},{damage:13,health:600,name:"Excalibat",value:75,weight:3},{damage:10,health:300,name:"Experimental MIRV",value:2500,weight:30},{damage:10,health:100,name:"Fat Man",value:1e3,weight:30},{damage:32,health:1e3,name:"Fawkes' Super Sledge",value:300,weight:18},{damage:100,health:1e3,name:"Fire Hydrant",value:100,weight:300},{damage:80,health:200,name:"Firelance",value:750,weight:2},{damage:25,health:600,name:"Fisto!",value:100,weight:6},{damage:0,health:2,name:"",value:0,weight:0},{damage:16,health:200,name:"Flamer",value:500,weight:15},{damage:6,health:100,name:"Flamer",value:210,weight:1},{damage:2,health:100,name:"Flamer",value:30,weight:1},{damage:6,health:100,name:"Flamer",value:210,weight:1},{damage:4,health:100,name:"Flamer",value:60,weight:1},{damage:2,health:100,name:"Flamer",value:60,weight:1},{damage:6,health:100,name:"Flamer",value:60,weight:1},{damage:1,health:5,name:"Frag Grenade",value:25,weight:.5},{damage:1,health:5,name:"Frag Mine",value:25,weight:.5},{damage:300,health:5,name:"Frag Mine",value:3900,weight:1},{damage:0,health:100,name:"GasTrap Dummy",value:0,weight:0},{damage:8,health:1500,name:"Gatling Laser",value:2e3,weight:18},{damage:9,health:1500,name:"Gatling Laser",value:611,weight:10},{damage:30,health:100,name:"Hand Laser",value:360,weight:1},{damage:30,health:100,name:"Head Laser",value:100,weight:1},{damage:10,health:500,name:"Highwayman's Friend",value:75,weight:5},{damage:25,health:500,name:"Hunting Rifle",value:150,weight:6},{damage:30,health:800,name:"Jack",value:200,weight:6},{damage:4,health:100,name:"Knife",value:20,weight:1},{damage:12,health:350,name:"Laser Pistol",value:320,weight:3},{damage:12,health:350,name:"Laser Pistol",value:320,weight:3},{damage:9,health:300,name:"Laser Pistol",value:420,weight:2},{damage:23,health:1e3,name:"Laser Rifle",value:1e3,weight:8},{damage:22,health:1e3,name:"Laser Rifle",value:1e3,weight:8},{damage:38,health:100,name:"Laser",value:1310,weight:1},{damage:8,health:50,name:"Laser",value:100,weight:1},{damage:9,health:100,name:"Laser",value:180,weight:1},{damage:10,health:150,name:"Laser",value:290,weight:1},{damage:9,health:150,name:"Law Dog",value:210,weight:2},{damage:9,health:300,name:"Lead Pipe",value:75,weight:3},{damage:1e3,health:100,name:"Liberty Laser",value:9674e3,weight:0},{damage:200,health:100,name:"LibertyPrimeWeapBomb",value:23730,weight:0},{damage:50,health:600,name:"Lincoln's Repeater",value:500,weight:5},{damage:8,health:100,name:"Love Tap",value:20,weight:1},{damage:1,health:100,name:"Mesmetron",value:500,weight:2},{damage:1,health:100,name:"Mesmetron",value:500,weight:2},{damage:5,health:1e3,name:"Minigun",value:1e3,weight:18},{damage:0,health:5,name:"Mirelurk Bait Grenade",value:5,weight:1},{damage:20,health:100,name:"Miss Launcher",value:400,weight:15},{damage:20,health:100,name:"Missile Launcher",value:500,weight:20},{damage:20,health:1e3,name:"Missile Launcher",value:4300,weight:15},{damage:8,health:60,name:"Nail Board",value:30,weight:4},{damage:8,health:60,name:"Nail Board",value:30,weight:4},{damage:1,health:5,name:"Nuka-Grenade",value:50,weight:.5},{damage:10,health:600,name:"Occam's Razor",value:65,weight:1},{damage:6,health:400,name:"O'Grady's Peacemaker",value:100,weight:2},{damage:30,health:500,name:"Ol' Painless",value:250,weight:6},{damage:1,health:5,name:"Plasma Grenade",value:50,weight:.5},{damage:60,health:400,name:"Plasma Gun",value:7200,weight:1},{damage:40,health:400,name:"Plasma Gun",value:7200,weight:1},{damage:1,health:5,name:"Plasma Mine",value:50,weight:.5},{damage:25,health:400,name:"Plasma Pistol",value:360,weight:3},{damage:45,health:900,name:"Plasma Rifle",value:1800,weight:8},{damage:12,health:200,name:"Plunkett's Valid Points",value:30,weight:1},{damage:4,health:250,name:"Police Baton",value:70,weight:2},{damage:3,health:50,name:"Pool Cue",value:15,weight:1},{damage:20,health:500,name:"Power Fist",value:100,weight:6},{damage:24,health:500,name:"Protectron's Gaze",value:320,weight:3},{damage:1,health:5,name:"Pulse Grenade",value:40,weight:.5},{damage:1,health:5,name:"Pulse Mine",value:40,weight:.5},{damage:30,health:1e3,name:"Radioactive Spit",value:130,weight:1},{damage:30,health:200,name:"Railway Rifle",value:200,weight:9},{damage:1,health:100,name:"Repellent Stick",value:120,weight:3},{damage:40,health:150,name:"Reservist's Rifle",value:500,weight:10},{damage:30,health:600,name:"Ripper",value:100,weight:6},{damage:50,health:300,name:"Rock-It Launcher",value:200,weight:8},{damage:20,health:100,name:"Rolling Pin",value:10,weight:2},{damage:3,health:100,name:"Rolling Pin",value:10,weight:1},{damage:20,health:100,name:"",value:500,weight:20},{damage:50,health:250,name:"Sawed-Off Shotgun",value:150,weight:4},{damage:50,health:100,name:"Sawed-Off Shotgun",value:190,weight:5},{damage:35,health:240,name:"Scoped .44 Magnum",value:300,weight:4},{damage:6,health:1e3,name:"SentryBot Laser Gatling",value:1070,weight:15},{damage:9,health:1e3,name:"SentryBot Minigun",value:1070,weight:15},{damage:35,health:750,name:"Shishkebab",value:200,weight:3},{damage:10,health:100,name:"Shriek",value:40,weight:1},{damage:8,health:80,name:"Silenced 10mm Pistol",value:250,weight:3},{damage:50,health:1e3,name:"Slasher Knife",value:50,weight:1},{damage:20,health:500,name:"Sledgehammer",value:130,weight:12},{damage:20,health:500,name:"Sledgehammer",value:130,weight:12},{damage:18,health:500,name:"Smuggler's End",value:450,weight:2},{damage:40,health:100,name:"Sniper Rifle",value:300,weight:10},{damage:9,health:300,name:"Spiked Knuckles",value:25,weight:1},{damage:10,health:600,name:"Stabhappy",value:65,weight:1},{damage:25,health:750,name:"Super Sledge",value:180,weight:20},{damage:25,health:250,name:"Super Sledge",value:130,weight:3},{damage:5,health:100,name:"Switchblade",value:35,weight:1},{damage:5,health:100,name:"Switchblade",value:50,weight:1},{damage:9,health:250,name:'Sydney\'s 10mm "Ultra" SMG',value:430,weight:5},{damage:9,health:250,name:'Sydney\'s 10mm "Ultra" SMG',value:430,weight:5},{damage:6,health:200,name:"The Break",value:50,weight:1},{damage:75,health:250,name:"The Kneecapper",value:350,weight:5},{damage:20,health:400,name:"The Shocker",value:150,weight:6},{damage:30,health:750,name:"The Tenderizer",value:230,weight:12},{damage:80,health:350,name:"The Terrible Shotgun",value:250,weight:10},{damage:6,health:200,name:"Tire Iron",value:40,weight:3},{damage:7,health:150,name:"Turret Gun",value:230,weight:7},{damage:10,health:150,name:"Turret Gun",value:370,weight:7},{damage:5,health:150,name:"Turret Gun",value:140,weight:7},{damage:15,health:750,name:"Vampire's Edge",value:100,weight:1},{damage:11,health:2e3,name:"Vengeance",value:2400,weight:18},{damage:10,health:30,name:"Vertibird Bomb Gun",value:1e3,weight:30},{damage:20,health:3e3,name:"Vertibird Gun",value:6040,weight:10},{damage:40,health:300,name:"Victory Rifle",value:450,weight:10},{damage:12,health:450,name:"Wanda",value:500,weight:7},{damage:28,health:1800,name:"Wazer Wifle",value:900,weight:8},{damage:12,health:400,name:"Xuanlong Assault Rifle",value:400,weight:7},{damage:4,health:200,name:"Zhu-Rong v418 Chinese Pistol",value:290,weight:2}],N="1.3.0",P=new s("PipBoy3000SettingsConfig"),T=e=>e.map(e=>({id:e.id,name:e.name,description:e.description,value:e.value,imageId:e.imageId}));class C{constructor(){this.loadFromLocalStorage(),r(()=>{this.userLevel(),this.userHealth(),this.userHealthMax(),this.userActionPoints(),this.userActionPointsMax(),this.userExperience(),this.userExperienceNextLevel(),this.userName(),this.stimpakLabel(),this.limbLabel(),this.radAwayLabel(),this.radXLabel(),this.equippedWeaponId(),this.equippedApparelId(),this.equippedAidId(),this.equippedMiscId(),this.equippedAmmoId(),this.weaponItems(),this.apparelItems(),this.aidItems(),this.miscItems(),this.ammoItems(),this.specialItems(),this.skillItems(),this.perkItems(),this.questItems(),this.generalItems(),this.notesItems(),this.radioItems(),this.selectedNotesItemId(),this.selectedRadioItemId(),this.effectItems(),this.radMeterLevel(),this.h20MeterLevel(),this.fodMeterLevel(),this.slpMeterLevel(),this.localMapImage(),this.worldMapImage(),this.radioVolume(),this.notesVolume(),this.localMapZoom(),this.worldMapZoom(),this.vaultBoyImages(),this.selectedVaultBoyImageIndex(),this.scanLinesEnabled(),this.editLockEnabled(),this.listFontScale(),this.secondaryTabSoundId(),this.mainTabSoundId(),this.clickSoundId(),this.bootVideoId(),this.rememberTabOnRefresh(),this.saveToLocalStorage()})}settingsConfig=l(P,{optional:!0});storageKey=this.settingsConfig?.storageKey??"pipBoy3000Settings";imageStore=l(k);userLevel=o(1,...ngDevMode?[{debugName:"userLevel"}]:[]);userHealth=o(99,...ngDevMode?[{debugName:"userHealth"}]:[]);userHealthMax=o(100,...ngDevMode?[{debugName:"userHealthMax"}]:[]);userActionPoints=o(50,...ngDevMode?[{debugName:"userActionPoints"}]:[]);userActionPointsMax=o(100,...ngDevMode?[{debugName:"userActionPointsMax"}]:[]);userExperience=o(1,...ngDevMode?[{debugName:"userExperience"}]:[]);userExperienceNextLevel=o(100,...ngDevMode?[{debugName:"userExperienceNextLevel"}]:[]);userName=o("Vault Dweller",...ngDevMode?[{debugName:"userName"}]:[]);stimpakLabel=o("(4) Stimpak",...ngDevMode?[{debugName:"stimpakLabel"}]:[]);limbLabel=o("Limbs",...ngDevMode?[{debugName:"limbLabel"}]:[]);radAwayLabel=o("RadAway",...ngDevMode?[{debugName:"radAwayLabel"}]:[]);radXLabel=o("Rad-X",...ngDevMode?[{debugName:"radXLabel"}]:[]);equippedWeaponId=o(null,...ngDevMode?[{debugName:"equippedWeaponId"}]:[]);equippedApparelId=o(null,...ngDevMode?[{debugName:"equippedApparelId"}]:[]);equippedAidId=o(null,...ngDevMode?[{debugName:"equippedAidId"}]:[]);equippedMiscId=o(null,...ngDevMode?[{debugName:"equippedMiscId"}]:[]);equippedAmmoId=o(null,...ngDevMode?[{debugName:"equippedAmmoId"}]:[]);weaponItems=o(this.getWeaponDefaults(),...ngDevMode?[{debugName:"weaponItems"}]:[]);apparelItems=o(this.getApparelDefaults(),...ngDevMode?[{debugName:"apparelItems"}]:[]);aidItems=o(this.getAidDefaults(),...ngDevMode?[{debugName:"aidItems"}]:[]);miscItems=o(this.getMiscDefaults(),...ngDevMode?[{debugName:"miscItems"}]:[]);ammoItems=o(this.getAmmoDefaults(),...ngDevMode?[{debugName:"ammoItems"}]:[]);specialItems=o(T(A),...ngDevMode?[{debugName:"specialItems"}]:[]);skillItems=o(this.getSkillDefaults(),...ngDevMode?[{debugName:"skillItems"}]:[]);perkItems=o(this.getPerkDefaults(),...ngDevMode?[{debugName:"perkItems"}]:[]);generalItems=o([],...ngDevMode?[{debugName:"generalItems"}]:[]);questItems=o([{id:1,name:"Quest item",completed:!1,tasks:[{id:1,name:"Task 1",completed:!1},{id:2,name:"Task 2",completed:!1},{id:3,name:"Task 3",completed:!1}]}],...ngDevMode?[{debugName:"questItems"}]:[]);notesItems=o([],...ngDevMode?[{debugName:"notesItems"}]:[]);radioItems=o([],...ngDevMode?[{debugName:"radioItems"}]:[]);selectedNotesItemId=o(null,...ngDevMode?[{debugName:"selectedNotesItemId"}]:[]);selectedRadioItemId=o(null,...ngDevMode?[{debugName:"selectedRadioItemId"}]:[]);effectItems=o([],...ngDevMode?[{debugName:"effectItems"}]:[]);radMeterLevel=o(0,...ngDevMode?[{debugName:"radMeterLevel"}]:[]);h20MeterLevel=o(0,...ngDevMode?[{debugName:"h20MeterLevel"}]:[]);fodMeterLevel=o(0,...ngDevMode?[{debugName:"fodMeterLevel"}]:[]);slpMeterLevel=o(0,...ngDevMode?[{debugName:"slpMeterLevel"}]:[]);localMapImage=o(null,...ngDevMode?[{debugName:"localMapImage"}]:[]);worldMapImage=o(null,...ngDevMode?[{debugName:"worldMapImage"}]:[]);radioVolume=o(100,...ngDevMode?[{debugName:"radioVolume"}]:[]);notesVolume=o(100,...ngDevMode?[{debugName:"notesVolume"}]:[]);localMapZoom=o(1,...ngDevMode?[{debugName:"localMapZoom"}]:[]);worldMapZoom=o(1,...ngDevMode?[{debugName:"worldMapZoom"}]:[]);vaultBoyImages=o([null,null,null],...ngDevMode?[{debugName:"vaultBoyImages"}]:[]);selectedVaultBoyImageIndex=o(0,...ngDevMode?[{debugName:"selectedVaultBoyImageIndex"}]:[]);scanLinesEnabled=o(!0,...ngDevMode?[{debugName:"scanLinesEnabled"}]:[]);editLockEnabled=o(!1,...ngDevMode?[{debugName:"editLockEnabled"}]:[]);listFontScale=o(1.25,...ngDevMode?[{debugName:"listFontScale"}]:[]);secondaryTabSoundId=o(null,...ngDevMode?[{debugName:"secondaryTabSoundId"}]:[]);mainTabSoundId=o(null,...ngDevMode?[{debugName:"mainTabSoundId"}]:[]);clickSoundId=o(null,...ngDevMode?[{debugName:"clickSoundId"}]:[]);bootVideoId=o(null,...ngDevMode?[{debugName:"bootVideoId"}]:[]);rememberTabOnRefresh=o(!1,...ngDevMode?[{debugName:"rememberTabOnRefresh"}]:[]);playbackResetToken=o(0,...ngDevMode?[{debugName:"playbackResetToken"}]:[]);exportSettingsSnapshot(){return{userLevel:this.userLevel(),userHealth:this.userHealth(),userHealthMax:this.userHealthMax(),userActionPoints:this.userActionPoints(),userActionPointsMax:this.userActionPointsMax(),userExperience:this.userExperience(),userExperienceNextLevel:this.userExperienceNextLevel(),userName:this.userName(),stimpakLabel:this.stimpakLabel(),limbLabel:this.limbLabel(),radAwayLabel:this.radAwayLabel(),radXLabel:this.radXLabel(),equippedWeaponId:this.equippedWeaponId(),equippedApparelId:this.equippedApparelId(),equippedAidId:this.equippedAidId(),equippedMiscId:this.equippedMiscId(),equippedAmmoId:this.equippedAmmoId(),weaponItems:this.weaponItems(),apparelItems:this.apparelItems(),aidItems:this.aidItems(),miscItems:this.miscItems(),ammoItems:this.ammoItems(),specialItems:this.specialItems(),skillItems:this.skillItems(),perkItems:this.perkItems(),questItems:this.questItems(),generalItems:this.generalItems(),notesItems:this.notesItems(),radioItems:this.radioItems(),selectedNotesItemId:this.selectedNotesItemId(),selectedRadioItemId:this.selectedRadioItemId(),effectItems:this.effectItems(),radMeterLevel:this.radMeterLevel(),h20MeterLevel:this.h20MeterLevel(),fodMeterLevel:this.fodMeterLevel(),slpMeterLevel:this.slpMeterLevel(),localMapImage:this.localMapImage(),worldMapImage:this.worldMapImage(),radioVolume:this.radioVolume(),notesVolume:this.notesVolume(),localMapZoom:this.localMapZoom(),worldMapZoom:this.worldMapZoom(),vaultBoyImages:this.vaultBoyImages(),selectedVaultBoyImageIndex:this.selectedVaultBoyImageIndex(),scanLinesEnabled:this.scanLinesEnabled(),editLockEnabled:this.editLockEnabled(),listFontScale:this.listFontScale(),secondaryTabSoundId:this.secondaryTabSoundId(),mainTabSoundId:this.mainTabSoundId(),clickSoundId:this.clickSoundId(),bootVideoId:this.bootVideoId(),rememberTabOnRefresh:this.rememberTabOnRefresh()}}exportSettingsJson(){return JSON.stringify(this.exportSettingsSnapshot())}importSettingsJson(e){const t=JSON.parse(e);this.importSettingsSnapshot(t)}importSettingsSnapshot(e){if(this.setNumberSignal(this.userLevel,e.userLevel),this.setNumberSignal(this.userHealth,e.userHealth),this.setNumberSignal(this.userHealthMax,e.userHealthMax),this.setNumberSignal(this.userActionPoints,e.userActionPoints),this.setNumberSignal(this.userActionPointsMax,e.userActionPointsMax),this.setNumberSignal(this.userExperience,e.userExperience),this.setNumberSignal(this.userExperienceNextLevel,e.userExperienceNextLevel),"string"==typeof e.userName&&this.userName.set(e.userName),"string"==typeof e.stimpakLabel&&this.stimpakLabel.set(e.stimpakLabel),"string"==typeof e.limbLabel&&this.limbLabel.set(e.limbLabel),"string"==typeof e.radAwayLabel&&this.radAwayLabel.set(e.radAwayLabel),"string"==typeof e.radXLabel&&this.radXLabel.set(e.radXLabel),"number"==typeof e.equippedWeaponId?this.equippedWeaponId.set(e.equippedWeaponId):null===e.equippedWeaponId&&this.equippedWeaponId.set(null),"number"==typeof e.equippedApparelId?this.equippedApparelId.set(e.equippedApparelId):null===e.equippedApparelId&&this.equippedApparelId.set(null),"number"==typeof e.equippedAidId?this.equippedAidId.set(e.equippedAidId):null===e.equippedAidId&&this.equippedAidId.set(null),"number"==typeof e.equippedMiscId?this.equippedMiscId.set(e.equippedMiscId):null===e.equippedMiscId&&this.equippedMiscId.set(null),"number"==typeof e.equippedAmmoId?this.equippedAmmoId.set(e.equippedAmmoId):null===e.equippedAmmoId&&this.equippedAmmoId.set(null),this.weaponItems.set(this.normalizeItems(e.weaponItems)),this.apparelItems.set(this.normalizeItems(e.apparelItems)),this.aidItems.set(this.normalizeItems(e.aidItems)),this.miscItems.set(this.normalizeItems(e.miscItems)),this.ammoItems.set(this.normalizeItems(e.ammoItems)),this.specialItems.set(this.normalizeStatItems(e.specialItems,T(A))),this.skillItems.set(this.normalizeStatItems(e.skillItems,T(D))),this.perkItems.set(this.normalizeStatItems(e.perkItems,T(R))),this.generalItems.set(this.normalizeStatItems(e.generalItems,[])),this.questItems.set(this.normalizeQuestItems(e.questItems)),this.notesItems.set(this.normalizeAudioItems(e.notesItems)),this.radioItems.set(this.normalizeAudioItems(e.radioItems)),"number"==typeof e.selectedNotesItemId?this.selectedNotesItemId.set(e.selectedNotesItemId):null===e.selectedNotesItemId&&this.selectedNotesItemId.set(null),"number"==typeof e.selectedRadioItemId?this.selectedRadioItemId.set(e.selectedRadioItemId):null===e.selectedRadioItemId&&this.selectedRadioItemId.set(null),this.effectItems.set(this.normalizeEffectItems(e.effectItems)),"number"==typeof e.radMeterLevel&&this.setUnitSignal(this.radMeterLevel,e.radMeterLevel),"number"==typeof e.h20MeterLevel&&this.setUnitSignal(this.h20MeterLevel,e.h20MeterLevel),"number"==typeof e.fodMeterLevel&&this.setUnitSignal(this.fodMeterLevel,e.fodMeterLevel),"number"==typeof e.slpMeterLevel&&this.setUnitSignal(this.slpMeterLevel,e.slpMeterLevel),"string"==typeof e.localMapImage?this.localMapImage.set(this.normalizeImageId(e.localMapImage)??null):null===e.localMapImage&&this.localMapImage.set(null),"string"==typeof e.worldMapImage?this.worldMapImage.set(this.normalizeImageId(e.worldMapImage)??null):null===e.worldMapImage&&this.worldMapImage.set(null),"number"==typeof e.radioVolume&&this.setVolumeSignal(this.radioVolume,e.radioVolume),"number"==typeof e.notesVolume&&this.setVolumeSignal(this.notesVolume,e.notesVolume),"number"==typeof e.localMapZoom&&this.setZoomSignal(this.localMapZoom,e.localMapZoom),"number"==typeof e.worldMapZoom&&this.setZoomSignal(this.worldMapZoom,e.worldMapZoom),Array.isArray(e.vaultBoyImages)){const t=this.normalizeImageSlots(e.vaultBoyImages);if(this.vaultBoyImages.set(t),"number"==typeof e.selectedVaultBoyImageIndex&&Number.isFinite(e.selectedVaultBoyImageIndex)){const n=Math.min(Math.max(0,e.selectedVaultBoyImageIndex),Math.max(0,t.length-1));this.selectedVaultBoyImageIndex.set(n)}}if("boolean"==typeof e.scanLinesEnabled&&this.scanLinesEnabled.set(e.scanLinesEnabled),"boolean"==typeof e.editLockEnabled&&this.editLockEnabled.set(e.editLockEnabled),"number"==typeof e.listFontScale){const t=Math.min(1.875,Math.max(.625,e.listFontScale));Number.isFinite(t)&&this.listFontScale.set(t)}"string"==typeof e.secondaryTabSoundId?this.secondaryTabSoundId.set(e.secondaryTabSoundId):null===e.secondaryTabSoundId&&this.secondaryTabSoundId.set(null),"string"==typeof e.mainTabSoundId?this.mainTabSoundId.set(e.mainTabSoundId):null===e.mainTabSoundId&&this.mainTabSoundId.set(null),"string"==typeof e.clickSoundId?this.clickSoundId.set(e.clickSoundId):null===e.clickSoundId&&this.clickSoundId.set(null),"string"==typeof e.bootVideoId?this.bootVideoId.set(e.bootVideoId):null===e.bootVideoId&&this.bootVideoId.set(null),"boolean"==typeof e.rememberTabOnRefresh&&this.rememberTabOnRefresh.set(e.rememberTabOnRefresh),this.playbackResetToken.update(e=>e+1)}saveToLocalStorage(e){if("undefined"==typeof localStorage)return;const t=e??this.storageKey;localStorage.setItem(t,this.exportSettingsJson())}loadFromLocalStorage(e){if("undefined"==typeof localStorage)return;const t=e??this.storageKey,n=localStorage.getItem(t);n&&this.importSettingsJson(n)}resetToDefaults(){this.userLevel.set(1),this.userHealth.set(99),this.userHealthMax.set(100),this.userActionPoints.set(50),this.userActionPointsMax.set(100),this.userExperience.set(1),this.userExperienceNextLevel.set(100),this.userName.set("Vault Dweller"),this.stimpakLabel.set("(4) Stimpak"),this.limbLabel.set("Limbs"),this.radAwayLabel.set("RadAway"),this.radXLabel.set("Rad-X"),this.equippedWeaponId.set(null),this.equippedApparelId.set(null),this.equippedAidId.set(null),this.equippedMiscId.set(null),this.equippedAmmoId.set(null),this.weaponItems.set(this.getWeaponDefaults()),this.apparelItems.set(this.getApparelDefaults()),this.aidItems.set(this.getAidDefaults()),this.miscItems.set(this.getMiscDefaults()),this.ammoItems.set(this.getAmmoDefaults()),this.specialItems.set(T(A)),this.skillItems.set(this.getSkillDefaults()),this.perkItems.set(this.getPerkDefaults()),this.generalItems.set([]),this.questItems.set([{id:1,name:"Quest item",completed:!1,tasks:[{id:1,name:"Task 1",completed:!1},{id:2,name:"Task 2",completed:!1},{id:3,name:"Task 3",completed:!1}]}]),this.notesItems.set([]),this.radioItems.set([]),this.selectedNotesItemId.set(null),this.selectedRadioItemId.set(null),this.effectItems.set([]),this.radMeterLevel.set(0),this.h20MeterLevel.set(0),this.fodMeterLevel.set(0),this.slpMeterLevel.set(0),this.localMapImage.set(null),this.worldMapImage.set(null),this.radioVolume.set(100),this.notesVolume.set(100),this.localMapZoom.set(1),this.worldMapZoom.set(1),this.vaultBoyImages.set([null,null,null]),this.selectedVaultBoyImageIndex.set(0),this.scanLinesEnabled.set(!0),this.editLockEnabled.set(!1),this.listFontScale.set(1.25),this.secondaryTabSoundId.set(null),this.mainTabSoundId.set(null),this.clickSoundId.set(null),this.bootVideoId.set(null),this.rememberTabOnRefresh.set(!1),this.playbackResetToken.update(e=>e+1)}getSkillDefaults(){const e=this.settingsConfig?.skillDefaults??D;return T(e)}getPerkDefaults(){const e=this.settingsConfig?.perkDefaults??R;return T(e)}getWeaponDefaults(){return(this.settingsConfig?.weaponDefaults??[]).map(e=>({...e}))}getApparelDefaults(){return(this.settingsConfig?.apparelDefaults??[]).map(e=>({...e}))}getAidDefaults(){return(this.settingsConfig?.aidDefaults??[]).map(e=>({...e}))}getMiscDefaults(){return(this.settingsConfig?.miscDefaults??[]).map(e=>({...e}))}getAmmoDefaults(){return(this.settingsConfig?.ammoDefaults??[]).map(e=>({...e}))}setNumberSignal(e,t){"number"==typeof t&&Number.isFinite(t)&&e.set(t)}setZoomSignal(e,t){if(!Number.isFinite(t))return;const n=Math.min(3,Math.max(.5,t));e.set(Number(n.toFixed(2)))}setVolumeSignal(e,t){if(!Number.isFinite(t))return;const n=Math.min(100,Math.max(0,t));e.set(Number(n.toFixed(0)))}setUnitSignal(e,t){if(!Number.isFinite(t))return;const n=Math.min(1,Math.max(0,t));e.set(Number(n.toFixed(2)))}normalizeItems(e){return Array.isArray(e)?e.filter(e=>!!e&&"number"==typeof e.id&&"string"==typeof e.name).map(e=>({id:e.id,name:e.name,damage:"number"==typeof e.damage&&Number.isFinite(e.damage)?e.damage:void 0,imageId:this.normalizeImageId(e.imageId??e.image),effects:"string"==typeof e.effects?e.effects:void 0,quantity:"number"==typeof e.quantity&&Number.isFinite(e.quantity)?e.quantity:void 0,value:"number"==typeof e.value&&Number.isFinite(e.value)?e.value:void 0,weight:"number"==typeof e.weight&&Number.isFinite(e.weight)?e.weight:void 0})):[]}normalizeStatItems(e,t){return Array.isArray(e)?e.filter(e=>!!e&&"number"==typeof e.id&&"string"==typeof e.name&&"string"==typeof e.description&&"number"==typeof e.value&&Number.isFinite(e.value)).map(e=>({id:e.id,name:e.name,description:e.description,value:e.value,imageId:this.normalizeImageId(e.imageId??e.image)})):t}normalizeAudioItems(e){return Array.isArray(e)?e.filter(e=>!!e&&"number"==typeof e.id&&"string"==typeof e.name&&"string"==typeof e.soundId).map(e=>({id:e.id,name:e.name,soundId:e.soundId})):[]}normalizeEffectItems(e){return Array.isArray(e)?e.filter(e=>!!e&&"number"==typeof e.id&&"string"==typeof e.name&&"string"==typeof e.description).map(e=>({id:e.id,name:e.name,description:e.description})):[]}normalizeQuestItems(e){return Array.isArray(e)?e.filter(e=>!!e&&"number"==typeof e.id&&"string"==typeof e.name&&"boolean"==typeof e.completed&&Array.isArray(e.tasks)).map(e=>({id:e.id,name:e.name,completed:e.completed,tasks:e.tasks.filter(e=>!!e&&"number"==typeof e.id&&"string"==typeof e.name&&"boolean"==typeof e.completed).map(e=>({id:e.id,name:e.name,completed:e.completed}))})):[]}normalizeImageSlots(e){if(!Array.isArray(e))return[];return e.map(e=>"string"!=typeof e?null:this.normalizeImageId(e)??null).slice(0,10)}normalizeImageId(e){if("string"==typeof e){if(e.startsWith("data:")){const t=this.imageStore.generateId();return this.imageStore.saveDataUrlWithId(t,e),t}return e}}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:C,deps:[],target:e.ɵɵFactoryTarget.Injectable});static"ɵprov"=e.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:C,providedIn:"root"})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:C,decorators:[{type:i,args:[{providedIn:"root"}]}],ctorParameters:()=>[]});const V="pipBoy3000TabState",z=["STATS","ITEMS","DATA"],O=["STATUS","S.P.E.C.I.A.L.","SKILLS","PERKS","GENERAL"],F=["WEAPONS","APPAREL","AID","MISC","AMMO"],q=["LOCAL MAP","WORLD MAP","QUESTS","NOTES","RADIO"],B=["CND","RAD","EFF","H20","FOD","SLP"];class W{constructor(){this.loadFromStorage(),r(()=>{this.primary(),this.secondary(),this.tertiary(),this.saveToStorage()})}primary=o("STATS",...ngDevMode?[{debugName:"primary"}]:[]);secondary=o("STATUS",...ngDevMode?[{debugName:"secondary"}]:[]);tertiary=o("CND",...ngDevMode?[{debugName:"tertiary"}]:[]);settings=l(C);selectPrimary(e){if(this.primary()!==e)switch(this.primary.set(e),e){case"STATS":this.secondary.set("STATUS"),this.tertiary.set("CND");break;case"ITEMS":this.secondary.set("WEAPONS"),this.tertiary.set(null);break;case"DATA":this.secondary.set("LOCAL MAP"),this.tertiary.set(null);break;default:throw new Error(`Unhandled primary tab selection: ${e}`)}}selectSecondary(e){this.secondary.set(e),"STATS"!==this.primary()||"STATUS"!==e?this.tertiary.set(null):null===this.tertiary()&&this.tertiary.set("CND")}selectTertiary(e){"STATS"===this.primary()&&"STATUS"===this.secondary()&&this.tertiary.set(e)}saveToStorage(){if("undefined"==typeof localStorage)return;if(!this.settings.rememberTabOnRefresh())return;const e={primary:this.primary(),secondary:this.secondary(),tertiary:this.tertiary()};localStorage.setItem(V,JSON.stringify(e))}loadFromStorage(){if("undefined"==typeof localStorage)return;if(!this.settings.rememberTabOnRefresh())return;const e=localStorage.getItem(V);if(e)try{const t=JSON.parse(e),n=t.primary&&z.includes(t.primary)?t.primary:"STATS";let a=null;a="STATS"===n?O.includes(t.secondary)?t.secondary:"STATUS":"ITEMS"===n?F.includes(t.secondary)?t.secondary:"WEAPONS":q.includes(t.secondary)?t.secondary:"LOCAL MAP";let o=null;"STATS"===n&&"STATUS"===a&&(o=B.includes(t.tertiary)?t.tertiary:"CND"),this.primary.set(n),this.secondary.set(a),this.tertiary.set(o)}catch{return}}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:W,deps:[],target:e.ɵɵFactoryTarget.Injectable});static"ɵprov"=e.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:W})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:W,decorators:[{type:i}],ctorParameters:()=>[]});class U{static nextId=0;dialogId="pip-boy-dialog-"+U.nextId++;open=t(!1,...ngDevMode?[{debugName:"open"}]:[]);title=t("Dialog",...ngDevMode?[{debugName:"title"}]:[]);subtitle=t(null,...ngDevMode?[{debugName:"subtitle"}]:[]);maxWidth=t("36rem",...ngDevMode?[{debugName:"maxWidth"}]:[]);width=t("92vw",...ngDevMode?[{debugName:"width"}]:[]);zIndex=t(110,...ngDevMode?[{debugName:"zIndex"}]:[]);closeOnBackdrop=t(!1,...ngDevMode?[{debugName:"closeOnBackdrop"}]:[]);closeResult=d();get titleId(){return`${this.dialogId}-title`}closeDialog(){this.closeResult.emit()}handleBackdropClick(){this.closeOnBackdrop()&&this.closeDialog()}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:U,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:U,isStandalone:!0,selector:"pip-boy-dialog",inputs:{open:{classPropertyName:"open",publicName:"open",isSignal:!0,isRequired:!1,transformFunction:null},title:{classPropertyName:"title",publicName:"title",isSignal:!0,isRequired:!1,transformFunction:null},subtitle:{classPropertyName:"subtitle",publicName:"subtitle",isSignal:!0,isRequired:!1,transformFunction:null},maxWidth:{classPropertyName:"maxWidth",publicName:"maxWidth",isSignal:!0,isRequired:!1,transformFunction:null},width:{classPropertyName:"width",publicName:"width",isSignal:!0,isRequired:!1,transformFunction:null},zIndex:{classPropertyName:"zIndex",publicName:"zIndex",isSignal:!0,isRequired:!1,transformFunction:null},closeOnBackdrop:{classPropertyName:"closeOnBackdrop",publicName:"closeOnBackdrop",isSignal:!0,isRequired:!1,transformFunction:null}},outputs:{closeResult:"closeResult"},ngImport:e,template:'@if (open()) {\n <div\n class="dialog-backdrop"\n [style.--dialog-z]="zIndex()"\n (click)="handleBackdropClick()"\n (keydown.escape)="closeDialog()"\n role="presentation"\n >\n <div\n class="dialog"\n role="dialog"\n aria-modal="true"\n [attr.aria-labelledby]="titleId"\n [style.--dialog-max-width]="maxWidth()"\n [style.--dialog-width]="width()"\n (click)="$event.stopPropagation()"\n (keydown.escape)="closeDialog()"\n tabindex="-1"\n >\n <header class="dialog__header">\n <div class="dialog__title-row">\n <div class="dialog__title" [id]="titleId">{{ title() }}</div>\n <ng-content select="[dialog-title-extra]"></ng-content>\n </div>\n @if (subtitle()) {\n <div class="dialog__subtitle">{{ subtitle() }}</div>\n }\n <ng-content select="[dialog-header]"></ng-content>\n </header>\n\n <div class="dialog__body">\n <ng-content></ng-content>\n </div>\n\n <footer class="dialog__actions">\n <ng-content select="[dialog-actions]"></ng-content>\n </footer>\n </div>\n </div>\n}\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{font-size:1rem}.dialog-backdrop{align-items:center;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);background:#0000009e;display:flex;inset:0;justify-content:center;padding:1rem;position:fixed;z-index:var(--dialog-z, 110)}.dialog{display:flex;flex-direction:column;overflow:hidden;margin:1rem;max-height:calc(100vh - 2rem);max-height:calc(100svh - 2rem);max-width:var(--dialog-max-width, 36rem);width:min(var(--dialog-width, 92vw),var(--dialog-max-width, 36rem));background:#062114f5;border:1px solid rgba(15,187,107,.42);border-radius:.9rem;box-shadow:0 0 34px #000000a6;color:#0fbb6b}.dialog:focus{outline:none}.dialog__header{padding:1.1rem 1.25rem .95rem;border-bottom:1px solid rgba(15,187,107,.18);background:linear-gradient(to bottom,#0fbb6b0f,#0fbb6b00)}.dialog__title-row{display:flex;align-items:baseline;gap:.5rem}.dialog__title{font-size:clamp(1.05rem,1.05rem + (1.3rem - 1.05rem) * (100vw - 360px) / (1200px - 360px),1.3rem);letter-spacing:.1em;text-transform:uppercase}.dialog__subtitle{margin-top:.35rem;color:#0fbb6bbf;font-size:clamp(.85rem,.85rem + (.95rem - .85rem) * (100vw - 360px) / (1200px - 360px),.95rem)}.dialog__body{flex:1 1 auto;min-height:0;overflow-y:auto;padding:1rem 1.25rem 0;margin-bottom:1rem;-webkit-overflow-scrolling:touch}.dialog__actions{display:flex;justify-content:flex-end;padding:.9rem 1.25rem 1.1rem;border-top:1px solid rgba(15,187,107,.12);background:#0000001f}:host ::ng-deep .dialog__actions [dialog-actions]{display:flex;justify-content:flex-end;gap:.5rem;width:100%}:host ::ng-deep .dialog__actions button{background:#0fbb6b0f;border:1px solid rgba(15,187,107,.5);border-radius:.6rem;color:#0fbb6b;cursor:pointer;padding:.55rem 1rem;text-transform:uppercase;letter-spacing:.08em}:host ::ng-deep .dialog__actions button:hover{border-color:#0fbb6b;background:#0fbb6b1f}\n"]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:U,decorators:[{type:a,args:[{selector:"pip-boy-dialog",standalone:!0,template:'@if (open()) {\n <div\n class="dialog-backdrop"\n [style.--dialog-z]="zIndex()"\n (click)="handleBackdropClick()"\n (keydown.escape)="closeDialog()"\n role="presentation"\n >\n <div\n class="dialog"\n role="dialog"\n aria-modal="true"\n [attr.aria-labelledby]="titleId"\n [style.--dialog-max-width]="maxWidth()"\n [style.--dialog-width]="width()"\n (click)="$event.stopPropagation()"\n (keydown.escape)="closeDialog()"\n tabindex="-1"\n >\n <header class="dialog__header">\n <div class="dialog__title-row">\n <div class="dialog__title" [id]="titleId">{{ title() }}</div>\n <ng-content select="[dialog-title-extra]"></ng-content>\n </div>\n @if (subtitle()) {\n <div class="dialog__subtitle">{{ subtitle() }}</div>\n }\n <ng-content select="[dialog-header]"></ng-content>\n </header>\n\n <div class="dialog__body">\n <ng-content></ng-content>\n </div>\n\n <footer class="dialog__actions">\n <ng-content select="[dialog-actions]"></ng-content>\n </footer>\n </div>\n </div>\n}\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{font-size:1rem}.dialog-backdrop{align-items:center;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);background:#0000009e;display:flex;inset:0;justify-content:center;padding:1rem;position:fixed;z-index:var(--dialog-z, 110)}.dialog{display:flex;flex-direction:column;overflow:hidden;margin:1rem;max-height:calc(100vh - 2rem);max-height:calc(100svh - 2rem);max-width:var(--dialog-max-width, 36rem);width:min(var(--dialog-width, 92vw),var(--dialog-max-width, 36rem));background:#062114f5;border:1px solid rgba(15,187,107,.42);border-radius:.9rem;box-shadow:0 0 34px #000000a6;color:#0fbb6b}.dialog:focus{outline:none}.dialog__header{padding:1.1rem 1.25rem .95rem;border-bottom:1px solid rgba(15,187,107,.18);background:linear-gradient(to bottom,#0fbb6b0f,#0fbb6b00)}.dialog__title-row{display:flex;align-items:baseline;gap:.5rem}.dialog__title{font-size:clamp(1.05rem,1.05rem + (1.3rem - 1.05rem) * (100vw - 360px) / (1200px - 360px),1.3rem);letter-spacing:.1em;text-transform:uppercase}.dialog__subtitle{margin-top:.35rem;color:#0fbb6bbf;font-size:clamp(.85rem,.85rem + (.95rem - .85rem) * (100vw - 360px) / (1200px - 360px),.95rem)}.dialog__body{flex:1 1 auto;min-height:0;overflow-y:auto;padding:1rem 1.25rem 0;margin-bottom:1rem;-webkit-overflow-scrolling:touch}.dialog__actions{display:flex;justify-content:flex-end;padding:.9rem 1.25rem 1.1rem;border-top:1px solid rgba(15,187,107,.12);background:#0000001f}:host ::ng-deep .dialog__actions [dialog-actions]{display:flex;justify-content:flex-end;gap:.5rem;width:100%}:host ::ng-deep .dialog__actions button{background:#0fbb6b0f;border:1px solid rgba(15,187,107,.5);border-radius:.6rem;color:#0fbb6b;cursor:pointer;padding:.55rem 1rem;text-transform:uppercase;letter-spacing:.08em}:host ::ng-deep .dialog__actions button:hover{border-color:#0fbb6b;background:#0fbb6b1f}\n"]}]}],propDecorators:{open:[{type:e.Input,args:[{isSignal:!0,alias:"open",required:!1}]}],title:[{type:e.Input,args:[{isSignal:!0,alias:"title",required:!1}]}],subtitle:[{type:e.Input,args:[{isSignal:!0,alias:"subtitle",required:!1}]}],maxWidth:[{type:e.Input,args:[{isSignal:!0,alias:"maxWidth",required:!1}]}],width:[{type:e.Input,args:[{isSignal:!0,alias:"width",required:!1}]}],zIndex:[{type:e.Input,args:[{isSignal:!0,alias:"zIndex",required:!1}]}],closeOnBackdrop:[{type:e.Input,args:[{isSignal:!0,alias:"closeOnBackdrop",required:!1}]}],closeResult:[{type:e.Output,args:["closeResult"]}]}});class _{static nextId=0;open=!1;title="";name="";nameLabel="Name";showName=!1;nameOptions=[];imageUrl=null;showImage=!1;fields=[];textFields=[];closeResult=new c;save=new c;nameChange=new c;values=o({},...ngDevMode?[{debugName:"values"}]:[]);draftName=o("",...ngDevMode?[{debugName:"draftName"}]:[]);draftImageUrl=o(null,...ngDevMode?[{debugName:"draftImageUrl"}]:[]);draftImageName=o(null,...ngDevMode?[{debugName:"draftImageName"}]:[]);draftImageFile=o(null,...ngDevMode?[{debugName:"draftImageFile"}]:[]);removedImage=o(!1,...ngDevMode?[{debugName:"removedImage"}]:[]);textValues=o({},...ngDevMode?[{debugName:"textValues"}]:[]);nameListId="stat-edit-name-"+_.nextId++;previewUrl=null;ngOnChanges(){if(this.open){this.draftName.set(this.name),this.draftImageUrl.set(this.imageUrl),this.draftImageName.set(null),this.draftImageFile.set(null),this.removedImage.set(!1),this.clearPreviewUrl();const e={};for(const t of this.fields)e[t.key]=t.value;this.values.set(e);const t={};for(const e of this.textFields)t[e.key]=e.value;this.textValues.set(t)}}closeModal(){this.clearPreviewUrl(),this.closeResult.emit()}updateName(e){this.draftName.set(e),this.nameChange.emit(e)}onImageSelected(e){const t=e.target,n=t.files?.[0]??null;this.draftImageName.set(n?n.name:null),n&&(this.removedImage.set(!1),this.draftImageFile.set(n),this.setPreviewUrl(URL.createObjectURL(n)),t.value="")}removeImage(){this.draftImageName.set(null),this.draftImageUrl.set(null),this.draftImageFile.set(null),this.removedImage.set(!0),this.clearPreviewUrl()}updateText(e,t){this.textValues.update(n=>({...n,[e]:t}))}onInput(e,t){const n=Number(t);this.values.update(t=>({...t,[e]:n}))}adjustFieldValue(e,t){const n=Number(this.values()[e]),a=Number.isFinite(n)?n+t:t;this.values.update(t=>({...t,[e]:a}))}submit(e){e?.preventDefault(),this.save.emit({name:this.draftName(),values:this.values(),imageFile:this.draftImageFile(),removeImage:this.removedImage(),textValues:this.textValues()}),this.clearPreviewUrl()}setPreviewUrl(e){this.clearPreviewUrl(),this.previewUrl=e,this.draftImageUrl.set(e)}clearPreviewUrl(){this.previewUrl&&(URL.revokeObjectURL(this.previewUrl),this.previewUrl=null)}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:_,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:_,isStandalone:!0,selector:"pip-boy-stat-edit-modal",inputs:{open:"open",title:"title",name:"name",nameLabel:"nameLabel",showName:"showName",nameOptions:"nameOptions",imageUrl:"imageUrl",showImage:"showImage",fields:"fields",textFields:"textFields"},outputs:{closeResult:"closeResult",save:"save",nameChange:"nameChange"},usesOnChanges:!0,ngImport:e,template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <form id="stat-edit-form" (submit)="submit($event)">\n <div class="stat-modal-body">\n @if (showName) {\n <label class="stat-modal-field">\n <span>{{ nameLabel }}</span>\n <input\n type="text"\n name="stat-name"\n [attr.list]="nameOptions.length ? nameListId : null"\n [value]="draftName()"\n (input)="updateName($any($event.target).value)"\n />\n </label>\n @if (nameOptions.length) {\n <datalist [id]="nameListId">\n @for (name of nameOptions; track name) {\n <option [value]="name"></option>\n }\n </datalist>\n }\n }\n @for (field of fields; track field.key) {\n <label class="stat-modal-field">\n <span>{{ field.label }}</span>\n <div class="number-input-row">\n <input\n type="number"\n inputmode="numeric"\n [attr.name]="\'stat-field-\' + field.key"\n [value]="values()[field.key]"\n (input)="onInput(field.key, $any($event.target).value)"\n />\n <div class="number-input-controls">\n <button\n type="button"\n class="number-input-control"\n aria-label="Increase value"\n (click)="adjustFieldValue(field.key, 1)"\n >\n &#8593;\n </button>\n <button\n type="button"\n class="number-input-control"\n aria-label="Decrease value"\n (click)="adjustFieldValue(field.key, -1)"\n >\n &#8595;\n </button>\n </div>\n </div>\n </label>\n }\n @for (field of textFields; track field.key) {\n <label class="stat-modal-field" [attr.for]="\'text-field-\' + field.key">\n <span>{{ field.label }}</span>\n @if (field.multiline) {\n <textarea\n [id]="\'text-field-\' + field.key"\n [attr.name]="\'text-field-\' + field.key"\n rows="4"\n [value]="textValues()[field.key]"\n (input)="updateText(field.key, $any($event.target).value)"\n ></textarea>\n } @else {\n <input\n [id]="\'text-field-\' + field.key"\n type="text"\n [attr.name]="\'text-field-\' + field.key"\n [value]="textValues()[field.key]"\n (input)="updateText(field.key, $any($event.target).value)"\n />\n }\n </label>\n }\n @if (showImage) {\n <div class="stat-modal-image">\n <button\n type="button"\n class="stat-modal-image-button"\n (click)="modalImageInput.click()"\n >\n {{ draftImageName() ? draftImageName() : \'Select Image\' }}\n </button>\n @if (draftImageUrl()) {\n <button\n type="button"\n class="stat-modal-image-remove"\n (click)="removeImage()"\n >\n Remove Image\n </button>\n }\n <input\n #modalImageInput\n type="file"\n accept="image/*"\n (change)="onImageSelected($event)"\n />\n @if (draftImageUrl()) {\n <img [src]="draftImageUrl()" alt="Item preview" />\n }\n </div>\n }\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="stat-edit-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.stat-modal-body{display:flex;flex-direction:column;gap:1rem}.stat-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.stat-modal-field input,.stat-modal-field textarea{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.stat-modal-field input:focus,.stat-modal-field textarea:focus{outline:none;border-color:#0fbb6b}.stat-modal-field input{height:2.5rem}.stat-modal-field textarea{min-height:6rem;resize:vertical;text-transform:none}.number-input-row{display:flex;align-items:stretch;gap:.5rem}.number-input-row input[type=number]{flex:1 1 auto;-moz-appearance:textfield}.number-input-row input[type=number]::-webkit-outer-spin-button,.number-input-row input[type=number]::-webkit-inner-spin-button{appearance:none;margin:0}.number-input-controls{display:flex;flex-direction:column;gap:.35rem}.number-input-control{flex:1 1 auto;background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.4rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);padding:.2rem .5rem;text-transform:uppercase}.number-input-control:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-modal-image{display:flex;flex-direction:column;gap:.75rem}.stat-modal-image input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.stat-modal-image img{border:1px solid rgba(15,187,107,.35);max-height:8rem;object-fit:contain;padding:.5rem}.stat-modal-image-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.stat-modal-image-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-modal-image-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.stat-modal-image-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"],dependencies:[{kind:"ngmodule",type:v},{kind:"component",type:U,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:_,decorators:[{type:a,args:[{selector:"pip-boy-stat-edit-modal",standalone:!0,imports:[v,U],template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <form id="stat-edit-form" (submit)="submit($event)">\n <div class="stat-modal-body">\n @if (showName) {\n <label class="stat-modal-field">\n <span>{{ nameLabel }}</span>\n <input\n type="text"\n name="stat-name"\n [attr.list]="nameOptions.length ? nameListId : null"\n [value]="draftName()"\n (input)="updateName($any($event.target).value)"\n />\n </label>\n @if (nameOptions.length) {\n <datalist [id]="nameListId">\n @for (name of nameOptions; track name) {\n <option [value]="name"></option>\n }\n </datalist>\n }\n }\n @for (field of fields; track field.key) {\n <label class="stat-modal-field">\n <span>{{ field.label }}</span>\n <div class="number-input-row">\n <input\n type="number"\n inputmode="numeric"\n [attr.name]="\'stat-field-\' + field.key"\n [value]="values()[field.key]"\n (input)="onInput(field.key, $any($event.target).value)"\n />\n <div class="number-input-controls">\n <button\n type="button"\n class="number-input-control"\n aria-label="Increase value"\n (click)="adjustFieldValue(field.key, 1)"\n >\n &#8593;\n </button>\n <button\n type="button"\n class="number-input-control"\n aria-label="Decrease value"\n (click)="adjustFieldValue(field.key, -1)"\n >\n &#8595;\n </button>\n </div>\n </div>\n </label>\n }\n @for (field of textFields; track field.key) {\n <label class="stat-modal-field" [attr.for]="\'text-field-\' + field.key">\n <span>{{ field.label }}</span>\n @if (field.multiline) {\n <textarea\n [id]="\'text-field-\' + field.key"\n [attr.name]="\'text-field-\' + field.key"\n rows="4"\n [value]="textValues()[field.key]"\n (input)="updateText(field.key, $any($event.target).value)"\n ></textarea>\n } @else {\n <input\n [id]="\'text-field-\' + field.key"\n type="text"\n [attr.name]="\'text-field-\' + field.key"\n [value]="textValues()[field.key]"\n (input)="updateText(field.key, $any($event.target).value)"\n />\n }\n </label>\n }\n @if (showImage) {\n <div class="stat-modal-image">\n <button\n type="button"\n class="stat-modal-image-button"\n (click)="modalImageInput.click()"\n >\n {{ draftImageName() ? draftImageName() : \'Select Image\' }}\n </button>\n @if (draftImageUrl()) {\n <button\n type="button"\n class="stat-modal-image-remove"\n (click)="removeImage()"\n >\n Remove Image\n </button>\n }\n <input\n #modalImageInput\n type="file"\n accept="image/*"\n (change)="onImageSelected($event)"\n />\n @if (draftImageUrl()) {\n <img [src]="draftImageUrl()" alt="Item preview" />\n }\n </div>\n }\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="stat-edit-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.stat-modal-body{display:flex;flex-direction:column;gap:1rem}.stat-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.stat-modal-field input,.stat-modal-field textarea{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.stat-modal-field input:focus,.stat-modal-field textarea:focus{outline:none;border-color:#0fbb6b}.stat-modal-field input{height:2.5rem}.stat-modal-field textarea{min-height:6rem;resize:vertical;text-transform:none}.number-input-row{display:flex;align-items:stretch;gap:.5rem}.number-input-row input[type=number]{flex:1 1 auto;-moz-appearance:textfield}.number-input-row input[type=number]::-webkit-outer-spin-button,.number-input-row input[type=number]::-webkit-inner-spin-button{appearance:none;margin:0}.number-input-controls{display:flex;flex-direction:column;gap:.35rem}.number-input-control{flex:1 1 auto;background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.4rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);padding:.2rem .5rem;text-transform:uppercase}.number-input-control:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-modal-image{display:flex;flex-direction:column;gap:.75rem}.stat-modal-image input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.stat-modal-image img{border:1px solid rgba(15,187,107,.35);max-height:8rem;object-fit:contain;padding:.5rem}.stat-modal-image-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.stat-modal-image-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-modal-image-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.stat-modal-image-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"]}]}],propDecorators:{open:[{type:m}],title:[{type:m}],name:[{type:m}],nameLabel:[{type:m}],showName:[{type:m}],nameOptions:[{type:m}],imageUrl:[{type:m}],showImage:[{type:m}],fields:[{type:m}],textFields:[{type:m}],closeResult:[{type:p}],save:[{type:p}],nameChange:[{type:p}]}});class H{state=l(W);settings=l(C);statModal=o(null,...ngDevMode?[{debugName:"statModal"}]:[]);statModalTitle=u(()=>{switch(this.statModal()){case"LVL":return"Edit Level";case"HP":return"Edit Health";case"AP":return"Edit Action Points";case"XP":return"Edit Experience";default:return""}},...ngDevMode?[{debugName:"statModalTitle"}]:[]);statModalFields=u(()=>{switch(this.statModal()){case"LVL":return[{key:"level",label:"Level",value:this.settings.userLevel()}];case"HP":return[{key:"current",label:"Current",value:this.settings.userHealth()},{key:"max",label:"Max",value:this.settings.userHealthMax()}];case"AP":return[{key:"current",label:"Current",value:this.settings.userActionPoints()},{key:"max",label:"Max",value:this.settings.userActionPointsMax()}];case"XP":return[{key:"current",label:"Current",value:this.settings.userExperience()},{key:"max",label:"Next Level",value:this.settings.userExperienceNextLevel()}];default:return[]}},...ngDevMode?[{debugName:"statModalFields"}]:[]);openStatModal(e){this.statModal.set(e)}closeStatModal(){this.statModal.set(null)}saveStatModal(e){const t=this.statModal();if(t){if("LVL"===t){const t=e.values.level;return Number.isFinite(t)&&this.settings.userLevel.set(t),void this.closeStatModal()}"HP"===t?this.applyPair(e.values,this.settings.userHealth,this.settings.userHealthMax):"AP"===t?this.applyPair(e.values,this.settings.userActionPoints,this.settings.userActionPointsMax):"XP"===t&&this.applyPair(e.values,this.settings.userExperience,this.settings.userExperienceNextLevel),this.closeStatModal()}}applyPair(e,t,n){Number.isFinite(e.current)&&t.set(e.current),Number.isFinite(e.max)&&n.set(e.max)}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:H,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:H,isStandalone:!0,selector:"pip-boy-3000-header",ngImport:e,template:'<header>\n <div class="header-top">\n <div class="main-title">\n <div class="main-title-left-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n <div class="main-title-text">\n @if (state.primary() === \'STATS\') {\n STATS\n } @else if (state.primary() === \'ITEMS\') {\n ITEMS\n } @else if (state.primary() === \'DATA\') {\n DATA\n }\n </div>\n <div class="main-title-right-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n </div>\n <div class="hp-title-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n <div class="ap-title-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n <div class="xp-title-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n </div>\n <div class="header-content">\n <button\n type="button"\n class="stats stat-button"\n (click)="openStatModal(\'LVL\')"\n >\n <span>LVL</span> {{ settings.userLevel() }}\n </button>\n <button type="button" class="hp stat-button" (click)="openStatModal(\'HP\')">\n <span>HP</span>\n <span>{{ settings.userHealth() }} / {{ settings.userHealthMax() }}</span>\n </button>\n <button type="button" class="ap stat-button" (click)="openStatModal(\'AP\')">\n <span>AP</span>\n {{ settings.userActionPoints() }} / {{ settings.userActionPointsMax() }}\n </button>\n <button type="button" class="xp stat-button" (click)="openStatModal(\'XP\')">\n <span>XP</span>\n {{ settings.userExperience() }} /\n {{ settings.userExperienceNextLevel() }}\n </button>\n </div>\n</header>\n<pip-boy-stat-edit-modal\n (closeResult)="closeStatModal()"\n (save)="saveStatModal($event)"\n [fields]="statModalFields()"\n [open]="statModal() !== null"\n [title]="statModalTitle()"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:50%;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}header{width:100%;box-sizing:border-box;display:flex;flex-direction:column;flex:0 0 auto;min-height:0;padding:0 1rem}header>.header-top,header>.header-content{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.25rem;padding:0}header>.header-top{height:2.25rem;align-items:center;text-transform:uppercase;overflow:visible}header>.header-top>.main-title{display:flex;align-items:center;justify-content:center;gap:.5rem;height:100%;overflow:visible}header>.header-top>.main-title>.main-title-left-line,header>.header-top>.main-title>.main-title-right-line{flex-grow:1;min-width:2rem;height:100%;position:relative;overflow:visible}header>.header-top>.main-title>.main-title-text{font-size:clamp(1.25rem,1.25rem + (1.5rem - 1.25rem) * (100vw - 360px) / (1200px - 360px),1.5rem);flex-grow:0;letter-spacing:.1em;white-space:nowrap;line-height:1}header>.header-top .main-title-left-line .bottom-half-line:before{left:0}header>.header-top .main-title-right-line .bottom-half-line:before{right:0}header>.header-top .hp-title-line,header>.header-top .ap-title-line,header>.header-top .xp-title-line{overflow:visible}header>.header-top .hp-title-line .bottom-half-line:before,header>.header-top .ap-title-line .bottom-half-line:before,header>.header-top .xp-title-line .bottom-half-line:before{right:0}header>.header-content{box-sizing:border-box;margin-top:-.5rem;font-size:calc(clamp(.9rem,.9rem + .2rem * (100vw - 360px) / 840px,1.1rem) * (1 + (var(--list-font-scale, 1) - 1) * .6))}header>.header-content>.stats,header>.header-content>.hp,header>.header-content>.ap,header>.header-content>.xp{display:flex;justify-content:flex-end;padding:0 1rem;gap:1rem}header>.header-content>.stat-button{align-items:center;background:transparent;border:none;color:inherit;cursor:pointer;font:inherit;text-align:right;text-transform:uppercase}header>.header-content>.stat-button:hover{background:#0fbb6b14}:host{font-size:inherit}\n'],dependencies:[{kind:"component",type:_,selector:"pip-boy-stat-edit-modal",inputs:["open","title","name","nameLabel","showName","nameOptions","imageUrl","showImage","fields","textFields"],outputs:["closeResult","save","nameChange"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:H,decorators:[{type:a,args:[{selector:"pip-boy-3000-header",standalone:!0,imports:[_],template:'<header>\n <div class="header-top">\n <div class="main-title">\n <div class="main-title-left-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n <div class="main-title-text">\n @if (state.primary() === \'STATS\') {\n STATS\n } @else if (state.primary() === \'ITEMS\') {\n ITEMS\n } @else if (state.primary() === \'DATA\') {\n DATA\n }\n </div>\n <div class="main-title-right-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n </div>\n <div class="hp-title-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n <div class="ap-title-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n <div class="xp-title-line center-line">\n <div class="bottom-half-line"></div>\n </div>\n </div>\n <div class="header-content">\n <button\n type="button"\n class="stats stat-button"\n (click)="openStatModal(\'LVL\')"\n >\n <span>LVL</span> {{ settings.userLevel() }}\n </button>\n <button type="button" class="hp stat-button" (click)="openStatModal(\'HP\')">\n <span>HP</span>\n <span>{{ settings.userHealth() }} / {{ settings.userHealthMax() }}</span>\n </button>\n <button type="button" class="ap stat-button" (click)="openStatModal(\'AP\')">\n <span>AP</span>\n {{ settings.userActionPoints() }} / {{ settings.userActionPointsMax() }}\n </button>\n <button type="button" class="xp stat-button" (click)="openStatModal(\'XP\')">\n <span>XP</span>\n {{ settings.userExperience() }} /\n {{ settings.userExperienceNextLevel() }}\n </button>\n </div>\n</header>\n<pip-boy-stat-edit-modal\n (closeResult)="closeStatModal()"\n (save)="saveStatModal($event)"\n [fields]="statModalFields()"\n [open]="statModal() !== null"\n [title]="statModalTitle()"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:50%;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}header{width:100%;box-sizing:border-box;display:flex;flex-direction:column;flex:0 0 auto;min-height:0;padding:0 1rem}header>.header-top,header>.header-content{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.25rem;padding:0}header>.header-top{height:2.25rem;align-items:center;text-transform:uppercase;overflow:visible}header>.header-top>.main-title{display:flex;align-items:center;justify-content:center;gap:.5rem;height:100%;overflow:visible}header>.header-top>.main-title>.main-title-left-line,header>.header-top>.main-title>.main-title-right-line{flex-grow:1;min-width:2rem;height:100%;position:relative;overflow:visible}header>.header-top>.main-title>.main-title-text{font-size:clamp(1.25rem,1.25rem + (1.5rem - 1.25rem) * (100vw - 360px) / (1200px - 360px),1.5rem);flex-grow:0;letter-spacing:.1em;white-space:nowrap;line-height:1}header>.header-top .main-title-left-line .bottom-half-line:before{left:0}header>.header-top .main-title-right-line .bottom-half-line:before{right:0}header>.header-top .hp-title-line,header>.header-top .ap-title-line,header>.header-top .xp-title-line{overflow:visible}header>.header-top .hp-title-line .bottom-half-line:before,header>.header-top .ap-title-line .bottom-half-line:before,header>.header-top .xp-title-line .bottom-half-line:before{right:0}header>.header-content{box-sizing:border-box;margin-top:-.5rem;font-size:calc(clamp(.9rem,.9rem + .2rem * (100vw - 360px) / 840px,1.1rem) * (1 + (var(--list-font-scale, 1) - 1) * .6))}header>.header-content>.stats,header>.header-content>.hp,header>.header-content>.ap,header>.header-content>.xp{display:flex;justify-content:flex-end;padding:0 1rem;gap:1rem}header>.header-content>.stat-button{align-items:center;background:transparent;border:none;color:inherit;cursor:pointer;font:inherit;text-align:right;text-transform:uppercase}header>.header-content>.stat-button:hover{background:#0fbb6b14}:host{font-size:inherit}\n']}]}]});class ${category="WEAPONS";settings=l(C);settingsConfig=l(P,{optional:!0});imageStore=l(k);showStatEditModal=o(!1,...ngDevMode?[{debugName:"showStatEditModal"}]:[]);editMode=o("EDIT",...ngDevMode?[{debugName:"editMode"}]:[]);modalName=o("",...ngDevMode?[{debugName:"modalName"}]:[]);modalImageId=o(null,...ngDevMode?[{debugName:"modalImageId"}]:[]);modalValues=o({damage:0,weight:0,value:0,quantity:0},...ngDevMode?[{debugName:"modalValues"}]:[]);modalTextValues=o({},...ngDevMode?[{debugName:"modalTextValues"}]:[]);selectedItem=u(()=>{const e=this.getEquippedId();return null===e?null:this.getItems().find(t=>t.id===e)??null},...ngDevMode?[{debugName:"selectedItem"}]:[]);itemNames=u(()=>{const e=this.getSourceNames();return Array.from(new Set(e)).sort()},...ngDevMode?[{debugName:"itemNames"}]:[]);editStatModalTitle=u(()=>{if("ADD"===this.editMode())return this.modalTitle();const e=this.selectedItem();return e?`Edit ${e.name}`:"Edit Stats"},...ngDevMode?[{debugName:"editStatModalTitle"}]:[]);statEditFields=u(()=>{const e=this.modalValues();switch(this.category){case"WEAPONS":return[{key:"damage",label:"Damage",value:e.damage??0},{key:"weight",label:"Weight",value:e.weight??0},{key:"value",label:"Value",value:e.value??0}];case"APPAREL":return[{key:"damage",label:"DR",value:e.damage??0},{key:"weight",label:"WG",value:e.weight??0},{key:"value",label:"VAL",value:e.value??0},{key:"quantity",label:"QTY",value:e.quantity??0}];default:return[{key:"weight",label:"WG",value:e.weight??0},{key:"value",label:"VAL",value:e.value??0},{key:"quantity",label:"QTY",value:e.quantity??0}]}},...ngDevMode?[{debugName:"statEditFields"}]:[]);textEditFields=u(()=>{const e=this.modalTextValues();return"AID"===this.category?[{key:"effects",label:"Effects",value:e.effects??"",multiline:!0}]:[]},...ngDevMode?[{debugName:"textEditFields"}]:[]);statRows=u(()=>{const e=this.selectedItem();return e?"WEAPONS"===this.category?[{key:"damage",label:"Damage",value:e.damage??"--"},{key:"weight",label:"Weight",value:e.weight??"--"},{key:"value",label:"Value",value:e.value??"--"}]:"APPAREL"===this.category?[{key:"damage",label:"DR",value:e.damage??"--"},{key:"weight",label:"WG",value:e.weight??"--"},{key:"value",label:"VAL",value:e.value??"--"}]:"AID"===this.category?[{key:"effects",label:"Effects",value:e.effects??"--"},{key:"weight",label:"WG",value:e.weight??"--"},{key:"value",label:"VAL",value:e.value??"--"}]:[{key:"weight",label:"WG",value:e.weight??"--"},{key:"value",label:"VAL",value:e.value??"--"}]:[]},...ngDevMode?[{debugName:"statRows"}]:[]);modalTitle=u(()=>{switch(this.category){case"WEAPONS":return"Add Weapon";case"APPAREL":return"Add Apparel";case"AID":return"Add Aid";case"MISC":return"Add Misc";case"AMMO":return"Add Ammo";default:return"Add Item"}},...ngDevMode?[{debugName:"modalTitle"}]:[]);openAddModal(){this.settings.editLockEnabled()||(this.editMode.set("ADD"),this.modalName.set(""),this.modalImageId.set(null),this.modalValues.set({damage:0,weight:0,value:0,quantity:this.defaultQuantity()}),this.modalTextValues.set({}),this.showStatEditModal.set(!0))}openStatEditModal(){if(this.settings.editLockEnabled())return;if(!this.selectedItem())return;const e=this.selectedItem();e&&(this.modalName.set(e.name),this.modalImageId.set(e.imageId??null),this.modalValues.set({damage:e.damage??0,weight:e.weight??0,value:e.value??0,quantity:this.normalizeQuantity(e.quantity)}),this.modalTextValues.set({effects:e.effects??""})),this.editMode.set("EDIT"),this.showStatEditModal.set(!0)}closeStatEditModal(){this.showStatEditModal.set(!1)}selectItem(e){const t=this.getEquippedId();this.setEquippedId(t===e?null:e)}async saveStatEditModal(e){const t=e.name?.trim()??"";if(!t)return;const n=this.selectedItem();let a;if(e.removeImage)a=void 0;else if(e.imageFile){const t=await this.imageStore.saveFile(e.imageFile);a=t.id}else a=n?.imageId;if("ADD"===this.editMode()){const n=this.supportsQuantity()?this.normalizeQuantity(e.values.quantity):void 0,o=this.getNextItemId();return this.updateItems(i=>[...i,{id:o,name:t,damage:this.normalizeStatValue(e.values.damage),weight:this.normalizeStatValue(e.values.weight),value:this.normalizeStatValue(e.values.value),imageId:a,effects:e.textValues?.effects,...this.supportsQuantity()?{quantity:n}:{}}]),this.setEquippedId(o),void this.closeStatEditModal()}const o=this.getEquippedId();null!==o&&(this.updateItems(n=>n.map(n=>n.id!==o?n:{...n,name:t,damage:this.normalizeStatValue(e.values.damage,n.damage),weight:this.normalizeStatValue(e.values.weight,n.weight),value:this.normalizeStatValue(e.values.value,n.value),imageId:a,...this.supportsQuantity()?{quantity:this.normalizeQuantity(e.values.quantity)}:{},effects:e.textValues?.effects??("AID"===this.category?n.effects:void 0)})),this.closeStatEditModal())}handleNameChange(e){if(this.modalName.set(e),"ADD"!==this.editMode())return;const t=this.getDefaultsForName(e);t&&("number"==typeof t.damage&&this.modalValues.set({...this.modalValues(),damage:t.damage}),"number"==typeof t.weight&&this.modalValues.set({...this.modalValues(),weight:t.weight}),"number"==typeof t.value&&this.modalValues.set({...this.modalValues(),value:t.value}),"string"==typeof t.effects&&this.modalTextValues.set({...this.modalTextValues(),effects:t.effects}))}dropSelected(){if(this.settings.editLockEnabled())return;const e=this.getEquippedId();null!==e&&(this.updateItems(t=>t.filter(t=>t.id!==e)),this.setEquippedId(null))}moveSelected(e){if(this.settings.editLockEnabled())return;const t=this.getEquippedId();null!==t&&this.updateItems(n=>{const a=n.findIndex(e=>e.id===t);if(-1===a)return n;const o=a+e;if(o<0||o>=n.length)return n;const i=n.slice(),[s]=i.splice(a,1);return i.splice(o,0,s),i})}displayItemName(e){const t="number"==typeof e.quantity&&Number.isFinite(e.quantity)?e.quantity:0;return this.supportsQuantity()&&t>1?`${e.name} (${t})`:e.name}getItems(){switch(this.category){case"WEAPONS":return this.settings.weaponItems();case"APPAREL":return this.settings.apparelItems();case"AID":return this.settings.aidItems();case"MISC":return this.settings.miscItems();case"AMMO":return this.settings.ammoItems();default:return[]}}updateItems(e){switch(this.category){case"WEAPONS":this.settings.weaponItems.update(t=>e(t));break;case"APPAREL":this.settings.apparelItems.update(t=>e(t));break;case"AID":this.settings.aidItems.update(t=>e(t));break;case"MISC":this.settings.miscItems.update(t=>e(t));break;case"AMMO":this.settings.ammoItems.update(t=>e(t))}}getEquippedId(){switch(this.category){case"WEAPONS":return this.settings.equippedWeaponId();case"APPAREL":return this.settings.equippedApparelId();case"AID":return this.settings.equippedAidId();case"MISC":return this.settings.equippedMiscId();case"AMMO":return this.settings.equippedAmmoId();default:return null}}setEquippedId(e){switch(this.category){case"WEAPONS":this.settings.equippedWeaponId.set(e);break;case"APPAREL":this.settings.equippedApparelId.set(e);break;case"AID":this.settings.equippedAidId.set(e);break;case"MISC":this.settings.equippedMiscId.set(e);break;case"AMMO":this.settings.equippedAmmoId.set(e)}}getSourceNames(){switch(this.category){case"WEAPONS":{const e=this.settingsConfig?.inventorySourceItems?.weapons;return(e??E).map(e=>e.name).filter(e=>e)}case"APPAREL":{const e=this.settingsConfig?.inventorySourceItems?.apparel;return(e??I).map(e=>e.name).filter(e=>e)}case"AID":{const e=this.settingsConfig?.inventorySourceItems?.aid;return(e??S).map(e=>e.name).filter(e=>e)}case"MISC":{const e=this.settingsConfig?.inventorySourceItems?.misc;return(e??L).map(e=>e.name).filter(e=>e)}case"AMMO":{const e=this.settingsConfig?.inventorySourceItems?.ammo;return(e??M).map(e=>e.name).filter(e=>e)}default:return[]}}getNextItemId(){return this.getItems().reduce((e,t)=>Math.max(e,t.id),0)+1}normalizeStatValue(e,t){return"number"==typeof e&&Number.isFinite(e)?e:t}normalizeQuantity(e){return"number"==typeof e&&Number.isFinite(e)?Math.max(1,Math.floor(e)):1}supportsQuantity(){return"APPAREL"===this.category||"AID"===this.category||"MISC"===this.category||"AMMO"===this.category}defaultQuantity(){return this.supportsQuantity()?1:0}getDefaultsForName(e){if("WEAPONS"===this.category){const t=this.settingsConfig?.inventorySourceItems?.weapons,n=(t??E).find(t=>t.name===e);return n?{damage:n.damage,weight:n.weight,value:n.value}:null}if("APPAREL"===this.category){const t=this.settingsConfig?.inventorySourceItems?.apparel,n=(t??I).find(t=>t.name===e);return n?{damage:n.dr,weight:n.wg,value:n.val}:null}if("AID"===this.category){const t=this.settingsConfig?.inventorySourceItems?.aid,n=(t??S).find(t=>t.name===e);return n?{weight:n.wg,value:n.val,effects:n.effects}:null}if("MISC"===this.category){const t=this.settingsConfig?.inventorySourceItems?.misc,n=(t??L).find(t=>t.name===e);return n?{weight:n.wg,value:n.val}:null}if("AMMO"===this.category){const t=this.settingsConfig?.inventorySourceItems?.ammo,n=(t??M).find(t=>t.name===e);return n?{weight:n.wg,value:n.val}:null}return null}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:$,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:$,isStandalone:!0,selector:"pip-boy-inventory-layout",inputs:{category:"category"},ngImport:e,template:'<div class="resource-layout">\n <div class="resource-list">\n <ul class="resource-list-items">\n @for (item of getItems(); track item.id) {\n <li>\n <button\n type="button"\n class="resource-list-item"\n [class.is-selected]="getEquippedId() === item.id"\n (click)="selectItem(item.id)"\n >\n {{ displayItemName(item) }}\n </button>\n </li>\n } @empty {\n <li class="is-empty">No items added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="inventory-actions">\n <button type="button" class="resource-add" (click)="openAddModal()">\n + Add\n </button>\n @if (getEquippedId() !== null) {\n <button\n type="button"\n class="resource-edit"\n (click)="openStatEditModal()"\n >\n Edit\n </button>\n <button type="button" class="resource-drop" (click)="dropSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n <div class="resources-detail">\n @if (getItems().length > 0 && selectedItem()) {\n <button\n type="button"\n class="resource-image"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openStatEditModal()"\n >\n @if (selectedItem()?.imageId) {\n <img\n [src]="imageStore.getImageUrl(selectedItem()?.imageId)"\n alt="Selected item"\n />\n }\n </button>\n <div class="resource-stats">\n @for (row of statRows(); track row.key) {\n <button\n type="button"\n class="resource-stat"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openStatEditModal()"\n >\n <span>{{ row.label }}</span>\n <span>{{ row.value }}</span>\n </button>\n }\n </div>\n }\n </div>\n</div>\n<pip-boy-stat-edit-modal\n (closeResult)="closeStatEditModal()"\n (nameChange)="handleNameChange($event)"\n (save)="saveStatEditModal($event)"\n [open]="showStatEditModal()"\n [title]="editStatModalTitle()"\n [name]="modalName()"\n nameLabel="Item Name"\n [nameOptions]="itemNames()"\n [showName]="true"\n [imageUrl]="imageStore.getImageUrl(modalImageId())"\n [showImage]="true"\n [textFields]="textEditFields()"\n [fields]="statEditFields()"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{width:100%;height:100%;display:block;font-size:inherit}.resource-layout{box-sizing:border-box;display:flex;gap:1.5rem;height:100%;min-height:0}.resource-list{display:flex;flex:1 1 55%;flex-direction:column;gap:.5rem;min-height:0}.resource-list-items{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.resource-list-items li{margin:0;padding:0;font-size:inherit}.resource-list-items .is-empty{opacity:.6}.resource-list-item{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font-size:inherit;padding:.25rem .35rem .25rem 1.2rem;position:relative;text-align:left;width:100%}.resource-list-item:hover{background:#0fbb6b1f}.resource-list-item.is-selected{background:#0fbb6b2e}.resource-list-item.is-selected:before{content:"";position:absolute;left:.35rem;top:50%;transform:translateY(-50%);width:.45rem;height:.45rem;background:#0fbb6b}.inventory-actions{display:flex;gap:.5rem}.resource-add{background:#0fbb6b14;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-add:hover{background:#0fbb6b2e}.resource-edit{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-edit:hover{background:#0fbb6b1f}.resource-drop{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-drop:hover{background:#0fbb6b1f}.resource-move{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.resource-move:hover{background:#0fbb6b1f}.resources-detail{display:flex;flex:1 1 45%;flex-direction:column;gap:1rem;height:100%;min-height:0;overflow:auto;padding-right:1rem}.resource-image{align-items:center;background:transparent;border:none;cursor:pointer;display:flex;flex:1 1 auto;flex-direction:column;min-height:60%;justify-content:flex-start;padding:1rem;text-transform:uppercase;width:100%}.resource-image span{margin-top:auto;opacity:.7}.resource-image img{align-self:center;max-height:100%;max-width:100%;object-fit:contain;padding:0}.resource-image:hover{background:#0fbb6b1f}.resource-image.is-locked{cursor:default;pointer-events:none}.resource-stats{display:flex;flex-direction:column;gap:.5rem;margin-top:auto;padding:0 1rem;font-size:calc(1.15rem * var(--list-font-scale, 1))}.resource-stat{background:transparent;border:1px solid transparent;color:#0fbb6b;cursor:pointer;display:flex;justify-content:space-between;padding:.2rem .35rem;text-align:left;text-transform:uppercase;width:100%;font-size:inherit}.resource-stat:hover{background:#0fbb6b1f}.resource-stat.is-locked{cursor:default;pointer-events:none}.resource-stat span{padding:.25rem}.resource-stat--name{font-size:calc(clamp(.9rem,.9rem + .15rem * (100vw - 360px) / 840px,1.05rem) * var(--list-font-scale, 1));letter-spacing:.04em}@media(max-width:720px),(max-height:560px){.inventory-actions{gap:.35rem}.resource-add,.resource-edit,.resource-drop{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.resource-move{flex:0 0 1.6rem;height:2.1rem}}\n'],dependencies:[{kind:"component",type:_,selector:"pip-boy-stat-edit-modal",inputs:["open","title","name","nameLabel","showName","nameOptions","imageUrl","showImage","fields","textFields"],outputs:["closeResult","save","nameChange"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:$,decorators:[{type:a,args:[{selector:"pip-boy-inventory-layout",standalone:!0,imports:[_],template:'<div class="resource-layout">\n <div class="resource-list">\n <ul class="resource-list-items">\n @for (item of getItems(); track item.id) {\n <li>\n <button\n type="button"\n class="resource-list-item"\n [class.is-selected]="getEquippedId() === item.id"\n (click)="selectItem(item.id)"\n >\n {{ displayItemName(item) }}\n </button>\n </li>\n } @empty {\n <li class="is-empty">No items added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="inventory-actions">\n <button type="button" class="resource-add" (click)="openAddModal()">\n + Add\n </button>\n @if (getEquippedId() !== null) {\n <button\n type="button"\n class="resource-edit"\n (click)="openStatEditModal()"\n >\n Edit\n </button>\n <button type="button" class="resource-drop" (click)="dropSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n <div class="resources-detail">\n @if (getItems().length > 0 && selectedItem()) {\n <button\n type="button"\n class="resource-image"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openStatEditModal()"\n >\n @if (selectedItem()?.imageId) {\n <img\n [src]="imageStore.getImageUrl(selectedItem()?.imageId)"\n alt="Selected item"\n />\n }\n </button>\n <div class="resource-stats">\n @for (row of statRows(); track row.key) {\n <button\n type="button"\n class="resource-stat"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openStatEditModal()"\n >\n <span>{{ row.label }}</span>\n <span>{{ row.value }}</span>\n </button>\n }\n </div>\n }\n </div>\n</div>\n<pip-boy-stat-edit-modal\n (closeResult)="closeStatEditModal()"\n (nameChange)="handleNameChange($event)"\n (save)="saveStatEditModal($event)"\n [open]="showStatEditModal()"\n [title]="editStatModalTitle()"\n [name]="modalName()"\n nameLabel="Item Name"\n [nameOptions]="itemNames()"\n [showName]="true"\n [imageUrl]="imageStore.getImageUrl(modalImageId())"\n [showImage]="true"\n [textFields]="textEditFields()"\n [fields]="statEditFields()"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{width:100%;height:100%;display:block;font-size:inherit}.resource-layout{box-sizing:border-box;display:flex;gap:1.5rem;height:100%;min-height:0}.resource-list{display:flex;flex:1 1 55%;flex-direction:column;gap:.5rem;min-height:0}.resource-list-items{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.resource-list-items li{margin:0;padding:0;font-size:inherit}.resource-list-items .is-empty{opacity:.6}.resource-list-item{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font-size:inherit;padding:.25rem .35rem .25rem 1.2rem;position:relative;text-align:left;width:100%}.resource-list-item:hover{background:#0fbb6b1f}.resource-list-item.is-selected{background:#0fbb6b2e}.resource-list-item.is-selected:before{content:"";position:absolute;left:.35rem;top:50%;transform:translateY(-50%);width:.45rem;height:.45rem;background:#0fbb6b}.inventory-actions{display:flex;gap:.5rem}.resource-add{background:#0fbb6b14;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-add:hover{background:#0fbb6b2e}.resource-edit{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-edit:hover{background:#0fbb6b1f}.resource-drop{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-drop:hover{background:#0fbb6b1f}.resource-move{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.resource-move:hover{background:#0fbb6b1f}.resources-detail{display:flex;flex:1 1 45%;flex-direction:column;gap:1rem;height:100%;min-height:0;overflow:auto;padding-right:1rem}.resource-image{align-items:center;background:transparent;border:none;cursor:pointer;display:flex;flex:1 1 auto;flex-direction:column;min-height:60%;justify-content:flex-start;padding:1rem;text-transform:uppercase;width:100%}.resource-image span{margin-top:auto;opacity:.7}.resource-image img{align-self:center;max-height:100%;max-width:100%;object-fit:contain;padding:0}.resource-image:hover{background:#0fbb6b1f}.resource-image.is-locked{cursor:default;pointer-events:none}.resource-stats{display:flex;flex-direction:column;gap:.5rem;margin-top:auto;padding:0 1rem;font-size:calc(1.15rem * var(--list-font-scale, 1))}.resource-stat{background:transparent;border:1px solid transparent;color:#0fbb6b;cursor:pointer;display:flex;justify-content:space-between;padding:.2rem .35rem;text-align:left;text-transform:uppercase;width:100%;font-size:inherit}.resource-stat:hover{background:#0fbb6b1f}.resource-stat.is-locked{cursor:default;pointer-events:none}.resource-stat span{padding:.25rem}.resource-stat--name{font-size:calc(clamp(.9rem,.9rem + .15rem * (100vw - 360px) / 840px,1.05rem) * var(--list-font-scale, 1));letter-spacing:.04em}@media(max-width:720px),(max-height:560px){.inventory-actions{gap:.35rem}.resource-add,.resource-edit,.resource-drop{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.resource-move{flex:0 0 1.6rem;height:2.1rem}}\n']}]}],propDecorators:{category:[{type:m}]}});class j{constructor(){r(()=>{this.open()&&(this.draftName.set(this.name()),this.draftDescription.set(this.description()),this.draftValue.set(this.value()),this.draftImageUrl.set(this.imageUrl()),this.draftImageName.set(null),this.draftImageFile.set(null),this.removedImage.set(!1),this.clearPreviewUrl())})}static nextId=0;open=t(!1,...ngDevMode?[{debugName:"open"}]:[]);title=t("Edit Entry",...ngDevMode?[{debugName:"title"}]:[]);name=t("",...ngDevMode?[{debugName:"name"}]:[]);itemNames=t([],...ngDevMode?[{debugName:"itemNames"}]:[]);sourceItems=t([],...ngDevMode?[{debugName:"sourceItems"}]:[]);autofillEnabled=t(!1,...ngDevMode?[{debugName:"autofillEnabled"}]:[]);autofillValue=t(!1,...ngDevMode?[{debugName:"autofillValue"}]:[]);description=t("",...ngDevMode?[{debugName:"description"}]:[]);value=t(0,...ngDevMode?[{debugName:"value"}]:[]);valueLabel=t("Value",...ngDevMode?[{debugName:"valueLabel"}]:[]);valueMin=t(null,...ngDevMode?[{debugName:"valueMin"}]:[]);valueMax=t(null,...ngDevMode?[{debugName:"valueMax"}]:[]);showValue=t(!0,...ngDevMode?[{debugName:"showValue"}]:[]);imageUrl=t(null,...ngDevMode?[{debugName:"imageUrl"}]:[]);closeResult=d();save=d();draftDescription=o("",...ngDevMode?[{debugName:"draftDescription"}]:[]);draftName=o("",...ngDevMode?[{debugName:"draftName"}]:[]);draftValue=o(0,...ngDevMode?[{debugName:"draftValue"}]:[]);draftImageName=o(null,...ngDevMode?[{debugName:"draftImageName"}]:[]);draftImageUrl=o(null,...ngDevMode?[{debugName:"draftImageUrl"}]:[]);draftImageFile=o(null,...ngDevMode?[{debugName:"draftImageFile"}]:[]);removedImage=o(!1,...ngDevMode?[{debugName:"removedImage"}]:[]);nameListId="stat-entry-name-"+j.nextId++;nameInputId=`${this.nameListId}-input`;previewUrl=null;closeModal(){this.clearPreviewUrl(),this.closeResult.emit()}updateName(e){const t=e.target.value;if(this.draftName.set(t),!this.autofillEnabled())return;const n=this.sourceItems().find(e=>e.name===t);n&&(this.draftDescription.set(n.description),this.autofillValue()&&"number"==typeof n.value&&this.draftValue.set(this.clampValue(n.value)))}updateDescription(e){this.draftDescription.set(e.target.value)}updateValue(e){const t=Number(e.target.value);Number.isFinite(t)&&this.draftValue.set(this.clampValue(t))}adjustValue(e){const t=Number(this.draftValue()),n=Number.isFinite(t)?t+e:e;this.draftValue.set(this.clampValue(n))}onImageSelected(e){const t=e.target,n=t.files?.[0]??null;this.draftImageName.set(n?n.name:null),n&&(this.removedImage.set(!1),this.draftImageFile.set(n),this.setPreviewUrl(URL.createObjectURL(n)),t.value="")}removeImage(){this.draftImageName.set(null),this.draftImageUrl.set(null),this.draftImageFile.set(null),this.removedImage.set(!0),this.clearPreviewUrl()}submit(e){e?.preventDefault();const t={name:this.draftName(),description:this.draftDescription(),imageFile:this.draftImageFile(),removeImage:this.removedImage()};this.showValue()&&(t.value=this.clampValue(this.draftValue())),this.clearPreviewUrl(),this.save.emit(t),this.closeResult.emit()}clampValue(e){let t=e;const n=this.valueMin(),a=this.valueMax();return"number"==typeof n&&(t=Math.max(n,t)),"number"==typeof a&&(t=Math.min(a,t)),t}setPreviewUrl(e){this.clearPreviewUrl(),this.previewUrl=e,this.draftImageUrl.set(e)}clearPreviewUrl(){this.previewUrl&&(URL.revokeObjectURL(this.previewUrl),this.previewUrl=null)}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:j,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:j,isStandalone:!0,selector:"pip-boy-stat-entry-modal",inputs:{open:{classPropertyName:"open",publicName:"open",isSignal:!0,isRequired:!1,transformFunction:null},title:{classPropertyName:"title",publicName:"title",isSignal:!0,isRequired:!1,transformFunction:null},name:{classPropertyName:"name",publicName:"name",isSignal:!0,isRequired:!1,transformFunction:null},itemNames:{classPropertyName:"itemNames",publicName:"itemNames",isSignal:!0,isRequired:!1,transformFunction:null},sourceItems:{classPropertyName:"sourceItems",publicName:"sourceItems",isSignal:!0,isRequired:!1,transformFunction:null},autofillEnabled:{classPropertyName:"autofillEnabled",publicName:"autofillEnabled",isSignal:!0,isRequired:!1,transformFunction:null},autofillValue:{classPropertyName:"autofillValue",publicName:"autofillValue",isSignal:!0,isRequired:!1,transformFunction:null},description:{classPropertyName:"description",publicName:"description",isSignal:!0,isRequired:!1,transformFunction:null},value:{classPropertyName:"value",publicName:"value",isSignal:!0,isRequired:!1,transformFunction:null},valueLabel:{classPropertyName:"valueLabel",publicName:"valueLabel",isSignal:!0,isRequired:!1,transformFunction:null},valueMin:{classPropertyName:"valueMin",publicName:"valueMin",isSignal:!0,isRequired:!1,transformFunction:null},valueMax:{classPropertyName:"valueMax",publicName:"valueMax",isSignal:!0,isRequired:!1,transformFunction:null},showValue:{classPropertyName:"showValue",publicName:"showValue",isSignal:!0,isRequired:!1,transformFunction:null},imageUrl:{classPropertyName:"imageUrl",publicName:"imageUrl",isSignal:!0,isRequired:!1,transformFunction:null}},outputs:{closeResult:"closeResult",save:"save"},ngImport:e,template:'<pip-boy-dialog [open]="open()" [title]="title()" (closeResult)="closeModal()">\n <form id="stat-entry-form" (submit)="submit($event)">\n <div class="stat-entry-modal-body">\n <label class="stat-entry-modal-field">\n <span>Name</span>\n <input\n type="text"\n [attr.list]="nameListId"\n [attr.name]="nameInputId"\n [value]="draftName()"\n (input)="updateName($event)"\n />\n </label>\n @if (itemNames().length) {\n <datalist [id]="nameListId">\n @for (name of itemNames(); track name) {\n <option [value]="name"></option>\n }\n </datalist>\n }\n @if (showValue()) {\n <label class="stat-entry-modal-field">\n <span>{{ valueLabel() }}</span>\n <div class="number-input-row">\n <input\n type="number"\n [attr.min]="valueMin()"\n [attr.max]="valueMax()"\n name="stat-entry-value"\n [value]="draftValue()"\n (input)="updateValue($event)"\n />\n <div class="number-input-controls">\n <button\n type="button"\n class="number-input-control"\n aria-label="Increase value"\n (click)="adjustValue(1)"\n >\n &#8593;\n </button>\n <button\n type="button"\n class="number-input-control"\n aria-label="Decrease value"\n (click)="adjustValue(-1)"\n >\n &#8595;\n </button>\n </div>\n </div>\n </label>\n }\n <label class="stat-entry-modal-field stat-entry-modal-field--description">\n <span>Description</span>\n <textarea\n rows="6"\n name="stat-entry-description"\n [value]="draftDescription()"\n (input)="updateDescription($event)"\n ></textarea>\n </label>\n <div class="stat-entry-modal-image">\n <button\n type="button"\n class="stat-entry-modal-image-button"\n (click)="modalImageInput.click()"\n >\n {{ draftImageName() ? draftImageName() : \'Select Image\' }}\n </button>\n @if (draftImageUrl()) {\n <button\n type="button"\n class="stat-entry-modal-image-remove"\n (click)="removeImage()"\n >\n Remove Image\n </button>\n }\n <input\n #modalImageInput\n type="file"\n accept="image/*"\n (change)="onImageSelected($event)"\n />\n @if (draftImageUrl()) {\n <img [src]="draftImageUrl()" alt="Entry preview" />\n }\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="stat-entry-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.stat-entry-modal-body{display:flex;flex-direction:column;gap:1rem}.stat-entry-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.stat-entry-modal-field input,.stat-entry-modal-field textarea{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.stat-entry-modal-field input:focus,.stat-entry-modal-field textarea:focus{outline:none;border-color:#0fbb6b}.stat-entry-modal-field textarea{min-height:6rem;resize:vertical;text-transform:none}.number-input-row{display:flex;align-items:stretch;gap:.5rem}.number-input-row input[type=number]{flex:1 1 auto;-moz-appearance:textfield}.number-input-row input[type=number]::-webkit-outer-spin-button,.number-input-row input[type=number]::-webkit-inner-spin-button{appearance:none;margin:0}.number-input-controls{display:flex;flex-direction:column;gap:.35rem}.number-input-control{flex:1 1 auto;background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.4rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);padding:.2rem .5rem;text-transform:uppercase}.number-input-control:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-entry-modal-image{display:flex;flex-direction:column;gap:.75rem}.stat-entry-modal-image input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.stat-entry-modal-image img{border:1px solid rgba(15,187,107,.35);max-height:8rem;object-fit:contain;padding:.5rem}.stat-entry-modal-image-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.stat-entry-modal-image-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-entry-modal-image-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.stat-entry-modal-image-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"],dependencies:[{kind:"component",type:U,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:j,decorators:[{type:a,args:[{selector:"pip-boy-stat-entry-modal",standalone:!0,imports:[U],template:'<pip-boy-dialog [open]="open()" [title]="title()" (closeResult)="closeModal()">\n <form id="stat-entry-form" (submit)="submit($event)">\n <div class="stat-entry-modal-body">\n <label class="stat-entry-modal-field">\n <span>Name</span>\n <input\n type="text"\n [attr.list]="nameListId"\n [attr.name]="nameInputId"\n [value]="draftName()"\n (input)="updateName($event)"\n />\n </label>\n @if (itemNames().length) {\n <datalist [id]="nameListId">\n @for (name of itemNames(); track name) {\n <option [value]="name"></option>\n }\n </datalist>\n }\n @if (showValue()) {\n <label class="stat-entry-modal-field">\n <span>{{ valueLabel() }}</span>\n <div class="number-input-row">\n <input\n type="number"\n [attr.min]="valueMin()"\n [attr.max]="valueMax()"\n name="stat-entry-value"\n [value]="draftValue()"\n (input)="updateValue($event)"\n />\n <div class="number-input-controls">\n <button\n type="button"\n class="number-input-control"\n aria-label="Increase value"\n (click)="adjustValue(1)"\n >\n &#8593;\n </button>\n <button\n type="button"\n class="number-input-control"\n aria-label="Decrease value"\n (click)="adjustValue(-1)"\n >\n &#8595;\n </button>\n </div>\n </div>\n </label>\n }\n <label class="stat-entry-modal-field stat-entry-modal-field--description">\n <span>Description</span>\n <textarea\n rows="6"\n name="stat-entry-description"\n [value]="draftDescription()"\n (input)="updateDescription($event)"\n ></textarea>\n </label>\n <div class="stat-entry-modal-image">\n <button\n type="button"\n class="stat-entry-modal-image-button"\n (click)="modalImageInput.click()"\n >\n {{ draftImageName() ? draftImageName() : \'Select Image\' }}\n </button>\n @if (draftImageUrl()) {\n <button\n type="button"\n class="stat-entry-modal-image-remove"\n (click)="removeImage()"\n >\n Remove Image\n </button>\n }\n <input\n #modalImageInput\n type="file"\n accept="image/*"\n (change)="onImageSelected($event)"\n />\n @if (draftImageUrl()) {\n <img [src]="draftImageUrl()" alt="Entry preview" />\n }\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="stat-entry-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.stat-entry-modal-body{display:flex;flex-direction:column;gap:1rem}.stat-entry-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.stat-entry-modal-field input,.stat-entry-modal-field textarea{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.stat-entry-modal-field input:focus,.stat-entry-modal-field textarea:focus{outline:none;border-color:#0fbb6b}.stat-entry-modal-field textarea{min-height:6rem;resize:vertical;text-transform:none}.number-input-row{display:flex;align-items:stretch;gap:.5rem}.number-input-row input[type=number]{flex:1 1 auto;-moz-appearance:textfield}.number-input-row input[type=number]::-webkit-outer-spin-button,.number-input-row input[type=number]::-webkit-inner-spin-button{appearance:none;margin:0}.number-input-controls{display:flex;flex-direction:column;gap:.35rem}.number-input-control{flex:1 1 auto;background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.4rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);padding:.2rem .5rem;text-transform:uppercase}.number-input-control:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-entry-modal-image{display:flex;flex-direction:column;gap:.75rem}.stat-entry-modal-image input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.stat-entry-modal-image img{border:1px solid rgba(15,187,107,.35);max-height:8rem;object-fit:contain;padding:.5rem}.stat-entry-modal-image-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.stat-entry-modal-image-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.stat-entry-modal-image-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.stat-entry-modal-image-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"]}]}],ctorParameters:()=>[],propDecorators:{open:[{type:e.Input,args:[{isSignal:!0,alias:"open",required:!1}]}],title:[{type:e.Input,args:[{isSignal:!0,alias:"title",required:!1}]}],name:[{type:e.Input,args:[{isSignal:!0,alias:"name",required:!1}]}],itemNames:[{type:e.Input,args:[{isSignal:!0,alias:"itemNames",required:!1}]}],sourceItems:[{type:e.Input,args:[{isSignal:!0,alias:"sourceItems",required:!1}]}],autofillEnabled:[{type:e.Input,args:[{isSignal:!0,alias:"autofillEnabled",required:!1}]}],autofillValue:[{type:e.Input,args:[{isSignal:!0,alias:"autofillValue",required:!1}]}],description:[{type:e.Input,args:[{isSignal:!0,alias:"description",required:!1}]}],value:[{type:e.Input,args:[{isSignal:!0,alias:"value",required:!1}]}],valueLabel:[{type:e.Input,args:[{isSignal:!0,alias:"valueLabel",required:!1}]}],valueMin:[{type:e.Input,args:[{isSignal:!0,alias:"valueMin",required:!1}]}],valueMax:[{type:e.Input,args:[{isSignal:!0,alias:"valueMax",required:!1}]}],showValue:[{type:e.Input,args:[{isSignal:!0,alias:"showValue",required:!1}]}],imageUrl:[{type:e.Input,args:[{isSignal:!0,alias:"imageUrl",required:!1}]}],closeResult:[{type:e.Output,args:["closeResult"]}],save:[{type:e.Output,args:["save"]}]}});class G{constructor(){r(()=>{const e=this.items(),t=this.selectedId();e.length?null!==t&&e.some(e=>e.id===t)||this.selectedId.set(e[0].id):null!==t&&this.selectedId.set(null)})}category="SPECIAL";valueLabel="Value";valueMin=null;valueMax=null;settings=l(C);settingsConfig=l(P,{optional:!0});imageStore=l(k);showEditModal=o(!1,...ngDevMode?[{debugName:"showEditModal"}]:[]);editMode=o("EDIT",...ngDevMode?[{debugName:"editMode"}]:[]);selectedId=o(null,...ngDevMode?[{debugName:"selectedId"}]:[]);items=u(()=>this.getItems(),...ngDevMode?[{debugName:"items"}]:[]);selectedItem=u(()=>{const e=this.selectedId();return null===e?null:this.items().find(t=>t.id===e)??null},...ngDevMode?[{debugName:"selectedItem"}]:[]);sourceItems=u(()=>this.getSourceItems(),...ngDevMode?[{debugName:"sourceItems"}]:[]);itemNames=u(()=>{const e=this.getSourceItems().map(e=>e.name);return Array.from(new Set(e)).sort()},...ngDevMode?[{debugName:"itemNames"}]:[]);autofillEnabled=u(()=>"ADD"===this.editMode(),...ngDevMode?[{debugName:"autofillEnabled"}]:[]);autofillValue=u(()=>"SPECIAL"===this.category,...ngDevMode?[{debugName:"autofillValue"}]:[]);editModalTitle=u(()=>{if("ADD"===this.editMode())return"Add Entry";const e=this.selectedItem();return e?`Edit ${e.name}`:"Edit Entry"},...ngDevMode?[{debugName:"editModalTitle"}]:[]);modalName=u(()=>{const e=this.selectedItem();return"ADD"===this.editMode()?"":e?.name??""},...ngDevMode?[{debugName:"modalName"}]:[]);modalDescription=u(()=>{const e=this.selectedItem();return"ADD"===this.editMode()?"":e?.description??""},...ngDevMode?[{debugName:"modalDescription"}]:[]);modalValue=u(()=>{if("ADD"===this.editMode())return this.valueMin??0;const e=this.selectedItem();return e?.value??0},...ngDevMode?[{debugName:"modalValue"}]:[]);modalImage=u(()=>{const e=this.selectedItem();return"ADD"===this.editMode()?null:this.imageStore.getImageUrl(e?.imageId??null)},...ngDevMode?[{debugName:"modalImage"}]:[]);openAddModal(){this.settings.editLockEnabled()||(this.editMode.set("ADD"),this.showEditModal.set(!0))}openEditModal(){this.settings.editLockEnabled()||this.selectedItem()&&(this.editMode.set("EDIT"),this.showEditModal.set(!0))}closeEditModal(){this.showEditModal.set(!1)}selectItem(e){this.selectedId.set(e)}async saveEditModal(e){const t=e.name.trim();if(!t)return;const n=this.selectedItem();let a;if(e.removeImage)a=void 0;else if(e.imageFile){const t=await this.imageStore.saveFile(e.imageFile);a=t.id}else a=n?.imageId;if("ADD"===this.editMode()){const n=this.getNextItemId(),o=this.valueMin??0;return this.updateItems(i=>[...i,{id:n,name:t,description:e.description,value:this.showValue()&&"number"==typeof e.value?e.value:o,imageId:a}]),this.selectedId.set(n),void this.closeEditModal()}const o=this.selectedId();null!==o&&(this.updateItems(n=>n.map(n=>n.id!==o?n:{...n,name:t,description:e.description,value:"number"==typeof e.value?e.value:n.value,imageId:a})),this.closeEditModal())}dropSelected(){if(this.settings.editLockEnabled())return;const e=this.selectedId();null!==e&&(this.updateItems(t=>t.filter(t=>t.id!==e)),this.selectedId.set(null))}moveSelected(e){if(this.settings.editLockEnabled())return;const t=this.selectedId();null!==t&&this.updateItems(n=>{const a=n.findIndex(e=>e.id===t);if(-1===a)return n;const o=a+e;if(o<0||o>=n.length)return n;const i=n.slice(),[s]=i.splice(a,1);return i.splice(o,0,s),i})}showValue(){return"SPECIAL"===this.category||"SKILLS"===this.category}getItems(){switch(this.category){case"SPECIAL":return this.settings.specialItems();case"SKILLS":return this.settings.skillItems();case"PERKS":return this.settings.perkItems();case"GENERAL":return this.settings.generalItems();default:return[]}}updateItems(e){switch(this.category){case"SPECIAL":this.settings.specialItems.update(e);break;case"SKILLS":this.settings.skillItems.update(e);break;case"PERKS":this.settings.perkItems.update(e);break;case"GENERAL":this.settings.generalItems.update(e)}}getSourceItems(){switch(this.category){case"SPECIAL":return this.settingsConfig?.statSourceItems?.special??A;case"SKILLS":return this.settingsConfig?.statSourceItems?.skills??D;case"PERKS":return this.settingsConfig?.statSourceItems?.perks??R;default:return[]}}getNextItemId(){return this.items().reduce((e,t)=>Math.max(e,t.id),0)+1}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:G,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:G,isStandalone:!0,selector:"pip-boy-stats-layout",inputs:{category:"category",valueLabel:"valueLabel",valueMin:"valueMin",valueMax:"valueMax"},ngImport:e,template:'<div class="resource-layout">\n <div class="resource-list">\n <ul class="resource-list-items">\n @for (item of items(); track item.id) {\n <li>\n <button\n type="button"\n class="resource-list-item"\n [class.is-selected]="selectedId() === item.id"\n (click)="selectItem(item.id)"\n >\n <span class="resource-list-item-name">{{ item.name }}</span>\n @if (showValue()) {\n <span class="resource-list-item-value">{{ item.value }}</span>\n }\n </button>\n </li>\n } @empty {\n <li class="is-empty">No entries available.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="inventory-actions">\n <button type="button" class="resource-add" (click)="openAddModal()">\n + Add\n </button>\n @if (selectedId() !== null) {\n <button type="button" class="resource-edit" (click)="openEditModal()">\n Edit\n </button>\n <button type="button" class="resource-drop" (click)="dropSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n <div class="resources-detail">\n @if (selectedItem()) {\n <button\n type="button"\n class="resource-image"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openEditModal()"\n [attr.aria-label]="\n selectedItem()?.imageId ? \'Edit image\' : \'Select image\'\n "\n >\n @if (selectedItem()?.imageId) {\n <img\n [src]="imageStore.getImageUrl(selectedItem()?.imageId)"\n alt="Selected entry"\n />\n }\n </button>\n <button\n type="button"\n class="resource-description"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openEditModal()"\n [innerHTML]="selectedItem()?.description || \'Add description.\'"\n ></button>\n }\n </div>\n</div>\n<pip-boy-stat-entry-modal\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n [open]="showEditModal()"\n [title]="editModalTitle()"\n [name]="modalName()"\n [itemNames]="itemNames()"\n [sourceItems]="sourceItems()"\n [autofillEnabled]="autofillEnabled()"\n [autofillValue]="autofillValue()"\n [description]="modalDescription()"\n [value]="modalValue()"\n [valueLabel]="valueLabel"\n [valueMin]="valueMin"\n [valueMax]="valueMax"\n [showValue]="showValue()"\n [imageUrl]="modalImage()"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{width:100%;height:100%;display:block;font-size:inherit}.resource-layout{box-sizing:border-box;display:flex;gap:1.5rem;height:100%;min-height:0}.resource-list{display:flex;flex:1 1 55%;flex-direction:column;gap:.5rem;min-height:0}.resource-list-items{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.resource-list-items li{margin:0;padding:0;font-size:inherit}.resource-list-items .is-empty{opacity:.6}.resource-list-item{align-items:center;background:transparent;border:none;color:#0fbb6b;cursor:pointer;display:flex;font-size:inherit;padding:.25rem .35rem .25rem 1.2rem;position:relative;text-align:left;justify-content:space-between;gap:.75rem;width:100%}.resource-list-item:hover{background:#0fbb6b1f}.resource-list-item.is-selected{background:#0fbb6b2e}.resource-list-item.is-selected:before{content:"";position:absolute;left:.35rem;top:50%;transform:translateY(-50%);width:.45rem;height:.45rem;background:#0fbb6b}.resource-list-item-name{flex:1 1 auto}.resource-list-item-value{flex:0 0 auto;min-width:2.5rem;text-align:right}.inventory-actions{display:flex;gap:.5rem}.resource-add{background:#0fbb6b14;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-add:hover{background:#0fbb6b2e}.resource-edit{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-edit:hover{background:#0fbb6b1f}.resource-drop{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-drop:hover{background:#0fbb6b1f}.resource-move{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.resource-move:hover{background:#0fbb6b1f}.resources-detail{display:flex;flex:1 1 45%;flex-direction:column;gap:1rem;height:100%;min-height:0;overflow:auto;padding-bottom:1rem;padding-right:1rem}.resource-image{align-items:center;background:transparent;border:none;cursor:pointer;display:flex;flex:1 1 auto;flex-direction:column;min-height:60%;justify-content:flex-start;padding:1rem;text-transform:uppercase;width:100%}.resource-image span{margin-top:auto;opacity:.7}.resource-image img{align-self:center;max-height:100%;max-width:100%;object-fit:contain;padding:0}.resource-image:hover{background:#0fbb6b1f}.resource-image.is-locked{cursor:default;pointer-events:none}.resource-description{background:transparent;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;display:block;position:relative;padding:.75rem;text-align:left;text-transform:none;width:100%;max-width:100%;font-size:calc(1.15rem * var(--list-font-scale, 1));white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere}.resource-description:before,.resource-description:after{content:"";position:absolute;pointer-events:none}.resource-description:before{left:0;right:0;top:0;height:2px;background:#0fbb6b}.resource-description:after{top:0;bottom:auto;right:0;width:2px;height:2rem;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 35%,#0fbb6b59 65%,#0fbb6b00)}.resource-description:hover{background:#0fbb6b14}.resource-description.is-locked{cursor:default;pointer-events:none}@media(max-width:720px),(max-height:560px){.inventory-actions{gap:.35rem}.resource-add,.resource-edit,.resource-drop{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.resource-move{flex:0 0 1.6rem;height:2.1rem}}\n'],dependencies:[{kind:"component",type:j,selector:"pip-boy-stat-entry-modal",inputs:["open","title","name","itemNames","sourceItems","autofillEnabled","autofillValue","description","value","valueLabel","valueMin","valueMax","showValue","imageUrl"],outputs:["closeResult","save"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:G,decorators:[{type:a,args:[{selector:"pip-boy-stats-layout",standalone:!0,imports:[j],template:'<div class="resource-layout">\n <div class="resource-list">\n <ul class="resource-list-items">\n @for (item of items(); track item.id) {\n <li>\n <button\n type="button"\n class="resource-list-item"\n [class.is-selected]="selectedId() === item.id"\n (click)="selectItem(item.id)"\n >\n <span class="resource-list-item-name">{{ item.name }}</span>\n @if (showValue()) {\n <span class="resource-list-item-value">{{ item.value }}</span>\n }\n </button>\n </li>\n } @empty {\n <li class="is-empty">No entries available.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="inventory-actions">\n <button type="button" class="resource-add" (click)="openAddModal()">\n + Add\n </button>\n @if (selectedId() !== null) {\n <button type="button" class="resource-edit" (click)="openEditModal()">\n Edit\n </button>\n <button type="button" class="resource-drop" (click)="dropSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="resource-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n <div class="resources-detail">\n @if (selectedItem()) {\n <button\n type="button"\n class="resource-image"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openEditModal()"\n [attr.aria-label]="\n selectedItem()?.imageId ? \'Edit image\' : \'Select image\'\n "\n >\n @if (selectedItem()?.imageId) {\n <img\n [src]="imageStore.getImageUrl(selectedItem()?.imageId)"\n alt="Selected entry"\n />\n }\n </button>\n <button\n type="button"\n class="resource-description"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openEditModal()"\n [innerHTML]="selectedItem()?.description || \'Add description.\'"\n ></button>\n }\n </div>\n</div>\n<pip-boy-stat-entry-modal\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n [open]="showEditModal()"\n [title]="editModalTitle()"\n [name]="modalName()"\n [itemNames]="itemNames()"\n [sourceItems]="sourceItems()"\n [autofillEnabled]="autofillEnabled()"\n [autofillValue]="autofillValue()"\n [description]="modalDescription()"\n [value]="modalValue()"\n [valueLabel]="valueLabel"\n [valueMin]="valueMin"\n [valueMax]="valueMax"\n [showValue]="showValue()"\n [imageUrl]="modalImage()"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{width:100%;height:100%;display:block;font-size:inherit}.resource-layout{box-sizing:border-box;display:flex;gap:1.5rem;height:100%;min-height:0}.resource-list{display:flex;flex:1 1 55%;flex-direction:column;gap:.5rem;min-height:0}.resource-list-items{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.resource-list-items li{margin:0;padding:0;font-size:inherit}.resource-list-items .is-empty{opacity:.6}.resource-list-item{align-items:center;background:transparent;border:none;color:#0fbb6b;cursor:pointer;display:flex;font-size:inherit;padding:.25rem .35rem .25rem 1.2rem;position:relative;text-align:left;justify-content:space-between;gap:.75rem;width:100%}.resource-list-item:hover{background:#0fbb6b1f}.resource-list-item.is-selected{background:#0fbb6b2e}.resource-list-item.is-selected:before{content:"";position:absolute;left:.35rem;top:50%;transform:translateY(-50%);width:.45rem;height:.45rem;background:#0fbb6b}.resource-list-item-name{flex:1 1 auto}.resource-list-item-value{flex:0 0 auto;min-width:2.5rem;text-align:right}.inventory-actions{display:flex;gap:.5rem}.resource-add{background:#0fbb6b14;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-add:hover{background:#0fbb6b2e}.resource-edit{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-edit:hover{background:#0fbb6b1f}.resource-drop{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.resource-drop:hover{background:#0fbb6b1f}.resource-move{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.resource-move:hover{background:#0fbb6b1f}.resources-detail{display:flex;flex:1 1 45%;flex-direction:column;gap:1rem;height:100%;min-height:0;overflow:auto;padding-bottom:1rem;padding-right:1rem}.resource-image{align-items:center;background:transparent;border:none;cursor:pointer;display:flex;flex:1 1 auto;flex-direction:column;min-height:60%;justify-content:flex-start;padding:1rem;text-transform:uppercase;width:100%}.resource-image span{margin-top:auto;opacity:.7}.resource-image img{align-self:center;max-height:100%;max-width:100%;object-fit:contain;padding:0}.resource-image:hover{background:#0fbb6b1f}.resource-image.is-locked{cursor:default;pointer-events:none}.resource-description{background:transparent;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;display:block;position:relative;padding:.75rem;text-align:left;text-transform:none;width:100%;max-width:100%;font-size:calc(1.15rem * var(--list-font-scale, 1));white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere}.resource-description:before,.resource-description:after{content:"";position:absolute;pointer-events:none}.resource-description:before{left:0;right:0;top:0;height:2px;background:#0fbb6b}.resource-description:after{top:0;bottom:auto;right:0;width:2px;height:2rem;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 35%,#0fbb6b59 65%,#0fbb6b00)}.resource-description:hover{background:#0fbb6b14}.resource-description.is-locked{cursor:default;pointer-events:none}@media(max-width:720px),(max-height:560px){.inventory-actions{gap:.35rem}.resource-add,.resource-edit,.resource-drop{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.resource-move{flex:0 0 1.6rem;height:2.1rem}}\n']}]}],ctorParameters:()=>[],propDecorators:{category:[{type:m}],valueLabel:[{type:m}],valueMin:[{type:m}],valueMax:[{type:m}]}});class Y{open=!1;title="Confirm";message="This action cannot be undone. Are you sure you want to continue?";confirmLabel="Confirm";cancelLabel="Cancel";confirm=new c;closeResult=new c;closeModal(){this.closeResult.emit()}confirmReset(){this.confirm.emit()}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:Y,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"21.1.1",type:Y,isStandalone:!0,selector:"pip-boy-reset-confirm-modal",inputs:{open:"open",title:"title",message:"message",confirmLabel:"confirmLabel",cancelLabel:"cancelLabel"},outputs:{confirm:"confirm",closeResult:"closeResult"},ngImport:e,template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <div class="reset-modal-body">\n <p>{{ message }}</p>\n </div>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">{{ cancelLabel }}</button>\n <button type="button" (click)="confirmReset()">\n {{ confirmLabel }}\n </button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.reset-modal-body p{margin:0;line-height:1.35;color:#0fbb6bd9}:host{font-size:inherit}\n"],dependencies:[{kind:"ngmodule",type:v},{kind:"component",type:U,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:Y,decorators:[{type:a,args:[{selector:"pip-boy-reset-confirm-modal",standalone:!0,imports:[v,U],template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <div class="reset-modal-body">\n <p>{{ message }}</p>\n </div>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">{{ cancelLabel }}</button>\n <button type="button" (click)="confirmReset()">\n {{ confirmLabel }}\n </button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.reset-modal-body p{margin:0;line-height:1.35;color:#0fbb6bd9}:host{font-size:inherit}\n"]}]}],propDecorators:{open:[{type:m}],title:[{type:m}],message:[{type:m}],confirmLabel:[{type:m}],cancelLabel:[{type:m}],confirm:[{type:p}],closeResult:[{type:p}]}});class Q{constructor(){r(()=>{this.open()&&this.draft.set(this.value())})}open=t(!1,...ngDevMode?[{debugName:"open"}]:[]);title=t("Edit Name",...ngDevMode?[{debugName:"title"}]:[]);value=t("",...ngDevMode?[{debugName:"value"}]:[]);placeholder=t("Name",...ngDevMode?[{debugName:"placeholder"}]:[]);allowEmpty=t(!1,...ngDevMode?[{debugName:"allowEmpty"}]:[]);inputType=t("text",...ngDevMode?[{debugName:"inputType"}]:[]);inputMin=t(null,...ngDevMode?[{debugName:"inputMin"}]:[]);inputStep=t(null,...ngDevMode?[{debugName:"inputStep"}]:[]);showNumberControls=t(!1,...ngDevMode?[{debugName:"showNumberControls"}]:[]);closeResult=d();save=d();draft=o("",...ngDevMode?[{debugName:"draft"}]:[]);updateDraft(e){this.draft.set(e.target.value)}closeModal(){this.closeResult.emit()}submit(){const e=this.draft().trim();(e||this.allowEmpty())&&this.save.emit(e),this.closeResult.emit()}adjustValue(e){const t=this.inputStep()??1,n=Number(this.draft());let a=(Number.isFinite(n)?n:this.inputMin()??0)+e*t;const o=this.inputMin();"number"==typeof o&&(a=Math.max(o,a)),this.draft.set(String(a))}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:Q,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:Q,isStandalone:!0,selector:"pip-boy-name-edit-modal",inputs:{open:{classPropertyName:"open",publicName:"open",isSignal:!0,isRequired:!1,transformFunction:null},title:{classPropertyName:"title",publicName:"title",isSignal:!0,isRequired:!1,transformFunction:null},value:{classPropertyName:"value",publicName:"value",isSignal:!0,isRequired:!1,transformFunction:null},placeholder:{classPropertyName:"placeholder",publicName:"placeholder",isSignal:!0,isRequired:!1,transformFunction:null},allowEmpty:{classPropertyName:"allowEmpty",publicName:"allowEmpty",isSignal:!0,isRequired:!1,transformFunction:null},inputType:{classPropertyName:"inputType",publicName:"inputType",isSignal:!0,isRequired:!1,transformFunction:null},inputMin:{classPropertyName:"inputMin",publicName:"inputMin",isSignal:!0,isRequired:!1,transformFunction:null},inputStep:{classPropertyName:"inputStep",publicName:"inputStep",isSignal:!0,isRequired:!1,transformFunction:null},showNumberControls:{classPropertyName:"showNumberControls",publicName:"showNumberControls",isSignal:!0,isRequired:!1,transformFunction:null}},outputs:{closeResult:"closeResult",save:"save"},ngImport:e,template:'<pip-boy-dialog [open]="open()" [title]="title()" (closeResult)="closeModal()">\n <div class="name-modal-body">\n <label class="name-modal-field">\n <span>{{ placeholder() }}</span>\n <div class="number-input-row">\n <input\n [type]="inputType()"\n [attr.min]="inputMin() ?? null"\n [attr.step]="inputStep() ?? null"\n [value]="draft()"\n (input)="updateDraft($event)"\n (keydown.enter)="submit()"\n />\n @if (showNumberControls() && inputType() === \'number\') {\n <div class="number-input-controls">\n <button\n type="button"\n class="number-input-control"\n (click)="adjustValue(1)"\n >\n &#8593;\n </button>\n <button\n type="button"\n class="number-input-control"\n (click)="adjustValue(-1)"\n >\n &#8595;\n </button>\n </div>\n }\n </div>\n </label>\n </div>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="button" (click)="submit()">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.name-modal-body{display:flex;flex-direction:column;gap:.5rem}.name-modal-field{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1.5rem}.name-modal-field span{font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);opacity:.8}.name-modal-field input{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;padding:.5rem .75rem;font:inherit;width:100%}.name-modal-field input:focus{outline:none;border-color:#0fbb6b}.number-input-row{display:flex;align-items:stretch;gap:.5rem}.number-input-row input[type=number]{flex:1 1 auto}.number-input-row input[type=number]::-webkit-outer-spin-button,.number-input-row input[type=number]::-webkit-inner-spin-button{appearance:none;margin:0}.number-input-controls{display:flex;flex-direction:column;gap:.35rem}.number-input-control{flex:1 1 auto;background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.4rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);padding:.2rem .5rem;text-transform:uppercase}.number-input-control:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"],dependencies:[{kind:"component",type:U,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:Q,decorators:[{type:a,args:[{selector:"pip-boy-name-edit-modal",standalone:!0,imports:[U],template:'<pip-boy-dialog [open]="open()" [title]="title()" (closeResult)="closeModal()">\n <div class="name-modal-body">\n <label class="name-modal-field">\n <span>{{ placeholder() }}</span>\n <div class="number-input-row">\n <input\n [type]="inputType()"\n [attr.min]="inputMin() ?? null"\n [attr.step]="inputStep() ?? null"\n [value]="draft()"\n (input)="updateDraft($event)"\n (keydown.enter)="submit()"\n />\n @if (showNumberControls() && inputType() === \'number\') {\n <div class="number-input-controls">\n <button\n type="button"\n class="number-input-control"\n (click)="adjustValue(1)"\n >\n &#8593;\n </button>\n <button\n type="button"\n class="number-input-control"\n (click)="adjustValue(-1)"\n >\n &#8595;\n </button>\n </div>\n }\n </div>\n </label>\n </div>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="button" (click)="submit()">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.name-modal-body{display:flex;flex-direction:column;gap:.5rem}.name-modal-field{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1.5rem}.name-modal-field span{font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);opacity:.8}.name-modal-field input{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;padding:.5rem .75rem;font:inherit;width:100%}.name-modal-field input:focus{outline:none;border-color:#0fbb6b}.number-input-row{display:flex;align-items:stretch;gap:.5rem}.number-input-row input[type=number]{flex:1 1 auto}.number-input-row input[type=number]::-webkit-outer-spin-button,.number-input-row input[type=number]::-webkit-inner-spin-button{appearance:none;margin:0}.number-input-controls{display:flex;flex-direction:column;gap:.35rem}.number-input-control{flex:1 1 auto;background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.4rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);padding:.2rem .5rem;text-transform:uppercase}.number-input-control:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"]}]}],ctorParameters:()=>[],propDecorators:{open:[{type:e.Input,args:[{isSignal:!0,alias:"open",required:!1}]}],title:[{type:e.Input,args:[{isSignal:!0,alias:"title",required:!1}]}],value:[{type:e.Input,args:[{isSignal:!0,alias:"value",required:!1}]}],placeholder:[{type:e.Input,args:[{isSignal:!0,alias:"placeholder",required:!1}]}],allowEmpty:[{type:e.Input,args:[{isSignal:!0,alias:"allowEmpty",required:!1}]}],inputType:[{type:e.Input,args:[{isSignal:!0,alias:"inputType",required:!1}]}],inputMin:[{type:e.Input,args:[{isSignal:!0,alias:"inputMin",required:!1}]}],inputStep:[{type:e.Input,args:[{isSignal:!0,alias:"inputStep",required:!1}]}],showNumberControls:[{type:e.Input,args:[{isSignal:!0,alias:"showNumberControls",required:!1}]}],closeResult:[{type:e.Output,args:["closeResult"]}],save:[{type:e.Output,args:["save"]}]}});class K{settings=l(C);imageStore=l(k);nameDraft=o("",...ngDevMode?[{debugName:"nameDraft"}]:[]);showNameModal=o(!1,...ngDevMode?[{debugName:"showNameModal"}]:[]);showVaultBoyDeleteModal=o(!1,...ngDevMode?[{debugName:"showVaultBoyDeleteModal"}]:[]);extraOptionModal=o(null,...ngDevMode?[{debugName:"extraOptionModal"}]:[]);extraOptionTitle=u(()=>{switch(this.extraOptionModal()){case"STIMPAK":case"LIMBS":return"Edit Text";default:return""}},...ngDevMode?[{debugName:"extraOptionTitle"}]:[]);extraOptionValue=u(()=>{const e=this.extraOptionModal();return"STIMPAK"===e?this.settings.stimpakLabel():"LIMBS"===e?this.settings.limbLabel():""},...ngDevMode?[{debugName:"extraOptionValue"}]:[]);selectVaultBoySlot(e){this.settings.selectedVaultBoyImageIndex.set(e)}addVaultBoySlot(){if(this.settings.editLockEnabled())return;if(this.settings.vaultBoyImages().length>=10)return;const e=this.settings.vaultBoyImages().length;this.settings.vaultBoyImages.update(e=>[...e,null]),this.settings.selectedVaultBoyImageIndex.set(e)}async onVaultBoyImageSelected(e){if(this.settings.editLockEnabled())return;const t=e.target,n=t.files?.[0]??null;if(!n)return;const a=await this.imageStore.saveFile(n),o=this.settings.selectedVaultBoyImageIndex();this.settings.vaultBoyImages.update(e=>e.map((e,t)=>t===o?a.id:e)),t.value=""}startNameEdit(){this.settings.editLockEnabled()||(this.nameDraft.set(this.settings.userName()),this.showNameModal.set(!0))}closeNameModal(){this.showNameModal.set(!1)}saveNameEdit(e){e.trim()&&this.settings.userName.set(e.trim()),this.closeNameModal()}openVaultBoyDeleteModal(){if(this.settings.editLockEnabled())return;const e=this.settings.vaultBoyImages();if(0===e.length)return;e[this.settings.selectedVaultBoyImageIndex()]?this.showVaultBoyDeleteModal.set(!0):this.confirmVaultBoyDelete()}closeVaultBoyDeleteModal(){this.showVaultBoyDeleteModal.set(!1)}confirmVaultBoyDelete(){if(this.settings.editLockEnabled())return;const e=this.settings.selectedVaultBoyImageIndex();this.settings.vaultBoyImages.update(t=>t.filter((t,n)=>n!==e));const t=this.settings.vaultBoyImages().length,n=0===t?0:Math.min(e,t-1);this.settings.selectedVaultBoyImageIndex.set(n),this.closeVaultBoyDeleteModal()}openExtraOptionModal(e){this.settings.editLockEnabled()||this.extraOptionModal.set(e)}closeExtraOptionModal(){this.extraOptionModal.set(null)}saveExtraOptionModal(e){const t=this.extraOptionModal();"STIMPAK"===t?this.settings.stimpakLabel.set(e):"LIMBS"===t&&this.settings.limbLabel.set(e),this.closeExtraOptionModal()}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:K,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:K,isStandalone:!0,selector:"pip-boy-cnd-status",ngImport:e,template:'<div class="status-panel">\n <label\n class="status-uploader"\n [class.is-locked]="settings.editLockEnabled()"\n for="status-image-input"\n >\n @if (settings.vaultBoyImages()[settings.selectedVaultBoyImageIndex()]) {\n <img\n [src]="\n imageStore.getImageUrl(\n settings.vaultBoyImages()[settings.selectedVaultBoyImageIndex()]\n )\n "\n alt="Vault Boy"\n />\n } @else if (settings.vaultBoyImages().length > 0) {\n <span>\n {{\n settings.editLockEnabled() ? \'NO IMAGE\' : \'Click to upload an Image\'\n }}\n </span>\n }\n </label>\n <input\n #vaultBoyImageInput\n id="status-image-input"\n type="file"\n accept="image/*"\n [disabled]="settings.editLockEnabled()"\n (change)="onVaultBoyImageSelected($event)"\n />\n <div class="status-slots">\n @for (slot of settings.vaultBoyImages(); track $index) {\n <button\n type="button"\n class="status-slot"\n [class.is-active]="settings.selectedVaultBoyImageIndex() === $index"\n [attr.aria-label]="\'Select action-buttonimage slot \' + ($index + 1)"\n (click)="selectVaultBoySlot($index)"\n ></button>\n }\n @if (!settings.editLockEnabled()) {\n <button\n type="button"\n class="status-slot status-slot--add"\n (click)="addVaultBoySlot()"\n [disabled]="settings.vaultBoyImages().length >= 10"\n >\n +\n </button>\n <button\n type="button"\n class="status-slot status-slot--delete"\n (click)="openVaultBoyDeleteModal()"\n [disabled]="settings.vaultBoyImages().length === 0"\n >\n -\n </button>\n }\n </div>\n <button\n type="button"\n class="user-name"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="startNameEdit()"\n >\n {{ settings.userName() }} - Level {{ settings.userLevel() }}\n </button>\n</div>\n<div class="extra-options">\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'STIMPAK\')"\n >\n {{ settings.stimpakLabel() }}\n </button>\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'LIMBS\')"\n >\n {{ settings.limbLabel() }}\n </button>\n <pip-boy-reset-confirm-modal\n [open]="showVaultBoyDeleteModal()"\n title="Delete image"\n message="This will remove the selected slot. Continue?"\n confirmLabel="Delete"\n (closeResult)="closeVaultBoyDeleteModal()"\n (confirm)="confirmVaultBoyDelete()"\n />\n <pip-boy-name-edit-modal\n [open]="showNameModal()"\n [value]="nameDraft()"\n title="Edit Name"\n placeholder="Name"\n (closeResult)="closeNameModal()"\n (save)="saveNameEdit($event)"\n />\n <pip-boy-name-edit-modal\n [open]="extraOptionModal() !== null"\n [value]="extraOptionValue()"\n [title]="extraOptionTitle()"\n placeholder="Value"\n [allowEmpty]="true"\n (closeResult)="closeExtraOptionModal()"\n (save)="saveExtraOptionModal($event)"\n />\n</div>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:flex;flex:1;gap:1rem;min-height:0;font-size:inherit}.status-panel{align-items:stretch;box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;gap:.75rem;justify-content:flex-start;margin:0 1rem 1rem;min-height:0;overflow:hidden}.status-uploader{align-items:center;cursor:pointer;display:flex;flex:1 1 auto;justify-content:center;min-height:0;overflow:hidden;text-transform:uppercase;width:100%}.status-uploader span{opacity:.7;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.status-uploader img{max-height:100%;max-width:100%;object-fit:contain;padding:.5rem}.status-uploader.is-locked{cursor:default;pointer-events:none}#status-image-input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.status-slots{display:flex;gap:.5rem;flex-wrap:wrap;justify-content:center}.status-slot{background:transparent;border:1px solid rgba(15,187,107,.5);color:#0fbb6b;cursor:pointer;height:2rem;padding:0;width:2rem}.status-slot.is-active{background:#0fbb6b33;border-color:#0fbb6b}.status-slot:disabled{cursor:not-allowed;opacity:.4}.status-slot--add,.status-slot--delete{border-style:dashed}.user-name{align-items:center;background:transparent;border:none;color:#0fbb6b;cursor:pointer;display:inline-flex;justify-content:center;padding:.35rem .75rem;text-align:center;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));width:100%}.user-name:hover{background:#0fbb6b1f}.user-name.is-locked{cursor:default}.extra-options{margin-top:0;display:flex;flex-direction:column;font-family:Roboto Mono,monospace;font-size:calc(clamp(1.05rem,1.05rem + .2rem * (100vw - 360px) / 840px,1.25rem) * var(--list-font-scale, 1));align-items:flex-end;gap:.75rem;white-space:nowrap;position:absolute;top:1rem;right:2rem;z-index:3}.extra-options button{background:transparent;border:none;color:var(--pip-boy-color, #0fbb6b);cursor:pointer;font:inherit;padding:0;white-space:nowrap}.extra-options button:hover{opacity:.8}.extra-options button.is-locked{cursor:default}.extra-options .controller-button{font-size:inherit;white-space:nowrap}.extra-options .controller-button .large-par{display:inline;padding-left:.5rem;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));top:-.15rem;position:relative;white-space:nowrap}\n"],dependencies:[{kind:"component",type:Y,selector:"pip-boy-reset-confirm-modal",inputs:["open","title","message","confirmLabel","cancelLabel"],outputs:["confirm","closeResult"]},{kind:"component",type:Q,selector:"pip-boy-name-edit-modal",inputs:["open","title","value","placeholder","allowEmpty","inputType","inputMin","inputStep","showNumberControls"],outputs:["closeResult","save"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:K,decorators:[{type:a,args:[{selector:"pip-boy-cnd-status",standalone:!0,imports:[Y,Q],template:'<div class="status-panel">\n <label\n class="status-uploader"\n [class.is-locked]="settings.editLockEnabled()"\n for="status-image-input"\n >\n @if (settings.vaultBoyImages()[settings.selectedVaultBoyImageIndex()]) {\n <img\n [src]="\n imageStore.getImageUrl(\n settings.vaultBoyImages()[settings.selectedVaultBoyImageIndex()]\n )\n "\n alt="Vault Boy"\n />\n } @else if (settings.vaultBoyImages().length > 0) {\n <span>\n {{\n settings.editLockEnabled() ? \'NO IMAGE\' : \'Click to upload an Image\'\n }}\n </span>\n }\n </label>\n <input\n #vaultBoyImageInput\n id="status-image-input"\n type="file"\n accept="image/*"\n [disabled]="settings.editLockEnabled()"\n (change)="onVaultBoyImageSelected($event)"\n />\n <div class="status-slots">\n @for (slot of settings.vaultBoyImages(); track $index) {\n <button\n type="button"\n class="status-slot"\n [class.is-active]="settings.selectedVaultBoyImageIndex() === $index"\n [attr.aria-label]="\'Select action-buttonimage slot \' + ($index + 1)"\n (click)="selectVaultBoySlot($index)"\n ></button>\n }\n @if (!settings.editLockEnabled()) {\n <button\n type="button"\n class="status-slot status-slot--add"\n (click)="addVaultBoySlot()"\n [disabled]="settings.vaultBoyImages().length >= 10"\n >\n +\n </button>\n <button\n type="button"\n class="status-slot status-slot--delete"\n (click)="openVaultBoyDeleteModal()"\n [disabled]="settings.vaultBoyImages().length === 0"\n >\n -\n </button>\n }\n </div>\n <button\n type="button"\n class="user-name"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="startNameEdit()"\n >\n {{ settings.userName() }} - Level {{ settings.userLevel() }}\n </button>\n</div>\n<div class="extra-options">\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'STIMPAK\')"\n >\n {{ settings.stimpakLabel() }}\n </button>\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'LIMBS\')"\n >\n {{ settings.limbLabel() }}\n </button>\n <pip-boy-reset-confirm-modal\n [open]="showVaultBoyDeleteModal()"\n title="Delete image"\n message="This will remove the selected slot. Continue?"\n confirmLabel="Delete"\n (closeResult)="closeVaultBoyDeleteModal()"\n (confirm)="confirmVaultBoyDelete()"\n />\n <pip-boy-name-edit-modal\n [open]="showNameModal()"\n [value]="nameDraft()"\n title="Edit Name"\n placeholder="Name"\n (closeResult)="closeNameModal()"\n (save)="saveNameEdit($event)"\n />\n <pip-boy-name-edit-modal\n [open]="extraOptionModal() !== null"\n [value]="extraOptionValue()"\n [title]="extraOptionTitle()"\n placeholder="Value"\n [allowEmpty]="true"\n (closeResult)="closeExtraOptionModal()"\n (save)="saveExtraOptionModal($event)"\n />\n</div>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:flex;flex:1;gap:1rem;min-height:0;font-size:inherit}.status-panel{align-items:stretch;box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;gap:.75rem;justify-content:flex-start;margin:0 1rem 1rem;min-height:0;overflow:hidden}.status-uploader{align-items:center;cursor:pointer;display:flex;flex:1 1 auto;justify-content:center;min-height:0;overflow:hidden;text-transform:uppercase;width:100%}.status-uploader span{opacity:.7;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.status-uploader img{max-height:100%;max-width:100%;object-fit:contain;padding:.5rem}.status-uploader.is-locked{cursor:default;pointer-events:none}#status-image-input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.status-slots{display:flex;gap:.5rem;flex-wrap:wrap;justify-content:center}.status-slot{background:transparent;border:1px solid rgba(15,187,107,.5);color:#0fbb6b;cursor:pointer;height:2rem;padding:0;width:2rem}.status-slot.is-active{background:#0fbb6b33;border-color:#0fbb6b}.status-slot:disabled{cursor:not-allowed;opacity:.4}.status-slot--add,.status-slot--delete{border-style:dashed}.user-name{align-items:center;background:transparent;border:none;color:#0fbb6b;cursor:pointer;display:inline-flex;justify-content:center;padding:.35rem .75rem;text-align:center;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));width:100%}.user-name:hover{background:#0fbb6b1f}.user-name.is-locked{cursor:default}.extra-options{margin-top:0;display:flex;flex-direction:column;font-family:Roboto Mono,monospace;font-size:calc(clamp(1.05rem,1.05rem + .2rem * (100vw - 360px) / 840px,1.25rem) * var(--list-font-scale, 1));align-items:flex-end;gap:.75rem;white-space:nowrap;position:absolute;top:1rem;right:2rem;z-index:3}.extra-options button{background:transparent;border:none;color:var(--pip-boy-color, #0fbb6b);cursor:pointer;font:inherit;padding:0;white-space:nowrap}.extra-options button:hover{opacity:.8}.extra-options button.is-locked{cursor:default}.extra-options .controller-button{font-size:inherit;white-space:nowrap}.extra-options .controller-button .large-par{display:inline;padding-left:.5rem;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));top:-.15rem;position:relative;white-space:nowrap}\n"]}]}]});class Z{options;constructor(e){this.options=e,this.trackSelector=e.trackSelector??".radiation-meter-track",this.indicatorSelector=e.indicatorSelector??".radiation-meter-indicator",this.trackClassName=this.trackSelector.startsWith(".")?this.trackSelector.slice(1):this.trackSelector}isPointerDown=!1;trackSelector;indicatorSelector;trackClassName;startPointer(e){if(0!==e.button)return;this.isPointerDown=!0;const t=this.getCaptureElement(e)??e.currentTarget;t instanceof HTMLElement&&t.setPointerCapture(e.pointerId),this.updateFromPointer(e)}dragPointer(e){this.isPointerDown&&this.updateFromPointer(e)}endPointer(e){if(this.isPointerDown){this.isPointerDown=!1;try{const t=this.getCaptureElement(e)??e.currentTarget;t instanceof HTMLElement&&t.releasePointerCapture(e.pointerId)}catch{}}}updateFromPointer(e){const t=this.getTrackElement(e);if(!t)return;const n=t.getBoundingClientRect();if(!n.width)return;const a=Math.max(0,Math.min(n.width,e.clientX-n.left))/n.width;this.options.onChange(Number(a.toFixed(2)))}getTrackElement(e){const t=e.currentTarget;if(!t)return null;if(t.classList.contains(this.trackClassName))return t;const n=t.closest(".radiation-meter");return n?.querySelector(this.trackSelector)??null}getCaptureElement(e){const t=e.currentTarget;return t?t.classList.contains(this.trackClassName)?t:t.closest(this.indicatorSelector):null}}class X{settings=l(C);pointerHandler=new Z({onChange:e=>this.settings.radMeterLevel.set(e)});showResistModal=o(!1,...ngDevMode?[{debugName:"showResistModal"}]:[]);resistPercent=o(12,...ngDevMode?[{debugName:"resistPercent"}]:[]);ticks=Array.from({length:101},(e,t)=>({large:t%10==0,end:100===t}));getLevelPercent(){return`${Math.round(100*this.settings.radMeterLevel())}%`}getLevelOffsetPercent(){return`${(100*this.settings.radMeterLevel()).toFixed(2)}%`}getLevelValue(){return Math.round(1e3*this.settings.radMeterLevel())}startPointer(e){this.pointerHandler.startPointer(e)}dragPointer(e){this.pointerHandler.dragPointer(e)}endPointer(e){this.pointerHandler.endPointer(e)}openResistModal(){this.showResistModal.set(!0)}closeResistModal(){this.showResistModal.set(!1)}saveResistModal(e){const t=Number.parseInt(e,10);Number.isFinite(t)&&this.resistPercent.set(Math.max(0,t)),this.closeResistModal()}getResistLabel(){const e=this.resistPercent();return e<=0?"":`RAD RESIST ${e}%`}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:X,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:X,isStandalone:!0,selector:"pip-boy-radiation-meter",ngImport:e,template:'<div class="radiation-panel">\n <div class="radiation-info">\n <button type="button" class="status-resist" (click)="openResistModal()">\n <span class="status-resist-text">{{ getResistLabel() }}</span>\n <span class="status-resist-right">\n <span class="bottom-half-line"></span>\n </span>\n </button>\n </div>\n <div class="radiation-meter">\n <div class="radiation-meter-scale">\n <span class="radiation-meter-scale-mid">500</span>\n <span class="radiation-meter-scale-max">1000</span>\n </div>\n <div class="radiation-meter-grid">\n <div class="status-label">RADS</div>\n <div\n class="radiation-meter-track"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <div class="radiation-meter-labels">\n @for (tick of ticks; track $index) {\n <span\n class="radiation-meter-tick"\n [class.radiation-meter-tick--large]="tick.large"\n [class.radiation-meter-tick--small]="!tick.large"\n [class.radiation-meter-tick--end-triangle]="tick.end"\n ></span>\n }\n </div>\n <div\n class="radiation-meter-fill"\n [style.width]="getLevelPercent()"\n ></div>\n </div>\n <div class="status-right">\n <span class="bottom-half-line"></span>\n </div>\n <div\n class="radiation-meter-indicator"\n aria-hidden="true"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <span\n class="radiation-meter-arrow"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n <span\n class="radiation-meter-handle"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n @if (getLevelValue() > 0) {\n <span\n class="radiation-meter-value"\n [style.left]="getLevelOffsetPercent()"\n >\n {{ getLevelValue() }}\n </span>\n }\n </div>\n </div>\n </div>\n</div>\n<pip-boy-name-edit-modal\n [open]="showResistModal()"\n title="RAD RESIST"\n [value]="resistPercent().toString()"\n placeholder="Percent"\n inputType="number"\n [inputMin]="0"\n [inputStep]="1"\n [showNumberControls]="true"\n (closeResult)="closeResistModal()"\n (save)="saveResistModal($event)"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:flex;flex:1 1 auto;min-height:0;font-size:inherit;flex-direction:column}.radiation-panel{display:flex;flex-direction:row;align-items:flex-start;gap:0;flex-wrap:nowrap;min-height:0;padding:1rem;width:100%;margin-top:auto;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.radiation-info{display:flex;flex-direction:column;flex:0 0 auto;margin-top:1.7rem}.status-resist{background:transparent;border:none;color:#0fbb6b;cursor:pointer;text-align:left;text-transform:uppercase;font-size:inherit;display:flex;align-items:flex-start;position:relative;margin:0}.status-resist:hover .status-resist-text{background:#ffffff14}.status-resist:hover,.status-resist:focus-visible{background:transparent}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:100%;height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:0;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.status-resist-text{display:flex;align-items:center;align-self:stretch;padding:.5rem .5rem 0;border-top:2px solid #0fbb6b;flex:1 1 auto;min-width:200px;white-space:nowrap}.status-resist-right{width:1.25rem;min-height:1.8rem;position:relative;flex:0 0 auto;align-self:stretch}.status-resist-right .bottom-half-line:before{left:0}.radiation-meter{display:flex;flex-direction:column;gap:.75rem;width:100%;justify-self:stretch;flex:1 1 0;min-width:0;--radiation-triangle-width: 14px}.radiation-meter-scale{position:relative;width:100%;height:1rem;line-height:1rem;text-transform:uppercase;letter-spacing:.08em}.radiation-meter-scale-mid{position:absolute;left:calc(50% + 60px);transform:translate(-50%)}.radiation-meter-scale-max{position:absolute;right:0}.radiation-meter-grid{display:grid;grid-template-columns:auto 1fr auto;grid-template-rows:auto auto;align-items:start;column-gap:0;row-gap:0}.status-label{grid-column:1;grid-row:1;text-transform:uppercase;padding:.5rem 2rem 0 .5rem;border-top:2px solid #0fbb6b;letter-spacing:.08em;white-space:nowrap}.status-right{width:1.25rem;height:100%;position:relative;grid-column:3;grid-row:1;pointer-events:none;border-top:2px solid #0fbb6b}.status-right .bottom-half-line:before{right:0}.radiation-meter-track{grid-column:2;grid-row:1;position:relative;width:100%;height:1.5rem;border-top:2px solid #0fbb6b;overflow:visible;cursor:grab;min-width:0}.radiation-meter-fill{position:absolute;top:0;left:0;height:100%;background:#0fbb6b73;box-shadow:0 0 20px #0fbb6b59}.radiation-meter-labels{position:absolute;top:-1px;left:0;width:100%;height:100%;display:flex;justify-content:space-between;align-items:flex-start;padding:0 .1rem 0 0;pointer-events:none}.radiation-meter-tick{width:2px;background:#0fbb6b99;border-radius:1px}.radiation-meter-tick:first-child{width:var(--radiation-triangle-width);margin-left:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,100% 100%)}.radiation-meter-tick--end-triangle{width:var(--radiation-triangle-width);margin-right:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,0 100%)}.radiation-meter-tick--large{height:65%}.radiation-meter-tick--small{height:35%}.radiation-meter-indicator{grid-column:2;grid-row:2;position:relative;height:2.2rem;width:100%;cursor:grab}.radiation-meter-value{position:absolute;top:1rem;color:#0fbb6b;font-size:.75em;letter-spacing:.08em;text-transform:uppercase;transform:translate(calc(-100% - .4rem));opacity:1;pointer-events:none;white-space:nowrap}.radiation-meter-arrow{position:absolute;top:.1rem;width:0;height:0;border-left:.75rem solid transparent;border-right:.75rem solid transparent;border-bottom:.75rem solid rgba(15,187,107,.7);transform:translate(-50%)}.radiation-meter-handle{position:absolute;top:.8rem;width:4px;height:30px;background:#0fbb6b99;transform:translate(-50%)}.radiation-meter-track:active,.radiation-meter-indicator:active,.radiation-meter-arrow:active,.radiation-meter-handle:active{cursor:grabbing}\n'],dependencies:[{kind:"component",type:Q,selector:"pip-boy-name-edit-modal",inputs:["open","title","value","placeholder","allowEmpty","inputType","inputMin","inputStep","showNumberControls"],outputs:["closeResult","save"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:X,decorators:[{type:a,args:[{selector:"pip-boy-radiation-meter",standalone:!0,imports:[Q],template:'<div class="radiation-panel">\n <div class="radiation-info">\n <button type="button" class="status-resist" (click)="openResistModal()">\n <span class="status-resist-text">{{ getResistLabel() }}</span>\n <span class="status-resist-right">\n <span class="bottom-half-line"></span>\n </span>\n </button>\n </div>\n <div class="radiation-meter">\n <div class="radiation-meter-scale">\n <span class="radiation-meter-scale-mid">500</span>\n <span class="radiation-meter-scale-max">1000</span>\n </div>\n <div class="radiation-meter-grid">\n <div class="status-label">RADS</div>\n <div\n class="radiation-meter-track"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <div class="radiation-meter-labels">\n @for (tick of ticks; track $index) {\n <span\n class="radiation-meter-tick"\n [class.radiation-meter-tick--large]="tick.large"\n [class.radiation-meter-tick--small]="!tick.large"\n [class.radiation-meter-tick--end-triangle]="tick.end"\n ></span>\n }\n </div>\n <div\n class="radiation-meter-fill"\n [style.width]="getLevelPercent()"\n ></div>\n </div>\n <div class="status-right">\n <span class="bottom-half-line"></span>\n </div>\n <div\n class="radiation-meter-indicator"\n aria-hidden="true"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <span\n class="radiation-meter-arrow"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n <span\n class="radiation-meter-handle"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n @if (getLevelValue() > 0) {\n <span\n class="radiation-meter-value"\n [style.left]="getLevelOffsetPercent()"\n >\n {{ getLevelValue() }}\n </span>\n }\n </div>\n </div>\n </div>\n</div>\n<pip-boy-name-edit-modal\n [open]="showResistModal()"\n title="RAD RESIST"\n [value]="resistPercent().toString()"\n placeholder="Percent"\n inputType="number"\n [inputMin]="0"\n [inputStep]="1"\n [showNumberControls]="true"\n (closeResult)="closeResistModal()"\n (save)="saveResistModal($event)"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:flex;flex:1 1 auto;min-height:0;font-size:inherit;flex-direction:column}.radiation-panel{display:flex;flex-direction:row;align-items:flex-start;gap:0;flex-wrap:nowrap;min-height:0;padding:1rem;width:100%;margin-top:auto;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.radiation-info{display:flex;flex-direction:column;flex:0 0 auto;margin-top:1.7rem}.status-resist{background:transparent;border:none;color:#0fbb6b;cursor:pointer;text-align:left;text-transform:uppercase;font-size:inherit;display:flex;align-items:flex-start;position:relative;margin:0}.status-resist:hover .status-resist-text{background:#ffffff14}.status-resist:hover,.status-resist:focus-visible{background:transparent}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:100%;height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:0;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.status-resist-text{display:flex;align-items:center;align-self:stretch;padding:.5rem .5rem 0;border-top:2px solid #0fbb6b;flex:1 1 auto;min-width:200px;white-space:nowrap}.status-resist-right{width:1.25rem;min-height:1.8rem;position:relative;flex:0 0 auto;align-self:stretch}.status-resist-right .bottom-half-line:before{left:0}.radiation-meter{display:flex;flex-direction:column;gap:.75rem;width:100%;justify-self:stretch;flex:1 1 0;min-width:0;--radiation-triangle-width: 14px}.radiation-meter-scale{position:relative;width:100%;height:1rem;line-height:1rem;text-transform:uppercase;letter-spacing:.08em}.radiation-meter-scale-mid{position:absolute;left:calc(50% + 60px);transform:translate(-50%)}.radiation-meter-scale-max{position:absolute;right:0}.radiation-meter-grid{display:grid;grid-template-columns:auto 1fr auto;grid-template-rows:auto auto;align-items:start;column-gap:0;row-gap:0}.status-label{grid-column:1;grid-row:1;text-transform:uppercase;padding:.5rem 2rem 0 .5rem;border-top:2px solid #0fbb6b;letter-spacing:.08em;white-space:nowrap}.status-right{width:1.25rem;height:100%;position:relative;grid-column:3;grid-row:1;pointer-events:none;border-top:2px solid #0fbb6b}.status-right .bottom-half-line:before{right:0}.radiation-meter-track{grid-column:2;grid-row:1;position:relative;width:100%;height:1.5rem;border-top:2px solid #0fbb6b;overflow:visible;cursor:grab;min-width:0}.radiation-meter-fill{position:absolute;top:0;left:0;height:100%;background:#0fbb6b73;box-shadow:0 0 20px #0fbb6b59}.radiation-meter-labels{position:absolute;top:-1px;left:0;width:100%;height:100%;display:flex;justify-content:space-between;align-items:flex-start;padding:0 .1rem 0 0;pointer-events:none}.radiation-meter-tick{width:2px;background:#0fbb6b99;border-radius:1px}.radiation-meter-tick:first-child{width:var(--radiation-triangle-width);margin-left:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,100% 100%)}.radiation-meter-tick--end-triangle{width:var(--radiation-triangle-width);margin-right:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,0 100%)}.radiation-meter-tick--large{height:65%}.radiation-meter-tick--small{height:35%}.radiation-meter-indicator{grid-column:2;grid-row:2;position:relative;height:2.2rem;width:100%;cursor:grab}.radiation-meter-value{position:absolute;top:1rem;color:#0fbb6b;font-size:.75em;letter-spacing:.08em;text-transform:uppercase;transform:translate(calc(-100% - .4rem));opacity:1;pointer-events:none;white-space:nowrap}.radiation-meter-arrow{position:absolute;top:.1rem;width:0;height:0;border-left:.75rem solid transparent;border-right:.75rem solid transparent;border-bottom:.75rem solid rgba(15,187,107,.7);transform:translate(-50%)}.radiation-meter-handle{position:absolute;top:.8rem;width:4px;height:30px;background:#0fbb6b99;transform:translate(-50%)}.radiation-meter-track:active,.radiation-meter-indicator:active,.radiation-meter-arrow:active,.radiation-meter-handle:active{cursor:grabbing}\n']}]}]});class J{kind=t("H20",...ngDevMode?[{debugName:"kind"}]:[]);settings=l(C);pointerHandler=new Z({onChange:e=>this.setLevel(e)});label=u(()=>this.kind(),...ngDevMode?[{debugName:"label"}]:[]);ticks=Array.from({length:101},(e,t)=>({large:t%10==0,end:100===t}));getLevelPercent(){return`${Math.round(100*this.getLevel())}%`}getLevelOffsetPercent(){return`${(100*this.getLevel()).toFixed(2)}%`}getLevelValue(){return Math.round(1e3*this.getLevel())}startPointer(e){this.pointerHandler.startPointer(e)}dragPointer(e){this.pointerHandler.dragPointer(e)}endPointer(e){this.pointerHandler.endPointer(e)}getLevel(){switch(this.kind()){case"H20":return this.settings.h20MeterLevel();case"FOD":return this.settings.fodMeterLevel();case"SLP":return this.settings.slpMeterLevel();default:return 0}}setLevel(e){switch(this.kind()){case"H20":this.settings.h20MeterLevel.set(e);break;case"FOD":this.settings.fodMeterLevel.set(e);break;case"SLP":this.settings.slpMeterLevel.set(e)}}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:J,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:J,isStandalone:!0,selector:"pip-boy-status-meter",inputs:{kind:{classPropertyName:"kind",publicName:"kind",isSignal:!0,isRequired:!1,transformFunction:null}},ngImport:e,template:'<div class="radiation-panel">\n <div class="radiation-info">\n <button type="button" class="status-resist" disabled>\n <span class="status-resist-text"></span>\n <span class="status-resist-right">\n <span class="bottom-half-line"></span>\n </span>\n </button>\n </div>\n <div class="radiation-meter">\n <div class="radiation-meter-scale">\n <span class="radiation-meter-scale-mid">500</span>\n <span class="radiation-meter-scale-max">1000</span>\n </div>\n <div class="radiation-meter-grid">\n <div class="status-label">{{ label() }}</div>\n <div\n class="radiation-meter-track"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <div class="radiation-meter-labels">\n @for (tick of ticks; track $index) {\n <span\n class="radiation-meter-tick"\n [class.radiation-meter-tick--large]="tick.large"\n [class.radiation-meter-tick--small]="!tick.large"\n [class.radiation-meter-tick--end-triangle]="tick.end"\n ></span>\n }\n </div>\n <div\n class="radiation-meter-fill"\n [style.width]="getLevelPercent()"\n ></div>\n </div>\n <div class="status-right">\n <span class="bottom-half-line"></span>\n </div>\n <div\n class="radiation-meter-indicator"\n aria-hidden="true"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <span\n class="radiation-meter-arrow"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n <span\n class="radiation-meter-handle"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n @if (getLevelValue() > 0) {\n <span\n class="radiation-meter-value"\n [style.left]="getLevelOffsetPercent()"\n >\n {{ getLevelValue() }}\n </span>\n }\n </div>\n </div>\n </div>\n</div>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:flex;flex:1 1 auto;min-height:0;font-size:inherit;flex-direction:column}.radiation-panel{display:flex;flex-direction:row;align-items:flex-start;gap:0;flex-wrap:nowrap;min-height:0;padding:1rem;width:100%;margin-top:auto;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.radiation-info{display:flex;flex-direction:column;flex:0 0 auto;margin-top:1.7rem}.status-resist{background:transparent;border:none;color:#0fbb6b;cursor:pointer;text-align:left;text-transform:uppercase;font-size:inherit;display:flex;align-items:flex-start;position:relative;margin:0}.status-resist:hover .status-resist-text{background:#ffffff14}.status-resist:hover,.status-resist:focus-visible{background:transparent}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:100%;height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:0;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.status-resist-text{display:flex;align-items:center;align-self:stretch;padding:.5rem .5rem 0;border-top:2px solid #0fbb6b;flex:1 1 auto;min-width:200px;white-space:nowrap}.status-resist-right{width:1.25rem;min-height:1.8rem;position:relative;flex:0 0 auto;align-self:stretch}.status-resist-right .bottom-half-line:before{left:0}.radiation-meter{display:flex;flex-direction:column;gap:.75rem;width:100%;justify-self:stretch;flex:1 1 0;min-width:0;--radiation-triangle-width: 14px}.radiation-meter-scale{position:relative;width:100%;height:1rem;line-height:1rem;text-transform:uppercase;letter-spacing:.08em}.radiation-meter-scale-mid{position:absolute;left:calc(50% + 60px);transform:translate(-50%)}.radiation-meter-scale-max{position:absolute;right:0}.radiation-meter-grid{display:grid;grid-template-columns:auto 1fr auto;grid-template-rows:auto auto;align-items:start;column-gap:0;row-gap:0}.status-label{grid-column:1;grid-row:1;text-transform:uppercase;padding:.5rem 2rem 0 .5rem;border-top:2px solid #0fbb6b;letter-spacing:.08em;white-space:nowrap}.status-right{width:1.25rem;height:100%;position:relative;grid-column:3;grid-row:1;pointer-events:none;border-top:2px solid #0fbb6b}.status-right .bottom-half-line:before{right:0}.radiation-meter-track{grid-column:2;grid-row:1;position:relative;width:100%;height:1.5rem;border-top:2px solid #0fbb6b;overflow:visible;cursor:grab;min-width:0}.radiation-meter-fill{position:absolute;top:0;left:0;height:100%;background:#0fbb6b73;box-shadow:0 0 20px #0fbb6b59}.radiation-meter-labels{position:absolute;top:-1px;left:0;width:100%;height:100%;display:flex;justify-content:space-between;align-items:flex-start;padding:0 .1rem 0 0;pointer-events:none}.radiation-meter-tick{width:2px;background:#0fbb6b99;border-radius:1px}.radiation-meter-tick:first-child{width:var(--radiation-triangle-width);margin-left:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,100% 100%)}.radiation-meter-tick--end-triangle{width:var(--radiation-triangle-width);margin-right:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,0 100%)}.radiation-meter-tick--large{height:65%}.radiation-meter-tick--small{height:35%}.radiation-meter-indicator{grid-column:2;grid-row:2;position:relative;height:2.2rem;width:100%;cursor:grab}.radiation-meter-value{position:absolute;top:1rem;color:#0fbb6b;font-size:.75em;letter-spacing:.08em;text-transform:uppercase;transform:translate(calc(-100% - .4rem));opacity:1;pointer-events:none;white-space:nowrap}.radiation-meter-arrow{position:absolute;top:.1rem;width:0;height:0;border-left:.75rem solid transparent;border-right:.75rem solid transparent;border-bottom:.75rem solid rgba(15,187,107,.7);transform:translate(-50%)}.radiation-meter-handle{position:absolute;top:.8rem;width:4px;height:30px;background:#0fbb6b99;transform:translate(-50%)}.radiation-meter-track:active,.radiation-meter-indicator:active,.radiation-meter-arrow:active,.radiation-meter-handle:active{cursor:grabbing}\n']})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:J,decorators:[{type:a,args:[{selector:"pip-boy-status-meter",standalone:!0,template:'<div class="radiation-panel">\n <div class="radiation-info">\n <button type="button" class="status-resist" disabled>\n <span class="status-resist-text"></span>\n <span class="status-resist-right">\n <span class="bottom-half-line"></span>\n </span>\n </button>\n </div>\n <div class="radiation-meter">\n <div class="radiation-meter-scale">\n <span class="radiation-meter-scale-mid">500</span>\n <span class="radiation-meter-scale-max">1000</span>\n </div>\n <div class="radiation-meter-grid">\n <div class="status-label">{{ label() }}</div>\n <div\n class="radiation-meter-track"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <div class="radiation-meter-labels">\n @for (tick of ticks; track $index) {\n <span\n class="radiation-meter-tick"\n [class.radiation-meter-tick--large]="tick.large"\n [class.radiation-meter-tick--small]="!tick.large"\n [class.radiation-meter-tick--end-triangle]="tick.end"\n ></span>\n }\n </div>\n <div\n class="radiation-meter-fill"\n [style.width]="getLevelPercent()"\n ></div>\n </div>\n <div class="status-right">\n <span class="bottom-half-line"></span>\n </div>\n <div\n class="radiation-meter-indicator"\n aria-hidden="true"\n (pointerdown)="startPointer($event)"\n (pointermove)="dragPointer($event)"\n (pointerup)="endPointer($event)"\n (pointercancel)="endPointer($event)"\n >\n <span\n class="radiation-meter-arrow"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n <span\n class="radiation-meter-handle"\n [style.left]="getLevelOffsetPercent()"\n ></span>\n @if (getLevelValue() > 0) {\n <span\n class="radiation-meter-value"\n [style.left]="getLevelOffsetPercent()"\n >\n {{ getLevelValue() }}\n </span>\n }\n </div>\n </div>\n </div>\n</div>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:flex;flex:1 1 auto;min-height:0;font-size:inherit;flex-direction:column}.radiation-panel{display:flex;flex-direction:row;align-items:flex-start;gap:0;flex-wrap:nowrap;min-height:0;padding:1rem;width:100%;margin-top:auto;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.radiation-info{display:flex;flex-direction:column;flex:0 0 auto;margin-top:1.7rem}.status-resist{background:transparent;border:none;color:#0fbb6b;cursor:pointer;text-align:left;text-transform:uppercase;font-size:inherit;display:flex;align-items:flex-start;position:relative;margin:0}.status-resist:hover .status-resist-text{background:#ffffff14}.status-resist:hover,.status-resist:focus-visible{background:transparent}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:100%;height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:0;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.status-resist-text{display:flex;align-items:center;align-self:stretch;padding:.5rem .5rem 0;border-top:2px solid #0fbb6b;flex:1 1 auto;min-width:200px;white-space:nowrap}.status-resist-right{width:1.25rem;min-height:1.8rem;position:relative;flex:0 0 auto;align-self:stretch}.status-resist-right .bottom-half-line:before{left:0}.radiation-meter{display:flex;flex-direction:column;gap:.75rem;width:100%;justify-self:stretch;flex:1 1 0;min-width:0;--radiation-triangle-width: 14px}.radiation-meter-scale{position:relative;width:100%;height:1rem;line-height:1rem;text-transform:uppercase;letter-spacing:.08em}.radiation-meter-scale-mid{position:absolute;left:calc(50% + 60px);transform:translate(-50%)}.radiation-meter-scale-max{position:absolute;right:0}.radiation-meter-grid{display:grid;grid-template-columns:auto 1fr auto;grid-template-rows:auto auto;align-items:start;column-gap:0;row-gap:0}.status-label{grid-column:1;grid-row:1;text-transform:uppercase;padding:.5rem 2rem 0 .5rem;border-top:2px solid #0fbb6b;letter-spacing:.08em;white-space:nowrap}.status-right{width:1.25rem;height:100%;position:relative;grid-column:3;grid-row:1;pointer-events:none;border-top:2px solid #0fbb6b}.status-right .bottom-half-line:before{right:0}.radiation-meter-track{grid-column:2;grid-row:1;position:relative;width:100%;height:1.5rem;border-top:2px solid #0fbb6b;overflow:visible;cursor:grab;min-width:0}.radiation-meter-fill{position:absolute;top:0;left:0;height:100%;background:#0fbb6b73;box-shadow:0 0 20px #0fbb6b59}.radiation-meter-labels{position:absolute;top:-1px;left:0;width:100%;height:100%;display:flex;justify-content:space-between;align-items:flex-start;padding:0 .1rem 0 0;pointer-events:none}.radiation-meter-tick{width:2px;background:#0fbb6b99;border-radius:1px}.radiation-meter-tick:first-child{width:var(--radiation-triangle-width);margin-left:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,100% 100%)}.radiation-meter-tick--end-triangle{width:var(--radiation-triangle-width);margin-right:calc(-1 * var(--radiation-triangle-width));border-radius:0;clip-path:polygon(0 0,100% 0,0 100%)}.radiation-meter-tick--large{height:65%}.radiation-meter-tick--small{height:35%}.radiation-meter-indicator{grid-column:2;grid-row:2;position:relative;height:2.2rem;width:100%;cursor:grab}.radiation-meter-value{position:absolute;top:1rem;color:#0fbb6b;font-size:.75em;letter-spacing:.08em;text-transform:uppercase;transform:translate(calc(-100% - .4rem));opacity:1;pointer-events:none;white-space:nowrap}.radiation-meter-arrow{position:absolute;top:.1rem;width:0;height:0;border-left:.75rem solid transparent;border-right:.75rem solid transparent;border-bottom:.75rem solid rgba(15,187,107,.7);transform:translate(-50%)}.radiation-meter-handle{position:absolute;top:.8rem;width:4px;height:30px;background:#0fbb6b99;transform:translate(-50%)}.radiation-meter-track:active,.radiation-meter-indicator:active,.radiation-meter-arrow:active,.radiation-meter-handle:active{cursor:grabbing}\n']}]}],propDecorators:{kind:[{type:e.Input,args:[{isSignal:!0,alias:"kind",required:!1}]}]}});class ee{open=!1;title="Edit Effect";name="";description="";closeResult=new c;save=new c;draftName=o("",...ngDevMode?[{debugName:"draftName"}]:[]);draftDescription=o("",...ngDevMode?[{debugName:"draftDescription"}]:[]);ngOnChanges(e){if(e.open&&this.open)return this.draftName.set(this.name??""),void this.draftDescription.set(this.description??"");e.name&&this.draftName.set(this.name??""),e.description&&this.draftDescription.set(this.description??"")}updateName(e){this.draftName.set(e)}updateDescription(e){this.draftDescription.set(e)}closeModal(){this.closeResult.emit()}submit(e){e.preventDefault();const t=this.draftName().trim();t&&this.save.emit({name:t,description:this.draftDescription().trim()})}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:ee,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"21.1.1",type:ee,isStandalone:!0,selector:"pip-boy-effect-edit-modal",inputs:{open:"open",title:"title",name:"name",description:"description"},outputs:{closeResult:"closeResult",save:"save"},usesOnChanges:!0,ngImport:e,template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <form id="effect-edit-form" (submit)="submit($event)">\n <div class="effect-modal-body">\n <label class="effect-modal-field">\n <span>Name</span>\n <input\n type="text"\n name="effect-name"\n [value]="draftName()"\n (input)="updateName($any($event.target).value)"\n />\n </label>\n <label class="effect-modal-field">\n <span>Description</span>\n <textarea\n name="effect-description"\n rows="5"\n [value]="draftDescription()"\n (input)="updateDescription($any($event.target).value)"\n ></textarea>\n </label>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="effect-edit-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.effect-modal-body{display:flex;flex-direction:column;gap:1rem}.effect-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.effect-modal-field input,.effect-modal-field textarea{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.effect-modal-field input:focus,.effect-modal-field textarea:focus{outline:none;border-color:#0fbb6b}.effect-modal-field textarea{resize:vertical;text-transform:none}:host{font-size:inherit}\n"],dependencies:[{kind:"component",type:U,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:ee,decorators:[{type:a,args:[{selector:"pip-boy-effect-edit-modal",standalone:!0,imports:[U],template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <form id="effect-edit-form" (submit)="submit($event)">\n <div class="effect-modal-body">\n <label class="effect-modal-field">\n <span>Name</span>\n <input\n type="text"\n name="effect-name"\n [value]="draftName()"\n (input)="updateName($any($event.target).value)"\n />\n </label>\n <label class="effect-modal-field">\n <span>Description</span>\n <textarea\n name="effect-description"\n rows="5"\n [value]="draftDescription()"\n (input)="updateDescription($any($event.target).value)"\n ></textarea>\n </label>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="effect-edit-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.effect-modal-body{display:flex;flex-direction:column;gap:1rem}.effect-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.effect-modal-field input,.effect-modal-field textarea{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.effect-modal-field input:focus,.effect-modal-field textarea:focus{outline:none;border-color:#0fbb6b}.effect-modal-field textarea{resize:vertical;text-transform:none}:host{font-size:inherit}\n"]}]}],propDecorators:{open:[{type:m}],title:[{type:m}],name:[{type:m}],description:[{type:m}],closeResult:[{type:p}],save:[{type:p}]}});class te{settings=l(C);selectedId=o(null,...ngDevMode?[{debugName:"selectedId"}]:[]);showEditModal=o(!1,...ngDevMode?[{debugName:"showEditModal"}]:[]);editMode=o("ADD",...ngDevMode?[{debugName:"editMode"}]:[]);modalName=o("",...ngDevMode?[{debugName:"modalName"}]:[]);modalDescription=o("",...ngDevMode?[{debugName:"modalDescription"}]:[]);items=u(()=>this.settings.effectItems(),...ngDevMode?[{debugName:"items"}]:[]);selectedItem=u(()=>{const e=this.selectedId();return null===e?null:this.items().find(t=>t.id===e)??null},...ngDevMode?[{debugName:"selectedItem"}]:[]);openAddModal(){this.settings.editLockEnabled()||(this.editMode.set("ADD"),this.modalName.set(""),this.modalDescription.set(""),this.showEditModal.set(!0))}openEditModal(){if(this.settings.editLockEnabled())return;const e=this.selectedItem();e&&(this.editMode.set("EDIT"),this.modalName.set(e.name),this.modalDescription.set(e.description),this.showEditModal.set(!0))}closeEditModal(){this.showEditModal.set(!1)}saveEditModal(e){if(this.settings.editLockEnabled())return;const t=e.name.trim(),n=e.description.trim();if(!t)return;if("ADD"===this.editMode()){const e=this.getNextItemId();return this.settings.effectItems.update(a=>[...a,{id:e,name:t,description:n}]),this.selectedId.set(e),void this.closeEditModal()}const a=this.selectedId();null!==a&&(this.settings.effectItems.update(e=>e.map(e=>e.id===a?{...e,name:t,description:n}:e)),this.closeEditModal())}selectItem(e){this.selectedId.set(this.selectedId()===e?null:e)}deleteSelected(){if(this.settings.editLockEnabled())return;const e=this.selectedId();null!==e&&(this.settings.effectItems.update(t=>t.filter(t=>t.id!==e)),this.selectedId.set(null))}moveSelected(e){if(this.settings.editLockEnabled())return;const t=this.selectedId();null!==t&&this.settings.effectItems.update(n=>{const a=n.findIndex(e=>e.id===t);if(-1===a)return n;const o=a+e;if(o<0||o>=n.length)return n;const i=n.slice(),[s]=i.splice(a,1);return i.splice(o,0,s),i})}getNextItemId(){return this.items().reduce((e,t)=>Math.max(e,t.id),0)+1}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:te,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:te,isStandalone:!0,selector:"pip-boy-eff-layout",ngImport:e,template:'<div class="eff-layout">\n <ul class="eff-list">\n @for (item of items(); track item.id) {\n <li>\n <button\n type="button"\n class="eff-row"\n [class.is-selected]="selectedId() === item.id"\n (click)="selectItem(item.id)"\n >\n <span class="eff-name">{{ item.name }}</span>\n <span class="eff-description">{{ item.description }}</span>\n </button>\n </li>\n } @empty {\n <li class="eff-empty">No effects added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="eff-actions">\n <button type="button" class="eff-add" (click)="openAddModal()">\n + Add\n </button>\n @if (selectedId() !== null) {\n <button type="button" class="eff-edit" (click)="openEditModal()">\n Edit\n </button>\n <button type="button" class="eff-delete" (click)="deleteSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="eff-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="eff-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n</div>\n<pip-boy-effect-edit-modal\n [open]="showEditModal()"\n [title]="editMode() === \'ADD\' ? \'Add Effect\' : \'Edit Effect\'"\n [name]="modalName()"\n [description]="modalDescription()"\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n/>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:block;width:100%;height:100%;font-size:inherit}.eff-layout{display:flex;flex-direction:column;height:100%;min-height:0}.eff-list{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.75rem 1rem .5rem;display:flex;flex-direction:column;justify-content:center;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.eff-list li{margin:0;padding:0}.eff-row{background:transparent;border:none;border-bottom:2px solid rgba(15,187,107,.6);color:#0fbb6b;cursor:pointer;font-size:inherit;padding:.6rem .2rem;text-align:left;text-transform:none;white-space:normal;width:100%;display:grid;grid-template-columns:1fr 1fr;gap:1rem}.eff-row:hover{background:#0fbb6b1f}.eff-row.is-selected{background:#0fbb6b2e}.eff-list li:last-child .eff-row{border-bottom:none}.eff-name,.eff-description{word-break:break-word;font-size:inherit}.eff-empty{opacity:.6;padding:.4rem .2rem}.eff-actions{display:flex;gap:.5rem;padding:.75rem 1rem 1rem}.eff-add,.eff-edit,.eff-delete{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.eff-add:hover,.eff-edit:hover,.eff-delete:hover{background:#0fbb6b1f}.eff-move{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.eff-move:hover{background:#0fbb6b1f}@media(max-width:720px),(max-height:560px){.eff-actions{gap:.35rem;padding:.75rem .75rem .9rem}.eff-add,.eff-edit,.eff-delete{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.eff-move{flex:0 0 1.6rem;height:2.1rem}}\n"],dependencies:[{kind:"component",type:ee,selector:"pip-boy-effect-edit-modal",inputs:["open","title","name","description"],outputs:["closeResult","save"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:te,decorators:[{type:a,args:[{selector:"pip-boy-eff-layout",standalone:!0,imports:[ee],template:'<div class="eff-layout">\n <ul class="eff-list">\n @for (item of items(); track item.id) {\n <li>\n <button\n type="button"\n class="eff-row"\n [class.is-selected]="selectedId() === item.id"\n (click)="selectItem(item.id)"\n >\n <span class="eff-name">{{ item.name }}</span>\n <span class="eff-description">{{ item.description }}</span>\n </button>\n </li>\n } @empty {\n <li class="eff-empty">No effects added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="eff-actions">\n <button type="button" class="eff-add" (click)="openAddModal()">\n + Add\n </button>\n @if (selectedId() !== null) {\n <button type="button" class="eff-edit" (click)="openEditModal()">\n Edit\n </button>\n <button type="button" class="eff-delete" (click)="deleteSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="eff-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="eff-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n</div>\n<pip-boy-effect-edit-modal\n [open]="showEditModal()"\n [title]="editMode() === \'ADD\' ? \'Add Effect\' : \'Edit Effect\'"\n [name]="modalName()"\n [description]="modalDescription()"\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n/>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:block;width:100%;height:100%;font-size:inherit}.eff-layout{display:flex;flex-direction:column;height:100%;min-height:0}.eff-list{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.75rem 1rem .5rem;display:flex;flex-direction:column;justify-content:center;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.eff-list li{margin:0;padding:0}.eff-row{background:transparent;border:none;border-bottom:2px solid rgba(15,187,107,.6);color:#0fbb6b;cursor:pointer;font-size:inherit;padding:.6rem .2rem;text-align:left;text-transform:none;white-space:normal;width:100%;display:grid;grid-template-columns:1fr 1fr;gap:1rem}.eff-row:hover{background:#0fbb6b1f}.eff-row.is-selected{background:#0fbb6b2e}.eff-list li:last-child .eff-row{border-bottom:none}.eff-name,.eff-description{word-break:break-word;font-size:inherit}.eff-empty{opacity:.6;padding:.4rem .2rem}.eff-actions{display:flex;gap:.5rem;padding:.75rem 1rem 1rem}.eff-add,.eff-edit,.eff-delete{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.eff-add:hover,.eff-edit:hover,.eff-delete:hover{background:#0fbb6b1f}.eff-move{background:#0fbb6b0d;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.eff-move:hover{background:#0fbb6b1f}@media(max-width:720px),(max-height:560px){.eff-actions{gap:.35rem;padding:.75rem .75rem .9rem}.eff-add,.eff-edit,.eff-delete{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.eff-move{flex:0 0 1.6rem;height:2.1rem}}\n"]}]}]});class ne{settings=l(C);selectedQuestId=o(null,...ngDevMode?[{debugName:"selectedQuestId"}]:[]);selectedTaskId=o(null,...ngDevMode?[{debugName:"selectedTaskId"}]:[]);showEditModal=o(!1,...ngDevMode?[{debugName:"showEditModal"}]:[]);editTarget=o("QUEST",...ngDevMode?[{debugName:"editTarget"}]:[]);editMode=o("ADD",...ngDevMode?[{debugName:"editMode"}]:[]);editingTaskId=o(null,...ngDevMode?[{debugName:"editingTaskId"}]:[]);modalName=o("",...ngDevMode?[{debugName:"modalName"}]:[]);quests=u(()=>this.settings.questItems(),...ngDevMode?[{debugName:"quests"}]:[]);selectedQuest=u(()=>{const e=this.selectedQuestId();return null===e?null:this.quests().find(t=>t.id===e)??null},...ngDevMode?[{debugName:"selectedQuest"}]:[]);tasks=u(()=>this.selectedQuest()?.tasks??[],...ngDevMode?[{debugName:"tasks"}]:[]);selectedTask=u(()=>{const e=this.selectedTaskId();return null===e?null:this.tasks().find(t=>t.id===e)??null},...ngDevMode?[{debugName:"selectedTask"}]:[]);modalTitle=u(()=>{const e=this.editTarget(),t=this.editMode();return"TASK"===e?"ADD"===t?"Add Task":"Edit Task":"ADD"===t?"Add Quest":"Edit Quest"},...ngDevMode?[{debugName:"modalTitle"}]:[]);selectQuest(e){const t=this.selectedQuestId()===e?null:e;this.selectedQuestId.set(t),null===t&&this.selectedTaskId.set(null)}selectTask(e){this.selectedTaskId.set(this.selectedTaskId()===e?null:e)}openAddQuest(){this.settings.editLockEnabled()||(this.editTarget.set("QUEST"),this.editMode.set("ADD"),this.modalName.set(""),this.showEditModal.set(!0))}openEditQuest(e){this.settings.editLockEnabled()||(this.editTarget.set("QUEST"),this.editMode.set("EDIT"),this.modalName.set(e.name),this.selectedQuestId.set(e.id),this.showEditModal.set(!0))}openAddTask(){this.settings.editLockEnabled()||this.selectedQuest()&&(this.editTarget.set("TASK"),this.editMode.set("ADD"),this.editingTaskId.set(null),this.modalName.set(""),this.showEditModal.set(!0))}openEditTask(e){this.settings.editLockEnabled()||(this.editTarget.set("TASK"),this.editMode.set("EDIT"),this.editingTaskId.set(e.id),this.modalName.set(e.name),this.showEditModal.set(!0))}openEditSelectedQuest(){if(this.settings.editLockEnabled())return;const e=this.selectedQuest();e&&this.openEditQuest(e)}openEditSelectedTask(){if(this.settings.editLockEnabled())return;const e=this.selectedTask();e&&this.openEditTask(e)}closeEditModal(){this.showEditModal.set(!1)}saveEditModal(e){const t=e.name?.trim()??"";if(!t)return;if("QUEST"===this.editTarget()){if("ADD"===this.editMode()){const e=this.getNextQuestId();this.settings.questItems.update(n=>[...n,{id:e,name:t,completed:!1,tasks:[]}]),this.selectedQuestId.set(e),this.selectedTaskId.set(null)}else{const e=this.selectedQuestId();if(null===e)return;this.settings.questItems.update(n=>n.map(n=>n.id===e?{...n,name:t}:n))}return void this.closeEditModal()}const n=this.selectedQuest();if(n){if("ADD"===this.editMode()){const e=this.getNextTaskId(n);this.settings.questItems.update(a=>a.map(a=>a.id===n.id?{...a,tasks:[...a.tasks,{id:e,name:t,completed:!1}]}:a))}else{const e=this.editingTaskId();if(null===e)return;this.settings.questItems.update(a=>a.map(a=>a.id===n.id?{...a,tasks:a.tasks.map(n=>n.id===e?{...n,name:t}:n)}:a))}this.closeEditModal()}}toggleQuest(e){this.settings.questItems.update(t=>t.map(t=>t.id===e?{...t,completed:!t.completed}:t))}toggleTask(e){const t=this.selectedQuest();t&&this.settings.questItems.update(n=>n.map(n=>n.id===t.id?{...n,tasks:n.tasks.map(t=>t.id===e?{...t,completed:!t.completed}:t)}:n))}deleteSelectedQuest(){if(this.settings.editLockEnabled())return;const e=this.selectedQuestId();null!==e&&(this.settings.questItems.update(t=>t.filter(t=>t.id!==e)),this.selectedQuestId.set(null),this.selectedTaskId.set(null))}deleteSelectedTask(){if(this.settings.editLockEnabled())return;const e=this.selectedQuest(),t=this.selectedTaskId();e&&null!==t&&(this.settings.questItems.update(n=>n.map(n=>n.id===e.id?{...n,tasks:n.tasks.filter(e=>e.id!==t)}:n)),this.selectedTaskId.set(null))}moveSelectedQuest(e){if(this.settings.editLockEnabled())return;const t=this.selectedQuestId();null!==t&&this.settings.questItems.update(n=>{const a=n.findIndex(e=>e.id===t);if(-1===a)return n;const o=a+e;if(o<0||o>=n.length)return n;const i=n.slice(),[s]=i.splice(a,1);return i.splice(o,0,s),i})}moveSelectedTask(e){if(this.settings.editLockEnabled())return;const t=this.selectedQuest(),n=this.selectedTaskId();t&&null!==n&&this.settings.questItems.update(a=>a.map(a=>{if(a.id!==t.id)return a;const o=a.tasks.findIndex(e=>e.id===n);if(-1===o)return a;const i=o+e;if(i<0||i>=a.tasks.length)return a;const s=a.tasks.slice(),[r]=s.splice(o,1);return s.splice(i,0,r),{...a,tasks:s}}))}getNextQuestId(){return this.quests().reduce((e,t)=>Math.max(e,t.id),0)+1}getNextTaskId(e){return e.tasks.reduce((e,t)=>Math.max(e,t.id),0)+1}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:ne,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:ne,isStandalone:!0,selector:"pip-boy-quests-layout",ngImport:e,template:'<div class="quest-layout">\n <div class="quest-column">\n <ul class="quest-list">\n @for (quest of quests(); track quest.id) {\n <li\n class="quest-row"\n [class.is-selected]="selectedQuestId() === quest.id"\n (click)="selectQuest(quest.id)"\n (keyup.enter)="selectQuest(quest.id)"\n tabindex="0"\n >\n <button\n type="button"\n class="quest-toggle"\n [class.is-checked]="quest.completed"\n (click)="toggleQuest(quest.id); $event.stopPropagation()"\n aria-label="Toggle quest"\n ></button>\n <button\n type="button"\n class="quest-name"\n (click)="selectQuest(quest.id); $event.stopPropagation()"\n >\n {{ quest.name }}\n </button>\n </li>\n } @empty {\n <li class="quest-empty">No quests added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="quest-actions">\n <button type="button" class="quest-add" (click)="openAddQuest()">\n + Add\n </button>\n <button\n type="button"\n class="quest-edit"\n [disabled]="!selectedQuest()"\n (click)="openEditSelectedQuest()"\n >\n Edit\n </button>\n <button\n type="button"\n class="quest-delete"\n [disabled]="!selectedQuest()"\n (click)="deleteSelectedQuest()"\n >\n - Delete\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedQuest()"\n (click)="moveSelectedQuest(-1)"\n aria-label="Move quest up"\n >\n ▲\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedQuest()"\n (click)="moveSelectedQuest(1)"\n aria-label="Move quest down"\n >\n ▼\n </button>\n </div>\n }\n </div>\n <div class="quest-column">\n <ul class="quest-list">\n @if (selectedQuest()) {\n @for (task of tasks(); track task.id) {\n <li\n class="quest-row"\n [class.is-selected]="selectedTaskId() === task.id"\n (click)="selectTask(task.id)"\n (keyup.enter)="selectTask(task.id)"\n tabindex="0"\n >\n <button\n type="button"\n class="quest-toggle"\n [class.is-checked]="task.completed"\n (click)="toggleTask(task.id); $event.stopPropagation()"\n aria-label="Toggle task"\n ></button>\n <button\n type="button"\n class="quest-name"\n (click)="selectTask(task.id); $event.stopPropagation()"\n >\n {{ task.name }}\n </button>\n </li>\n } @empty {\n <li class="quest-empty">No tasks added.</li>\n }\n } @else {\n <li class="quest-empty">Select a quest to view tasks.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="quest-actions">\n @if (selectedQuest()) {\n <button type="button" class="quest-add" (click)="openAddTask()">\n + Add\n </button>\n <button\n type="button"\n class="quest-edit"\n [disabled]="!selectedTask()"\n (click)="openEditSelectedTask()"\n >\n Edit\n </button>\n <button\n type="button"\n class="quest-delete"\n [disabled]="!selectedTask()"\n (click)="deleteSelectedTask()"\n >\n - Delete\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedTask()"\n (click)="moveSelectedTask(-1)"\n aria-label="Move task up"\n >\n ▲\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedTask()"\n (click)="moveSelectedTask(1)"\n aria-label="Move task down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n</div>\n<pip-boy-stat-edit-modal\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n [open]="showEditModal()"\n [title]="modalTitle()"\n [name]="modalName()"\n nameLabel="Name"\n [showName]="true"\n [fields]="[]"\n/>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:block;width:100%;height:100%;font-size:inherit}.quest-layout{display:flex;gap:1.5rem;height:100%;min-height:0}.quest-column{display:flex;flex:1 1 50%;flex-direction:column;min-height:0}.quest-list{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.quest-row{align-items:center;display:grid;grid-template-columns:1.5rem 1fr;gap:.6rem;padding:.25rem .35rem .25rem .2rem;font-size:inherit}.quest-row.is-selected{background:#0fbb6b2e}.quest-toggle{background:transparent;border:1px solid rgba(15,187,107,.65);cursor:pointer;height:.9rem;width:.9rem}.quest-toggle.is-checked{background:#0fbb6b}.quest-toggle:disabled{cursor:default;opacity:.6}.quest-name{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font-size:inherit;padding:0;text-align:left}.quest-name:hover{opacity:.8}.quest-empty{opacity:.6;padding:0 .2rem}.quest-actions{display:flex;gap:.5rem;justify-content:flex-end;padding:0}.quest-add{background:#0fbb6b14;border:none;border-left:0;border-right:0;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.quest-add:hover{background:#0fbb6b2e}.quest-edit,.quest-delete{background:#0fbb6b0d;border:none;border-left:0;border-right:0;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.quest-edit:hover,.quest-delete:hover{background:#0fbb6b1f}.quest-edit:disabled,.quest-delete:disabled{cursor:not-allowed;opacity:.5}.quest-move{background:#0fbb6b0d;border:none;border-left:0;border-right:0;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.quest-move:hover{background:#0fbb6b1f}.quest-move:disabled{cursor:not-allowed;opacity:.5}.quest-actions button{flex:1 1 0}.quest-actions .quest-move{flex:0 0 2rem;width:2rem;padding:0}@media(max-width:720px),(max-height:560px){.quest-actions{gap:.35rem}.quest-add,.quest-edit,.quest-delete{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.quest-move,.quest-actions .quest-move{flex:0 0 1.6rem;width:1.6rem;height:2.1rem}}\n"],dependencies:[{kind:"component",type:_,selector:"pip-boy-stat-edit-modal",inputs:["open","title","name","nameLabel","showName","nameOptions","imageUrl","showImage","fields","textFields"],outputs:["closeResult","save","nameChange"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:ne,decorators:[{type:a,args:[{selector:"pip-boy-quests-layout",standalone:!0,imports:[_],template:'<div class="quest-layout">\n <div class="quest-column">\n <ul class="quest-list">\n @for (quest of quests(); track quest.id) {\n <li\n class="quest-row"\n [class.is-selected]="selectedQuestId() === quest.id"\n (click)="selectQuest(quest.id)"\n (keyup.enter)="selectQuest(quest.id)"\n tabindex="0"\n >\n <button\n type="button"\n class="quest-toggle"\n [class.is-checked]="quest.completed"\n (click)="toggleQuest(quest.id); $event.stopPropagation()"\n aria-label="Toggle quest"\n ></button>\n <button\n type="button"\n class="quest-name"\n (click)="selectQuest(quest.id); $event.stopPropagation()"\n >\n {{ quest.name }}\n </button>\n </li>\n } @empty {\n <li class="quest-empty">No quests added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="quest-actions">\n <button type="button" class="quest-add" (click)="openAddQuest()">\n + Add\n </button>\n <button\n type="button"\n class="quest-edit"\n [disabled]="!selectedQuest()"\n (click)="openEditSelectedQuest()"\n >\n Edit\n </button>\n <button\n type="button"\n class="quest-delete"\n [disabled]="!selectedQuest()"\n (click)="deleteSelectedQuest()"\n >\n - Delete\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedQuest()"\n (click)="moveSelectedQuest(-1)"\n aria-label="Move quest up"\n >\n ▲\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedQuest()"\n (click)="moveSelectedQuest(1)"\n aria-label="Move quest down"\n >\n ▼\n </button>\n </div>\n }\n </div>\n <div class="quest-column">\n <ul class="quest-list">\n @if (selectedQuest()) {\n @for (task of tasks(); track task.id) {\n <li\n class="quest-row"\n [class.is-selected]="selectedTaskId() === task.id"\n (click)="selectTask(task.id)"\n (keyup.enter)="selectTask(task.id)"\n tabindex="0"\n >\n <button\n type="button"\n class="quest-toggle"\n [class.is-checked]="task.completed"\n (click)="toggleTask(task.id); $event.stopPropagation()"\n aria-label="Toggle task"\n ></button>\n <button\n type="button"\n class="quest-name"\n (click)="selectTask(task.id); $event.stopPropagation()"\n >\n {{ task.name }}\n </button>\n </li>\n } @empty {\n <li class="quest-empty">No tasks added.</li>\n }\n } @else {\n <li class="quest-empty">Select a quest to view tasks.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="quest-actions">\n @if (selectedQuest()) {\n <button type="button" class="quest-add" (click)="openAddTask()">\n + Add\n </button>\n <button\n type="button"\n class="quest-edit"\n [disabled]="!selectedTask()"\n (click)="openEditSelectedTask()"\n >\n Edit\n </button>\n <button\n type="button"\n class="quest-delete"\n [disabled]="!selectedTask()"\n (click)="deleteSelectedTask()"\n >\n - Delete\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedTask()"\n (click)="moveSelectedTask(-1)"\n aria-label="Move task up"\n >\n ▲\n </button>\n <button\n type="button"\n class="quest-move"\n [disabled]="!selectedTask()"\n (click)="moveSelectedTask(1)"\n aria-label="Move task down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n</div>\n<pip-boy-stat-edit-modal\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n [open]="showEditModal()"\n [title]="modalTitle()"\n [name]="modalName()"\n nameLabel="Name"\n [showName]="true"\n [fields]="[]"\n/>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{display:block;width:100%;height:100%;font-size:inherit}.quest-layout{display:flex;gap:1.5rem;height:100%;min-height:0}.quest-column{display:flex;flex:1 1 50%;flex-direction:column;min-height:0}.quest-list{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.quest-row{align-items:center;display:grid;grid-template-columns:1.5rem 1fr;gap:.6rem;padding:.25rem .35rem .25rem .2rem;font-size:inherit}.quest-row.is-selected{background:#0fbb6b2e}.quest-toggle{background:transparent;border:1px solid rgba(15,187,107,.65);cursor:pointer;height:.9rem;width:.9rem}.quest-toggle.is-checked{background:#0fbb6b}.quest-toggle:disabled{cursor:default;opacity:.6}.quest-name{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font-size:inherit;padding:0;text-align:left}.quest-name:hover{opacity:.8}.quest-empty{opacity:.6;padding:0 .2rem}.quest-actions{display:flex;gap:.5rem;justify-content:flex-end;padding:0}.quest-add{background:#0fbb6b14;border:none;border-left:0;border-right:0;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.quest-add:hover{background:#0fbb6b2e}.quest-edit,.quest-delete{background:#0fbb6b0d;border:none;border-left:0;border-right:0;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.quest-edit:hover,.quest-delete:hover{background:#0fbb6b1f}.quest-edit:disabled,.quest-delete:disabled{cursor:not-allowed;opacity:.5}.quest-move{background:#0fbb6b0d;border:none;border-left:0;border-right:0;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.quest-move:hover{background:#0fbb6b1f}.quest-move:disabled{cursor:not-allowed;opacity:.5}.quest-actions button{flex:1 1 0}.quest-actions .quest-move{flex:0 0 2rem;width:2rem;padding:0}@media(max-width:720px),(max-height:560px){.quest-actions{gap:.35rem}.quest-add,.quest-edit,.quest-delete{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.quest-move,.quest-actions .quest-move{flex:0 0 1.6rem;width:1.6rem;height:2.1rem}}\n"]}]}]});class ae{dbPromise=this.openDb();soundUrls=o({},...ngDevMode?[{debugName:"soundUrls"}]:[]);soundLabels=o({},...ngDevMode?[{debugName:"soundLabels"}]:[]);metaLoading=new Set;activeSounds=new Set;getSoundLabel(e){if(!e)return null;const t=this.soundLabels()[e];return t||(this.loadSoundMeta(e),null)}async playSound(e){if(!e)return;const t=this.soundUrls()[e];if(t){const e=new Audio(t);return this.trackAudio(e),void await e.play().catch(()=>{this.activeSounds.delete(e)})}const n=await this.getRecord(e);if(!n)return;const a=URL.createObjectURL(n.blob);this.cacheUrl(e,a),this.cacheLabel(e,n.fileName);const o=new Audio(a);this.trackAudio(o),await o.play().catch(()=>{this.activeSounds.delete(o)})}stopAll(){for(const e of this.activeSounds)e.pause(),e.currentTime=0;this.activeSounds.clear()}async saveFile(e){const t=this.createId(),n={id:t,fileName:e.name,mime:e.type||"application/octet-stream"};return await this.putRecord({...n,blob:e}),this.cacheUrl(t,URL.createObjectURL(e)),this.cacheLabel(t,n.fileName),n}async saveBlobWithId(e,t,n,a){await this.putRecord({id:e,blob:t,fileName:n,mime:a}),this.cacheUrl(e,URL.createObjectURL(t)),this.cacheLabel(e,n)}async getRecord(e){const t=await this.dbPromise;return new Promise((n,a)=>{const o=t.transaction("sounds","readonly").objectStore("sounds").get(e);o.onsuccess=()=>{n(o.result??null)},o.onerror=()=>a(o.error)})}extensionFromMime(e){switch(e){case"audio/mpeg":case"audio/mp3":return".mp3";case"audio/wav":case"audio/x-wav":case"audio/wave":return".wav";case"audio/ogg":return".ogg";case"audio/aac":return".aac";case"audio/mp4":case"audio/x-m4a":return".m4a";case"audio/webm":return".webm";default:return""}}cacheUrl(e,t){this.soundUrls.update(n=>({...n,[e]:t}))}cacheLabel(e,t){this.soundLabels.update(n=>({...n,[e]:t}))}trackAudio(e){const t=()=>{this.activeSounds.delete(e),e.onended=null,e.onpause=null};this.activeSounds.add(e),e.onended=t,e.onpause=t}async loadSoundMeta(e){if(!this.metaLoading.has(e)){this.metaLoading.add(e);try{const t=await this.getRecord(e);if(!t)return;this.cacheLabel(e,t.fileName)}finally{this.metaLoading.delete(e)}}}async putRecord(e){const t=await this.dbPromise;return new Promise((n,a)=>{const o=t.transaction("sounds","readwrite").objectStore("sounds").put(e);o.onsuccess=()=>n(),o.onerror=()=>a(o.error)})}openDb(){return new Promise((e,t)=>{const n=indexedDB.open("pipBoy3000Sounds",1);n.onupgradeneeded=()=>{const e=n.result;e.objectStoreNames.contains("sounds")||e.createObjectStore("sounds",{keyPath:"id"})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}createId(){return"undefined"!=typeof crypto&&"randomUUID"in crypto?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:ae,deps:[],target:e.ɵɵFactoryTarget.Injectable});static"ɵprov"=e.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:ae,providedIn:"root"})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:ae,decorators:[{type:i,args:[{providedIn:"root"}]}]});class oe{soundStore=l(ae);audio=null;audioUrl=null;currentChannel=null;currentSoundId=null;volumeByChannel=new Map;endedHandlers=new Map;playingSignals={NOTES:o(!1),RADIO:o(!1)};currentChannelSignal=o(null,...ngDevMode?[{debugName:"currentChannelSignal"}]:[]);currentSoundIdSignal=o(null,...ngDevMode?[{debugName:"currentSoundIdSignal"}]:[]);analyserByChannel=new Map;sourceByChannel=new Map;audioContext=null;setPlaying(e,t){this.playingSignals[e].set(t)}updateEndedHandler(){if(!this.audio||!this.currentChannel)return;const e=this.currentChannel,t=this.endedHandlers.get(e);this.audio.onended=()=>{this.setPlaying(e,!1),t?.()}}getAudioContext(){if(this.audioContext)return this.audioContext;if("undefined"==typeof window)return null;if("undefined"!=typeof AudioContext)this.audioContext=new AudioContext;else{if(void 0===window.webkitAudioContext)return null;this.audioContext=new window.webkitAudioContext}return this.audioContext}attachAnalyser(e,t){this.detachAnalyser(e);const n=this.getAudioContext();if(!n)return;"suspended"===n.state&&n.resume();const a=n.createMediaElementSource(t),o=n.createAnalyser();o.fftSize=256,a.connect(o),o.connect(n.destination),this.analyserByChannel.set(e,o),this.sourceByChannel.set(e,a)}detachAnalyser(e){const t=this.analyserByChannel.get(e);t&&t.disconnect();const n=this.sourceByChannel.get(e);n&&n.disconnect(),this.analyserByChannel.delete(e),this.sourceByChannel.delete(e)}setOnEnded(e,t){this.endedHandlers.set(e,t),this.currentChannel===e&&this.audio&&this.updateEndedHandler()}getCurrentSoundId(e){return this.currentChannelSignal()!==e?null:this.currentSoundIdSignal()}isPlaying(e){return this.playingSignals[e]()}async play(e,t){if(!t)return;if(this.audio&&this.currentChannel===e&&this.currentSoundId===t){try{await this.audio.play(),this.setPlaying(e,!0)}catch{this.setPlaying(e,!1)}return}this.stop();const n=await this.soundStore.getRecord(t);if(!n)return;const a=URL.createObjectURL(n.blob),o=new Audio(a),i=this.volumeByChannel.get(e);"number"==typeof i&&(o.volume=Math.min(1,Math.max(0,i))),this.audio=o,this.audioUrl=a,this.currentChannel=e,this.currentSoundId=t,this.currentChannelSignal.set(e),this.currentSoundIdSignal.set(t),this.attachAnalyser(e,o),this.updateEndedHandler();try{await o.play(),this.setPlaying(e,!0)}catch{this.setPlaying(e,!1)}}async toggle(e,t){if(this.audio&&this.currentChannel===e&&this.currentSoundId===t)if(this.audio.paused)try{await this.audio.play(),this.setPlaying(e,!0)}catch{this.setPlaying(e,!1)}else this.audio.pause(),this.setPlaying(e,!1);else await this.play(e,t)}pause(e){this.audio&&this.currentChannel===e&&(this.audio.pause(),this.setPlaying(e,!1))}stop(e){e&&this.currentChannel!==e||(this.audio&&(this.audio.pause(),this.audio.currentTime=0),this.audioUrl&&URL.revokeObjectURL(this.audioUrl),e?this.detachAnalyser(e):this.currentChannel&&this.detachAnalyser(this.currentChannel),e&&this.setPlaying(e,!1),this.currentChannel&&this.setPlaying(this.currentChannel,!1),this.audio=null,this.audioUrl=null,this.currentChannel=null,this.currentSoundId=null,this.currentChannelSignal.set(null),this.currentSoundIdSignal.set(null))}fillWaveform(e,t){const n=this.analyserByChannel.get(e);return!!n&&(n.getByteTimeDomainData(t),!0)}setVolume(e,t){const n=Math.min(1,Math.max(0,t));this.volumeByChannel.set(e,n),this.audio&&this.currentChannel===e&&(this.audio.volume=n)}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:oe,deps:[],target:e.ɵɵFactoryTarget.Injectable});static"ɵprov"=e.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:oe,providedIn:"root"})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:oe,decorators:[{type:i,args:[{providedIn:"root"}]}]});class ie{openValue=!1;nameValue="";fileLabelValue=null;set open(e){this.openValue=e,e&&(this.draftName.set(this.nameValue??""),this.draftFileLabel.set(this.fileLabelValue),this.draftFile=null)}get open(){return this.openValue}set name(e){this.nameValue=e??"",this.openValue&&this.draftName.set(this.nameValue)}get name(){return this.nameValue}set fileLabel(e){this.fileLabelValue=e,this.openValue&&this.draftFileLabel.set(e)}get fileLabel(){return this.fileLabelValue}title="Edit Audio";nameLabel="Song Name";fileFieldLabel="Song File";selectLabel="Select Song";closeResult=new c;save=new c;draftName=o("",...ngDevMode?[{debugName:"draftName"}]:[]);draftFileLabel=o(null,...ngDevMode?[{debugName:"draftFileLabel"}]:[]);draftFile=null;closeModal(){this.closeResult.emit()}updateName(e){this.draftName.set(e)}onFileSelected(e){const t=e.target,n=t.files?.[0]??null;this.draftFile=n,this.draftFileLabel.set(n?.name??this.fileLabel),t&&(t.value="")}removeFile(){this.draftFile=null,this.draftFileLabel.set(null)}submit(e){e.preventDefault();const t=this.draftName().trim();t&&this.save.emit({name:t,file:this.draftFile})}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:ie,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:ie,isStandalone:!0,selector:"pip-boy-audio-edit-modal",inputs:{open:"open",name:"name",fileLabel:"fileLabel",title:"title",nameLabel:"nameLabel",fileFieldLabel:"fileFieldLabel",selectLabel:"selectLabel"},outputs:{closeResult:"closeResult",save:"save"},ngImport:e,template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <form id="audio-edit-form" (submit)="submit($event)">\n <div class="audio-modal-body">\n <label class="audio-modal-field">\n <span>{{ nameLabel }}</span>\n <input\n type="text"\n [value]="draftName()"\n (input)="updateName($any($event.target).value)"\n />\n </label>\n <div class="audio-modal-field">\n <span>{{ fileFieldLabel }}</span>\n <div class="audio-modal-file-row">\n <button\n type="button"\n class="audio-modal-file-button"\n (click)="audioFileInput.click()"\n >\n {{ draftFileLabel() ?? selectLabel }}\n </button>\n @if (draftFileLabel()) {\n <button\n type="button"\n class="audio-modal-file-remove"\n (click)="removeFile()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #audioFileInput\n type="file"\n accept="audio/*"\n (change)="onFileSelected($event)"\n />\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="audio-edit-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.audio-modal-body{display:flex;flex-direction:column;gap:1rem}.audio-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.audio-modal-field input{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.audio-modal-field input:focus{outline:none;border-color:#0fbb6b}.audio-modal-file-row{display:flex;gap:.5rem;align-items:center}.audio-modal-file-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;flex:1 1 auto;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.audio-modal-file-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.audio-modal-file-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.audio-modal-file-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}:host{font-size:inherit}\n"],dependencies:[{kind:"component",type:U,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:ie,decorators:[{type:a,args:[{selector:"pip-boy-audio-edit-modal",standalone:!0,imports:[U],template:'<pip-boy-dialog [open]="open" [title]="title" (closeResult)="closeModal()">\n <form id="audio-edit-form" (submit)="submit($event)">\n <div class="audio-modal-body">\n <label class="audio-modal-field">\n <span>{{ nameLabel }}</span>\n <input\n type="text"\n [value]="draftName()"\n (input)="updateName($any($event.target).value)"\n />\n </label>\n <div class="audio-modal-field">\n <span>{{ fileFieldLabel }}</span>\n <div class="audio-modal-file-row">\n <button\n type="button"\n class="audio-modal-file-button"\n (click)="audioFileInput.click()"\n >\n {{ draftFileLabel() ?? selectLabel }}\n </button>\n @if (draftFileLabel()) {\n <button\n type="button"\n class="audio-modal-file-remove"\n (click)="removeFile()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #audioFileInput\n type="file"\n accept="audio/*"\n (change)="onFileSelected($event)"\n />\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="audio-edit-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.audio-modal-body{display:flex;flex-direction:column;gap:1rem}.audio-modal-field{display:flex;flex-direction:column;gap:.5rem;text-transform:uppercase}.audio-modal-field input{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);padding:.6rem .75rem}.audio-modal-field input:focus{outline:none;border-color:#0fbb6b}.audio-modal-file-row{display:flex;gap:.5rem;align-items:center}.audio-modal-file-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;flex:1 1 auto;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.audio-modal-file-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.audio-modal-file-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.audio-modal-file-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}:host{font-size:inherit}\n"]}]}],propDecorators:{open:[{type:m}],name:[{type:m}],fileLabel:[{type:m}],title:[{type:m}],nameLabel:[{type:m}],fileFieldLabel:[{type:m}],selectLabel:[{type:m}],closeResult:[{type:p}],save:[{type:p}]}});class se{constructor(){r(()=>{const e=this.items(),t=this.selectedId();e.length?null!==t&&e.some(e=>e.id===t)||this.setSelectedId(e[0].id):null!==t&&this.setSelectedId(null)}),r(()=>{this.settings.playbackResetToken(),this.autoplayEnabled.set(!1),this.shuffleEnabled.set(!1),this.currentPlayingId.set(null)}),r(()=>{const e=this.audioPlayer.getCurrentSoundId(this.getChannel());if(!e)return void(null!==this.currentPlayingId()&&this.currentPlayingId.set(null));const t=this.items().find(t=>t.soundId===e);t?this.currentPlayingId()!==t.id&&this.currentPlayingId.set(t.id):null!==this.currentPlayingId()&&this.currentPlayingId.set(null)})}category="NOTES";waveformColorRgb="116, 255, 126";settings=l(C);soundStore=l(ae);audioPlayer=l(oe);showEditModal=o(!1,...ngDevMode?[{debugName:"showEditModal"}]:[]);editMode=o("ADD",...ngDevMode?[{debugName:"editMode"}]:[]);modalName=o("",...ngDevMode?[{debugName:"modalName"}]:[]);modalFileLabel=o(null,...ngDevMode?[{debugName:"modalFileLabel"}]:[]);autoplayEnabled=o(!1,...ngDevMode?[{debugName:"autoplayEnabled"}]:[]);shuffleEnabled=o(!1,...ngDevMode?[{debugName:"shuffleEnabled"}]:[]);currentPlayingId=o(null,...ngDevMode?[{debugName:"currentPlayingId"}]:[]);channelPlaying=u(()=>this.audioPlayer.isPlaying(this.getChannel()),...ngDevMode?[{debugName:"channelPlaying"}]:[]);waveformCanvas=b("waveformCanvas",...ngDevMode?[{debugName:"waveformCanvas"}]:[]);animationFrameId=null;animationAngle=0;waveformResizeObserver=null;lastWaveformPixelRatio=1;waveformSamples=new Uint8Array(new ArrayBuffer(256));items=u(()=>this.getItems(),...ngDevMode?[{debugName:"items"}]:[]);selectedItem=u(()=>{const e=this.selectedId();return null===e?null:this.items().find(t=>t.id===e)??null},...ngDevMode?[{debugName:"selectedItem"}]:[]);modalTitle=u(()=>{const e=this.editMode(),t="RADIO"===this.category?"Radio":"Note";return"ADD"===e?`Add ${t}`:`Edit ${t}`},...ngDevMode?[{debugName:"modalTitle"}]:[]);modalLabelPrefix=u(()=>"RADIO"===this.category?"Song":"Note",...ngDevMode?[{debugName:"modalLabelPrefix"}]:[]);currentPlayingName=u(()=>{const e=this.currentPlayingId();return null===e?"":this.items().find(t=>t.id===e)?.name??""},...ngDevMode?[{debugName:"currentPlayingName"}]:[]);ngOnInit(){this.audioPlayer.setOnEnded(this.getChannel(),this.onEndedHandler)}ngAfterViewInit(){this.updateWaveformCanvasSize(),this.attachWaveformResizeObserver(),this.startWaveAnimation()}ngOnDestroy(){"NOTES"===this.category&&this.audioPlayer.stop("NOTES"),this.audioPlayer.setOnEnded(this.getChannel(),null),this.stopWaveAnimation(),this.waveformResizeObserver?.disconnect(),this.waveformResizeObserver=null}onEndedHandler=()=>{this.autoplayEnabled()?this.playNext():this.currentPlayingId.set(null)};openAddModal(){this.settings.editLockEnabled()||(this.editMode.set("ADD"),this.modalName.set(""),this.modalFileLabel.set(null),this.showEditModal.set(!0))}openEditModal(){if(this.settings.editLockEnabled())return;const e=this.selectedItem();e&&(this.editMode.set("EDIT"),this.modalName.set(e.name),this.modalFileLabel.set(this.soundStore.getSoundLabel(e.soundId)),this.showEditModal.set(!0))}closeEditModal(){this.showEditModal.set(!1)}selectItem(e){const t=this.selectedId();this.setSelectedId(t===e?null:e)}async saveEditModal(e){if(this.settings.editLockEnabled())return;const t=e.name.trim();if(!t)return;if("ADD"===this.editMode()){if(!e.file)return;const n=await this.soundStore.saveFile(e.file),a=this.getNextItemId();return this.updateItems(e=>[...e,{id:a,name:t,soundId:n.id}]),this.setSelectedId(a),void this.closeEditModal()}const n=this.selectedId();if(null!==n){if(e.file){const a=await this.soundStore.saveFile(e.file);this.updateItems(e=>e.map(e=>e.id===n?{...e,name:t,soundId:a.id}:e))}else this.updateItems(e=>e.map(e=>e.id===n?{...e,name:t}:e));this.closeEditModal()}}deleteSelected(){if(this.settings.editLockEnabled())return;const e=this.selectedId();null!==e&&(this.updateItems(t=>t.filter(t=>t.id!==e)),this.setSelectedId(null),this.audioPlayer.stop(this.getChannel()),this.currentPlayingId.set(null))}moveSelected(e){if(this.settings.editLockEnabled())return;const t=this.selectedId();null!==t&&this.updateItems(n=>{const a=n.findIndex(e=>e.id===t);if(-1===a)return n;const o=a+e;if(o<0||o>=n.length)return n;const i=n.slice(),[s]=i.splice(a,1);return i.splice(o,0,s),i})}async playSelected(){const e=this.items();if(!e.length)return;let t=this.selectedItem();t||(t=e[0],this.setSelectedId(t.id)),this.currentPlayingId.set(t.id),this.audioPlayer.setVolume(this.getChannel(),this.getVolumePercent()/100),await this.audioPlayer.play(this.getChannel(),t.soundId)}async playNextManual(){const e=this.items();if(!e.length)return;const t=this.currentPlayingId(),n=this.selectedId(),a=e.findIndex(e=>e.id===(t??n));let o;if(this.shuffleEnabled()&&e.length>1)do{o=Math.floor(Math.random()*e.length)}while(o===a);else o=-1===a?0:(a+1)%e.length;const i=e[o];this.setSelectedId(i.id),this.currentPlayingId.set(i.id),this.audioPlayer.setVolume(this.getChannel(),this.getVolumePercent()/100),await this.audioPlayer.play(this.getChannel(),i.soundId)}async playPreviousManual(){const e=this.items();if(!e.length)return;const t=this.currentPlayingId(),n=this.selectedId(),a=e.findIndex(e=>e.id===(t??n));let o;if(this.shuffleEnabled()&&e.length>1)do{o=Math.floor(Math.random()*e.length)}while(o===a);else o=a<=0?e.length-1:a-1;const i=e[o];this.setSelectedId(i.id),this.currentPlayingId.set(i.id),this.audioPlayer.setVolume(this.getChannel(),this.getVolumePercent()/100),await this.audioPlayer.play(this.getChannel(),i.soundId)}pauseSelected(){this.audioPlayer.pause(this.getChannel())}stopSelected(){this.audioPlayer.stop(this.getChannel()),this.currentPlayingId.set(null),this.autoplayEnabled.set(!1),this.shuffleEnabled.set(!1)}updateVolume(e){const t=Number(e);if(!Number.isFinite(t))return;const n=Math.min(100,Math.max(0,t));this.setVolumePercent(n),this.audioPlayer.setVolume(this.getChannel(),n/100)}toggleAutoplay(){const e=!this.autoplayEnabled();this.autoplayEnabled.set(e),e||this.shuffleEnabled.set(!1)}toggleShuffle(){this.shuffleEnabled.update(e=>!e)}isChannelPlaying(){return this.channelPlaying()}startWaveAnimation(){null===this.animationFrameId&&(this.animationFrameId=requestAnimationFrame(this.animateWaveform))}stopWaveAnimation(){null!==this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}animateWaveform=()=>{this.drawWaveformFrame(),this.animationFrameId=requestAnimationFrame(this.animateWaveform)};drawWaveformFrame(){const e=this.getWaveCanvas();if(!e)return;this.updateWaveformCanvasSize();const t=e.getContext("2d");if(!t)return;const n=this.lastWaveformPixelRatio,a=e.width/n,o=e.height/n;t.setTransform(n,0,0,n,0,0),t.clearRect(0,0,a,o);const i=this.channelPlaying(),s=i?.35*o:.04*o,r=o/2+(i?4*Math.sin(.7*this.animationAngle):0);t.lineJoin="round",t.lineCap="round",t.lineWidth=i?2.4:1,t.strokeStyle=i?this.waveformColor(.95):this.waveformColor(.25),t.shadowBlur=i?8:2,t.shadowColor=i?this.waveformColor(.6):this.waveformColor(.35);const l=this.audioPlayer.fillWaveform(this.getChannel(),this.waveformSamples);if(t.beginPath(),l){let e=0;for(const t of this.waveformSamples){const n=Math.abs(t-128)/128;e=Math.max(e,n)}const n=Math.min(1,1.4*Math.pow(e,.6)),i=o*Math.max(.3,.95*n),s=a/(this.waveformSamples.length-1);for(let e=0;e<this.waveformSamples.length;e+=1){const n=e*s,a=r+(this.waveformSamples[e]-128)/128*i;0===e?t.moveTo(n,a):t.lineTo(n,a)}}else{const e=i?4:1;for(let n=0;n<=a;n+=1){const o=n/a,i=r+Math.sin(this.animationAngle+o*Math.PI*3)*s*(.65+.35*o)+Math.sin(1.4*this.animationAngle+o*Math.PI*4)*e;0===n?t.moveTo(n,i):t.lineTo(n,i)}}t.stroke(),this.drawWaveformTicks(t,a,o),this.drawWaveformBottomTicks(t,a,o),this.animationAngle+=.04}waveformColor(e){return`rgba(${this.waveformColorRgb}, ${e})`}drawWaveformTicks(e,t,n){const a=this.getWaveformTickMetrics(),o=a.spacing,i=a.smallTick,s=a.bigTick,r=a.bottomPadding;e.save(),e.strokeStyle=this.waveformColor(.5),e.lineWidth=1,e.beginPath();const l=this.getWaveformTickCount(t,n,o,r);for(let n=0;n<=l;n+=1){const a=n*o+.5,r=n%5==0?s:i;e.moveTo(t-1,a),e.lineTo(t-1-r,a)}e.stroke(),e.restore()}drawWaveformBottomTicks(e,t,n){e.save(),e.strokeStyle=this.waveformColor(.5),e.lineWidth=1,e.beginPath();const a=Math.floor((t-8)/6);for(let t=0;t<=a;t+=1){const a=6*t+.5,o=t%6==0?12:6;e.moveTo(a,n-1),e.lineTo(a,n-1-o)}e.stroke(),e.restore()}getWaveformTickMetrics(){return{spacing:6,smallTick:6,bigTick:12,bottomPadding:8}}getWaveformTickCount(e,t,n,a){const o=Math.floor((t-a)/n),i=o+1;if(e<=0||t<=0)return o;const s="undefined"==typeof window?e:window.innerWidth;if(!(s>("undefined"==typeof window?t:window.innerHeight)))return o;if(s<=800){const e=Math.max(0,Math.min(800,s)),t=e<=400?0:(e-400)/400,n=Math.round(20+10*t),a=Math.min(Math.max(1,n),i);return Math.max(0,a-1)}return o}getWaveCanvas(){const e=this.waveformCanvas();return e?e.nativeElement:null}attachWaveformResizeObserver(){const e=this.getWaveCanvas();e&&"undefined"!=typeof ResizeObserver&&(this.waveformResizeObserver=new ResizeObserver(()=>{this.updateWaveformCanvasSize()}),this.waveformResizeObserver.observe(e))}updateWaveformCanvasSize(){const e=this.getWaveCanvas();if(!e)return;const t=e.getBoundingClientRect();if(!t.width||!t.height)return;const n=Math.max(1,window.devicePixelRatio||1),a=Math.max(1,Math.floor(t.width*n)),o=Math.max(1,Math.floor(t.height*n));e.width===a&&e.height===o&&this.lastWaveformPixelRatio===n||(this.lastWaveformPixelRatio=n,e.width=a,e.height=o)}async playNext(){const e=this.items();if(!e.length)return;const t=this.currentPlayingId(),n=this.selectedId(),a=e.findIndex(e=>e.id===(t??n));let o;if(this.shuffleEnabled())if(1===e.length)o=0;else do{o=Math.floor(Math.random()*e.length)}while(o===a);else o=-1===a?0:(a+1)%e.length;const i=e[o];this.setSelectedId(i.id),this.currentPlayingId.set(i.id),this.audioPlayer.setVolume(this.getChannel(),this.getVolumePercent()/100),await this.audioPlayer.play(this.getChannel(),i.soundId)}getChannel(){return"RADIO"===this.category?"RADIO":"NOTES"}getVolumePercent(){return"RADIO"===this.category?this.settings.radioVolume():this.settings.notesVolume()}setVolumePercent(e){"RADIO"===this.category?this.settings.radioVolume.set(e):this.settings.notesVolume.set(e)}getItems(){return"RADIO"===this.category?this.settings.radioItems():this.settings.notesItems()}updateItems(e){"RADIO"===this.category?this.settings.radioItems.update(e):this.settings.notesItems.update(e)}selectedId(){return"RADIO"===this.category?this.settings.selectedRadioItemId():this.settings.selectedNotesItemId()}setSelectedId(e){"RADIO"===this.category?this.settings.selectedRadioItemId.set(e):this.settings.selectedNotesItemId.set(e)}getNextItemId(){return this.items().reduce((e,t)=>Math.max(e,t.id),0)+1}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:se,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:se,isStandalone:!0,selector:"pip-boy-music-layout",inputs:{category:"category",waveformColorRgb:"waveformColorRgb"},viewQueries:[{propertyName:"waveformCanvas",first:!0,predicate:["waveformCanvas"],descendants:!0,isSignal:!0}],ngImport:e,template:'<div class="music-layout">\n <div class="music-list">\n <ul class="music-list-items">\n @for (item of items(); track item.id) {\n <li>\n <button\n type="button"\n class="music-list-item"\n [class.is-selected]="selectedId() === item.id"\n (click)="selectItem(item.id)"\n >\n {{ item.name }}\n </button>\n </li>\n } @empty {\n <li class="is-empty">No items added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="music-actions">\n <button type="button" class="music-add" (click)="openAddModal()">\n + Add\n </button>\n @if (selectedId() !== null) {\n <button type="button" class="music-edit" (click)="openEditModal()">\n Edit\n </button>\n <button type="button" class="music-delete" (click)="deleteSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="music-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="music-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n <div class="music-controls">\n <div class="music-controls-inner">\n <div class="music-waveform">\n <canvas #waveformCanvas width="320" height="140"></canvas>\n </div>\n <div class="music-controls-stack">\n <div class="music-controls-row">\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="playSelected()"\n [disabled]="!items().length || isChannelPlaying()"\n aria-label="Play"\n >\n &#9654;\n </button>\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="pauseSelected()"\n [disabled]="!isChannelPlaying()"\n aria-label="Pause"\n >\n &#10074;&#10074;\n </button>\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="stopSelected()"\n [disabled]="!isChannelPlaying()"\n aria-label="Stop"\n >\n &#9632;\n </button>\n </div>\n <div class="music-controls-row">\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="playPreviousManual()"\n [disabled]="!isChannelPlaying() || items().length <= 1"\n aria-label="Previous"\n >\n &#9198;\n </button>\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="playNextManual()"\n [disabled]="!isChannelPlaying() || items().length <= 1"\n aria-label="Next"\n >\n &#9197;\n </button>\n </div>\n <div class="music-control-row">\n <button\n type="button"\n class="music-control music-control--autoplay"\n [class.is-active]="autoplayEnabled()"\n [disabled]="!isChannelPlaying()"\n (click)="toggleAutoplay()"\n >\n Autoplay\n </button>\n <button\n type="button"\n class="music-control music-control--shuffle"\n [class.is-active]="shuffleEnabled()"\n [disabled]="!isChannelPlaying()"\n (click)="toggleShuffle()"\n aria-label="Shuffle"\n >\n Shuffle\n </button>\n </div>\n <div class="music-volume">\n <div\n class="music-now-playing"\n [class.is-disabled]="!isChannelPlaying()"\n >\n <span class="music-now-playing-label">Currently Playing</span>\n <span class="music-now-playing-value">\n <span class="music-now-playing-text">\n {{ currentPlayingName() }}\n </span>\n </span>\n </div>\n <div class="music-volume-row">\n <span class="music-volume-label">VOL</span>\n <input\n type="range"\n min="0"\n max="100"\n step="1"\n [value]="getVolumePercent()"\n [disabled]="!items().length"\n (input)="updateVolume($any($event.target).value)"\n aria-label="Volume"\n />\n <span class="music-volume-value">{{ getVolumePercent() }}%</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n<pip-boy-audio-edit-modal\n [open]="showEditModal()"\n [title]="modalTitle()"\n [name]="modalName()"\n [fileLabel]="modalFileLabel()"\n [nameLabel]="modalLabelPrefix() + \' Name\'"\n [fileFieldLabel]="modalLabelPrefix() + \' File\'"\n [selectLabel]="\'Select \' + modalLabelPrefix()"\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{width:100%;height:100%;display:block;font-size:inherit}.music-layout{box-sizing:border-box;display:flex;gap:1.5rem;height:100%;min-height:0}.music-list{display:flex;flex:1 1 55%;flex-direction:column;gap:.5rem;min-height:0}.music-list-items{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.music-list-items li{margin:0;padding:0;font-size:inherit}.music-list-items .is-empty{opacity:.6}.music-list-item{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font-size:inherit;padding:.25rem .35rem .25rem 1.2rem;position:relative;text-align:left;width:100%}.music-list-item:hover{background:#0fbb6b1f}.music-list-item.is-selected{background:#0fbb6b2e}.music-list-item.is-selected:before{content:"";position:absolute;left:.35rem;top:50%;transform:translateY(-50%);width:.45rem;height:.45rem;background:#0fbb6b}.music-actions{display:flex;gap:.5rem}.music-add{background:#0fbb6b14;border:none;border-left:0;border-right:0;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.music-add:hover{background:#0fbb6b2e}.music-edit,.music-delete{background:#0fbb6b0d;border:none;border-left:0;border-right:0;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.music-edit:hover,.music-delete:hover{background:#0fbb6b1f}.music-move{background:#0fbb6b0d;border:none;border-left:0;border-right:0;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.music-move:hover{background:#0fbb6b1f}.music-controls{display:flex;flex:1 1 45%;min-height:0;align-items:stretch;justify-content:center}.music-controls-inner{display:flex;flex-direction:column;gap:0;width:100%;min-height:0;height:100%;max-height:100%;overflow-y:auto;padding-right:.35rem;box-sizing:content-box}.music-controls-stack{display:flex;flex-direction:column;gap:.6rem;margin-top:auto;width:100%}.music-control-row{display:flex;flex-wrap:wrap;gap:.5rem;width:100%}.music-control-row button{flex:1 1 4rem;text-align:center}.music-waveform{width:100%;display:flex;justify-content:center;flex:1 1 auto;min-height:clamp(96px,22vh,160px);margin-bottom:1rem;padding:0}.music-waveform canvas{width:100%;max-width:none;height:100%;border-radius:0;border:0;border-right:1px solid rgba(15,187,107,.25);border-bottom:1px solid rgba(15,187,107,.25);background:transparent;box-shadow:none}.music-controls-row{display:flex;flex-wrap:wrap;gap:.5rem}.music-control{background:#0fbb6b0d;border:1px solid rgba(15,187,107,.6);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:calc(clamp(.85rem,.85rem + .15rem * (100vw - 360px) / 840px,1rem) * var(--list-font-scale, 1));letter-spacing:.08em;padding:.6rem .75rem;text-transform:uppercase}.music-control:hover,.music-control.is-active{background:#0fbb6b1f;border-color:#0fbb6b}.music-control:disabled{cursor:default;background:#0fbb6b08;border-color:#0fbb6b40;color:#0fbb6b73;opacity:.8}.music-control--icon{flex:1 1 4rem;text-align:center}.music-control--autoplay.is-active,.music-control--shuffle.is-active{background:#0fbb6b33;border-color:#0fbb6b;box-shadow:0 0 .6rem #0fbb6b47}.music-volume{border:1px solid rgba(15,187,107,.35);border-radius:.6rem;box-sizing:border-box;padding:.6rem .75rem;display:flex;flex-direction:column;gap:.5rem;align-items:stretch;background:#0fbb6b0a;min-height:calc(2.6rem * var(--list-font-scale, 1))}.music-now-playing{display:flex;flex-direction:column;gap:.35rem}.music-now-playing.is-disabled .music-now-playing-label,.music-now-playing.is-disabled .music-now-playing-value{color:#0fbb6b73}.music-now-playing.is-disabled .music-now-playing-value{background:#0fbb6b08;border-color:#0fbb6b33}.music-now-playing-label{text-transform:uppercase;letter-spacing:.08em;font-size:calc(clamp(.7rem,.7rem + .1rem * (100vw - 360px) / 840px,.8rem) * var(--list-font-scale, 1));color:#0fbb6bb3}.music-now-playing-value{display:flex;align-items:center;border:1px solid rgba(15,187,107,.4);border-radius:.4rem;padding:.35rem .5rem;font-size:calc(clamp(.8rem,.8rem + .15rem * (100vw - 360px) / 840px,.95rem) * var(--list-font-scale, 1));color:#0fbb6bd9;min-height:calc(1.4rem * var(--list-font-scale, 1));min-width:0}.music-now-playing-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.music-volume-row{display:flex;align-items:center;gap:.75rem;width:100%}.music-volume-row input[type=range]{appearance:none;background:#0fbb6b33;border-radius:999px;cursor:pointer;flex:1 1 0;height:.35rem;min-width:0;outline:none}.music-volume-row input[type=range]::-webkit-slider-thumb{appearance:none;background:#0fbb6b;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.music-volume-row input[type=range]::-moz-range-thumb{background:#0fbb6b;border:none;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.music-volume-label{text-transform:uppercase;letter-spacing:.08em;font-size:calc(clamp(.75rem,.75rem + .1rem * (100vw - 360px) / 840px,.85rem) * var(--list-font-scale, 1));color:#0fbb6bcc;flex:0 0 3.2ch;max-width:3.2ch;min-width:3.2ch;text-align:left;white-space:nowrap}.music-volume-value{font-size:calc(clamp(.75rem,.75rem + .1rem * (100vw - 360px) / 840px,.85rem) * var(--list-font-scale, 1));color:#0fbb6bcc;letter-spacing:.08em;flex:0 0 4.5ch;max-width:4.5ch;min-width:4.5ch;text-align:right;white-space:nowrap}@media(max-width:720px),(max-height:560px){.music-actions{gap:.35rem}.music-add,.music-edit,.music-delete{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.music-move{flex:0 0 1.6rem;height:2.1rem}.music-controls-inner{flex-direction:row;flex-wrap:wrap;gap:.5rem;justify-content:center;padding:.25rem;width:100%}.music-waveform{flex:0 0 auto;height:clamp(96px,22vh,160px);max-height:clamp(96px,22vh,160px);margin-bottom:.5rem}.music-controls-row{width:100%;justify-content:center}.music-control{flex:1 1 calc(50% - .5rem);font-size:calc(clamp(.7rem,.7rem + .15rem * (100vw - 360px) / 840px,.85rem) * var(--list-font-scale, 1));padding:.35rem .5rem;border-radius:.4rem}.music-control--icon{flex:1 1 3rem}.music-volume{width:100%}.music-volume-row{flex-wrap:wrap}.music-volume-label{min-width:auto}}\n'],dependencies:[{kind:"component",type:ie,selector:"pip-boy-audio-edit-modal",inputs:["open","name","fileLabel","title","nameLabel","fileFieldLabel","selectLabel"],outputs:["closeResult","save"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:se,decorators:[{type:a,args:[{selector:"pip-boy-music-layout",standalone:!0,imports:[ie],template:'<div class="music-layout">\n <div class="music-list">\n <ul class="music-list-items">\n @for (item of items(); track item.id) {\n <li>\n <button\n type="button"\n class="music-list-item"\n [class.is-selected]="selectedId() === item.id"\n (click)="selectItem(item.id)"\n >\n {{ item.name }}\n </button>\n </li>\n } @empty {\n <li class="is-empty">No items added.</li>\n }\n </ul>\n @if (!settings.editLockEnabled()) {\n <div class="music-actions">\n <button type="button" class="music-add" (click)="openAddModal()">\n + Add\n </button>\n @if (selectedId() !== null) {\n <button type="button" class="music-edit" (click)="openEditModal()">\n Edit\n </button>\n <button type="button" class="music-delete" (click)="deleteSelected()">\n - Delete\n </button>\n <button\n type="button"\n class="music-move"\n (click)="moveSelected(-1)"\n aria-label="Move up"\n >\n ▲\n </button>\n <button\n type="button"\n class="music-move"\n (click)="moveSelected(1)"\n aria-label="Move down"\n >\n ▼\n </button>\n }\n </div>\n }\n </div>\n <div class="music-controls">\n <div class="music-controls-inner">\n <div class="music-waveform">\n <canvas #waveformCanvas width="320" height="140"></canvas>\n </div>\n <div class="music-controls-stack">\n <div class="music-controls-row">\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="playSelected()"\n [disabled]="!items().length || isChannelPlaying()"\n aria-label="Play"\n >\n &#9654;\n </button>\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="pauseSelected()"\n [disabled]="!isChannelPlaying()"\n aria-label="Pause"\n >\n &#10074;&#10074;\n </button>\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="stopSelected()"\n [disabled]="!isChannelPlaying()"\n aria-label="Stop"\n >\n &#9632;\n </button>\n </div>\n <div class="music-controls-row">\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="playPreviousManual()"\n [disabled]="!isChannelPlaying() || items().length <= 1"\n aria-label="Previous"\n >\n &#9198;\n </button>\n <button\n type="button"\n class="music-control music-control--icon"\n (click)="playNextManual()"\n [disabled]="!isChannelPlaying() || items().length <= 1"\n aria-label="Next"\n >\n &#9197;\n </button>\n </div>\n <div class="music-control-row">\n <button\n type="button"\n class="music-control music-control--autoplay"\n [class.is-active]="autoplayEnabled()"\n [disabled]="!isChannelPlaying()"\n (click)="toggleAutoplay()"\n >\n Autoplay\n </button>\n <button\n type="button"\n class="music-control music-control--shuffle"\n [class.is-active]="shuffleEnabled()"\n [disabled]="!isChannelPlaying()"\n (click)="toggleShuffle()"\n aria-label="Shuffle"\n >\n Shuffle\n </button>\n </div>\n <div class="music-volume">\n <div\n class="music-now-playing"\n [class.is-disabled]="!isChannelPlaying()"\n >\n <span class="music-now-playing-label">Currently Playing</span>\n <span class="music-now-playing-value">\n <span class="music-now-playing-text">\n {{ currentPlayingName() }}\n </span>\n </span>\n </div>\n <div class="music-volume-row">\n <span class="music-volume-label">VOL</span>\n <input\n type="range"\n min="0"\n max="100"\n step="1"\n [value]="getVolumePercent()"\n [disabled]="!items().length"\n (input)="updateVolume($any($event.target).value)"\n aria-label="Volume"\n />\n <span class="music-volume-value">{{ getVolumePercent() }}%</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n<pip-boy-audio-edit-modal\n [open]="showEditModal()"\n [title]="modalTitle()"\n [name]="modalName()"\n [fileLabel]="modalFileLabel()"\n [nameLabel]="modalLabelPrefix() + \' Name\'"\n [fileFieldLabel]="modalLabelPrefix() + \' File\'"\n [selectLabel]="\'Select \' + modalLabelPrefix()"\n (closeResult)="closeEditModal()"\n (save)="saveEditModal($event)"\n/>\n',styles:[':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{width:100%;height:100%;display:block;font-size:inherit}.music-layout{box-sizing:border-box;display:flex;gap:1.5rem;height:100%;min-height:0}.music-list{display:flex;flex:1 1 55%;flex-direction:column;gap:.5rem;min-height:0}.music-list-items{flex:1 1 auto;list-style:none;margin:0;min-height:0;overflow:auto;padding:.5rem .75rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.music-list-items li{margin:0;padding:0;font-size:inherit}.music-list-items .is-empty{opacity:.6}.music-list-item{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font-size:inherit;padding:.25rem .35rem .25rem 1.2rem;position:relative;text-align:left;width:100%}.music-list-item:hover{background:#0fbb6b1f}.music-list-item.is-selected{background:#0fbb6b2e}.music-list-item.is-selected:before{content:"";position:absolute;left:.35rem;top:50%;transform:translateY(-50%);width:.45rem;height:.45rem;background:#0fbb6b}.music-actions{display:flex;gap:.5rem}.music-add{background:#0fbb6b14;border:none;border-left:0;border-right:0;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.music-add:hover{background:#0fbb6b2e}.music-edit,.music-delete{background:#0fbb6b0d;border:none;border-left:0;border-right:0;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:1 1 33%;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);height:2.5rem;padding:0 .75rem;text-transform:uppercase;white-space:nowrap}.music-edit:hover,.music-delete:hover{background:#0fbb6b1f}.music-move{background:#0fbb6b0d;border:none;border-left:0;border-right:0;box-sizing:border-box;color:#0fbb6b;cursor:pointer;flex:0 0 2rem;height:2.5rem;padding:0;text-transform:uppercase;white-space:nowrap}.music-move:hover{background:#0fbb6b1f}.music-controls{display:flex;flex:1 1 45%;min-height:0;align-items:stretch;justify-content:center}.music-controls-inner{display:flex;flex-direction:column;gap:0;width:100%;min-height:0;height:100%;max-height:100%;overflow-y:auto;padding-right:.35rem;box-sizing:content-box}.music-controls-stack{display:flex;flex-direction:column;gap:.6rem;margin-top:auto;width:100%}.music-control-row{display:flex;flex-wrap:wrap;gap:.5rem;width:100%}.music-control-row button{flex:1 1 4rem;text-align:center}.music-waveform{width:100%;display:flex;justify-content:center;flex:1 1 auto;min-height:clamp(96px,22vh,160px);margin-bottom:1rem;padding:0}.music-waveform canvas{width:100%;max-width:none;height:100%;border-radius:0;border:0;border-right:1px solid rgba(15,187,107,.25);border-bottom:1px solid rgba(15,187,107,.25);background:transparent;box-shadow:none}.music-controls-row{display:flex;flex-wrap:wrap;gap:.5rem}.music-control{background:#0fbb6b0d;border:1px solid rgba(15,187,107,.6);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:calc(clamp(.85rem,.85rem + .15rem * (100vw - 360px) / 840px,1rem) * var(--list-font-scale, 1));letter-spacing:.08em;padding:.6rem .75rem;text-transform:uppercase}.music-control:hover,.music-control.is-active{background:#0fbb6b1f;border-color:#0fbb6b}.music-control:disabled{cursor:default;background:#0fbb6b08;border-color:#0fbb6b40;color:#0fbb6b73;opacity:.8}.music-control--icon{flex:1 1 4rem;text-align:center}.music-control--autoplay.is-active,.music-control--shuffle.is-active{background:#0fbb6b33;border-color:#0fbb6b;box-shadow:0 0 .6rem #0fbb6b47}.music-volume{border:1px solid rgba(15,187,107,.35);border-radius:.6rem;box-sizing:border-box;padding:.6rem .75rem;display:flex;flex-direction:column;gap:.5rem;align-items:stretch;background:#0fbb6b0a;min-height:calc(2.6rem * var(--list-font-scale, 1))}.music-now-playing{display:flex;flex-direction:column;gap:.35rem}.music-now-playing.is-disabled .music-now-playing-label,.music-now-playing.is-disabled .music-now-playing-value{color:#0fbb6b73}.music-now-playing.is-disabled .music-now-playing-value{background:#0fbb6b08;border-color:#0fbb6b33}.music-now-playing-label{text-transform:uppercase;letter-spacing:.08em;font-size:calc(clamp(.7rem,.7rem + .1rem * (100vw - 360px) / 840px,.8rem) * var(--list-font-scale, 1));color:#0fbb6bb3}.music-now-playing-value{display:flex;align-items:center;border:1px solid rgba(15,187,107,.4);border-radius:.4rem;padding:.35rem .5rem;font-size:calc(clamp(.8rem,.8rem + .15rem * (100vw - 360px) / 840px,.95rem) * var(--list-font-scale, 1));color:#0fbb6bd9;min-height:calc(1.4rem * var(--list-font-scale, 1));min-width:0}.music-now-playing-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.music-volume-row{display:flex;align-items:center;gap:.75rem;width:100%}.music-volume-row input[type=range]{appearance:none;background:#0fbb6b33;border-radius:999px;cursor:pointer;flex:1 1 0;height:.35rem;min-width:0;outline:none}.music-volume-row input[type=range]::-webkit-slider-thumb{appearance:none;background:#0fbb6b;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.music-volume-row input[type=range]::-moz-range-thumb{background:#0fbb6b;border:none;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.music-volume-label{text-transform:uppercase;letter-spacing:.08em;font-size:calc(clamp(.75rem,.75rem + .1rem * (100vw - 360px) / 840px,.85rem) * var(--list-font-scale, 1));color:#0fbb6bcc;flex:0 0 3.2ch;max-width:3.2ch;min-width:3.2ch;text-align:left;white-space:nowrap}.music-volume-value{font-size:calc(clamp(.75rem,.75rem + .1rem * (100vw - 360px) / 840px,.85rem) * var(--list-font-scale, 1));color:#0fbb6bcc;letter-spacing:.08em;flex:0 0 4.5ch;max-width:4.5ch;min-width:4.5ch;text-align:right;white-space:nowrap}@media(max-width:720px),(max-height:560px){.music-actions{gap:.35rem}.music-add,.music-edit,.music-delete{font-size:clamp(.65rem,.65rem + (.8rem - .65rem) * (100vw - 360px) / (1200px - 360px),.8rem);height:2.1rem;padding:0 .5rem}.music-move{flex:0 0 1.6rem;height:2.1rem}.music-controls-inner{flex-direction:row;flex-wrap:wrap;gap:.5rem;justify-content:center;padding:.25rem;width:100%}.music-waveform{flex:0 0 auto;height:clamp(96px,22vh,160px);max-height:clamp(96px,22vh,160px);margin-bottom:.5rem}.music-controls-row{width:100%;justify-content:center}.music-control{flex:1 1 calc(50% - .5rem);font-size:calc(clamp(.7rem,.7rem + .15rem * (100vw - 360px) / 840px,.85rem) * var(--list-font-scale, 1));padding:.35rem .5rem;border-radius:.4rem}.music-control--icon{flex:1 1 3rem}.music-volume{width:100%}.music-volume-row{flex-wrap:wrap}.music-volume-label{min-width:auto}}\n']}]}],ctorParameters:()=>[],propDecorators:{category:[{type:m}],waveformColorRgb:[{type:m}],waveformCanvas:[{type:e.ViewChild,args:["waveformCanvas",{isSignal:!0}]}]}});class re{open=!1;listFontScale=1.25;closeResult=new c;previewListFontScale=new c;appVersion=N;updateListFontScale(e){const t=Number(e);if(!Number.isFinite(t))return;const n=Math.min(150,Math.max(50,t))/100*1.25;this.listFontScale=n,this.previewListFontScale.emit(n)}listFontScalePercent(){return Math.round(this.listFontScale/1.25*100)}closeModal(){this.closeResult.emit()}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:re,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"21.1.1",type:re,isStandalone:!0,selector:"pip-boy-welcome-modal",inputs:{open:"open",listFontScale:"listFontScale"},outputs:{closeResult:"closeResult",previewListFontScale:"previewListFontScale"},ngImport:e,template:'<pip-boy-dialog\n [open]="open"\n title="Welcome to Pip UI"\n subtitle="Fan made Pip-Boy inspired simulators from the Fallout universe."\n (closeResult)="closeModal()"\n>\n <span dialog-title-extra class="welcome__version">v{{ appVersion }}</span>\n\n <div class="welcome__body">\n <section class="welcome__section" aria-labelledby="welcomeFontTitle">\n <div class="welcome__section-head">\n <div class="welcome__section-title" id="welcomeFontTitle">\n Global Font Size\n </div>\n <p class="welcome__section-text">\n Adjusts key UI font sizes to match your device.\n </p>\n </div>\n\n <div class="welcome__slider">\n <input\n class="welcome__range"\n type="range"\n min="50"\n max="150"\n step="1"\n [value]="listFontScalePercent()"\n (input)="updateListFontScale($any($event.target).value)"\n aria-label="Global font size"\n />\n <span class="welcome__value">{{ listFontScalePercent() }}%</span>\n </div>\n\n <p class="welcome__hint">\n You can adjust this any time later in the settings menu.\n </p>\n </section>\n\n <div class="welcome__divider" aria-hidden="true"></div>\n\n <section class="welcome__section" aria-labelledby="welcomeNpmTitle">\n <div class="welcome__section-head">\n <div class="welcome__section-title" id="welcomeNpmTitle">Npm</div>\n <p class="welcome__section-text">\n Use this package for free in your own projects.\n </p>\n </div>\n\n <dl class="welcome__meta" aria-label="Install information">\n <div class="welcome__row">\n <dt class="welcome__label">Package</dt>\n <dd class="welcome__data"><code>@vault-tec/pip-boy</code></dd>\n </div>\n\n <div class="welcome__row">\n <dt class="welcome__label">Install</dt>\n <dd class="welcome__data">\n <code>npm install @vault-tec/pip-boy</code>\n </dd>\n </div>\n\n <div class="welcome__row">\n <dt class="welcome__label">NPM</dt>\n <dd class="welcome__data">\n <a\n href="https://www.npmjs.com/package/@vault-tec/pip-boy"\n target="_blank"\n rel="noreferrer"\n >\n npmjs.com/package/@vault-tec/pip-boy\n </a>\n </dd>\n </div>\n </dl>\n\n <p class="welcome__disclaimer">\n Please note that this is an unofficial fan project. No official game\n assets are included. Not affiliated with or endorsed by Bethesda\n Softworks or ZeniMax Media.\n </p>\n </section>\n </div>\n\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Close</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.welcome__version{color:#0fbb6bc7;font-size:clamp(.8rem,.8rem + (.9rem - .8rem) * (100vw - 360px) / (1200px - 360px),.9rem);letter-spacing:.1em}.welcome__body{display:flex;flex-direction:column;gap:.9rem}.welcome__body p{margin:0}.welcome__divider{border-top:1px solid rgba(15,187,107,.22);margin:.15rem 0}.welcome__section{border:1px solid rgba(15,187,107,.2);border-radius:.75rem;padding:.9rem .95rem;background:#0fbb6b0a;display:flex;flex-direction:column;gap:.75rem}.welcome__section:last-child{margin-bottom:1rem}.welcome__section-head{display:flex;flex-direction:column;gap:.35rem}.welcome__section-title{text-transform:uppercase;letter-spacing:.08em;color:#0fbb6bd1;font-size:clamp(.8rem,.8rem + (.95rem - .8rem) * (100vw - 360px) / (1200px - 360px),.95rem)}.welcome__section-text{color:#0fbb6bc7;font-size:clamp(.85rem,.85rem + (.95rem - .85rem) * (100vw - 360px) / (1200px - 360px),.95rem);line-height:1.35}.welcome__slider{align-items:center;display:flex;gap:.8rem}.welcome__range{appearance:none;background:#0fbb6b33;border-radius:999px;cursor:pointer;flex:1 1 auto;height:.35rem;outline:none}.welcome__range::-webkit-slider-thumb{appearance:none;background:#0fbb6b;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.welcome__range::-moz-range-thumb{background:#0fbb6b;border:none;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.welcome__value{font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);color:#0fbb6bd1;letter-spacing:.08em;min-width:3.25rem;text-align:right}.welcome__hint{color:#0fbb6bbf;font-size:clamp(.5rem,.5rem + (.7rem - .5rem) * (100vw - 360px) / (1200px - 360px),.7rem);line-height:1.35}.welcome__meta{display:grid;gap:.6rem;margin:0}.welcome__row{display:grid;grid-template-columns:5.25rem 1fr;align-items:start;gap:.75rem}.welcome__label{color:#0fbb6bbd;text-transform:uppercase;letter-spacing:.08em;font-size:.75rem;line-height:1.25;padding-top:.15rem}.welcome__data{margin:0}.welcome__data code{background:#0fbb6b14;border:1px solid rgba(15,187,107,.22);border-radius:.45rem;color:#0fbb6b;display:inline-block;padding:.25rem .55rem;max-width:100%;overflow-wrap:anywhere}.welcome__data a{color:#0fbb6b;text-decoration:none;overflow-wrap:anywhere}.welcome__data a:hover{text-decoration:underline}.welcome__disclaimer{color:#0fbb6bc2;font-size:clamp(.5rem,.5rem + (.7rem - .5rem) * (100vw - 360px) / (1200px - 360px),.7rem);line-height:1.35}:host{font-size:inherit}\n"],dependencies:[{kind:"ngmodule",type:v},{kind:"component",type:U,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:re,decorators:[{type:a,args:[{selector:"pip-boy-welcome-modal",standalone:!0,imports:[v,U],template:'<pip-boy-dialog\n [open]="open"\n title="Welcome to Pip UI"\n subtitle="Fan made Pip-Boy inspired simulators from the Fallout universe."\n (closeResult)="closeModal()"\n>\n <span dialog-title-extra class="welcome__version">v{{ appVersion }}</span>\n\n <div class="welcome__body">\n <section class="welcome__section" aria-labelledby="welcomeFontTitle">\n <div class="welcome__section-head">\n <div class="welcome__section-title" id="welcomeFontTitle">\n Global Font Size\n </div>\n <p class="welcome__section-text">\n Adjusts key UI font sizes to match your device.\n </p>\n </div>\n\n <div class="welcome__slider">\n <input\n class="welcome__range"\n type="range"\n min="50"\n max="150"\n step="1"\n [value]="listFontScalePercent()"\n (input)="updateListFontScale($any($event.target).value)"\n aria-label="Global font size"\n />\n <span class="welcome__value">{{ listFontScalePercent() }}%</span>\n </div>\n\n <p class="welcome__hint">\n You can adjust this any time later in the settings menu.\n </p>\n </section>\n\n <div class="welcome__divider" aria-hidden="true"></div>\n\n <section class="welcome__section" aria-labelledby="welcomeNpmTitle">\n <div class="welcome__section-head">\n <div class="welcome__section-title" id="welcomeNpmTitle">Npm</div>\n <p class="welcome__section-text">\n Use this package for free in your own projects.\n </p>\n </div>\n\n <dl class="welcome__meta" aria-label="Install information">\n <div class="welcome__row">\n <dt class="welcome__label">Package</dt>\n <dd class="welcome__data"><code>@vault-tec/pip-boy</code></dd>\n </div>\n\n <div class="welcome__row">\n <dt class="welcome__label">Install</dt>\n <dd class="welcome__data">\n <code>npm install @vault-tec/pip-boy</code>\n </dd>\n </div>\n\n <div class="welcome__row">\n <dt class="welcome__label">NPM</dt>\n <dd class="welcome__data">\n <a\n href="https://www.npmjs.com/package/@vault-tec/pip-boy"\n target="_blank"\n rel="noreferrer"\n >\n npmjs.com/package/@vault-tec/pip-boy\n </a>\n </dd>\n </div>\n </dl>\n\n <p class="welcome__disclaimer">\n Please note that this is an unofficial fan project. No official game\n assets are included. Not affiliated with or endorsed by Bethesda\n Softworks or ZeniMax Media.\n </p>\n </section>\n </div>\n\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Close</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.welcome__version{color:#0fbb6bc7;font-size:clamp(.8rem,.8rem + (.9rem - .8rem) * (100vw - 360px) / (1200px - 360px),.9rem);letter-spacing:.1em}.welcome__body{display:flex;flex-direction:column;gap:.9rem}.welcome__body p{margin:0}.welcome__divider{border-top:1px solid rgba(15,187,107,.22);margin:.15rem 0}.welcome__section{border:1px solid rgba(15,187,107,.2);border-radius:.75rem;padding:.9rem .95rem;background:#0fbb6b0a;display:flex;flex-direction:column;gap:.75rem}.welcome__section:last-child{margin-bottom:1rem}.welcome__section-head{display:flex;flex-direction:column;gap:.35rem}.welcome__section-title{text-transform:uppercase;letter-spacing:.08em;color:#0fbb6bd1;font-size:clamp(.8rem,.8rem + (.95rem - .8rem) * (100vw - 360px) / (1200px - 360px),.95rem)}.welcome__section-text{color:#0fbb6bc7;font-size:clamp(.85rem,.85rem + (.95rem - .85rem) * (100vw - 360px) / (1200px - 360px),.95rem);line-height:1.35}.welcome__slider{align-items:center;display:flex;gap:.8rem}.welcome__range{appearance:none;background:#0fbb6b33;border-radius:999px;cursor:pointer;flex:1 1 auto;height:.35rem;outline:none}.welcome__range::-webkit-slider-thumb{appearance:none;background:#0fbb6b;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.welcome__range::-moz-range-thumb{background:#0fbb6b;border:none;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.welcome__value{font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);color:#0fbb6bd1;letter-spacing:.08em;min-width:3.25rem;text-align:right}.welcome__hint{color:#0fbb6bbf;font-size:clamp(.5rem,.5rem + (.7rem - .5rem) * (100vw - 360px) / (1200px - 360px),.7rem);line-height:1.35}.welcome__meta{display:grid;gap:.6rem;margin:0}.welcome__row{display:grid;grid-template-columns:5.25rem 1fr;align-items:start;gap:.75rem}.welcome__label{color:#0fbb6bbd;text-transform:uppercase;letter-spacing:.08em;font-size:.75rem;line-height:1.25;padding-top:.15rem}.welcome__data{margin:0}.welcome__data code{background:#0fbb6b14;border:1px solid rgba(15,187,107,.22);border-radius:.45rem;color:#0fbb6b;display:inline-block;padding:.25rem .55rem;max-width:100%;overflow-wrap:anywhere}.welcome__data a{color:#0fbb6b;text-decoration:none;overflow-wrap:anywhere}.welcome__data a:hover{text-decoration:underline}.welcome__disclaimer{color:#0fbb6bc2;font-size:clamp(.5rem,.5rem + (.7rem - .5rem) * (100vw - 360px) / (1200px - 360px),.7rem);line-height:1.35}:host{font-size:inherit}\n"]}]}],propDecorators:{open:[{type:m}],listFontScale:[{type:m}],closeResult:[{type:p}],previewListFontScale:[{type:p}]}});class le{open=!1;scanLinesEnabled=!0;rememberTabOnRefreshEnabled=!1;editLockEnabled=!1;listFontScale=1.25;secondaryTabSoundLabel=null;mainTabSoundLabel=null;clickSoundLabel=null;bootVideoLabel=null;closeResult=new c;save=new c;previewListFontScale=new c;playSecondarySound=new c;playMainSound=new c;playClickSound=new c;playBootVideo=new c;draftScanLines=o(!0,...ngDevMode?[{debugName:"draftScanLines"}]:[]);draftRememberTabOnRefresh=o(!1,...ngDevMode?[{debugName:"draftRememberTabOnRefresh"}]:[]);draftEditLock=o(!1,...ngDevMode?[{debugName:"draftEditLock"}]:[]);draftListFontScale=o(1.25,...ngDevMode?[{debugName:"draftListFontScale"}]:[]);secondarySoundName=o(null,...ngDevMode?[{debugName:"secondarySoundName"}]:[]);mainSoundName=o(null,...ngDevMode?[{debugName:"mainSoundName"}]:[]);clickSoundName=o(null,...ngDevMode?[{debugName:"clickSoundName"}]:[]);bootVideoName=o(null,...ngDevMode?[{debugName:"bootVideoName"}]:[]);secondarySoundFile=null;mainSoundFile=null;clickSoundFile=null;bootVideoFile=null;removeSecondary=!1;removeMain=!1;removeClick=!1;removeBootVideoFlag=!1;ngOnChanges(e){e.scanLinesEnabled&&this.draftScanLines.set(this.scanLinesEnabled),e.rememberTabOnRefreshEnabled&&this.draftRememberTabOnRefresh.set(this.rememberTabOnRefreshEnabled),e.editLockEnabled&&this.draftEditLock.set(this.editLockEnabled),e.listFontScale&&this.draftListFontScale.set(this.listFontScale),e.secondaryTabSoundLabel&&this.secondarySoundName.set(this.secondaryTabSoundLabel),e.mainTabSoundLabel&&this.mainSoundName.set(this.mainTabSoundLabel),e.clickSoundLabel&&this.clickSoundName.set(this.clickSoundLabel),e.bootVideoLabel&&this.bootVideoName.set(this.bootVideoLabel),e.open&&this.open&&(this.draftScanLines.set(this.scanLinesEnabled),this.draftRememberTabOnRefresh.set(this.rememberTabOnRefreshEnabled),this.draftEditLock.set(this.editLockEnabled),this.draftListFontScale.set(this.listFontScale),this.secondarySoundName.set(this.secondaryTabSoundLabel),this.mainSoundName.set(this.mainTabSoundLabel),this.clickSoundName.set(this.clickSoundLabel),this.bootVideoName.set(this.bootVideoLabel),this.secondarySoundFile=null,this.mainSoundFile=null,this.clickSoundFile=null,this.bootVideoFile=null,this.removeSecondary=!1,this.removeMain=!1,this.removeClick=!1,this.removeBootVideoFlag=!1)}closeModal(){this.closeResult.emit()}toggleScanLines(){this.draftScanLines.update(e=>!e)}toggleRememberTabOnRefresh(){this.draftRememberTabOnRefresh.update(e=>!e)}toggleEditLock(){this.draftEditLock.update(e=>!e)}updateListFontScale(e){const t=Number(e);if(!Number.isFinite(t))return;const n=Math.min(150,Math.max(50,t))/100*1.25;this.draftListFontScale.set(n),this.previewListFontScale.emit(n)}resetListFontScale(){this.draftListFontScale.set(1.25),this.previewListFontScale.emit(1.25)}listFontScalePercent(){return Math.round(this.draftListFontScale()/1.25*100)}onSecondarySoundSelected(e){const t=e.target,n=t.files?.[0]??null;this.secondarySoundFile=n,this.removeSecondary=!1,this.secondarySoundName.set(n?.name??this.secondaryTabSoundLabel),t&&(t.value="")}onMainSoundSelected(e){const t=e.target,n=t.files?.[0]??null;this.mainSoundFile=n,this.removeMain=!1,this.mainSoundName.set(n?.name??this.mainTabSoundLabel),t&&(t.value="")}onClickSoundSelected(e){const t=e.target,n=t.files?.[0]??null;this.clickSoundFile=n,this.removeClick=!1,this.clickSoundName.set(n?.name??this.clickSoundLabel),t&&(t.value="")}onBootVideoSelected(e){const t=e.target,n=t.files?.[0]??null;this.bootVideoFile=n,this.removeBootVideoFlag=!1,this.bootVideoName.set(n?.name??this.bootVideoLabel),t&&(t.value="")}removeSecondarySound(){this.secondarySoundFile=null,this.removeSecondary=!0,this.secondarySoundName.set(null)}removeMainSound(){this.mainSoundFile=null,this.removeMain=!0,this.mainSoundName.set(null)}removeClickSound(){this.clickSoundFile=null,this.removeClick=!0,this.clickSoundName.set(null)}previewSecondarySound(){this.playSecondarySound.emit()}previewMainSound(){this.playMainSound.emit()}previewClickSound(){this.playClickSound.emit()}previewBootVideo(){this.playBootVideo.emit(this.bootVideoFile)}removeBootVideo(){this.bootVideoFile=null,this.removeBootVideoFlag=!0,this.bootVideoName.set(null)}submit(e){e.preventDefault(),this.save.emit({scanLinesEnabled:this.draftScanLines(),rememberTabOnRefreshEnabled:this.draftRememberTabOnRefresh(),editLockEnabled:this.draftEditLock(),listFontScale:this.draftListFontScale(),secondaryTabSoundFile:this.secondarySoundFile,mainTabSoundFile:this.mainSoundFile,clickSoundFile:this.clickSoundFile,bootVideoFile:this.bootVideoFile,removeSecondaryTabSound:this.removeSecondary,removeMainTabSound:this.removeMain,removeClickSound:this.removeClick,removeBootVideo:this.removeBootVideoFlag})}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:le,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:le,isStandalone:!0,selector:"pip-boy-settings-modal",inputs:{open:"open",scanLinesEnabled:"scanLinesEnabled",rememberTabOnRefreshEnabled:"rememberTabOnRefreshEnabled",editLockEnabled:"editLockEnabled",listFontScale:"listFontScale",secondaryTabSoundLabel:"secondaryTabSoundLabel",mainTabSoundLabel:"mainTabSoundLabel",clickSoundLabel:"clickSoundLabel",bootVideoLabel:"bootVideoLabel"},outputs:{closeResult:"closeResult",save:"save",previewListFontScale:"previewListFontScale",playSecondarySound:"playSecondarySound",playMainSound:"playMainSound",playClickSound:"playClickSound",playBootVideo:"playBootVideo"},usesOnChanges:!0,ngImport:e,template:'<pip-boy-dialog [open]="open" title="Settings" (closeResult)="closeModal()">\n <form id="settings-form" (submit)="submit($event)">\n <div class="settings-modal-body">\n <label class="settings-modal-field settings-modal-toggle">\n <span>Screen Line Effect</span>\n <input\n type="checkbox"\n [checked]="draftScanLines()"\n (change)="toggleScanLines()"\n hidden\n />\n <button\n type="button"\n class="settings-toggle"\n [class.is-on]="draftScanLines()"\n (click)="toggleScanLines()"\n >\n {{ draftScanLines() ? \'On\' : \'Off\' }}\n </button>\n </label>\n <label class="settings-modal-field settings-modal-toggle">\n <span>Remember Tab on Refresh</span>\n <input\n type="checkbox"\n [checked]="draftRememberTabOnRefresh()"\n (change)="toggleRememberTabOnRefresh()"\n hidden\n />\n <button\n type="button"\n class="settings-toggle"\n [class.is-on]="draftRememberTabOnRefresh()"\n (click)="toggleRememberTabOnRefresh()"\n >\n {{ draftRememberTabOnRefresh() ? \'On\' : \'Off\' }}\n </button>\n </label>\n <label class="settings-modal-field settings-modal-toggle">\n <span>Edit Lock</span>\n <input\n type="checkbox"\n [checked]="draftEditLock()"\n (change)="toggleEditLock()"\n hidden\n />\n <button\n type="button"\n class="settings-toggle"\n [class.is-on]="draftEditLock()"\n (click)="toggleEditLock()"\n >\n {{ draftEditLock() ? \'Locked\' : \'Unlocked\' }}\n </button>\n </label>\n <div class="settings-divider"></div>\n <label class="settings-modal-field settings-modal-slider">\n <div class="settings-slider-head">\n <span>Content Font Size</span>\n <button\n type="button"\n class="settings-reset"\n [disabled]="listFontScalePercent() === 100"\n (click)="resetListFontScale()"\n >\n Reset\n </button>\n </div>\n <div class="settings-slider-row">\n <input\n type="range"\n min="50"\n max="150"\n step="1"\n [value]="listFontScalePercent()"\n (input)="updateListFontScale($any($event.target).value)"\n />\n <span class="settings-slider-value">\n {{ listFontScalePercent() }}%\n </span>\n </div>\n </label>\n <div class="settings-divider"></div>\n <div class="settings-modal-field">\n <span>Main Tab Sound</span>\n <div class="settings-sound-actions">\n <button\n type="button"\n class="settings-sound-button"\n (click)="mainSoundInput.click()"\n >\n {{ mainSoundName() ?? \'Select Sound\' }}\n </button>\n @if (mainSoundName()) {\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="previewMainSound()"\n >\n Play\n </button>\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="removeMainSound()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #mainSoundInput\n type="file"\n accept="audio/*"\n (change)="onMainSoundSelected($event)"\n />\n </div>\n <div class="settings-modal-field">\n <span>Secondary Tab Sound</span>\n <div class="settings-sound-actions">\n <button\n type="button"\n class="settings-sound-button"\n (click)="secondarySoundInput.click()"\n >\n {{ secondarySoundName() ?? \'Select Sound\' }}\n </button>\n @if (secondarySoundName()) {\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="previewSecondarySound()"\n >\n Play\n </button>\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="removeSecondarySound()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #secondarySoundInput\n type="file"\n accept="audio/*"\n (change)="onSecondarySoundSelected($event)"\n />\n </div>\n <div class="settings-modal-field">\n <span>Click Sound</span>\n <div class="settings-sound-actions">\n <button\n type="button"\n class="settings-sound-button"\n (click)="clickSoundInput.click()"\n >\n {{ clickSoundName() ?? \'Select Sound\' }}\n </button>\n @if (clickSoundName()) {\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="previewClickSound()"\n >\n Play\n </button>\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="removeClickSound()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #clickSoundInput\n type="file"\n accept="audio/*"\n (change)="onClickSoundSelected($event)"\n />\n </div>\n <div class="settings-modal-field">\n <span>Boot Sequence Video</span>\n <div class="settings-sound-actions">\n <button\n type="button"\n class="settings-sound-button"\n (click)="bootVideoInput.click()"\n >\n {{ bootVideoName() ?? \'Select Video\' }}\n </button>\n @if (bootVideoName()) {\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="previewBootVideo()"\n >\n Play\n </button>\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="removeBootVideo()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #bootVideoInput\n type="file"\n accept="video/mp4,video/webm"\n (change)="onBootVideoSelected($event)"\n />\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="settings-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.settings-modal-body{display:flex;flex-direction:column;gap:1rem}.settings-modal-field{display:flex;flex-direction:column;gap:.5rem}.settings-modal-slider{gap:.65rem}.settings-slider-head{display:flex;align-items:center;justify-content:space-between;gap:.75rem;flex-wrap:wrap}.settings-slider-row{align-items:center;display:flex;gap:.75rem}.settings-slider-row input[type=range]{appearance:none;background:#0fbb6b33;border-radius:999px;cursor:pointer;flex:1 1 auto;height:.35rem;outline:none}.settings-slider-row input[type=range]::-webkit-slider-thumb{appearance:none;background:#0fbb6b;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.settings-slider-row input[type=range]::-moz-range-thumb{background:#0fbb6b;border:none;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.settings-slider-value{font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);color:#0fbb6bcc;letter-spacing:.08em;min-width:3.25rem;text-align:right}.settings-reset{background:transparent;border:1px solid rgba(15,187,107,.45);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.4rem .75rem;text-transform:uppercase;width:auto}.settings-reset:hover{background:#0fbb6b1f;border-color:#0fbb6b}.settings-reset:disabled{cursor:default;opacity:.55}.settings-modal-toggle{align-items:center;flex-direction:row;justify-content:space-between}.settings-divider{border-top:1px solid rgba(15,187,107,.2);margin:.5rem 0}.settings-sound-actions{display:flex;gap:.5rem;align-items:center}.settings-sound-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;flex:1 1 auto;padding:.5rem .75rem;text-align:left;text-transform:uppercase}.settings-sound-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.settings-sound-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.4rem .7rem;text-transform:uppercase}.settings-sound-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.settings-toggle{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:999px;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.35rem .9rem;text-transform:uppercase}.settings-toggle.is-on{background:#0fbb6b33;border-color:#0fbb6b}.settings-toggle:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"],dependencies:[{kind:"component",type:U,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:le,decorators:[{type:a,args:[{selector:"pip-boy-settings-modal",standalone:!0,imports:[U],template:'<pip-boy-dialog [open]="open" title="Settings" (closeResult)="closeModal()">\n <form id="settings-form" (submit)="submit($event)">\n <div class="settings-modal-body">\n <label class="settings-modal-field settings-modal-toggle">\n <span>Screen Line Effect</span>\n <input\n type="checkbox"\n [checked]="draftScanLines()"\n (change)="toggleScanLines()"\n hidden\n />\n <button\n type="button"\n class="settings-toggle"\n [class.is-on]="draftScanLines()"\n (click)="toggleScanLines()"\n >\n {{ draftScanLines() ? \'On\' : \'Off\' }}\n </button>\n </label>\n <label class="settings-modal-field settings-modal-toggle">\n <span>Remember Tab on Refresh</span>\n <input\n type="checkbox"\n [checked]="draftRememberTabOnRefresh()"\n (change)="toggleRememberTabOnRefresh()"\n hidden\n />\n <button\n type="button"\n class="settings-toggle"\n [class.is-on]="draftRememberTabOnRefresh()"\n (click)="toggleRememberTabOnRefresh()"\n >\n {{ draftRememberTabOnRefresh() ? \'On\' : \'Off\' }}\n </button>\n </label>\n <label class="settings-modal-field settings-modal-toggle">\n <span>Edit Lock</span>\n <input\n type="checkbox"\n [checked]="draftEditLock()"\n (change)="toggleEditLock()"\n hidden\n />\n <button\n type="button"\n class="settings-toggle"\n [class.is-on]="draftEditLock()"\n (click)="toggleEditLock()"\n >\n {{ draftEditLock() ? \'Locked\' : \'Unlocked\' }}\n </button>\n </label>\n <div class="settings-divider"></div>\n <label class="settings-modal-field settings-modal-slider">\n <div class="settings-slider-head">\n <span>Content Font Size</span>\n <button\n type="button"\n class="settings-reset"\n [disabled]="listFontScalePercent() === 100"\n (click)="resetListFontScale()"\n >\n Reset\n </button>\n </div>\n <div class="settings-slider-row">\n <input\n type="range"\n min="50"\n max="150"\n step="1"\n [value]="listFontScalePercent()"\n (input)="updateListFontScale($any($event.target).value)"\n />\n <span class="settings-slider-value">\n {{ listFontScalePercent() }}%\n </span>\n </div>\n </label>\n <div class="settings-divider"></div>\n <div class="settings-modal-field">\n <span>Main Tab Sound</span>\n <div class="settings-sound-actions">\n <button\n type="button"\n class="settings-sound-button"\n (click)="mainSoundInput.click()"\n >\n {{ mainSoundName() ?? \'Select Sound\' }}\n </button>\n @if (mainSoundName()) {\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="previewMainSound()"\n >\n Play\n </button>\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="removeMainSound()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #mainSoundInput\n type="file"\n accept="audio/*"\n (change)="onMainSoundSelected($event)"\n />\n </div>\n <div class="settings-modal-field">\n <span>Secondary Tab Sound</span>\n <div class="settings-sound-actions">\n <button\n type="button"\n class="settings-sound-button"\n (click)="secondarySoundInput.click()"\n >\n {{ secondarySoundName() ?? \'Select Sound\' }}\n </button>\n @if (secondarySoundName()) {\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="previewSecondarySound()"\n >\n Play\n </button>\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="removeSecondarySound()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #secondarySoundInput\n type="file"\n accept="audio/*"\n (change)="onSecondarySoundSelected($event)"\n />\n </div>\n <div class="settings-modal-field">\n <span>Click Sound</span>\n <div class="settings-sound-actions">\n <button\n type="button"\n class="settings-sound-button"\n (click)="clickSoundInput.click()"\n >\n {{ clickSoundName() ?? \'Select Sound\' }}\n </button>\n @if (clickSoundName()) {\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="previewClickSound()"\n >\n Play\n </button>\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="removeClickSound()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #clickSoundInput\n type="file"\n accept="audio/*"\n (change)="onClickSoundSelected($event)"\n />\n </div>\n <div class="settings-modal-field">\n <span>Boot Sequence Video</span>\n <div class="settings-sound-actions">\n <button\n type="button"\n class="settings-sound-button"\n (click)="bootVideoInput.click()"\n >\n {{ bootVideoName() ?? \'Select Video\' }}\n </button>\n @if (bootVideoName()) {\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="previewBootVideo()"\n >\n Play\n </button>\n <button\n type="button"\n class="settings-sound-remove"\n data-skip-click-sound="true"\n (click)="removeBootVideo()"\n >\n Remove\n </button>\n }\n </div>\n <input\n #bootVideoInput\n type="file"\n accept="video/mp4,video/webm"\n (change)="onBootVideoSelected($event)"\n />\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="settings-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.settings-modal-body{display:flex;flex-direction:column;gap:1rem}.settings-modal-field{display:flex;flex-direction:column;gap:.5rem}.settings-modal-slider{gap:.65rem}.settings-slider-head{display:flex;align-items:center;justify-content:space-between;gap:.75rem;flex-wrap:wrap}.settings-slider-row{align-items:center;display:flex;gap:.75rem}.settings-slider-row input[type=range]{appearance:none;background:#0fbb6b33;border-radius:999px;cursor:pointer;flex:1 1 auto;height:.35rem;outline:none}.settings-slider-row input[type=range]::-webkit-slider-thumb{appearance:none;background:#0fbb6b;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.settings-slider-row input[type=range]::-moz-range-thumb{background:#0fbb6b;border:none;border-radius:999px;cursor:pointer;height:.9rem;width:.9rem}.settings-slider-value{font-size:clamp(.75rem,.75rem + (.85rem - .75rem) * (100vw - 360px) / (1200px - 360px),.85rem);color:#0fbb6bcc;letter-spacing:.08em;min-width:3.25rem;text-align:right}.settings-reset{background:transparent;border:1px solid rgba(15,187,107,.45);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.4rem .75rem;text-transform:uppercase;width:auto}.settings-reset:hover{background:#0fbb6b1f;border-color:#0fbb6b}.settings-reset:disabled{cursor:default;opacity:.55}.settings-modal-toggle{align-items:center;flex-direction:row;justify-content:space-between}.settings-divider{border-top:1px solid rgba(15,187,107,.2);margin:.5rem 0}.settings-sound-actions{display:flex;gap:.5rem;align-items:center}.settings-sound-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;flex:1 1 auto;padding:.5rem .75rem;text-align:left;text-transform:uppercase}.settings-sound-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.settings-sound-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.4rem .7rem;text-transform:uppercase}.settings-sound-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.settings-toggle{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:999px;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.35rem .9rem;text-transform:uppercase}.settings-toggle.is-on{background:#0fbb6b33;border-color:#0fbb6b}.settings-toggle:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"]}]}],propDecorators:{open:[{type:m}],scanLinesEnabled:[{type:m}],rememberTabOnRefreshEnabled:[{type:m}],editLockEnabled:[{type:m}],listFontScale:[{type:m}],secondaryTabSoundLabel:[{type:m}],mainTabSoundLabel:[{type:m}],clickSoundLabel:[{type:m}],bootVideoLabel:[{type:m}],closeResult:[{type:p}],save:[{type:p}],previewListFontScale:[{type:p}],playSecondarySound:[{type:p}],playMainSound:[{type:p}],playClickSound:[{type:p}],playBootVideo:[{type:p}]}});class de{constructor(){r(()=>{this.open()&&(this.draftImageUrl.set(this.imageUrl()),this.draftImageName.set(null),this.draftImageFile.set(null),this.removedImage.set(!1),this.clearPreviewUrl())})}open=t(!1,...ngDevMode?[{debugName:"open"}]:[]);title=t("Map Image",...ngDevMode?[{debugName:"title"}]:[]);imageUrl=t(null,...ngDevMode?[{debugName:"imageUrl"}]:[]);closeResult=d();save=d();draftImageName=o(null,...ngDevMode?[{debugName:"draftImageName"}]:[]);draftImageUrl=o(null,...ngDevMode?[{debugName:"draftImageUrl"}]:[]);draftImageFile=o(null,...ngDevMode?[{debugName:"draftImageFile"}]:[]);removedImage=o(!1,...ngDevMode?[{debugName:"removedImage"}]:[]);previewUrl=null;closeModal(){this.clearPreviewUrl(),this.closeResult.emit()}onImageSelected(e){const t=e.target,n=t.files?.[0]??null;this.draftImageName.set(n?n.name:null),n&&(this.removedImage.set(!1),this.draftImageFile.set(n),this.setPreviewUrl(URL.createObjectURL(n)),t.value="")}removeImage(){this.draftImageName.set(null),this.draftImageUrl.set(null),this.draftImageFile.set(null),this.removedImage.set(!0),this.clearPreviewUrl()}submit(e){e?.preventDefault(),this.save.emit({imageFile:this.draftImageFile(),removeImage:this.removedImage()}),this.clearPreviewUrl(),this.closeResult.emit()}setPreviewUrl(e){this.clearPreviewUrl(),this.previewUrl=e,this.draftImageUrl.set(e)}clearPreviewUrl(){this.previewUrl&&(URL.revokeObjectURL(this.previewUrl),this.previewUrl=null)}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:de,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:de,isStandalone:!0,selector:"pip-boy-map-image-modal",inputs:{open:{classPropertyName:"open",publicName:"open",isSignal:!0,isRequired:!1,transformFunction:null},title:{classPropertyName:"title",publicName:"title",isSignal:!0,isRequired:!1,transformFunction:null},imageUrl:{classPropertyName:"imageUrl",publicName:"imageUrl",isSignal:!0,isRequired:!1,transformFunction:null}},outputs:{closeResult:"closeResult",save:"save"},ngImport:e,template:'<pip-boy-dialog [open]="open()" [title]="title()" (closeResult)="closeModal()">\n <form id="map-image-form" (submit)="submit($event)">\n <div class="map-image-modal-body">\n <div class="map-image-modal-image">\n <button\n type="button"\n class="map-image-modal-image-button"\n (click)="modalImageInput.click()"\n >\n {{ draftImageName() ? draftImageName() : \'Select Image\' }}\n </button>\n @if (draftImageUrl()) {\n <button\n type="button"\n class="map-image-modal-image-remove"\n (click)="removeImage()"\n >\n Remove Image\n </button>\n }\n <input\n #modalImageInput\n type="file"\n accept="image/*"\n (change)="onImageSelected($event)"\n />\n @if (draftImageUrl()) {\n <img [src]="draftImageUrl()" alt="Map preview" />\n }\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="map-image-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.map-image-modal-body{display:flex;flex-direction:column;gap:1rem}.map-image-modal-image{display:flex;flex-direction:column;gap:.75rem}.map-image-modal-image input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.map-image-modal-image img{border:1px solid rgba(15,187,107,.35);max-height:12rem;object-fit:contain;padding:.5rem}.map-image-modal-image-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.map-image-modal-image-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.map-image-modal-image-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.map-image-modal-image-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"],dependencies:[{kind:"component",type:U,selector:"pip-boy-dialog",inputs:["open","title","subtitle","maxWidth","width","zIndex","closeOnBackdrop"],outputs:["closeResult"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:de,decorators:[{type:a,args:[{selector:"pip-boy-map-image-modal",standalone:!0,imports:[U],template:'<pip-boy-dialog [open]="open()" [title]="title()" (closeResult)="closeModal()">\n <form id="map-image-form" (submit)="submit($event)">\n <div class="map-image-modal-body">\n <div class="map-image-modal-image">\n <button\n type="button"\n class="map-image-modal-image-button"\n (click)="modalImageInput.click()"\n >\n {{ draftImageName() ? draftImageName() : \'Select Image\' }}\n </button>\n @if (draftImageUrl()) {\n <button\n type="button"\n class="map-image-modal-image-remove"\n (click)="removeImage()"\n >\n Remove Image\n </button>\n }\n <input\n #modalImageInput\n type="file"\n accept="image/*"\n (change)="onImageSelected($event)"\n />\n @if (draftImageUrl()) {\n <img [src]="draftImageUrl()" alt="Map preview" />\n }\n </div>\n </div>\n </form>\n <div dialog-actions>\n <button type="button" (click)="closeModal()">Cancel</button>\n <button type="submit" form="map-image-form">Save</button>\n </div>\n</pip-boy-dialog>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}form,.map-image-modal-body{display:flex;flex-direction:column;gap:1rem}.map-image-modal-image{display:flex;flex-direction:column;gap:.75rem}.map-image-modal-image input{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.map-image-modal-image img{border:1px solid rgba(15,187,107,.35);max-height:12rem;object-fit:contain;padding:.5rem}.map-image-modal-image-button{background:transparent;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;padding:.6rem .75rem;text-align:left;text-transform:uppercase}.map-image-modal-image-button:hover{border-color:#0fbb6b;background:#0fbb6b1f}.map-image-modal-image-remove{background:transparent;border:1px solid rgba(15,187,107,.4);border-radius:.5rem;color:#0fbb6b;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.45rem .75rem;text-transform:uppercase}.map-image-modal-image-remove:hover{border-color:#0fbb6b;background:#0fbb6b1f}:host{font-size:inherit}\n"]}]}],ctorParameters:()=>[],propDecorators:{open:[{type:e.Input,args:[{isSignal:!0,alias:"open",required:!1}]}],title:[{type:e.Input,args:[{isSignal:!0,alias:"title",required:!1}]}],imageUrl:[{type:e.Input,args:[{isSignal:!0,alias:"imageUrl",required:!1}]}],closeResult:[{type:e.Output,args:["closeResult"]}],save:[{type:e.Output,args:["save"]}]}});class ce{dbPromise=this.openDb();videoUrls=o({},...ngDevMode?[{debugName:"videoUrls"}]:[]);videoLabels=o({},...ngDevMode?[{debugName:"videoLabels"}]:[]);urlLoading=new Set;metaLoading=new Set;getVideoLabel(e){if(!e)return null;const t=this.videoLabels()[e];return t||(this.loadVideoMeta(e),null)}getVideoUrl(e){if(!e)return null;const t=this.videoUrls()[e];return t||(this.loadVideoUrl(e),null)}async saveFile(e){const t=this.createId(),n={id:t,fileName:e.name,mime:e.type||"application/octet-stream"};return await this.putRecord({...n,blob:e}),this.cacheUrl(t,URL.createObjectURL(e)),this.cacheLabel(t,n.fileName),n}async saveBlobWithId(e,t,n,a){await this.putRecord({id:e,blob:t,fileName:n,mime:a}),this.cacheUrl(e,URL.createObjectURL(t)),this.cacheLabel(e,n)}async getRecord(e){const t=await this.dbPromise;return new Promise((n,a)=>{const o=t.transaction("videos","readonly").objectStore("videos").get(e);o.onsuccess=()=>{n(o.result??null)},o.onerror=()=>a(o.error)})}extensionFromMime(e){switch(e){case"video/mp4":return".mp4";case"video/webm":return".webm";case"video/ogg":return".ogv";case"video/quicktime":return".mov";case"video/mpeg":return".mpeg";default:return""}}cacheUrl(e,t){this.videoUrls.update(n=>({...n,[e]:t}))}cacheLabel(e,t){this.videoLabels.update(n=>({...n,[e]:t}))}async loadVideoUrl(e){if(!this.urlLoading.has(e)){this.urlLoading.add(e);try{const t=await this.getRecord(e);if(!t)return;this.cacheUrl(e,URL.createObjectURL(t.blob)),this.cacheLabel(e,t.fileName)}finally{this.urlLoading.delete(e)}}}async loadVideoMeta(e){if(!this.metaLoading.has(e)){this.metaLoading.add(e);try{const t=await this.getRecord(e);if(!t)return;this.cacheLabel(e,t.fileName)}finally{this.metaLoading.delete(e)}}}async putRecord(e){const t=await this.dbPromise;return new Promise((n,a)=>{const o=t.transaction("videos","readwrite").objectStore("videos").put(e);o.onsuccess=()=>n(),o.onerror=()=>a(o.error)})}openDb(){return new Promise((e,t)=>{const n=indexedDB.open("pipBoy3000Videos",1);n.onupgradeneeded=()=>{const e=n.result;e.objectStoreNames.contains("videos")||e.createObjectStore("videos",{keyPath:"id"})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}createId(){return"undefined"!=typeof crypto&&"randomUUID"in crypto?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:ce,deps:[],target:e.ɵɵFactoryTarget.Injectable});static"ɵprov"=e.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:ce,providedIn:"root"})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:ce,decorators:[{type:i,args:[{providedIn:"root"}]}]});const pe=[],me=[],ue=[],be=[],ge=[],he=[],fe=[],ve=[],ye=[],we=[],xe=[],ke=[],Se=[],Me=[],Ie=[];class Le{returnToUrl=t("https://www.pip-boy.com",...ngDevMode?[{debugName:"returnToUrl"}]:[]);state=l(W);settings=l(C);imageStore=l(k);soundStore=l(ae);videoStore=l(ce);audioPlayer=l(oe);hostRef=l(g);appVersion=N;tabsOpen=o(!1,...ngDevMode?[{debugName:"tabsOpen"}]:[]);showResetModal=o(!1,...ngDevMode?[{debugName:"showResetModal"}]:[]);showExitModal=o(!1,...ngDevMode?[{debugName:"showExitModal"}]:[]);showBugModal=o(!1,...ngDevMode?[{debugName:"showBugModal"}]:[]);showSettingsModal=o(!1,...ngDevMode?[{debugName:"showSettingsModal"}]:[]);settingsListFontScaleSnapshot=o(null,...ngDevMode?[{debugName:"settingsListFontScaleSnapshot"}]:[]);showWelcomeModal=o(!0,...ngDevMode?[{debugName:"showWelcomeModal"}]:[]);showBootSequence=o(!1,...ngDevMode?[{debugName:"showBootSequence"}]:[]);bootSequenceStarted=o(!1,...ngDevMode?[{debugName:"bootSequenceStarted"}]:[]);bootSequenceShowWelcome=o(!0,...ngDevMode?[{debugName:"bootSequenceShowWelcome"}]:[]);bootAutoplayAttempted=o(!1,...ngDevMode?[{debugName:"bootAutoplayAttempted"}]:[]);bootNeedsClick=o(!1,...ngDevMode?[{debugName:"bootNeedsClick"}]:[]);bootIsPlaying=o(!1,...ngDevMode?[{debugName:"bootIsPlaying"}]:[]);mapImageModal=o(null,...ngDevMode?[{debugName:"mapImageModal"}]:[]);localMapImage=b("localMapImage",...ngDevMode?[{debugName:"localMapImage"}]:[]);worldMapImage=b("worldMapImage",...ngDevMode?[{debugName:"worldMapImage"}]:[]);localMapView=b("localMapView",...ngDevMode?[{debugName:"localMapView"}]:[]);worldMapView=b("worldMapView",...ngDevMode?[{debugName:"worldMapView"}]:[]);extraOptionModal=o(null,...ngDevMode?[{debugName:"extraOptionModal"}]:[]);tabsActionsLeftOpen=o(!1,...ngDevMode?[{debugName:"tabsActionsLeftOpen"}]:[]);tabsActionsRightOpen=o(!1,...ngDevMode?[{debugName:"tabsActionsRightOpen"}]:[]);isMapDragging=o(!1,...ngDevMode?[{debugName:"isMapDragging"}]:[]);viewportWidth=o("undefined"==typeof window?0:window.innerWidth,...ngDevMode?[{debugName:"viewportWidth"}]:[]);mapImageModalTitle=u(()=>"WORLD"===this.mapImageModal()?"World Map":"Local Map",...ngDevMode?[{debugName:"mapImageModalTitle"}]:[]);mapImageModalImage=u(()=>{const e="WORLD"===this.mapImageModal()?this.settings.worldMapImage():this.settings.localMapImage();return this.imageStore.getImageUrl(e)},...ngDevMode?[{debugName:"mapImageModalImage"}]:[]);secondaryTabSoundLabel=u(()=>this.soundStore.getSoundLabel(this.settings.secondaryTabSoundId()),...ngDevMode?[{debugName:"secondaryTabSoundLabel"}]:[]);mainTabSoundLabel=u(()=>this.soundStore.getSoundLabel(this.settings.mainTabSoundId()),...ngDevMode?[{debugName:"mainTabSoundLabel"}]:[]);clickSoundLabel=u(()=>this.soundStore.getSoundLabel(this.settings.clickSoundId()),...ngDevMode?[{debugName:"clickSoundLabel"}]:[]);bootVideoLabel=u(()=>this.videoStore.getVideoLabel(this.settings.bootVideoId()),...ngDevMode?[{debugName:"bootVideoLabel"}]:[]);bootVideoUrl=u(()=>this.videoStore.getVideoUrl(this.settings.bootVideoId()),...ngDevMode?[{debugName:"bootVideoUrl"}]:[]);bootVideoPreviewUrl=o(null,...ngDevMode?[{debugName:"bootVideoPreviewUrl"}]:[]);bootVideoPlaybackUrl=u(()=>this.bootVideoPreviewUrl()??this.bootVideoUrl(),...ngDevMode?[{debugName:"bootVideoPlaybackUrl"}]:[]);mapDragState={target:null,startX:0,startY:0,scrollLeft:0,scrollTop:0,moved:!1};suppressMapClick=!1;isScreenTooSmall=u(()=>this.viewportWidth()<650,...ngDevMode?[{debugName:"isScreenTooSmall"}]:[]);bootSequenceWatcher=r(()=>{this.settings.bootVideoId(),this.maybeStartBootSequence()},...ngDevMode?[{debugName:"bootSequenceWatcher"}]:[]);extraOptionTitle=u(()=>{switch(this.extraOptionModal()){case"RADAWAY":case"RADX":return"Edit Text";default:return""}},...ngDevMode?[{debugName:"extraOptionTitle"}]:[]);extraOptionValue=u(()=>{const e=this.extraOptionModal();return"STIMPAK"===e?this.settings.stimpakLabel():"LIMBS"===e?this.settings.limbLabel():"RADAWAY"===e?this.settings.radAwayLabel():"RADX"===e?this.settings.radXLabel():""},...ngDevMode?[{debugName:"extraOptionValue"}]:[]);documentClickHandler=e=>{const t=e.target;if(!t)return;if(!this.hostRef.nativeElement.contains(t))return;if(t.closest('[data-skip-click-sound="true"]'))return;const n=t.closest("button, input, select, textarea");n&&n.disabled||this.soundStore.playSound(this.settings.clickSoundId())};toggleTabs(){this.tabsOpen.update(e=>!e)}toggleTabsActions(e){"left"===e?(this.tabsActionsLeftOpen.update(e=>!e),this.tabsActionsRightOpen.set(!1)):(this.tabsActionsRightOpen.update(e=>!e),this.tabsActionsLeftOpen.set(!1))}onResize(){this.viewportWidth.set(window.innerWidth)}ngOnInit(){"undefined"!=typeof document&&(document.addEventListener("click",this.documentClickHandler,!0),this.maybeStartBootSequence())}ngOnDestroy(){"undefined"!=typeof document&&(document.removeEventListener("click",this.documentClickHandler,!0),this.clearBootVideoPreview())}async saveSettingsToFile(){const e=this.settings.exportSettingsSnapshot(),t=this.collectImageIds(e),n=this.collectSoundIds(e),a=this.collectVideoIds(e),o=[],i=[],s=[],r=new y;for(const e of t){const t=await this.imageStore.getRecord(e);if(!t)continue;const n=this.getExtension(t.fileName,t.mime);r.file(`images/${e}${n}`,t.blob),o.push({id:e,fileName:t.fileName,mime:t.mime})}for(const e of n){const t=await this.soundStore.getRecord(e);if(!t)continue;const n=this.getSoundExtension(t.fileName,t.mime);r.file(`sounds/${e}${n}`,t.blob),i.push({id:e,fileName:t.fileName,mime:t.mime})}for(const e of a){const t=await this.videoStore.getRecord(e);if(!t)continue;const n=this.getVideoExtension(t.fileName,t.mime);r.file(`videos/${e}${n}`,t.blob),s.push({id:e,fileName:t.fileName,mime:t.mime})}const l={version:1,images:o,sounds:i,videos:s,pipBoy3000Settings:e};r.file("settings.json",JSON.stringify(l));const d=await r.generateAsync({type:"blob"}),c=URL.createObjectURL(d),p=document.createElement("a");p.href=c,p.download="pip-boy-3000a.zip",p.click(),URL.revokeObjectURL(c)}openResetModal(){this.showResetModal.set(!0)}closeResetModal(){this.showResetModal.set(!1)}confirmReset(){this.stopAllSounds(),this.settings.resetToDefaults(),this.closeResetModal(),this.showWelcomeModal.set(!0)}openExitModal(){this.showExitModal.set(!0)}closeExitModal(){this.showExitModal.set(!1)}confirmExit(){window.location.href=this.returnToUrl()}openBugModal(){this.showBugModal.set(!0)}closeBugModal(){this.showBugModal.set(!1)}confirmBugReport(){window.open("https://github.com/CodyTolene/pip-terminal/issues","_blank"),this.closeBugModal()}openSettingsModal(){this.settingsListFontScaleSnapshot.set(this.settings.listFontScale()),this.showSettingsModal.set(!0)}closeSettingsModal(){this.showSettingsModal.set(!1)}cancelSettingsModal(){const e=this.settingsListFontScaleSnapshot();null!==e&&this.settings.listFontScale.set(e),this.settingsListFontScaleSnapshot.set(null),this.showSettingsModal.set(!1)}closeWelcomeModal(){this.showWelcomeModal.set(!1)}finishBootSequence(){this.showBootSequence.set(!1),this.clearBootVideoPreview(),this.bootAutoplayAttempted.set(!1),this.bootNeedsClick.set(!1),this.bootIsPlaying.set(!1),this.bootSequenceShowWelcome()&&this.showWelcomeModal.set(!0)}saveSettingsModal(e){this.settings.scanLinesEnabled.set(e.scanLinesEnabled),this.settings.rememberTabOnRefresh.set(e.rememberTabOnRefreshEnabled),this.settings.editLockEnabled.set(e.editLockEnabled),this.settings.listFontScale.set(e.listFontScale),this.settingsListFontScaleSnapshot.set(null),e.removeSecondaryTabSound&&this.settings.secondaryTabSoundId.set(null),e.removeMainTabSound&&this.settings.mainTabSoundId.set(null),e.removeClickSound&&this.settings.clickSoundId.set(null),e.removeBootVideo&&this.settings.bootVideoId.set(null),e.secondaryTabSoundFile&&this.soundStore.saveFile(e.secondaryTabSoundFile).then(e=>this.settings.secondaryTabSoundId.set(e.id)),e.mainTabSoundFile&&this.soundStore.saveFile(e.mainTabSoundFile).then(e=>this.settings.mainTabSoundId.set(e.id)),e.clickSoundFile&&this.soundStore.saveFile(e.clickSoundFile).then(e=>this.settings.clickSoundId.set(e.id)),e.bootVideoFile&&this.videoStore.saveFile(e.bootVideoFile).then(e=>this.settings.bootVideoId.set(e.id)),this.closeSettingsModal()}previewListFontScale(e){this.settings.listFontScale.set(e)}previewSecondaryTabSound(){this.soundStore.playSound(this.settings.secondaryTabSoundId())}previewMainTabSound(){this.soundStore.playSound(this.settings.mainTabSoundId())}previewClickSound(){this.soundStore.playSound(this.settings.clickSoundId())}previewBootVideo(e){if(e){const t=URL.createObjectURL(e);this.setBootVideoPreviewUrl(t)}else{if(!this.settings.bootVideoId())return;this.clearBootVideoPreview()}this.bootSequenceShowWelcome.set(!1),this.bootAutoplayAttempted.set(!1),this.bootNeedsClick.set(!1),this.bootIsPlaying.set(!1),this.showWelcomeModal.set(!1),this.showBootSequence.set(!0)}maybeStartBootSequence(){"undefined"!=typeof document&&(this.bootSequenceStarted()||this.settings.bootVideoId()&&(this.clearBootVideoPreview(),this.bootSequenceShowWelcome.set(!0),this.bootSequenceStarted.set(!0),this.bootAutoplayAttempted.set(!1),this.bootNeedsClick.set(!1),this.bootIsPlaying.set(!1),this.showWelcomeModal.set(!1),this.showBootSequence.set(!0)))}handleBootCanPlay(e){this.bootAutoplayAttempted()||(this.bootAutoplayAttempted.set(!0),e.play().then(()=>{this.bootNeedsClick.set(!1),this.bootIsPlaying.set(!0)}).catch(()=>{this.bootNeedsClick.set(!0)}))}playBootVideo(e,t){t?.stopPropagation(),this.bootIsPlaying()||e.play().then(()=>{this.bootNeedsClick.set(!1),this.bootIsPlaying.set(!0)}).catch(()=>{this.bootNeedsClick.set(!0)})}setBootVideoPreviewUrl(e){const t=this.bootVideoPreviewUrl();t&&URL.revokeObjectURL(t),this.bootVideoPreviewUrl.set(e)}clearBootVideoPreview(){const e=this.bootVideoPreviewUrl();e&&(URL.revokeObjectURL(e),this.bootVideoPreviewUrl.set(null))}openGithubProfile(){window.open("https://github.com/CodyTolene","_blank")}selectPrimary(e){this.soundStore.playSound(this.settings.mainTabSoundId()),this.state.selectPrimary(e)}selectSecondary(e){this.soundStore.playSound(this.settings.secondaryTabSoundId()),this.state.selectSecondary(e)}openExtraOptionModal(e){this.settings.editLockEnabled()||this.extraOptionModal.set(e)}closeExtraOptionModal(){this.extraOptionModal.set(null)}saveExtraOptionModal(e){const t=this.extraOptionModal();"STIMPAK"===t?this.settings.stimpakLabel.set(e):"LIMBS"===t?this.settings.limbLabel.set(e):"RADAWAY"===t?this.settings.radAwayLabel.set(e):"RADX"===t&&this.settings.radXLabel.set(e),this.closeExtraOptionModal()}async loadSettingsFromFile(e){const t=e.target,n=t.files?.[0]??null;if(!n)return;this.stopAllSounds();const a=await y.loadAsync(n),o=a.file("settings.json");if(!o)return void(t.value="");const i=await o.async("string"),s=JSON.parse(i),r=s.pipBoy3000Settings??s;if(Array.isArray(s.images))for(const e of s.images){const t=this.getExtension(e.fileName,e.mime),n=a.file(`images/${e.id}${t}`)??a.file(new RegExp(`^images/${e.id}\\.`))?.[0];if(!n)continue;const o=await n.async("blob");await this.imageStore.saveBlobWithId(e.id,o,e.fileName,e.mime)}if(Array.isArray(s.sounds))for(const e of s.sounds){const t=this.getSoundExtension(e.fileName,e.mime),n=a.file(`sounds/${e.id}${t}`)??a.file(new RegExp(`^sounds/${e.id}\\.`))?.[0];if(!n)continue;const o=await n.async("blob");await this.soundStore.saveBlobWithId(e.id,o,e.fileName,e.mime)}if(Array.isArray(s.videos))for(const e of s.videos){const t=this.getVideoExtension(e.fileName,e.mime),n=a.file(`videos/${e.id}${t}`)??a.file(new RegExp(`^videos/${e.id}\\.`))?.[0];if(!n)continue;const o=await n.async("blob");await this.videoStore.saveBlobWithId(e.id,o,e.fileName,e.mime)}this.settings.importSettingsSnapshot(r),t.value=""}stopAllSounds(){this.audioPlayer.stop(),this.soundStore.stopAll()}collectImageIds(e){const t=new Set,n=e=>{e&&t.add(e)};return e.weaponItems.forEach(e=>n(e.imageId)),e.apparelItems.forEach(e=>n(e.imageId)),e.aidItems.forEach(e=>n(e.imageId)),e.miscItems.forEach(e=>n(e.imageId)),e.ammoItems.forEach(e=>n(e.imageId)),e.specialItems.forEach(e=>n(e.imageId)),e.skillItems.forEach(e=>n(e.imageId)),e.perkItems.forEach(e=>n(e.imageId)),e.vaultBoyImages.forEach(e=>n(e)),n(e.localMapImage),n(e.worldMapImage),Array.from(t)}collectSoundIds(e){const t=new Set,n=e=>{e&&t.add(e)};return n(e.secondaryTabSoundId),n(e.mainTabSoundId),n(e.clickSoundId),e.notesItems.forEach(e=>n(e.soundId)),e.radioItems.forEach(e=>n(e.soundId)),Array.from(t)}collectVideoIds(e){const t=new Set;var n;return(n=e.bootVideoId)&&t.add(n),Array.from(t)}getExtension(e,t){const n=e.match(/\.[a-z0-9]+$/i);return n?n[0]:this.imageStore.extensionFromMime(t)}getSoundExtension(e,t){const n=e.match(/\.[a-z0-9]+$/i);return n?n[0]:this.soundStore.extensionFromMime(t)}getVideoExtension(e,t){const n=e.match(/\.[a-z0-9]+$/i);return n?n[0]:this.videoStore.extensionFromMime(t)}openMapImageModal(e){this.settings.editLockEnabled()||(this.suppressMapClick?this.suppressMapClick=!1:this.mapImageModal.set(e))}closeMapImageModal(){this.mapImageModal.set(null)}zoomMap(e,t){const n="WORLD"===e?this.settings.worldMapZoom:this.settings.localMapZoom,a=Math.min(3,Math.max(.5,n()+t));n.set(Number(a.toFixed(2)))}resetMapZoom(e){"WORLD"===e?this.settings.worldMapZoom.set(1):this.settings.localMapZoom.set(1)}startMapDrag(e){if(0!==e.button)return;const t=e.currentTarget;t&&t.querySelector("img")&&(this.mapDragState={target:t,startX:e.clientX,startY:e.clientY,scrollLeft:t.scrollLeft,scrollTop:t.scrollTop,moved:!1},this.isMapDragging.set(!0),e.preventDefault())}onMapDrag(e){const t=this.mapDragState.target;if(!t)return;const n=e.clientX-this.mapDragState.startX,a=e.clientY-this.mapDragState.startY;if(!this.mapDragState.moved){if(Math.abs(n)<3&&Math.abs(a)<3)return;this.mapDragState.moved=!0}t.scrollLeft=this.mapDragState.scrollLeft-n,t.scrollTop=this.mapDragState.scrollTop-a,e.preventDefault()}endMapDrag(){this.mapDragState.target&&(this.mapDragState.moved&&(this.suppressMapClick=!0),this.mapDragState={target:null,startX:0,startY:0,scrollLeft:0,scrollTop:0,moved:!1},this.isMapDragging.set(!1))}fitMapZoom(e){const t="WORLD"===e?this.worldMapView():this.localMapView(),n="WORLD"===e?this.worldMapImage():this.localMapImage();if(!t||!n)return;const a=t.nativeElement.clientWidth,o=n.nativeElement.naturalWidth;if(!a||!o)return;const i=Math.min(3,Math.max(.5,a/o));("WORLD"===e?this.settings.worldMapZoom:this.settings.localMapZoom).set(Number(i.toFixed(2)))}isMapFit(e){const t="WORLD"===e?this.worldMapView():this.localMapView(),n="WORLD"===e?this.worldMapImage():this.localMapImage();if(!t||!n)return!1;const a=t.nativeElement.clientWidth,o=n.nativeElement.naturalWidth;if(!a||!o)return!1;const i=Math.min(3,Math.max(.5,a/o)),s="WORLD"===e?this.settings.worldMapZoom():this.settings.localMapZoom();return Math.abs(s-Number(i.toFixed(2)))<.01}async saveMapImageModal(e){const t=this.mapImageModal();if(t){if(e.removeImage)return"WORLD"===t?this.settings.worldMapImage.set(null):this.settings.localMapImage.set(null),void this.closeMapImageModal();if(e.imageFile){const n=await this.imageStore.saveFile(e.imageFile);"WORLD"===t?this.settings.worldMapImage.set(n.id):this.settings.localMapImage.set(n.id)}this.closeMapImageModal()}}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:Le,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:Le,isStandalone:!0,selector:"pip-boy-3000a",inputs:{returnToUrl:{classPropertyName:"returnToUrl",publicName:"returnToUrl",isSignal:!0,isRequired:!1,transformFunction:null}},host:{listeners:{"window:resize":"onResize()"},classAttribute:"pip-boy-3000a-theme"},providers:[W,C,{provide:P,useValue:{storageKey:"pipBoy3000aSettings",skillDefaults:xe,perkDefaults:ke,weaponDefaults:pe,apparelDefaults:me,aidDefaults:ue,miscDefaults:be,ammoDefaults:ge,statSourceItems:{special:Se,skills:Me,perks:Ie},inventorySourceItems:{weapons:he,apparel:fe,aid:ve,misc:ye,ammo:we}}}],viewQueries:[{propertyName:"localMapImage",first:!0,predicate:["localMapImage"],descendants:!0,isSignal:!0},{propertyName:"worldMapImage",first:!0,predicate:["worldMapImage"],descendants:!0,isSignal:!0},{propertyName:"localMapView",first:!0,predicate:["localMapView"],descendants:!0,isSignal:!0},{propertyName:"worldMapView",first:!0,predicate:["worldMapView"],descendants:!0,isSignal:!0}],ngImport:e,template:'<main\n #screen\n class="screen"\n [style.--list-font-scale]="settings.listFontScale()"\n [class.is-booting]="showBootSequence()"\n>\n @if (settings.scanLinesEnabled()) {\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="300"\n [scanColorRgb]="\'255, 159, 28\'"\n />\n }\n @if (isScreenTooSmall()) {\n <div class="screen-size-overlay" role="alert" aria-live="assertive">\n Screen is too small.<br />Please rotate to landscape.\n </div>\n }\n @if (showBootSequence()) {\n <div\n class="boot-sequence"\n [class.is-playing]="bootIsPlaying()"\n tabindex="0"\n data-skip-click-sound="true"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n <button\n type="button"\n class="boot-sequence__close"\n aria-label="Close boot sequence"\n data-skip-click-sound="true"\n (click)="finishBootSequence()"\n >\n X\n </button>\n @if (bootVideoPlaybackUrl()) {\n <video\n #bootVideo\n [src]="bootVideoPlaybackUrl()"\n muted\n playsinline\n preload="auto"\n (canplay)="handleBootCanPlay(bootVideo)"\n (click)="playBootVideo(bootVideo, $event)"\n (ended)="finishBootSequence()"\n ></video>\n @if (bootNeedsClick()) {\n <button\n type="button"\n class="boot-sequence__prompt"\n data-skip-click-sound="true"\n (click)="playBootVideo(bootVideo, $event)"\n >\n Click to play\n </button>\n }\n } @else {\n <div class="boot-sequence__loading">Loading boot sequence...</div>\n }\n </div>\n }\n \x3c!-- HEADER --\x3e\n <pip-boy-3000-header />\n \x3c!-- CONTENT --\x3e\n <section class="content">\n @if (state.primary() === \'STATS\') {\n @if (state.secondary() === \'STATUS\') {\n <div class="status-content">\n <nav class="column sub-content" aria-label="Status tabs">\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'CND\'"\n (click)="state.selectTertiary(\'CND\')"\n >\n CND\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'RAD\'"\n (click)="state.selectTertiary(\'RAD\')"\n >\n RAD\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'EFF\'"\n (click)="state.selectTertiary(\'EFF\')"\n >\n EFF\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'H20\'"\n (click)="state.selectTertiary(\'H20\')"\n >\n H20\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'FOD\'"\n (click)="state.selectTertiary(\'FOD\')"\n >\n FOD\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'SLP\'"\n (click)="state.selectTertiary(\'SLP\')"\n >\n SLP\n </button>\n </nav>\n @if (state.tertiary() === \'CND\') {\n <pip-boy-cnd-status />\n } @else if (state.tertiary() === \'RAD\') {\n <pip-boy-radiation-meter />\n <div class="extra-options">\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADAWAY\')"\n >\n {{ settings.radAwayLabel() }}\n </button>\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADX\')"\n >\n {{ settings.radXLabel() }}\n </button>\n </div>\n } @else if (state.tertiary() === \'EFF\') {\n <pip-boy-eff-layout />\n } @else if (state.tertiary() === \'H20\') {\n <pip-boy-status-meter kind="H20" />\n } @else if (state.tertiary() === \'FOD\') {\n <pip-boy-status-meter kind="FOD" />\n } @else if (state.tertiary() === \'SLP\') {\n <pip-boy-status-meter kind="SLP" />\n }\n </div>\n } @else if (state.secondary() === \'S.P.E.C.I.A.L.\') {\n <pip-boy-stats-layout\n category="SPECIAL"\n valueLabel="Rating"\n [valueMin]="1"\n [valueMax]="10"\n />\n } @else if (state.secondary() === \'SKILLS\') {\n <pip-boy-stats-layout\n category="SKILLS"\n valueLabel="Skill"\n [valueMin]="0"\n [valueMax]="100"\n />\n } @else if (state.secondary() === \'PERKS\') {\n <pip-boy-stats-layout\n category="PERKS"\n valueLabel="Rank"\n [valueMin]="0"\n />\n } @else if (state.secondary() === \'GENERAL\') {\n <pip-boy-stats-layout category="GENERAL" valueLabel="Value" />\n }\n } @else if (state.primary() === \'ITEMS\') {\n @if (state.secondary() === \'WEAPONS\') {\n <pip-boy-inventory-layout category="WEAPONS" />\n } @else if (state.secondary() === \'APPAREL\') {\n <pip-boy-inventory-layout category="APPAREL" />\n } @else if (state.secondary() === \'AID\') {\n <pip-boy-inventory-layout category="AID" />\n } @else if (state.secondary() === \'MISC\') {\n <pip-boy-inventory-layout category="MISC" />\n } @else if (state.secondary() === \'AMMO\') {\n <pip-boy-inventory-layout category="AMMO" />\n }\n } @else if (state.primary() === \'DATA\') {\n @if (state.secondary() === \'LOCAL MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #localMapView\n [class.is-draggable]="settings.localMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'LOCAL\')"\n >\n @if (settings.localMapImage()) {\n <img\n #localMapImage\n [src]="imageStore.getImageUrl(settings.localMapImage())"\n alt="Local map"\n [style.zoom]="settings.localMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.localMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.localMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'LOCAL\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'LOCAL\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'LOCAL\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'WORLD MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #worldMapView\n [class.is-draggable]="settings.worldMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'WORLD\')"\n >\n @if (settings.worldMapImage()) {\n <img\n #worldMapImage\n [src]="imageStore.getImageUrl(settings.worldMapImage())"\n alt="World map"\n [style.zoom]="settings.worldMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.worldMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.worldMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'WORLD\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'WORLD\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'WORLD\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'QUESTS\') {\n <pip-boy-quests-layout />\n } @else if (state.secondary() === \'NOTES\') {\n <pip-boy-stats-layout category="GENERAL" valueLabel="Value" />\n } @else if (state.secondary() === \'RADIO\') {\n <pip-boy-music-layout\n category="RADIO"\n [waveformColorRgb]="\'255, 159, 28\'"\n />\n }\n }\n </section>\n \x3c!-- SUB TABS --\x3e\n <section class="sub-tabs">\n @if (state.primary() === \'STATS\') {\n <nav aria-label="Stats tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'STATUS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'STATUS\')"\n >\n Status\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'S.P.E.C.I.A.L.\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'S.P.E.C.I.A.L.\')"\n >\n S.P.E.C.I.A.L.\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'SKILLS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'SKILLS\')"\n >\n Skills\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'PERKS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'PERKS\')"\n >\n Perks\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'GENERAL\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'GENERAL\')"\n >\n General\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'ITEMS\') {\n <nav aria-label="Items tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WEAPONS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'WEAPONS\')"\n >\n Weapons\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'APPAREL\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'APPAREL\')"\n >\n Apparel\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AID\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'AID\')"\n >\n Aid\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'MISC\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'MISC\')"\n >\n Misc\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AMMO\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'AMMO\')"\n >\n Ammo\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'DATA\') {\n <nav aria-label="Data tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'LOCAL MAP\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'LOCAL MAP\')"\n >\n Local Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WORLD MAP\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'WORLD MAP\')"\n >\n World Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'QUESTS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'QUESTS\')"\n >\n Quests\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'NOTES\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'NOTES\')"\n >\n Misc\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'RADIO\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'RADIO\')"\n >\n Radio\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n }\n </section>\n \x3c!-- MAIN TABS --\x3e\n <section class="tabs" [class.is-collapsed]="!tabsOpen()">\n <button\n type="button"\n class="tabs-toggle"\n aria-label="Toggle main tabs"\n [attr.aria-expanded]="tabsOpen()"\n aria-controls="main-tabs"\n data-skip-click-sound="true"\n (click)="toggleTabs()"\n >\n <span class="tabs-toggle-label tabs-toggle-label--state">\n {{ tabsOpen() ? \'CLOSE\' : \'OPEN\' }}\n </span>\n <span class="caret" aria-hidden="true"></span>\n <span class="tabs-toggle-label tabs-toggle-label--menu">MENU</span>\n </button>\n <nav id="main-tabs" aria-label="Main tabs">\n <div\n class="tabs-actions tabs-actions--left"\n [class.is-open]="tabsActionsLeftOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open settings actions"\n (click)="toggleTabsActions(\'left\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Save settings"\n title="Save settings"\n (click)="saveSettingsToFile()"\n >\n Save\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Load settings"\n title="Load settings"\n (click)="loadSettingsInputRight.click()"\n >\n Load\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Reset settings"\n title="Reset settings"\n (click)="openResetModal()"\n >\n Reset\n </button>\n <input\n #loadSettingsInputRight\n type="file"\n accept=".zip,application/zip"\n (change)="loadSettingsFromFile($event)"\n />\n </div>\n </div>\n <button\n type="button"\n [class.is-active]="state.primary() === \'STATS\'"\n data-skip-click-sound="true"\n (click)="selectPrimary(\'STATS\')"\n >\n <span>STATS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'ITEMS\'"\n data-skip-click-sound="true"\n (click)="selectPrimary(\'ITEMS\')"\n >\n <span>ITEMS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'DATA\'"\n data-skip-click-sound="true"\n (click)="selectPrimary(\'DATA\')"\n >\n <span>DATA</span>\n </button>\n <div\n class="tabs-actions tabs-actions--right"\n [class.is-open]="tabsActionsRightOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open utility actions"\n (click)="toggleTabsActions(\'right\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Open GitHub profile"\n title="Open GitHub profile"\n (click)="openGithubProfile()"\n >\n ❤\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Open settings"\n title="Settings"\n (click)="openSettingsModal()"\n >\n Settings\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Report a bug"\n title="Report a bug"\n (click)="openBugModal()"\n >\n Bug\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Exit"\n title="Exit"\n (click)="openExitModal()"\n >\n Exit\n </button>\n </div>\n </div>\n @if (tabsOpen()) {\n <div class="tabs-version">v{{ appVersion }}</div>\n }\n </nav>\n </section>\n <pip-boy-welcome-modal\n [open]="showWelcomeModal() && !showBootSequence()"\n [listFontScale]="settings.listFontScale()"\n (previewListFontScale)="previewListFontScale($event)"\n (closeResult)="closeWelcomeModal()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showResetModal()"\n title="Reset Settings"\n message="This will reset all values back to defaults. This cannot be undone."\n confirmLabel="Reset"\n (closeResult)="closeResetModal()"\n (confirm)="confirmReset()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showExitModal()"\n title="Exit"\n message="Are you sure you want to leave this screen?"\n confirmLabel="Exit"\n (closeResult)="closeExitModal()"\n (confirm)="confirmExit()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showBugModal()"\n title="Report a bug"\n message="Would you like to report a bug?"\n confirmLabel="Yes"\n cancelLabel="No"\n (closeResult)="closeBugModal()"\n (confirm)="confirmBugReport()"\n />\n <pip-boy-map-image-modal\n [open]="mapImageModal() !== null"\n [title]="mapImageModalTitle()"\n [imageUrl]="mapImageModalImage()"\n (closeResult)="closeMapImageModal()"\n (save)="saveMapImageModal($event)"\n />\n <pip-boy-settings-modal\n [open]="showSettingsModal()"\n [scanLinesEnabled]="settings.scanLinesEnabled()"\n [rememberTabOnRefreshEnabled]="settings.rememberTabOnRefresh()"\n [editLockEnabled]="settings.editLockEnabled()"\n [listFontScale]="settings.listFontScale()"\n [secondaryTabSoundLabel]="secondaryTabSoundLabel()"\n [mainTabSoundLabel]="mainTabSoundLabel()"\n [clickSoundLabel]="clickSoundLabel()"\n [bootVideoLabel]="bootVideoLabel()"\n (closeResult)="cancelSettingsModal()"\n (previewListFontScale)="previewListFontScale($event)"\n (playSecondarySound)="previewSecondaryTabSound()"\n (playMainSound)="previewMainTabSound()"\n (playClickSound)="previewClickSound()"\n (playBootVideo)="previewBootVideo($event)"\n (save)="saveSettingsModal($event)"\n />\n <pip-boy-name-edit-modal\n [open]="extraOptionModal() !== null"\n [value]="extraOptionValue()"\n [title]="extraOptionTitle()"\n placeholder="Value"\n [allowEmpty]="true"\n (closeResult)="closeExtraOptionModal()"\n (save)="saveExtraOptionModal($event)"\n />\n</main>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.content{box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;height:100%;overflow:auto;padding:1rem 2rem;position:relative;width:100%}.content .status-content{box-sizing:border-box;display:flex;flex-direction:row;height:100%;gap:1rem}.content .column{box-sizing:border-box;display:flex;flex:1;flex-direction:column}.content .sub-content{max-width:max-content}.content .sub-content button{width:auto;max-width:10rem;height:2.5rem;background:transparent;color:#ff9f1c;display:flex;align-items:center;justify-content:center;text-align:center;text-transform:uppercase;border:none;border-left:2px solid transparent;border-right:2px solid transparent;cursor:pointer;padding:0 1rem;margin-bottom:1rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1) * 1.25)}.content .sub-content button.is-active{background:#ff9f1c14;border-left:2px solid #ff9f1c;border-right:2px solid #ff9f1c}.content .sub-content button:hover{background:#ff9f1c26}.content .radiation-status,.content .effects-status{box-sizing:border-box;display:flex;align-items:center;justify-content:center}.content .actions{box-sizing:border-box;display:flex;align-items:flex-end;max-width:max-content}:host{font-size:inherit}\n",":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.sub-tabs{flex:0 0 auto;min-height:0;margin-bottom:.5rem;padding:0 1rem;position:relative;z-index:1}.sub-tabs>nav{box-sizing:border-box;display:flex;align-items:center;width:100%;height:2.25rem;gap:0}.sub-tabs>nav .center-line{flex:1 1 auto;height:100%;min-width:1.5rem}.sub-tabs>nav>.center-line:last-child .top-half-line:before{left:auto;right:0}.sub-tabs>nav button{background:transparent;border:2px solid transparent;color:#ff9f1c;cursor:pointer;font-size:clamp(1.25rem,1.25rem + (1.5rem - 1.25rem) * (100vw - 360px) / (1200px - 360px),1.5rem);padding:.5rem}.sub-tabs>nav button.is-active{background:#ff9f1c14;border:2px solid #ff9f1c}.sub-tabs>nav button:hover{background:#ff9f1c26}@media(max-width:700px)and (orientation:landscape){.sub-tabs>nav .center-line{min-width:.5rem}}:host{font-size:inherit}\n",':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.tabs{align-items:center;box-sizing:border-box;display:flex;flex-direction:column;flex:0 0 auto;gap:.5rem;max-height:12rem;overflow:hidden;padding:0;position:relative;z-index:5;transition:max-height .35s ease-in-out,padding .35s ease-in-out,gap .35s ease-in-out;width:100%}.tabs.is-collapsed{gap:0;max-height:2rem}.tabs.is-collapsed>nav{opacity:0;pointer-events:none;transform:translateY(100%)}.tabs.is-collapsed .tabs-toggle .caret{transform:translateY(2px) rotate(-135deg)}.tabs .tabs-toggle{align-items:center;background:transparent;border:none;box-sizing:border-box;color:#ff9f1c;cursor:pointer;display:inline-flex;height:2rem;justify-content:center;line-height:0;max-height:2rem;min-height:2rem;overflow:hidden;padding:0 1rem;transition:border-color .2s ease;width:100%}.tabs .tabs-toggle:hover{background-color:#ff9f1c1f}.tabs .tabs-toggle .caret{border:solid #ff9f1c;border-width:0 2px 2px 0;box-sizing:border-box;display:inline-block;height:.6rem;margin:0 .5rem;padding:0;transform:translateY(-4px) rotate(45deg);transform-origin:center;transition:transform .35s ease;width:.6rem}.tabs .tabs-toggle .tabs-toggle-label{font-size:clamp(.7rem,.7rem + (.85rem - .7rem) * (100vw - 360px) / (1200px - 360px),.85rem);letter-spacing:.1em;line-height:1;text-transform:uppercase;white-space:nowrap}.tabs>nav{display:flex;justify-content:center;opacity:1;padding-bottom:.5rem;transform:translateY(0);transition:transform .35s ease-in-out,opacity .35s ease-in-out;transform-origin:bottom;will-change:transform,opacity;width:100%;position:relative}.tabs .tabs-version{bottom:14px;color:#ff9f1cbf;font-size:10px;letter-spacing:.08em;position:absolute;right:22px}.tabs .tabs-actions{align-items:center;display:flex;gap:.5rem;left:1rem;position:absolute;top:50%;transform:translateY(-50%)}.tabs .tabs-actions.right,.tabs .tabs-actions.tabs-actions--right{left:auto;right:1rem}.tabs .tabs-actions .tabs-actions-toggle{align-items:center;background:transparent;border:1px solid rgba(255,159,28,.6);border-radius:9999px;color:#ff9f1c;cursor:pointer;display:none;height:2.1rem;justify-content:center;padding:0 .6rem;text-transform:uppercase;width:2.4rem}.tabs .tabs-actions .tabs-actions-toggle:hover{background:#ff9f1c1f;border-color:#ff9f1c}.tabs .tabs-actions .tabs-actions-icon{background:#ff9f1c;border-radius:9999px;display:block;height:2px;position:relative;width:1.1rem}.tabs .tabs-actions .tabs-actions-icon:before,.tabs .tabs-actions .tabs-actions-icon:after{content:"";background:#ff9f1c;border-radius:9999px;height:2px;left:0;position:absolute;width:100%}.tabs .tabs-actions .tabs-actions-icon:before{top:-5px}.tabs .tabs-actions .tabs-actions-icon:after{top:5px}.tabs .tabs-actions .tabs-actions-menu{display:flex;gap:.5rem;align-items:center}.tabs .tabs-actions .action-button{background:transparent;border:1px solid rgba(255,159,28,.7);color:#ff9f1cb3;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.25rem .35rem;text-align:left;width:100%;border-radius:1rem;text-align:center}.tabs .tabs-actions .action-button:hover{background:#ff9f1c1f;border-color:#ff9f1c}.tabs .tabs-actions input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.tabs .tabs-action{align-items:center;background:#ff9f1c1a;border:2px solid rgba(255,159,28,.6);border-radius:.4rem;color:#ff9f1c;cursor:pointer;display:inline-flex;font-size:clamp(.65rem,.65rem + (.75rem - .65rem) * (100vw - 360px) / (1200px - 360px),.75rem);height:2.5rem;justify-content:center;letter-spacing:.08em;padding:0 .85rem;text-transform:uppercase;transition:background .2s ease,border-color .2s ease;width:auto}.tabs .tabs-action:hover{background:#ff9f1c2e;border-color:#ff9f1c}.tabs>nav>button{align-items:center;background:transparent;border-radius:9999px;border:2px solid rgba(255,159,28,.35);box-sizing:border-box;color:#ff9f1c;cursor:pointer;display:inline-flex;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);height:5rem;justify-content:center;line-height:1;margin:0 1rem;padding:0;text-transform:uppercase;width:5rem}.tabs>nav>button>span{align-items:center;display:inline-flex;justify-content:center;line-height:1;white-space:nowrap;width:100%;height:100%;border-radius:9999px;padding:0}.tabs>nav>button:hover{border-color:#ff9f1ca6}.tabs>nav>button:hover>span{background:#ff9f1c1f}.tabs>nav>button.is-active{border-color:#ff9f1c}.tabs>nav>button.is-active>span{background:#ff9f1c29}@media(max-width:750px){.tabs .tabs-actions{z-index:5}.tabs .tabs-actions .tabs-actions-toggle{display:inline-flex}.tabs .tabs-actions .tabs-actions-menu{display:none}.tabs .tabs-actions.is-open .tabs-actions-menu{background:#1f1002f2;border:1px solid rgba(255,159,28,.35);border-radius:.5rem;display:flex;flex-direction:column;gap:.35rem;padding:.5rem;position:absolute;bottom:2.6rem;z-index:1000}.tabs .tabs-actions.tabs-actions--left.is-open .tabs-actions-menu{left:0}.tabs .tabs-actions.tabs-actions--right.is-open .tabs-actions-menu{right:0}.tabs .tabs-actions .action-button{width:100%}}@media(max-width:750px){.tabs{overflow:visible}}:host{font-size:inherit}\n',':host{--pip-boy-color: #ff9f1c;--pip-boy-color-rgb: 255, 159, 28;--pip-boy-bg-dark: #1f1002;--pip-boy-bg-darker: #3d2104}:host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host.pip-boy-3000a-theme ::ng-deep{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep button{color:#ff9f1c;border-color:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep button:hover{background:#ff9f1c1f;border-color:#ff9f1ca6}:host.pip-boy-3000a-theme ::ng-deep button.is-active{border-color:#ff9f1c;background:#ff9f1c29;border-left-color:#ff9f1c;border-right-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep input,:host.pip-boy-3000a-theme ::ng-deep select,:host.pip-boy-3000a-theme ::ng-deep textarea{color:#ff9f1c;border-color:#ff9f1c99;background:#1f10024d}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout,:host.pip-boy-3000a-theme ::ng-deep .stats-layout,:host.pip-boy-3000a-theme ::ng-deep .quests-layout,:host.pip-boy-3000a-theme ::ng-deep .music-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header *,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout *,:host.pip-boy-3000a-theme ::ng-deep .stats-layout *,:host.pip-boy-3000a-theme ::ng-deep .quests-layout *,:host.pip-boy-3000a-theme ::ng-deep .music-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal *{color:#ff9f1c;border-color:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header button,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout button,:host.pip-boy-3000a-theme ::ng-deep .stats-layout button,:host.pip-boy-3000a-theme ::ng-deep .quests-layout button,:host.pip-boy-3000a-theme ::ng-deep .music-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal button{color:#ff9f1c;border-color:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header button:hover,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep .stats-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep .quests-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep .music-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal button:hover{background:#ff9f1c1f;border-color:#ff9f1ca6}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header button.is-active,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep .stats-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep .quests-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep .music-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal button.is-active{border-color:#ff9f1c;background:#ff9f1c29}:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header header>.header-content>.stat-button:hover{background:#ff9f1c1f!important}:host.pip-boy-3000a-theme ::ng-deep [role=dialog],:host.pip-boy-3000a-theme ::ng-deep .dialog,:host.pip-boy-3000a-theme ::ng-deep .modal,:host.pip-boy-3000a-theme ::ng-deep .pip-boy-dialog{background:#1f1002fa;border-color:#ff9f1c99;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep [role=dialog] *,:host.pip-boy-3000a-theme ::ng-deep .dialog *,:host.pip-boy-3000a-theme ::ng-deep .modal *,:host.pip-boy-3000a-theme ::ng-deep .pip-boy-dialog *{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .center-line:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .bottom-half-line:before{background:linear-gradient(to bottom,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}:host.pip-boy-3000a-theme ::ng-deep .top-half-line:before{background:linear-gradient(to top,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}:host.pip-boy-3000a-theme ::ng-deep .main-title-left-line .bottom-half-line:before{left:0}:host.pip-boy-3000a-theme ::ng-deep .main-title-right-line .bottom-half-line:before{right:0}:host.pip-boy-3000a-theme ::ng-deep .hp-title-line .bottom-half-line:before,:host.pip-boy-3000a-theme ::ng-deep .ap-title-line .bottom-half-line:before,:host.pip-boy-3000a-theme ::ng-deep .xp-title-line .bottom-half-line:before{right:0}:host.pip-boy-3000a-theme ::ng-deep ::-webkit-scrollbar-thumb{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep ::-webkit-scrollbar-track{background:#1f100299}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-tick{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-tick:first-child,:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-tick--end-triangle{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-arrow{border-left-color:transparent;border-right-color:transparent;border-bottom-color:#ff9f1cb3}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-handle{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-value{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-fill{background:#ff9f1c73;box-shadow:0 0 20px #ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-track,:host.pip-boy-3000a-theme ::ng-deep .status-label,:host.pip-boy-3000a-theme ::ng-deep .status-right,:host.pip-boy-3000a-theme ::ng-deep .status-resist-text{border-top-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .status-resist:hover,:host.pip-boy-3000a-theme ::ng-deep .status-resist:focus-visible{background:transparent;border-color:transparent}:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-add,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-edit,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-delete,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-move{background:#ff9f1c0d;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-add:hover,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-delete:hover,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .eff-row.is-selected{background:#ff9f1c2e!important}:host.pip-boy-3000a-theme ::ng-deep .quest-toggle{border-color:#ff9f1ca6}:host.pip-boy-3000a-theme ::ng-deep .quest-toggle.is-checked{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .quest-add{background:#ff9f1c14;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .quest-edit,:host.pip-boy-3000a-theme ::ng-deep .quest-delete,:host.pip-boy-3000a-theme ::ng-deep .quest-move{background:#ff9f1c0d;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .quest-add:hover{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .quest-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .quest-delete:hover,:host.pip-boy-3000a-theme ::ng-deep .quest-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .music-add{background:#ff9f1c14;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-edit,:host.pip-boy-3000a-theme ::ng-deep .music-delete,:host.pip-boy-3000a-theme ::ng-deep .music-move{background:#ff9f1c0d;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-add:hover{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .music-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .music-delete:hover,:host.pip-boy-3000a-theme ::ng-deep .music-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .music-waveform canvas{border-right-color:#ff9f1c40;border-bottom-color:#ff9f1c40}:host.pip-boy-3000a-theme ::ng-deep .music-list-item.is-selected{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .music-list-item.is-selected:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-control{background:#ff9f1c0d;border-color:#ff9f1c99;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-control:hover,:host.pip-boy-3000a-theme ::ng-deep .music-control.is-active{background:#ff9f1c1f;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-control--autoplay.is-active,:host.pip-boy-3000a-theme ::ng-deep .music-control--shuffle.is-active{background:#ff9f1c33;border-color:#ff9f1c;box-shadow:0 0 .6rem #ff9f1c47}:host.pip-boy-3000a-theme ::ng-deep .music-volume{border-color:#ff9f1c59;background:#ff9f1c0a}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing-label{color:#ff9f1cb3}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing-value{border-color:#ff9f1c66;color:#ff9f1cd9}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing.is-disabled .music-now-playing-label,:host.pip-boy-3000a-theme ::ng-deep .music-now-playing.is-disabled .music-now-playing-value{color:#ff9f1c73}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing.is-disabled .music-now-playing-value{background:#ff9f1c08;border-color:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep .music-volume-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep .music-volume-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-volume-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-volume-label,:host.pip-boy-3000a-theme ::ng-deep .music-volume-value{color:#ff9f1ccc}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-value{color:#ff9f1ccc}:host.pip-boy-3000a-theme ::ng-deep .settings-toggle.is-on{background:#ff9f1c33;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .map-control-button:hover{background:#1f1002e6;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .welcome__range{background:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .welcome__range::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .welcome__range::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-list-item.is-selected{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .resource-list-item.is-selected:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-add,:host.pip-boy-3000a-theme ::ng-deep .resource-edit,:host.pip-boy-3000a-theme ::ng-deep .resource-drop,:host.pip-boy-3000a-theme ::ng-deep .resource-move{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-add{background:#ff9f1c14}:host.pip-boy-3000a-theme ::ng-deep .resource-add:hover{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .resource-edit,:host.pip-boy-3000a-theme ::ng-deep .resource-drop,:host.pip-boy-3000a-theme ::ng-deep .resource-move{background:#ff9f1c0d}:host.pip-boy-3000a-theme ::ng-deep .resource-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .resource-drop:hover,:host.pip-boy-3000a-theme ::ng-deep .resource-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .resource-description:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-description:after{background:linear-gradient(to bottom,#ff9f1c,#ff9f1ca6 35%,#ff9f1c59 65%,#ff9f1c00)}:host.pip-boy-3000a-theme ::ng-deep .resource-stat{border:none}:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field textarea{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal .settings-slider-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal .settings-slider-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal .settings-slider-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__data{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__data code{background:#ff9f1c14;border-color:#ff9f1c38;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__data a{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__section{background:#ff9f1c0a;border-color:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal .reset-modal-body{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal .reset-modal-body p{color:#ff9f1cd9}:host.pip-boy-3000a-theme ::ng-deep pip-boy-audio-edit-modal .audio-modal-field input{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-audio-edit-modal .audio-modal-field input:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .stat-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .number-input-row input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .number-input-row input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field textarea,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal .number-input-row input{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .stat-modal-field input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .number-input-row input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .number-input-row input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field textarea:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal .number-input-row input:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep input:focus,:host.pip-boy-3000a-theme ::ng-deep select:focus,:host.pip-boy-3000a-theme ::ng-deep textarea:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field textarea{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field textarea:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep #text-field-effects{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep #text-field-effects:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control{background:#ff9f1c0d;border-color:#ff9f1c99;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control.is-active{background:#ff9f1c1f;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control--autoplay.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control--shuffle.is-active{background:#ff9f1c33;border-color:#ff9f1c;box-shadow:0 0 .6rem #ff9f1c47}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control:disabled{background:#ff9f1c05;border-color:#ff9f1c33;color:#ff9f1c59;opacity:.8}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing-label{color:#ff9f1cb3}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing-value{border-color:#ff9f1c66;color:#ff9f1cd9}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing.is-disabled .music-now-playing-label,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing.is-disabled .music-now-playing-value{color:#ff9f1c73}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing.is-disabled .music-now-playing-value{background:#ff9f1c08;border-color:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-volume-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-volume-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-volume-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host{font-family:Roboto Condensed,sans-serif;font-size:clamp(.95rem,.95rem + (1.15rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.15rem);scrollbar-color:rgba(255,159,28,.6) rgba(31,16,2,.6);scrollbar-width:thin;background-color:#1f1002;background-image:repeating-linear-gradient(to bottom,#ffffff0a 0 1px,#0000 4px);background-size:100% 6px;animation:scan-lines 6s linear infinite;box-shadow:inset 0 0 24px #0009,inset 0 0 90px #00000073;box-sizing:border-box;color:#ff9f1c;display:block;height:100%;overflow:hidden;position:relative;width:100%;font-size:inherit}:host ::-webkit-scrollbar{width:6px;height:6px}:host ::-webkit-scrollbar-track{background:#1f100299}:host ::-webkit-scrollbar-thumb{background:#ff9f1c99;border-radius:9999px}:host:before{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,#1f100200 55%,#00000040 70%,#0009);mix-blend-mode:multiply}@keyframes scan-lines{0%{background-position:0 0}to{background-position:0 60px}}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:0;position:relative;width:100%;display:flex;flex-direction:column;min-height:0}.screen-size-overlay{position:absolute;inset:0;background:#000000d9;color:#ff9f1c;display:flex;align-items:center;justify-content:center;text-align:center;padding:2rem;text-transform:uppercase;font-size:clamp(1.1rem,1.1rem + (1.35rem - 1.1rem) * (100vw - 360px) / (1200px - 360px),1.35rem);z-index:200}.boot-sequence{position:fixed;inset:0;background:#000;display:flex;align-items:center;justify-content:center;pointer-events:auto;z-index:99999}.boot-sequence video{width:100%;height:100%;object-fit:cover}.boot-sequence.is-playing{pointer-events:auto}.boot-sequence__loading{font-size:clamp(.95rem,.95rem + (1.2rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.2rem);letter-spacing:.08em;text-transform:uppercase;color:#ff9f1c}.boot-sequence__prompt{position:absolute;bottom:2rem;left:50%;transform:translate(-50%);font-size:clamp(.95rem,.95rem + (1.2rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.2rem);letter-spacing:.1em;text-transform:uppercase;color:#ff9f1c;background:#0009;border:1px solid rgba(255,159,28,.5);border-radius:.5rem;padding:.4rem .75rem;cursor:pointer}.boot-sequence__prompt:hover{background:#ff9f1c1f;border-color:#ff9f1c}.boot-sequence__close{position:absolute;top:1rem;right:1rem;z-index:1;background:#0009;border:1px solid rgba(255,159,28,.5);border-radius:.5rem;color:#ff9f1c;cursor:pointer;padding:.6rem .95rem;font-size:1.35rem;line-height:1;text-transform:uppercase}.boot-sequence__close:hover{background:#ff9f1c1f;border-color:#ff9f1c}.screen.is-booting ::ng-deep .dialog-backdrop{display:none}.screen.is-booting ::ng-deep .dialog{display:none}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:2px;background:#ff9f1c}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:50%;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}.top-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.top-half-line:before{content:"";position:absolute;bottom:50%;top:-1.25rem;width:2px;z-index:2;left:0;background:linear-gradient(to top,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}.extra-options{margin-top:0;display:flex;flex-direction:column;font-family:Roboto Mono,monospace;font-size:calc(clamp(1.05rem,1.05rem + .2rem * (100vw - 360px) / 840px,1.25rem) * var(--list-font-scale, 1));align-items:flex-end;gap:.75rem;white-space:nowrap;position:absolute;top:1rem;right:2rem;z-index:3}.extra-options button{background:transparent;border:none;color:#ff9f1c;cursor:pointer;font:inherit;padding:0;white-space:nowrap}.extra-options button:hover{opacity:.8}.extra-options button:disabled,.extra-options button.is-locked{cursor:default}.extra-options .controller-button{font-size:inherit;white-space:nowrap}.extra-options .controller-button .large-par{display:inline;padding-left:.5rem;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));top:-.15rem;position:relative;white-space:nowrap}.map-panel{display:flex;flex:1 1 auto;min-height:0;position:relative;width:100%}.map-view{align-items:flex-start;background:transparent;border:none;color:#ff9f1c;cursor:pointer;display:flex;flex:1 1 auto;justify-content:flex-start;min-height:0;overflow:auto;padding:0;width:100%}.map-view span{letter-spacing:.1em;margin:auto;text-transform:uppercase;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.map-view img{display:block;max-width:none;max-height:none}.map-view.is-locked,.map-view:disabled{cursor:default}.map-view.is-draggable{cursor:grab}.map-view.is-dragging{cursor:grabbing}.map-zoom{display:flex;gap:.5rem;position:absolute;right:1.5rem;top:.5rem;z-index:2}.map-zoom .map-zoom-button{padding:0;width:calc(2rem * var(--list-font-scale, 1))}.map-fit{position:absolute;right:1.5rem;bottom:.5rem;z-index:2}.map-control-button{align-items:center;background:#1f1002f2;border:1px solid rgba(255,159,28,.65);border-radius:.5rem;color:#ff9f1c;cursor:pointer;display:inline-flex;font-size:calc(clamp(.75rem,.75rem + .15rem * (100vw - 360px) / 840px,.9rem) * var(--list-font-scale, 1));justify-content:center;text-transform:uppercase;height:calc(2rem * var(--list-font-scale, 1));padding:0 calc(.6rem * var(--list-font-scale, 1))}.map-control-button:hover{border-color:#ff9f1c;background:#1f1002e6}\n'],dependencies:[{kind:"component",type:w,selector:"pip-boy-screen-scan-lines",inputs:["replayTimeoutSeconds","screen","scanSpeedSeconds","tailLengthPx","scanColorRgb"]},{kind:"component",type:H,selector:"pip-boy-3000-header"},{kind:"component",type:$,selector:"pip-boy-inventory-layout",inputs:["category"]},{kind:"component",type:G,selector:"pip-boy-stats-layout",inputs:["category","valueLabel","valueMin","valueMax"]},{kind:"component",type:Y,selector:"pip-boy-reset-confirm-modal",inputs:["open","title","message","confirmLabel","cancelLabel"],outputs:["confirm","closeResult"]},{kind:"component",type:Q,selector:"pip-boy-name-edit-modal",inputs:["open","title","value","placeholder","allowEmpty","inputType","inputMin","inputStep","showNumberControls"],outputs:["closeResult","save"]},{kind:"component",type:K,selector:"pip-boy-cnd-status"},{kind:"component",type:X,selector:"pip-boy-radiation-meter"},{kind:"component",type:J,selector:"pip-boy-status-meter",inputs:["kind"]},{kind:"component",type:te,selector:"pip-boy-eff-layout"},{kind:"component",type:de,selector:"pip-boy-map-image-modal",inputs:["open","title","imageUrl"],outputs:["closeResult","save"]},{kind:"component",type:ne,selector:"pip-boy-quests-layout"},{kind:"component",type:le,selector:"pip-boy-settings-modal",inputs:["open","scanLinesEnabled","rememberTabOnRefreshEnabled","editLockEnabled","listFontScale","secondaryTabSoundLabel","mainTabSoundLabel","clickSoundLabel","bootVideoLabel"],outputs:["closeResult","save","previewListFontScale","playSecondarySound","playMainSound","playClickSound","playBootVideo"]},{kind:"component",type:se,selector:"pip-boy-music-layout",inputs:["category","waveformColorRgb"]},{kind:"component",type:re,selector:"pip-boy-welcome-modal",inputs:["open","listFontScale"],outputs:["closeResult","previewListFontScale"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:Le,decorators:[{type:a,args:[{selector:"pip-boy-3000a",standalone:!0,host:{class:"pip-boy-3000a-theme"},imports:[w,H,$,G,Y,Q,K,X,J,te,de,ne,le,se,re],providers:[W,C,{provide:P,useValue:{storageKey:"pipBoy3000aSettings",skillDefaults:xe,perkDefaults:ke,weaponDefaults:pe,apparelDefaults:me,aidDefaults:ue,miscDefaults:be,ammoDefaults:ge,statSourceItems:{special:Se,skills:Me,perks:Ie},inventorySourceItems:{weapons:he,apparel:fe,aid:ve,misc:ye,ammo:we}}}],template:'<main\n #screen\n class="screen"\n [style.--list-font-scale]="settings.listFontScale()"\n [class.is-booting]="showBootSequence()"\n>\n @if (settings.scanLinesEnabled()) {\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="300"\n [scanColorRgb]="\'255, 159, 28\'"\n />\n }\n @if (isScreenTooSmall()) {\n <div class="screen-size-overlay" role="alert" aria-live="assertive">\n Screen is too small.<br />Please rotate to landscape.\n </div>\n }\n @if (showBootSequence()) {\n <div\n class="boot-sequence"\n [class.is-playing]="bootIsPlaying()"\n tabindex="0"\n data-skip-click-sound="true"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n <button\n type="button"\n class="boot-sequence__close"\n aria-label="Close boot sequence"\n data-skip-click-sound="true"\n (click)="finishBootSequence()"\n >\n X\n </button>\n @if (bootVideoPlaybackUrl()) {\n <video\n #bootVideo\n [src]="bootVideoPlaybackUrl()"\n muted\n playsinline\n preload="auto"\n (canplay)="handleBootCanPlay(bootVideo)"\n (click)="playBootVideo(bootVideo, $event)"\n (ended)="finishBootSequence()"\n ></video>\n @if (bootNeedsClick()) {\n <button\n type="button"\n class="boot-sequence__prompt"\n data-skip-click-sound="true"\n (click)="playBootVideo(bootVideo, $event)"\n >\n Click to play\n </button>\n }\n } @else {\n <div class="boot-sequence__loading">Loading boot sequence...</div>\n }\n </div>\n }\n \x3c!-- HEADER --\x3e\n <pip-boy-3000-header />\n \x3c!-- CONTENT --\x3e\n <section class="content">\n @if (state.primary() === \'STATS\') {\n @if (state.secondary() === \'STATUS\') {\n <div class="status-content">\n <nav class="column sub-content" aria-label="Status tabs">\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'CND\'"\n (click)="state.selectTertiary(\'CND\')"\n >\n CND\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'RAD\'"\n (click)="state.selectTertiary(\'RAD\')"\n >\n RAD\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'EFF\'"\n (click)="state.selectTertiary(\'EFF\')"\n >\n EFF\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'H20\'"\n (click)="state.selectTertiary(\'H20\')"\n >\n H20\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'FOD\'"\n (click)="state.selectTertiary(\'FOD\')"\n >\n FOD\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'SLP\'"\n (click)="state.selectTertiary(\'SLP\')"\n >\n SLP\n </button>\n </nav>\n @if (state.tertiary() === \'CND\') {\n <pip-boy-cnd-status />\n } @else if (state.tertiary() === \'RAD\') {\n <pip-boy-radiation-meter />\n <div class="extra-options">\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADAWAY\')"\n >\n {{ settings.radAwayLabel() }}\n </button>\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADX\')"\n >\n {{ settings.radXLabel() }}\n </button>\n </div>\n } @else if (state.tertiary() === \'EFF\') {\n <pip-boy-eff-layout />\n } @else if (state.tertiary() === \'H20\') {\n <pip-boy-status-meter kind="H20" />\n } @else if (state.tertiary() === \'FOD\') {\n <pip-boy-status-meter kind="FOD" />\n } @else if (state.tertiary() === \'SLP\') {\n <pip-boy-status-meter kind="SLP" />\n }\n </div>\n } @else if (state.secondary() === \'S.P.E.C.I.A.L.\') {\n <pip-boy-stats-layout\n category="SPECIAL"\n valueLabel="Rating"\n [valueMin]="1"\n [valueMax]="10"\n />\n } @else if (state.secondary() === \'SKILLS\') {\n <pip-boy-stats-layout\n category="SKILLS"\n valueLabel="Skill"\n [valueMin]="0"\n [valueMax]="100"\n />\n } @else if (state.secondary() === \'PERKS\') {\n <pip-boy-stats-layout\n category="PERKS"\n valueLabel="Rank"\n [valueMin]="0"\n />\n } @else if (state.secondary() === \'GENERAL\') {\n <pip-boy-stats-layout category="GENERAL" valueLabel="Value" />\n }\n } @else if (state.primary() === \'ITEMS\') {\n @if (state.secondary() === \'WEAPONS\') {\n <pip-boy-inventory-layout category="WEAPONS" />\n } @else if (state.secondary() === \'APPAREL\') {\n <pip-boy-inventory-layout category="APPAREL" />\n } @else if (state.secondary() === \'AID\') {\n <pip-boy-inventory-layout category="AID" />\n } @else if (state.secondary() === \'MISC\') {\n <pip-boy-inventory-layout category="MISC" />\n } @else if (state.secondary() === \'AMMO\') {\n <pip-boy-inventory-layout category="AMMO" />\n }\n } @else if (state.primary() === \'DATA\') {\n @if (state.secondary() === \'LOCAL MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #localMapView\n [class.is-draggable]="settings.localMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'LOCAL\')"\n >\n @if (settings.localMapImage()) {\n <img\n #localMapImage\n [src]="imageStore.getImageUrl(settings.localMapImage())"\n alt="Local map"\n [style.zoom]="settings.localMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.localMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.localMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'LOCAL\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'LOCAL\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'LOCAL\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'WORLD MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #worldMapView\n [class.is-draggable]="settings.worldMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'WORLD\')"\n >\n @if (settings.worldMapImage()) {\n <img\n #worldMapImage\n [src]="imageStore.getImageUrl(settings.worldMapImage())"\n alt="World map"\n [style.zoom]="settings.worldMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.worldMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.worldMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'WORLD\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'WORLD\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'WORLD\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'QUESTS\') {\n <pip-boy-quests-layout />\n } @else if (state.secondary() === \'NOTES\') {\n <pip-boy-stats-layout category="GENERAL" valueLabel="Value" />\n } @else if (state.secondary() === \'RADIO\') {\n <pip-boy-music-layout\n category="RADIO"\n [waveformColorRgb]="\'255, 159, 28\'"\n />\n }\n }\n </section>\n \x3c!-- SUB TABS --\x3e\n <section class="sub-tabs">\n @if (state.primary() === \'STATS\') {\n <nav aria-label="Stats tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'STATUS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'STATUS\')"\n >\n Status\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'S.P.E.C.I.A.L.\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'S.P.E.C.I.A.L.\')"\n >\n S.P.E.C.I.A.L.\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'SKILLS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'SKILLS\')"\n >\n Skills\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'PERKS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'PERKS\')"\n >\n Perks\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'GENERAL\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'GENERAL\')"\n >\n General\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'ITEMS\') {\n <nav aria-label="Items tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WEAPONS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'WEAPONS\')"\n >\n Weapons\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'APPAREL\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'APPAREL\')"\n >\n Apparel\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AID\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'AID\')"\n >\n Aid\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'MISC\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'MISC\')"\n >\n Misc\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AMMO\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'AMMO\')"\n >\n Ammo\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'DATA\') {\n <nav aria-label="Data tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'LOCAL MAP\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'LOCAL MAP\')"\n >\n Local Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WORLD MAP\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'WORLD MAP\')"\n >\n World Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'QUESTS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'QUESTS\')"\n >\n Quests\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'NOTES\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'NOTES\')"\n >\n Misc\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'RADIO\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'RADIO\')"\n >\n Radio\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n }\n </section>\n \x3c!-- MAIN TABS --\x3e\n <section class="tabs" [class.is-collapsed]="!tabsOpen()">\n <button\n type="button"\n class="tabs-toggle"\n aria-label="Toggle main tabs"\n [attr.aria-expanded]="tabsOpen()"\n aria-controls="main-tabs"\n data-skip-click-sound="true"\n (click)="toggleTabs()"\n >\n <span class="tabs-toggle-label tabs-toggle-label--state">\n {{ tabsOpen() ? \'CLOSE\' : \'OPEN\' }}\n </span>\n <span class="caret" aria-hidden="true"></span>\n <span class="tabs-toggle-label tabs-toggle-label--menu">MENU</span>\n </button>\n <nav id="main-tabs" aria-label="Main tabs">\n <div\n class="tabs-actions tabs-actions--left"\n [class.is-open]="tabsActionsLeftOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open settings actions"\n (click)="toggleTabsActions(\'left\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Save settings"\n title="Save settings"\n (click)="saveSettingsToFile()"\n >\n Save\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Load settings"\n title="Load settings"\n (click)="loadSettingsInputRight.click()"\n >\n Load\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Reset settings"\n title="Reset settings"\n (click)="openResetModal()"\n >\n Reset\n </button>\n <input\n #loadSettingsInputRight\n type="file"\n accept=".zip,application/zip"\n (change)="loadSettingsFromFile($event)"\n />\n </div>\n </div>\n <button\n type="button"\n [class.is-active]="state.primary() === \'STATS\'"\n data-skip-click-sound="true"\n (click)="selectPrimary(\'STATS\')"\n >\n <span>STATS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'ITEMS\'"\n data-skip-click-sound="true"\n (click)="selectPrimary(\'ITEMS\')"\n >\n <span>ITEMS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'DATA\'"\n data-skip-click-sound="true"\n (click)="selectPrimary(\'DATA\')"\n >\n <span>DATA</span>\n </button>\n <div\n class="tabs-actions tabs-actions--right"\n [class.is-open]="tabsActionsRightOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open utility actions"\n (click)="toggleTabsActions(\'right\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Open GitHub profile"\n title="Open GitHub profile"\n (click)="openGithubProfile()"\n >\n ❤\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Open settings"\n title="Settings"\n (click)="openSettingsModal()"\n >\n Settings\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Report a bug"\n title="Report a bug"\n (click)="openBugModal()"\n >\n Bug\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Exit"\n title="Exit"\n (click)="openExitModal()"\n >\n Exit\n </button>\n </div>\n </div>\n @if (tabsOpen()) {\n <div class="tabs-version">v{{ appVersion }}</div>\n }\n </nav>\n </section>\n <pip-boy-welcome-modal\n [open]="showWelcomeModal() && !showBootSequence()"\n [listFontScale]="settings.listFontScale()"\n (previewListFontScale)="previewListFontScale($event)"\n (closeResult)="closeWelcomeModal()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showResetModal()"\n title="Reset Settings"\n message="This will reset all values back to defaults. This cannot be undone."\n confirmLabel="Reset"\n (closeResult)="closeResetModal()"\n (confirm)="confirmReset()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showExitModal()"\n title="Exit"\n message="Are you sure you want to leave this screen?"\n confirmLabel="Exit"\n (closeResult)="closeExitModal()"\n (confirm)="confirmExit()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showBugModal()"\n title="Report a bug"\n message="Would you like to report a bug?"\n confirmLabel="Yes"\n cancelLabel="No"\n (closeResult)="closeBugModal()"\n (confirm)="confirmBugReport()"\n />\n <pip-boy-map-image-modal\n [open]="mapImageModal() !== null"\n [title]="mapImageModalTitle()"\n [imageUrl]="mapImageModalImage()"\n (closeResult)="closeMapImageModal()"\n (save)="saveMapImageModal($event)"\n />\n <pip-boy-settings-modal\n [open]="showSettingsModal()"\n [scanLinesEnabled]="settings.scanLinesEnabled()"\n [rememberTabOnRefreshEnabled]="settings.rememberTabOnRefresh()"\n [editLockEnabled]="settings.editLockEnabled()"\n [listFontScale]="settings.listFontScale()"\n [secondaryTabSoundLabel]="secondaryTabSoundLabel()"\n [mainTabSoundLabel]="mainTabSoundLabel()"\n [clickSoundLabel]="clickSoundLabel()"\n [bootVideoLabel]="bootVideoLabel()"\n (closeResult)="cancelSettingsModal()"\n (previewListFontScale)="previewListFontScale($event)"\n (playSecondarySound)="previewSecondaryTabSound()"\n (playMainSound)="previewMainTabSound()"\n (playClickSound)="previewClickSound()"\n (playBootVideo)="previewBootVideo($event)"\n (save)="saveSettingsModal($event)"\n />\n <pip-boy-name-edit-modal\n [open]="extraOptionModal() !== null"\n [value]="extraOptionValue()"\n [title]="extraOptionTitle()"\n placeholder="Value"\n [allowEmpty]="true"\n (closeResult)="closeExtraOptionModal()"\n (save)="saveExtraOptionModal($event)"\n />\n</main>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.content{box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;height:100%;overflow:auto;padding:1rem 2rem;position:relative;width:100%}.content .status-content{box-sizing:border-box;display:flex;flex-direction:row;height:100%;gap:1rem}.content .column{box-sizing:border-box;display:flex;flex:1;flex-direction:column}.content .sub-content{max-width:max-content}.content .sub-content button{width:auto;max-width:10rem;height:2.5rem;background:transparent;color:#ff9f1c;display:flex;align-items:center;justify-content:center;text-align:center;text-transform:uppercase;border:none;border-left:2px solid transparent;border-right:2px solid transparent;cursor:pointer;padding:0 1rem;margin-bottom:1rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1) * 1.25)}.content .sub-content button.is-active{background:#ff9f1c14;border-left:2px solid #ff9f1c;border-right:2px solid #ff9f1c}.content .sub-content button:hover{background:#ff9f1c26}.content .radiation-status,.content .effects-status{box-sizing:border-box;display:flex;align-items:center;justify-content:center}.content .actions{box-sizing:border-box;display:flex;align-items:flex-end;max-width:max-content}:host{font-size:inherit}\n",":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.sub-tabs{flex:0 0 auto;min-height:0;margin-bottom:.5rem;padding:0 1rem;position:relative;z-index:1}.sub-tabs>nav{box-sizing:border-box;display:flex;align-items:center;width:100%;height:2.25rem;gap:0}.sub-tabs>nav .center-line{flex:1 1 auto;height:100%;min-width:1.5rem}.sub-tabs>nav>.center-line:last-child .top-half-line:before{left:auto;right:0}.sub-tabs>nav button{background:transparent;border:2px solid transparent;color:#ff9f1c;cursor:pointer;font-size:clamp(1.25rem,1.25rem + (1.5rem - 1.25rem) * (100vw - 360px) / (1200px - 360px),1.5rem);padding:.5rem}.sub-tabs>nav button.is-active{background:#ff9f1c14;border:2px solid #ff9f1c}.sub-tabs>nav button:hover{background:#ff9f1c26}@media(max-width:700px)and (orientation:landscape){.sub-tabs>nav .center-line{min-width:.5rem}}:host{font-size:inherit}\n",':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.tabs{align-items:center;box-sizing:border-box;display:flex;flex-direction:column;flex:0 0 auto;gap:.5rem;max-height:12rem;overflow:hidden;padding:0;position:relative;z-index:5;transition:max-height .35s ease-in-out,padding .35s ease-in-out,gap .35s ease-in-out;width:100%}.tabs.is-collapsed{gap:0;max-height:2rem}.tabs.is-collapsed>nav{opacity:0;pointer-events:none;transform:translateY(100%)}.tabs.is-collapsed .tabs-toggle .caret{transform:translateY(2px) rotate(-135deg)}.tabs .tabs-toggle{align-items:center;background:transparent;border:none;box-sizing:border-box;color:#ff9f1c;cursor:pointer;display:inline-flex;height:2rem;justify-content:center;line-height:0;max-height:2rem;min-height:2rem;overflow:hidden;padding:0 1rem;transition:border-color .2s ease;width:100%}.tabs .tabs-toggle:hover{background-color:#ff9f1c1f}.tabs .tabs-toggle .caret{border:solid #ff9f1c;border-width:0 2px 2px 0;box-sizing:border-box;display:inline-block;height:.6rem;margin:0 .5rem;padding:0;transform:translateY(-4px) rotate(45deg);transform-origin:center;transition:transform .35s ease;width:.6rem}.tabs .tabs-toggle .tabs-toggle-label{font-size:clamp(.7rem,.7rem + (.85rem - .7rem) * (100vw - 360px) / (1200px - 360px),.85rem);letter-spacing:.1em;line-height:1;text-transform:uppercase;white-space:nowrap}.tabs>nav{display:flex;justify-content:center;opacity:1;padding-bottom:.5rem;transform:translateY(0);transition:transform .35s ease-in-out,opacity .35s ease-in-out;transform-origin:bottom;will-change:transform,opacity;width:100%;position:relative}.tabs .tabs-version{bottom:14px;color:#ff9f1cbf;font-size:10px;letter-spacing:.08em;position:absolute;right:22px}.tabs .tabs-actions{align-items:center;display:flex;gap:.5rem;left:1rem;position:absolute;top:50%;transform:translateY(-50%)}.tabs .tabs-actions.right,.tabs .tabs-actions.tabs-actions--right{left:auto;right:1rem}.tabs .tabs-actions .tabs-actions-toggle{align-items:center;background:transparent;border:1px solid rgba(255,159,28,.6);border-radius:9999px;color:#ff9f1c;cursor:pointer;display:none;height:2.1rem;justify-content:center;padding:0 .6rem;text-transform:uppercase;width:2.4rem}.tabs .tabs-actions .tabs-actions-toggle:hover{background:#ff9f1c1f;border-color:#ff9f1c}.tabs .tabs-actions .tabs-actions-icon{background:#ff9f1c;border-radius:9999px;display:block;height:2px;position:relative;width:1.1rem}.tabs .tabs-actions .tabs-actions-icon:before,.tabs .tabs-actions .tabs-actions-icon:after{content:"";background:#ff9f1c;border-radius:9999px;height:2px;left:0;position:absolute;width:100%}.tabs .tabs-actions .tabs-actions-icon:before{top:-5px}.tabs .tabs-actions .tabs-actions-icon:after{top:5px}.tabs .tabs-actions .tabs-actions-menu{display:flex;gap:.5rem;align-items:center}.tabs .tabs-actions .action-button{background:transparent;border:1px solid rgba(255,159,28,.7);color:#ff9f1cb3;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.25rem .35rem;text-align:left;width:100%;border-radius:1rem;text-align:center}.tabs .tabs-actions .action-button:hover{background:#ff9f1c1f;border-color:#ff9f1c}.tabs .tabs-actions input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.tabs .tabs-action{align-items:center;background:#ff9f1c1a;border:2px solid rgba(255,159,28,.6);border-radius:.4rem;color:#ff9f1c;cursor:pointer;display:inline-flex;font-size:clamp(.65rem,.65rem + (.75rem - .65rem) * (100vw - 360px) / (1200px - 360px),.75rem);height:2.5rem;justify-content:center;letter-spacing:.08em;padding:0 .85rem;text-transform:uppercase;transition:background .2s ease,border-color .2s ease;width:auto}.tabs .tabs-action:hover{background:#ff9f1c2e;border-color:#ff9f1c}.tabs>nav>button{align-items:center;background:transparent;border-radius:9999px;border:2px solid rgba(255,159,28,.35);box-sizing:border-box;color:#ff9f1c;cursor:pointer;display:inline-flex;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);height:5rem;justify-content:center;line-height:1;margin:0 1rem;padding:0;text-transform:uppercase;width:5rem}.tabs>nav>button>span{align-items:center;display:inline-flex;justify-content:center;line-height:1;white-space:nowrap;width:100%;height:100%;border-radius:9999px;padding:0}.tabs>nav>button:hover{border-color:#ff9f1ca6}.tabs>nav>button:hover>span{background:#ff9f1c1f}.tabs>nav>button.is-active{border-color:#ff9f1c}.tabs>nav>button.is-active>span{background:#ff9f1c29}@media(max-width:750px){.tabs .tabs-actions{z-index:5}.tabs .tabs-actions .tabs-actions-toggle{display:inline-flex}.tabs .tabs-actions .tabs-actions-menu{display:none}.tabs .tabs-actions.is-open .tabs-actions-menu{background:#1f1002f2;border:1px solid rgba(255,159,28,.35);border-radius:.5rem;display:flex;flex-direction:column;gap:.35rem;padding:.5rem;position:absolute;bottom:2.6rem;z-index:1000}.tabs .tabs-actions.tabs-actions--left.is-open .tabs-actions-menu{left:0}.tabs .tabs-actions.tabs-actions--right.is-open .tabs-actions-menu{right:0}.tabs .tabs-actions .action-button{width:100%}}@media(max-width:750px){.tabs{overflow:visible}}:host{font-size:inherit}\n',':host{--pip-boy-color: #ff9f1c;--pip-boy-color-rgb: 255, 159, 28;--pip-boy-bg-dark: #1f1002;--pip-boy-bg-darker: #3d2104}:host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host.pip-boy-3000a-theme ::ng-deep{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep button{color:#ff9f1c;border-color:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep button:hover{background:#ff9f1c1f;border-color:#ff9f1ca6}:host.pip-boy-3000a-theme ::ng-deep button.is-active{border-color:#ff9f1c;background:#ff9f1c29;border-left-color:#ff9f1c;border-right-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep input,:host.pip-boy-3000a-theme ::ng-deep select,:host.pip-boy-3000a-theme ::ng-deep textarea{color:#ff9f1c;border-color:#ff9f1c99;background:#1f10024d}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout,:host.pip-boy-3000a-theme ::ng-deep .stats-layout,:host.pip-boy-3000a-theme ::ng-deep .quests-layout,:host.pip-boy-3000a-theme ::ng-deep .music-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header *,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout *,:host.pip-boy-3000a-theme ::ng-deep .stats-layout *,:host.pip-boy-3000a-theme ::ng-deep .quests-layout *,:host.pip-boy-3000a-theme ::ng-deep .music-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal *,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal *{color:#ff9f1c;border-color:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header button,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout button,:host.pip-boy-3000a-theme ::ng-deep .stats-layout button,:host.pip-boy-3000a-theme ::ng-deep .quests-layout button,:host.pip-boy-3000a-theme ::ng-deep .music-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal button,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal button{color:#ff9f1c;border-color:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header button:hover,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep .stats-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep .quests-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep .music-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal button:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal button:hover{background:#ff9f1c1f;border-color:#ff9f1ca6}:host.pip-boy-3000a-theme ::ng-deep .pip-boy-3000-header button.is-active,:host.pip-boy-3000a-theme ::ng-deep .inventory-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep .stats-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep .quests-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep .music-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-inventory-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stats-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-quests-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-cnd-status button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-radiation-meter button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-eff-layout button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal button.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-map-image-modal button.is-active{border-color:#ff9f1c;background:#ff9f1c29}:host.pip-boy-3000a-theme ::ng-deep pip-boy-3000-header header>.header-content>.stat-button:hover{background:#ff9f1c1f!important}:host.pip-boy-3000a-theme ::ng-deep [role=dialog],:host.pip-boy-3000a-theme ::ng-deep .dialog,:host.pip-boy-3000a-theme ::ng-deep .modal,:host.pip-boy-3000a-theme ::ng-deep .pip-boy-dialog{background:#1f1002fa;border-color:#ff9f1c99;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep [role=dialog] *,:host.pip-boy-3000a-theme ::ng-deep .dialog *,:host.pip-boy-3000a-theme ::ng-deep .modal *,:host.pip-boy-3000a-theme ::ng-deep .pip-boy-dialog *{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .center-line:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .bottom-half-line:before{background:linear-gradient(to bottom,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}:host.pip-boy-3000a-theme ::ng-deep .top-half-line:before{background:linear-gradient(to top,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}:host.pip-boy-3000a-theme ::ng-deep .main-title-left-line .bottom-half-line:before{left:0}:host.pip-boy-3000a-theme ::ng-deep .main-title-right-line .bottom-half-line:before{right:0}:host.pip-boy-3000a-theme ::ng-deep .hp-title-line .bottom-half-line:before,:host.pip-boy-3000a-theme ::ng-deep .ap-title-line .bottom-half-line:before,:host.pip-boy-3000a-theme ::ng-deep .xp-title-line .bottom-half-line:before{right:0}:host.pip-boy-3000a-theme ::ng-deep ::-webkit-scrollbar-thumb{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep ::-webkit-scrollbar-track{background:#1f100299}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-tick{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-tick:first-child,:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-tick--end-triangle{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-arrow{border-left-color:transparent;border-right-color:transparent;border-bottom-color:#ff9f1cb3}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-handle{background:#ff9f1c99}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-value{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-fill{background:#ff9f1c73;box-shadow:0 0 20px #ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .radiation-meter-track,:host.pip-boy-3000a-theme ::ng-deep .status-label,:host.pip-boy-3000a-theme ::ng-deep .status-right,:host.pip-boy-3000a-theme ::ng-deep .status-resist-text{border-top-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .status-resist:hover,:host.pip-boy-3000a-theme ::ng-deep .status-resist:focus-visible{background:transparent;border-color:transparent}:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-add,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-edit,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-delete,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-move{background:#ff9f1c0d;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-add:hover,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-delete:hover,:host.pip-boy-3000a-theme ::ng-deep .eff-actions .eff-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .eff-row.is-selected{background:#ff9f1c2e!important}:host.pip-boy-3000a-theme ::ng-deep .quest-toggle{border-color:#ff9f1ca6}:host.pip-boy-3000a-theme ::ng-deep .quest-toggle.is-checked{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .quest-add{background:#ff9f1c14;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .quest-edit,:host.pip-boy-3000a-theme ::ng-deep .quest-delete,:host.pip-boy-3000a-theme ::ng-deep .quest-move{background:#ff9f1c0d;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .quest-add:hover{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .quest-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .quest-delete:hover,:host.pip-boy-3000a-theme ::ng-deep .quest-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .music-add{background:#ff9f1c14;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-edit,:host.pip-boy-3000a-theme ::ng-deep .music-delete,:host.pip-boy-3000a-theme ::ng-deep .music-move{background:#ff9f1c0d;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-add:hover{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .music-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .music-delete:hover,:host.pip-boy-3000a-theme ::ng-deep .music-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .music-waveform canvas{border-right-color:#ff9f1c40;border-bottom-color:#ff9f1c40}:host.pip-boy-3000a-theme ::ng-deep .music-list-item.is-selected{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .music-list-item.is-selected:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-control{background:#ff9f1c0d;border-color:#ff9f1c99;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-control:hover,:host.pip-boy-3000a-theme ::ng-deep .music-control.is-active{background:#ff9f1c1f;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-control--autoplay.is-active,:host.pip-boy-3000a-theme ::ng-deep .music-control--shuffle.is-active{background:#ff9f1c33;border-color:#ff9f1c;box-shadow:0 0 .6rem #ff9f1c47}:host.pip-boy-3000a-theme ::ng-deep .music-volume{border-color:#ff9f1c59;background:#ff9f1c0a}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing-label{color:#ff9f1cb3}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing-value{border-color:#ff9f1c66;color:#ff9f1cd9}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing.is-disabled .music-now-playing-label,:host.pip-boy-3000a-theme ::ng-deep .music-now-playing.is-disabled .music-now-playing-value{color:#ff9f1c73}:host.pip-boy-3000a-theme ::ng-deep .music-now-playing.is-disabled .music-now-playing-value{background:#ff9f1c08;border-color:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep .music-volume-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep .music-volume-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-volume-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .music-volume-label,:host.pip-boy-3000a-theme ::ng-deep .music-volume-value{color:#ff9f1ccc}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .settings-slider-value{color:#ff9f1ccc}:host.pip-boy-3000a-theme ::ng-deep .settings-toggle.is-on{background:#ff9f1c33;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .map-control-button:hover{background:#1f1002e6;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .welcome__range{background:#ff9f1c59}:host.pip-boy-3000a-theme ::ng-deep .welcome__range::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .welcome__range::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-list-item.is-selected{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .resource-list-item.is-selected:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-add,:host.pip-boy-3000a-theme ::ng-deep .resource-edit,:host.pip-boy-3000a-theme ::ng-deep .resource-drop,:host.pip-boy-3000a-theme ::ng-deep .resource-move{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-add{background:#ff9f1c14}:host.pip-boy-3000a-theme ::ng-deep .resource-add:hover{background:#ff9f1c2e}:host.pip-boy-3000a-theme ::ng-deep .resource-edit,:host.pip-boy-3000a-theme ::ng-deep .resource-drop,:host.pip-boy-3000a-theme ::ng-deep .resource-move{background:#ff9f1c0d}:host.pip-boy-3000a-theme ::ng-deep .resource-edit:hover,:host.pip-boy-3000a-theme ::ng-deep .resource-drop:hover,:host.pip-boy-3000a-theme ::ng-deep .resource-move:hover{background:#ff9f1c1f}:host.pip-boy-3000a-theme ::ng-deep .resource-description:before{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep .resource-description:after{background:linear-gradient(to bottom,#ff9f1c,#ff9f1ca6 35%,#ff9f1c59 65%,#ff9f1c00)}:host.pip-boy-3000a-theme ::ng-deep .resource-stat{border:none}:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field textarea{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal .settings-slider-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal .settings-slider-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-settings-modal .settings-slider-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__data{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__data code{background:#ff9f1c14;border-color:#ff9f1c38;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__data a{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-welcome-modal .welcome__section{background:#ff9f1c0a;border-color:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal .reset-modal-body{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-reset-confirm-modal .reset-modal-body p{color:#ff9f1cd9}:host.pip-boy-3000a-theme ::ng-deep pip-boy-audio-edit-modal .audio-modal-field input{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-audio-edit-modal .audio-modal-field input:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .stat-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .number-input-row input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .number-input-row input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field textarea,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal .number-input-row input{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .stat-modal-field input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-edit-modal .number-input-row input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .number-input-row input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-stat-entry-modal .stat-entry-modal-field textarea:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-name-edit-modal .number-input-row input:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep input:focus,:host.pip-boy-3000a-theme ::ng-deep select:focus,:host.pip-boy-3000a-theme ::ng-deep textarea:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field{color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field input,:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field textarea{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field input:focus,:host.pip-boy-3000a-theme ::ng-deep pip-boy-effect-edit-modal .effect-modal-field textarea:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep #text-field-effects{border-color:#ff9f1c80;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep #text-field-effects:focus{border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control{background:#ff9f1c0d;border-color:#ff9f1c99;color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control:hover,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control.is-active{background:#ff9f1c1f;border-color:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control--autoplay.is-active,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control--shuffle.is-active{background:#ff9f1c33;border-color:#ff9f1c;box-shadow:0 0 .6rem #ff9f1c47}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-control:disabled{background:#ff9f1c05;border-color:#ff9f1c33;color:#ff9f1c59;opacity:.8}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing-label{color:#ff9f1cb3}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing-value{border-color:#ff9f1c66;color:#ff9f1cd9}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing.is-disabled .music-now-playing-label,:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing.is-disabled .music-now-playing-value{color:#ff9f1c73}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-now-playing.is-disabled .music-now-playing-value{background:#ff9f1c08;border-color:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-volume-row input[type=range]{background:#ff9f1c33}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-volume-row input[type=range]::-webkit-slider-thumb{background:#ff9f1c}:host.pip-boy-3000a-theme ::ng-deep pip-boy-music-layout .music-volume-row input[type=range]::-moz-range-thumb{background:#ff9f1c}:host{font-family:Roboto Condensed,sans-serif;font-size:clamp(.95rem,.95rem + (1.15rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.15rem);scrollbar-color:rgba(255,159,28,.6) rgba(31,16,2,.6);scrollbar-width:thin;background-color:#1f1002;background-image:repeating-linear-gradient(to bottom,#ffffff0a 0 1px,#0000 4px);background-size:100% 6px;animation:scan-lines 6s linear infinite;box-shadow:inset 0 0 24px #0009,inset 0 0 90px #00000073;box-sizing:border-box;color:#ff9f1c;display:block;height:100%;overflow:hidden;position:relative;width:100%;font-size:inherit}:host ::-webkit-scrollbar{width:6px;height:6px}:host ::-webkit-scrollbar-track{background:#1f100299}:host ::-webkit-scrollbar-thumb{background:#ff9f1c99;border-radius:9999px}:host:before{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,#1f100200 55%,#00000040 70%,#0009);mix-blend-mode:multiply}@keyframes scan-lines{0%{background-position:0 0}to{background-position:0 60px}}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:0;position:relative;width:100%;display:flex;flex-direction:column;min-height:0}.screen-size-overlay{position:absolute;inset:0;background:#000000d9;color:#ff9f1c;display:flex;align-items:center;justify-content:center;text-align:center;padding:2rem;text-transform:uppercase;font-size:clamp(1.1rem,1.1rem + (1.35rem - 1.1rem) * (100vw - 360px) / (1200px - 360px),1.35rem);z-index:200}.boot-sequence{position:fixed;inset:0;background:#000;display:flex;align-items:center;justify-content:center;pointer-events:auto;z-index:99999}.boot-sequence video{width:100%;height:100%;object-fit:cover}.boot-sequence.is-playing{pointer-events:auto}.boot-sequence__loading{font-size:clamp(.95rem,.95rem + (1.2rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.2rem);letter-spacing:.08em;text-transform:uppercase;color:#ff9f1c}.boot-sequence__prompt{position:absolute;bottom:2rem;left:50%;transform:translate(-50%);font-size:clamp(.95rem,.95rem + (1.2rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.2rem);letter-spacing:.1em;text-transform:uppercase;color:#ff9f1c;background:#0009;border:1px solid rgba(255,159,28,.5);border-radius:.5rem;padding:.4rem .75rem;cursor:pointer}.boot-sequence__prompt:hover{background:#ff9f1c1f;border-color:#ff9f1c}.boot-sequence__close{position:absolute;top:1rem;right:1rem;z-index:1;background:#0009;border:1px solid rgba(255,159,28,.5);border-radius:.5rem;color:#ff9f1c;cursor:pointer;padding:.6rem .95rem;font-size:1.35rem;line-height:1;text-transform:uppercase}.boot-sequence__close:hover{background:#ff9f1c1f;border-color:#ff9f1c}.screen.is-booting ::ng-deep .dialog-backdrop{display:none}.screen.is-booting ::ng-deep .dialog{display:none}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:2px;background:#ff9f1c}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:50%;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}.top-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.top-half-line:before{content:"";position:absolute;bottom:50%;top:-1.25rem;width:2px;z-index:2;left:0;background:linear-gradient(to top,#ff9f1c,#ff9f1ca6 18%,#ff9f1c59 40%,#ff9f1c26 65%,#ff9f1c00)}.extra-options{margin-top:0;display:flex;flex-direction:column;font-family:Roboto Mono,monospace;font-size:calc(clamp(1.05rem,1.05rem + .2rem * (100vw - 360px) / 840px,1.25rem) * var(--list-font-scale, 1));align-items:flex-end;gap:.75rem;white-space:nowrap;position:absolute;top:1rem;right:2rem;z-index:3}.extra-options button{background:transparent;border:none;color:#ff9f1c;cursor:pointer;font:inherit;padding:0;white-space:nowrap}.extra-options button:hover{opacity:.8}.extra-options button:disabled,.extra-options button.is-locked{cursor:default}.extra-options .controller-button{font-size:inherit;white-space:nowrap}.extra-options .controller-button .large-par{display:inline;padding-left:.5rem;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));top:-.15rem;position:relative;white-space:nowrap}.map-panel{display:flex;flex:1 1 auto;min-height:0;position:relative;width:100%}.map-view{align-items:flex-start;background:transparent;border:none;color:#ff9f1c;cursor:pointer;display:flex;flex:1 1 auto;justify-content:flex-start;min-height:0;overflow:auto;padding:0;width:100%}.map-view span{letter-spacing:.1em;margin:auto;text-transform:uppercase;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.map-view img{display:block;max-width:none;max-height:none}.map-view.is-locked,.map-view:disabled{cursor:default}.map-view.is-draggable{cursor:grab}.map-view.is-dragging{cursor:grabbing}.map-zoom{display:flex;gap:.5rem;position:absolute;right:1.5rem;top:.5rem;z-index:2}.map-zoom .map-zoom-button{padding:0;width:calc(2rem * var(--list-font-scale, 1))}.map-fit{position:absolute;right:1.5rem;bottom:.5rem;z-index:2}.map-control-button{align-items:center;background:#1f1002f2;border:1px solid rgba(255,159,28,.65);border-radius:.5rem;color:#ff9f1c;cursor:pointer;display:inline-flex;font-size:calc(clamp(.75rem,.75rem + .15rem * (100vw - 360px) / 840px,.9rem) * var(--list-font-scale, 1));justify-content:center;text-transform:uppercase;height:calc(2rem * var(--list-font-scale, 1));padding:0 calc(.6rem * var(--list-font-scale, 1))}.map-control-button:hover{border-color:#ff9f1c;background:#1f1002e6}\n']}]}],propDecorators:{returnToUrl:[{type:e.Input,args:[{isSignal:!0,alias:"returnToUrl",required:!1}]}],localMapImage:[{type:e.ViewChild,args:["localMapImage",{isSignal:!0}]}],worldMapImage:[{type:e.ViewChild,args:["worldMapImage",{isSignal:!0}]}],localMapView:[{type:e.ViewChild,args:["localMapView",{isSignal:!0}]}],worldMapView:[{type:e.ViewChild,args:["worldMapView",{isSignal:!0}]}],onResize:[{type:h,args:["window:resize"]}]}});class Re{static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:Re,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"21.1.1",type:Re,isStandalone:!0,selector:"pip-boy-3000-mk-iv",ngImport:e,template:'<section #screen class="screen">\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="200"\n />\n</section>\n',styles:[":host{background:#030703;box-sizing:border-box;color:#3ad03a;display:block;height:100%;width:100%}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:1rem;position:relative;width:100%}\n"],dependencies:[{kind:"component",type:w,selector:"pip-boy-screen-scan-lines",inputs:["replayTimeoutSeconds","screen","scanSpeedSeconds","tailLengthPx","scanColorRgb"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:Re,decorators:[{type:a,args:[{selector:"pip-boy-3000-mk-iv",standalone:!0,imports:[w],template:'<section #screen class="screen">\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="200"\n />\n</section>\n',styles:[":host{background:#030703;box-sizing:border-box;color:#3ad03a;display:block;height:100%;width:100%}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:1rem;position:relative;width:100%}\n"]}]}]});class De{returnToUrl=t("https://www.pip-boy.com",...ngDevMode?[{debugName:"returnToUrl"}]:[]);state=l(W);settings=l(C);imageStore=l(k);soundStore=l(ae);videoStore=l(ce);audioPlayer=l(oe);hostRef=l(g);appVersion=N;tabsOpen=o(!1,...ngDevMode?[{debugName:"tabsOpen"}]:[]);showResetModal=o(!1,...ngDevMode?[{debugName:"showResetModal"}]:[]);showExitModal=o(!1,...ngDevMode?[{debugName:"showExitModal"}]:[]);showBugModal=o(!1,...ngDevMode?[{debugName:"showBugModal"}]:[]);showSettingsModal=o(!1,...ngDevMode?[{debugName:"showSettingsModal"}]:[]);settingsListFontScaleSnapshot=o(null,...ngDevMode?[{debugName:"settingsListFontScaleSnapshot"}]:[]);showWelcomeModal=o(!0,...ngDevMode?[{debugName:"showWelcomeModal"}]:[]);showBootSequence=o(!1,...ngDevMode?[{debugName:"showBootSequence"}]:[]);bootSequenceStarted=o(!1,...ngDevMode?[{debugName:"bootSequenceStarted"}]:[]);bootSequenceShowWelcome=o(!0,...ngDevMode?[{debugName:"bootSequenceShowWelcome"}]:[]);bootAutoplayAttempted=o(!1,...ngDevMode?[{debugName:"bootAutoplayAttempted"}]:[]);bootNeedsClick=o(!1,...ngDevMode?[{debugName:"bootNeedsClick"}]:[]);bootIsPlaying=o(!1,...ngDevMode?[{debugName:"bootIsPlaying"}]:[]);mapImageModal=o(null,...ngDevMode?[{debugName:"mapImageModal"}]:[]);localMapImage=b("localMapImage",...ngDevMode?[{debugName:"localMapImage"}]:[]);worldMapImage=b("worldMapImage",...ngDevMode?[{debugName:"worldMapImage"}]:[]);localMapView=b("localMapView",...ngDevMode?[{debugName:"localMapView"}]:[]);worldMapView=b("worldMapView",...ngDevMode?[{debugName:"worldMapView"}]:[]);extraOptionModal=o(null,...ngDevMode?[{debugName:"extraOptionModal"}]:[]);tabsActionsLeftOpen=o(!1,...ngDevMode?[{debugName:"tabsActionsLeftOpen"}]:[]);tabsActionsRightOpen=o(!1,...ngDevMode?[{debugName:"tabsActionsRightOpen"}]:[]);isMapDragging=o(!1,...ngDevMode?[{debugName:"isMapDragging"}]:[]);viewportWidth=o("undefined"==typeof window?0:window.innerWidth,...ngDevMode?[{debugName:"viewportWidth"}]:[]);mapImageModalTitle=u(()=>"WORLD"===this.mapImageModal()?"World Map":"Local Map",...ngDevMode?[{debugName:"mapImageModalTitle"}]:[]);mapImageModalImage=u(()=>{const e="WORLD"===this.mapImageModal()?this.settings.worldMapImage():this.settings.localMapImage();return this.imageStore.getImageUrl(e)},...ngDevMode?[{debugName:"mapImageModalImage"}]:[]);secondaryTabSoundLabel=u(()=>this.soundStore.getSoundLabel(this.settings.secondaryTabSoundId()),...ngDevMode?[{debugName:"secondaryTabSoundLabel"}]:[]);mainTabSoundLabel=u(()=>this.soundStore.getSoundLabel(this.settings.mainTabSoundId()),...ngDevMode?[{debugName:"mainTabSoundLabel"}]:[]);clickSoundLabel=u(()=>this.soundStore.getSoundLabel(this.settings.clickSoundId()),...ngDevMode?[{debugName:"clickSoundLabel"}]:[]);bootVideoLabel=u(()=>this.videoStore.getVideoLabel(this.settings.bootVideoId()),...ngDevMode?[{debugName:"bootVideoLabel"}]:[]);bootVideoUrl=u(()=>this.videoStore.getVideoUrl(this.settings.bootVideoId()),...ngDevMode?[{debugName:"bootVideoUrl"}]:[]);bootVideoPreviewUrl=o(null,...ngDevMode?[{debugName:"bootVideoPreviewUrl"}]:[]);bootVideoPlaybackUrl=u(()=>this.bootVideoPreviewUrl()??this.bootVideoUrl(),...ngDevMode?[{debugName:"bootVideoPlaybackUrl"}]:[]);mapDragState={target:null,startX:0,startY:0,scrollLeft:0,scrollTop:0,moved:!1};suppressMapClick=!1;isScreenTooSmall=u(()=>this.viewportWidth()<650,...ngDevMode?[{debugName:"isScreenTooSmall"}]:[]);bootSequenceWatcher=r(()=>{this.settings.bootVideoId(),this.maybeStartBootSequence()},...ngDevMode?[{debugName:"bootSequenceWatcher"}]:[]);extraOptionTitle=u(()=>{switch(this.extraOptionModal()){case"RADAWAY":case"RADX":return"Edit Text";default:return""}},...ngDevMode?[{debugName:"extraOptionTitle"}]:[]);extraOptionValue=u(()=>{const e=this.extraOptionModal();return"STIMPAK"===e?this.settings.stimpakLabel():"LIMBS"===e?this.settings.limbLabel():"RADAWAY"===e?this.settings.radAwayLabel():"RADX"===e?this.settings.radXLabel():""},...ngDevMode?[{debugName:"extraOptionValue"}]:[]);documentClickHandler=e=>{const t=e.target;if(!t)return;if(!this.hostRef.nativeElement.contains(t))return;if(t.closest('[data-skip-click-sound="true"]'))return;const n=t.closest("button, input, select, textarea");n&&n.disabled||this.soundStore.playSound(this.settings.clickSoundId())};toggleTabs(){this.tabsOpen.update(e=>!e)}toggleTabsActions(e){"left"===e?(this.tabsActionsLeftOpen.update(e=>!e),this.tabsActionsRightOpen.set(!1)):(this.tabsActionsRightOpen.update(e=>!e),this.tabsActionsLeftOpen.set(!1))}onResize(){this.viewportWidth.set(window.innerWidth)}ngOnInit(){"undefined"!=typeof document&&(document.addEventListener("click",this.documentClickHandler,!0),this.maybeStartBootSequence())}ngOnDestroy(){"undefined"!=typeof document&&(document.removeEventListener("click",this.documentClickHandler,!0),this.clearBootVideoPreview())}async saveSettingsToFile(){const e=this.settings.exportSettingsSnapshot(),t=this.collectImageIds(e),n=this.collectSoundIds(e),a=this.collectVideoIds(e),o=[],i=[],s=[],r=new y;for(const e of t){const t=await this.imageStore.getRecord(e);if(!t)continue;const n=this.getExtension(t.fileName,t.mime);r.file(`images/${e}${n}`,t.blob),o.push({id:e,fileName:t.fileName,mime:t.mime})}for(const e of n){const t=await this.soundStore.getRecord(e);if(!t)continue;const n=this.getSoundExtension(t.fileName,t.mime);r.file(`sounds/${e}${n}`,t.blob),i.push({id:e,fileName:t.fileName,mime:t.mime})}for(const e of a){const t=await this.videoStore.getRecord(e);if(!t)continue;const n=this.getVideoExtension(t.fileName,t.mime);r.file(`videos/${e}${n}`,t.blob),s.push({id:e,fileName:t.fileName,mime:t.mime})}const l={version:1,images:o,sounds:i,videos:s,pipBoy3000Settings:e};r.file("settings.json",JSON.stringify(l));const d=await r.generateAsync({type:"blob"}),c=URL.createObjectURL(d),p=document.createElement("a");p.href=c,p.download="pip-boy-3000.zip",p.click(),URL.revokeObjectURL(c)}openResetModal(){this.showResetModal.set(!0)}closeResetModal(){this.showResetModal.set(!1)}confirmReset(){this.stopAllSounds(),this.settings.resetToDefaults(),this.closeResetModal(),this.showWelcomeModal.set(!0)}openExitModal(){this.showExitModal.set(!0)}closeExitModal(){this.showExitModal.set(!1)}confirmExit(){window.location.href=this.returnToUrl()}openBugModal(){this.showBugModal.set(!0)}closeBugModal(){this.showBugModal.set(!1)}confirmBugReport(){window.open("https://github.com/CodyTolene/pip-terminal/issues","_blank"),this.closeBugModal()}openSettingsModal(){this.settingsListFontScaleSnapshot.set(this.settings.listFontScale()),this.showSettingsModal.set(!0)}closeSettingsModal(){this.showSettingsModal.set(!1)}cancelSettingsModal(){const e=this.settingsListFontScaleSnapshot();null!==e&&this.settings.listFontScale.set(e),this.settingsListFontScaleSnapshot.set(null),this.showSettingsModal.set(!1)}closeWelcomeModal(){this.showWelcomeModal.set(!1)}finishBootSequence(){this.showBootSequence.set(!1),this.clearBootVideoPreview(),this.bootAutoplayAttempted.set(!1),this.bootNeedsClick.set(!1),this.bootIsPlaying.set(!1),this.bootSequenceShowWelcome()&&this.showWelcomeModal.set(!0)}saveSettingsModal(e){this.settings.scanLinesEnabled.set(e.scanLinesEnabled),this.settings.rememberTabOnRefresh.set(e.rememberTabOnRefreshEnabled),this.settings.editLockEnabled.set(e.editLockEnabled),this.settings.listFontScale.set(e.listFontScale),this.settingsListFontScaleSnapshot.set(null),e.removeSecondaryTabSound&&this.settings.secondaryTabSoundId.set(null),e.removeMainTabSound&&this.settings.mainTabSoundId.set(null),e.removeClickSound&&this.settings.clickSoundId.set(null),e.removeBootVideo&&this.settings.bootVideoId.set(null),e.secondaryTabSoundFile&&this.soundStore.saveFile(e.secondaryTabSoundFile).then(e=>this.settings.secondaryTabSoundId.set(e.id)),e.mainTabSoundFile&&this.soundStore.saveFile(e.mainTabSoundFile).then(e=>this.settings.mainTabSoundId.set(e.id)),e.clickSoundFile&&this.soundStore.saveFile(e.clickSoundFile).then(e=>this.settings.clickSoundId.set(e.id)),e.bootVideoFile&&this.videoStore.saveFile(e.bootVideoFile).then(e=>this.settings.bootVideoId.set(e.id)),this.closeSettingsModal()}previewListFontScale(e){this.settings.listFontScale.set(e)}previewSecondaryTabSound(){this.soundStore.playSound(this.settings.secondaryTabSoundId())}previewMainTabSound(){this.soundStore.playSound(this.settings.mainTabSoundId())}previewClickSound(){this.soundStore.playSound(this.settings.clickSoundId())}previewBootVideo(e){if(e){const t=URL.createObjectURL(e);this.setBootVideoPreviewUrl(t)}else{if(!this.settings.bootVideoId())return;this.clearBootVideoPreview()}this.bootSequenceShowWelcome.set(!1),this.bootAutoplayAttempted.set(!1),this.bootNeedsClick.set(!1),this.bootIsPlaying.set(!1),this.showWelcomeModal.set(!1),this.showBootSequence.set(!0)}maybeStartBootSequence(){"undefined"!=typeof document&&(this.bootSequenceStarted()||this.settings.bootVideoId()&&(this.clearBootVideoPreview(),this.bootSequenceShowWelcome.set(!0),this.bootSequenceStarted.set(!0),this.bootAutoplayAttempted.set(!1),this.bootNeedsClick.set(!1),this.bootIsPlaying.set(!1),this.showWelcomeModal.set(!1),this.showBootSequence.set(!0)))}handleBootCanPlay(e){this.bootAutoplayAttempted()||(this.bootAutoplayAttempted.set(!0),e.play().then(()=>{this.bootNeedsClick.set(!1),this.bootIsPlaying.set(!0)}).catch(()=>{this.bootNeedsClick.set(!0)}))}playBootVideo(e,t){t?.stopPropagation(),this.bootIsPlaying()||e.play().then(()=>{this.bootNeedsClick.set(!1),this.bootIsPlaying.set(!0)}).catch(()=>{this.bootNeedsClick.set(!0)})}setBootVideoPreviewUrl(e){const t=this.bootVideoPreviewUrl();t&&URL.revokeObjectURL(t),this.bootVideoPreviewUrl.set(e)}clearBootVideoPreview(){const e=this.bootVideoPreviewUrl();e&&(URL.revokeObjectURL(e),this.bootVideoPreviewUrl.set(null))}openGithubProfile(){window.open("https://github.com/CodyTolene","_blank")}selectPrimary(e){this.soundStore.playSound(this.settings.mainTabSoundId()),this.state.selectPrimary(e)}selectSecondary(e){this.soundStore.playSound(this.settings.secondaryTabSoundId()),this.state.selectSecondary(e)}openExtraOptionModal(e){this.settings.editLockEnabled()||this.extraOptionModal.set(e)}closeExtraOptionModal(){this.extraOptionModal.set(null)}saveExtraOptionModal(e){const t=this.extraOptionModal();"STIMPAK"===t?this.settings.stimpakLabel.set(e):"LIMBS"===t?this.settings.limbLabel.set(e):"RADAWAY"===t?this.settings.radAwayLabel.set(e):"RADX"===t&&this.settings.radXLabel.set(e),this.closeExtraOptionModal()}async loadSettingsFromFile(e){const t=e.target,n=t.files?.[0]??null;if(!n)return;this.stopAllSounds();const a=await y.loadAsync(n),o=a.file("settings.json");if(!o)return void(t.value="");const i=await o.async("string"),s=JSON.parse(i),r=s.pipBoy3000Settings??s;if(Array.isArray(s.images))for(const e of s.images){const t=this.getExtension(e.fileName,e.mime),n=a.file(`images/${e.id}${t}`)??a.file(new RegExp(`^images/${e.id}\\.`))?.[0];if(!n)continue;const o=await n.async("blob");await this.imageStore.saveBlobWithId(e.id,o,e.fileName,e.mime)}if(Array.isArray(s.sounds))for(const e of s.sounds){const t=this.getSoundExtension(e.fileName,e.mime),n=a.file(`sounds/${e.id}${t}`)??a.file(new RegExp(`^sounds/${e.id}\\.`))?.[0];if(!n)continue;const o=await n.async("blob");await this.soundStore.saveBlobWithId(e.id,o,e.fileName,e.mime)}if(Array.isArray(s.videos))for(const e of s.videos){const t=this.getVideoExtension(e.fileName,e.mime),n=a.file(`videos/${e.id}${t}`)??a.file(new RegExp(`^videos/${e.id}\\.`))?.[0];if(!n)continue;const o=await n.async("blob");await this.videoStore.saveBlobWithId(e.id,o,e.fileName,e.mime)}this.settings.importSettingsSnapshot(r),t.value=""}stopAllSounds(){this.audioPlayer.stop(),this.soundStore.stopAll()}collectImageIds(e){const t=new Set,n=e=>{e&&t.add(e)};return e.weaponItems.forEach(e=>n(e.imageId)),e.apparelItems.forEach(e=>n(e.imageId)),e.aidItems.forEach(e=>n(e.imageId)),e.miscItems.forEach(e=>n(e.imageId)),e.ammoItems.forEach(e=>n(e.imageId)),e.specialItems.forEach(e=>n(e.imageId)),e.skillItems.forEach(e=>n(e.imageId)),e.perkItems.forEach(e=>n(e.imageId)),e.vaultBoyImages.forEach(e=>n(e)),n(e.localMapImage),n(e.worldMapImage),Array.from(t)}collectSoundIds(e){const t=new Set,n=e=>{e&&t.add(e)};return n(e.secondaryTabSoundId),n(e.mainTabSoundId),n(e.clickSoundId),e.notesItems.forEach(e=>n(e.soundId)),e.radioItems.forEach(e=>n(e.soundId)),Array.from(t)}collectVideoIds(e){const t=new Set;var n;return(n=e.bootVideoId)&&t.add(n),Array.from(t)}getExtension(e,t){const n=e.match(/\.[a-z0-9]+$/i);return n?n[0]:this.imageStore.extensionFromMime(t)}getSoundExtension(e,t){const n=e.match(/\.[a-z0-9]+$/i);return n?n[0]:this.soundStore.extensionFromMime(t)}getVideoExtension(e,t){const n=e.match(/\.[a-z0-9]+$/i);return n?n[0]:this.videoStore.extensionFromMime(t)}openMapImageModal(e){this.settings.editLockEnabled()||(this.suppressMapClick?this.suppressMapClick=!1:this.mapImageModal.set(e))}closeMapImageModal(){this.mapImageModal.set(null)}zoomMap(e,t){const n="WORLD"===e?this.settings.worldMapZoom:this.settings.localMapZoom,a=Math.min(3,Math.max(.5,n()+t));n.set(Number(a.toFixed(2)))}resetMapZoom(e){"WORLD"===e?this.settings.worldMapZoom.set(1):this.settings.localMapZoom.set(1)}startMapDrag(e){if(0!==e.button)return;const t=e.currentTarget;t&&t.querySelector("img")&&(this.mapDragState={target:t,startX:e.clientX,startY:e.clientY,scrollLeft:t.scrollLeft,scrollTop:t.scrollTop,moved:!1},this.isMapDragging.set(!0),e.preventDefault())}onMapDrag(e){const t=this.mapDragState.target;if(!t)return;const n=e.clientX-this.mapDragState.startX,a=e.clientY-this.mapDragState.startY;if(!this.mapDragState.moved){if(Math.abs(n)<3&&Math.abs(a)<3)return;this.mapDragState.moved=!0}t.scrollLeft=this.mapDragState.scrollLeft-n,t.scrollTop=this.mapDragState.scrollTop-a,e.preventDefault()}endMapDrag(){this.mapDragState.target&&(this.mapDragState.moved&&(this.suppressMapClick=!0),this.mapDragState={target:null,startX:0,startY:0,scrollLeft:0,scrollTop:0,moved:!1},this.isMapDragging.set(!1))}fitMapZoom(e){const t="WORLD"===e?this.worldMapView():this.localMapView(),n="WORLD"===e?this.worldMapImage():this.localMapImage();if(!t||!n)return;const a=t.nativeElement.clientWidth,o=n.nativeElement.naturalWidth;if(!a||!o)return;const i=Math.min(3,Math.max(.5,a/o));("WORLD"===e?this.settings.worldMapZoom:this.settings.localMapZoom).set(Number(i.toFixed(2)))}isMapFit(e){const t="WORLD"===e?this.worldMapView():this.localMapView(),n="WORLD"===e?this.worldMapImage():this.localMapImage();if(!t||!n)return!1;const a=t.nativeElement.clientWidth,o=n.nativeElement.naturalWidth;if(!a||!o)return!1;const i=Math.min(3,Math.max(.5,a/o)),s="WORLD"===e?this.settings.worldMapZoom():this.settings.localMapZoom();return Math.abs(s-Number(i.toFixed(2)))<.01}async saveMapImageModal(e){const t=this.mapImageModal();if(t){if(e.removeImage)return"WORLD"===t?this.settings.worldMapImage.set(null):this.settings.localMapImage.set(null),void this.closeMapImageModal();if(e.imageFile){const n=await this.imageStore.saveFile(e.imageFile);"WORLD"===t?this.settings.worldMapImage.set(n.id):this.settings.localMapImage.set(n.id)}this.closeMapImageModal()}}static"ɵfac"=e.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:De,deps:[],target:e.ɵɵFactoryTarget.Component});static"ɵcmp"=e.ɵɵngDeclareComponent({minVersion:"17.0.0",version:"21.1.1",type:De,isStandalone:!0,selector:"pip-boy-3000",inputs:{returnToUrl:{classPropertyName:"returnToUrl",publicName:"returnToUrl",isSignal:!0,isRequired:!1,transformFunction:null}},host:{listeners:{"window:resize":"onResize()"}},providers:[W],viewQueries:[{propertyName:"localMapImage",first:!0,predicate:["localMapImage"],descendants:!0,isSignal:!0},{propertyName:"worldMapImage",first:!0,predicate:["worldMapImage"],descendants:!0,isSignal:!0},{propertyName:"localMapView",first:!0,predicate:["localMapView"],descendants:!0,isSignal:!0},{propertyName:"worldMapView",first:!0,predicate:["worldMapView"],descendants:!0,isSignal:!0}],ngImport:e,template:'<main\n #screen\n class="screen"\n [style.--list-font-scale]="settings.listFontScale()"\n [class.is-booting]="showBootSequence()"\n>\n @if (settings.scanLinesEnabled()) {\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="300"\n />\n }\n @if (isScreenTooSmall()) {\n <div class="screen-size-overlay" role="alert" aria-live="assertive">\n Screen is too small.<br />Please rotate to landscape.\n </div>\n }\n @if (showBootSequence()) {\n <div\n class="boot-sequence"\n [class.is-playing]="bootIsPlaying()"\n tabindex="0"\n data-skip-click-sound="true"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n <button\n type="button"\n class="boot-sequence__close"\n aria-label="Close boot sequence"\n data-skip-click-sound="true"\n (click)="finishBootSequence()"\n >\n X\n </button>\n @if (bootVideoPlaybackUrl()) {\n <video\n #bootVideo\n [src]="bootVideoPlaybackUrl()"\n muted\n playsinline\n preload="auto"\n (canplay)="handleBootCanPlay(bootVideo)"\n (click)="playBootVideo(bootVideo, $event)"\n (ended)="finishBootSequence()"\n ></video>\n @if (bootNeedsClick()) {\n <button\n type="button"\n class="boot-sequence__prompt"\n data-skip-click-sound="true"\n (click)="playBootVideo(bootVideo, $event)"\n >\n Click to play\n </button>\n }\n } @else {\n <div class="boot-sequence__loading">Loading boot sequence...</div>\n }\n </div>\n }\n \x3c!-- HEADER --\x3e\n <pip-boy-3000-header />\n \x3c!-- CONTENT --\x3e\n <section class="content">\n @if (state.primary() === \'STATS\') {\n @if (state.secondary() === \'STATUS\') {\n <div class="status-content">\n <nav class="column sub-content" aria-label="Status tabs">\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'CND\'"\n (click)="state.selectTertiary(\'CND\')"\n >\n CND\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'RAD\'"\n (click)="state.selectTertiary(\'RAD\')"\n >\n RAD\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'EFF\'"\n (click)="state.selectTertiary(\'EFF\')"\n >\n EFF\n </button>\n </nav>\n @if (state.tertiary() === \'CND\') {\n <pip-boy-cnd-status />\n } @else if (state.tertiary() === \'RAD\') {\n <pip-boy-radiation-meter />\n <div class="extra-options">\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADAWAY\')"\n >\n {{ settings.radAwayLabel() }}\n </button>\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADX\')"\n >\n {{ settings.radXLabel() }}\n </button>\n </div>\n } @else if (state.tertiary() === \'EFF\') {\n <pip-boy-eff-layout />\n }\n </div>\n } @else if (state.secondary() === \'S.P.E.C.I.A.L.\') {\n <pip-boy-stats-layout\n category="SPECIAL"\n valueLabel="Rating"\n [valueMin]="1"\n [valueMax]="10"\n />\n } @else if (state.secondary() === \'SKILLS\') {\n <pip-boy-stats-layout\n category="SKILLS"\n valueLabel="Skill"\n [valueMin]="0"\n [valueMax]="100"\n />\n } @else if (state.secondary() === \'PERKS\') {\n <pip-boy-stats-layout\n category="PERKS"\n valueLabel="Rank"\n [valueMin]="0"\n />\n } @else if (state.secondary() === \'GENERAL\') {\n <pip-boy-stats-layout category="GENERAL" valueLabel="Value" />\n }\n } @else if (state.primary() === \'ITEMS\') {\n @if (state.secondary() === \'WEAPONS\') {\n <pip-boy-inventory-layout category="WEAPONS" />\n } @else if (state.secondary() === \'APPAREL\') {\n <pip-boy-inventory-layout category="APPAREL" />\n } @else if (state.secondary() === \'AID\') {\n <pip-boy-inventory-layout category="AID" />\n } @else if (state.secondary() === \'MISC\') {\n <pip-boy-inventory-layout category="MISC" />\n } @else if (state.secondary() === \'AMMO\') {\n <pip-boy-inventory-layout category="AMMO" />\n }\n } @else if (state.primary() === \'DATA\') {\n @if (state.secondary() === \'LOCAL MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #localMapView\n [class.is-draggable]="settings.localMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'LOCAL\')"\n >\n @if (settings.localMapImage()) {\n <img\n #localMapImage\n [src]="imageStore.getImageUrl(settings.localMapImage())"\n alt="Local map"\n [style.zoom]="settings.localMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.localMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.localMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'LOCAL\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'LOCAL\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'LOCAL\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'WORLD MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #worldMapView\n [class.is-draggable]="settings.worldMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'WORLD\')"\n >\n @if (settings.worldMapImage()) {\n <img\n #worldMapImage\n [src]="imageStore.getImageUrl(settings.worldMapImage())"\n alt="World map"\n [style.zoom]="settings.worldMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.worldMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.worldMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'WORLD\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'WORLD\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'WORLD\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'QUESTS\') {\n <pip-boy-quests-layout />\n } @else if (state.secondary() === \'NOTES\') {\n <pip-boy-music-layout category="NOTES" />\n } @else if (state.secondary() === \'RADIO\') {\n <pip-boy-music-layout category="RADIO" />\n }\n }\n </section>\n \x3c!-- SUB TABS --\x3e\n <section class="sub-tabs">\n @if (state.primary() === \'STATS\') {\n <nav aria-label="Stats tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'STATUS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'STATUS\')"\n >\n Status\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'S.P.E.C.I.A.L.\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'S.P.E.C.I.A.L.\')"\n >\n S.P.E.C.I.A.L.\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'SKILLS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'SKILLS\')"\n >\n Skills\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'PERKS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'PERKS\')"\n >\n Perks\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'GENERAL\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'GENERAL\')"\n >\n General\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'ITEMS\') {\n <nav aria-label="Items tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WEAPONS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'WEAPONS\')"\n >\n Weapons\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'APPAREL\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'APPAREL\')"\n >\n Apparel\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AID\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'AID\')"\n >\n Aid\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'MISC\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'MISC\')"\n >\n Misc\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AMMO\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'AMMO\')"\n >\n Ammo\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'DATA\') {\n <nav aria-label="Data tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'LOCAL MAP\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'LOCAL MAP\')"\n >\n Local Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WORLD MAP\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'WORLD MAP\')"\n >\n World Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'QUESTS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'QUESTS\')"\n >\n Quests\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'NOTES\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'NOTES\')"\n >\n Notes\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'RADIO\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'RADIO\')"\n >\n Radio\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n }\n </section>\n \x3c!-- MAIN TABS --\x3e\n <section class="tabs" [class.is-collapsed]="!tabsOpen()">\n <button\n type="button"\n class="tabs-toggle"\n aria-label="Toggle main tabs"\n [attr.aria-expanded]="tabsOpen()"\n aria-controls="main-tabs"\n data-skip-click-sound="true"\n (click)="toggleTabs()"\n >\n <span class="tabs-toggle-label tabs-toggle-label--state">\n {{ tabsOpen() ? \'CLOSE\' : \'OPEN\' }}\n </span>\n <span class="caret" aria-hidden="true"></span>\n <span class="tabs-toggle-label tabs-toggle-label--menu">MENU</span>\n </button>\n <nav id="main-tabs" aria-label="Main tabs">\n <div\n class="tabs-actions tabs-actions--left"\n [class.is-open]="tabsActionsLeftOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open settings actions"\n (click)="toggleTabsActions(\'left\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Save settings"\n title="Save settings"\n (click)="saveSettingsToFile()"\n >\n Save\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Load settings"\n title="Load settings"\n (click)="loadSettingsInput.click()"\n >\n Load\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Reset settings"\n title="Reset settings"\n (click)="openResetModal()"\n >\n Reset\n </button>\n <input\n #loadSettingsInput\n type="file"\n accept=".zip,application/zip"\n (change)="loadSettingsFromFile($event)"\n />\n </div>\n </div>\n <button\n type="button"\n [class.is-active]="state.primary() === \'STATS\'"\n data-skip-click-sound="true"\n (click)="selectPrimary(\'STATS\')"\n >\n <span>STATS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'ITEMS\'"\n data-skip-click-sound="true"\n (click)="selectPrimary(\'ITEMS\')"\n >\n <span>ITEMS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'DATA\'"\n data-skip-click-sound="true"\n (click)="selectPrimary(\'DATA\')"\n >\n <span>DATA</span>\n </button>\n <div\n class="tabs-actions tabs-actions--right"\n [class.is-open]="tabsActionsRightOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open utility actions"\n (click)="toggleTabsActions(\'right\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Open GitHub profile"\n title="Open GitHub profile"\n (click)="openGithubProfile()"\n >\n ❤\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Open settings"\n title="Settings"\n (click)="openSettingsModal()"\n >\n Settings\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Report a bug"\n title="Report a bug"\n (click)="openBugModal()"\n >\n Bug\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Exit"\n title="Exit"\n (click)="openExitModal()"\n >\n Exit\n </button>\n </div>\n </div>\n @if (tabsOpen()) {\n <div class="tabs-version">v{{ appVersion }}</div>\n }\n </nav>\n </section>\n <pip-boy-welcome-modal\n [open]="showWelcomeModal() && !showBootSequence()"\n [listFontScale]="settings.listFontScale()"\n (previewListFontScale)="previewListFontScale($event)"\n (closeResult)="closeWelcomeModal()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showResetModal()"\n title="Reset Settings"\n message="This will reset all values back to defaults. This cannot be undone."\n confirmLabel="Reset"\n (closeResult)="closeResetModal()"\n (confirm)="confirmReset()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showExitModal()"\n title="Exit"\n message="Are you sure you want to leave this screen?"\n confirmLabel="Exit"\n (closeResult)="closeExitModal()"\n (confirm)="confirmExit()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showBugModal()"\n title="Report a bug"\n message="Would you like to report a bug?"\n confirmLabel="Yes"\n cancelLabel="No"\n (closeResult)="closeBugModal()"\n (confirm)="confirmBugReport()"\n />\n <pip-boy-map-image-modal\n [open]="mapImageModal() !== null"\n [title]="mapImageModalTitle()"\n [imageUrl]="mapImageModalImage()"\n (closeResult)="closeMapImageModal()"\n (save)="saveMapImageModal($event)"\n />\n <pip-boy-settings-modal\n [open]="showSettingsModal()"\n [scanLinesEnabled]="settings.scanLinesEnabled()"\n [rememberTabOnRefreshEnabled]="settings.rememberTabOnRefresh()"\n [editLockEnabled]="settings.editLockEnabled()"\n [listFontScale]="settings.listFontScale()"\n [secondaryTabSoundLabel]="secondaryTabSoundLabel()"\n [mainTabSoundLabel]="mainTabSoundLabel()"\n [clickSoundLabel]="clickSoundLabel()"\n [bootVideoLabel]="bootVideoLabel()"\n (closeResult)="cancelSettingsModal()"\n (previewListFontScale)="previewListFontScale($event)"\n (playSecondarySound)="previewSecondaryTabSound()"\n (playMainSound)="previewMainTabSound()"\n (playClickSound)="previewClickSound()"\n (playBootVideo)="previewBootVideo($event)"\n (save)="saveSettingsModal($event)"\n />\n <pip-boy-name-edit-modal\n [open]="extraOptionModal() !== null"\n [value]="extraOptionValue()"\n [title]="extraOptionTitle()"\n placeholder="Value"\n [allowEmpty]="true"\n (closeResult)="closeExtraOptionModal()"\n (save)="saveExtraOptionModal($event)"\n />\n</main>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.content{box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;height:100%;overflow:auto;padding:1rem 2rem;position:relative;width:100%}.content .status-content{box-sizing:border-box;display:flex;flex-direction:row;height:100%;gap:1rem}.content .column{box-sizing:border-box;display:flex;flex:1;flex-direction:column}.content .sub-content{max-width:max-content}.content .sub-content button{width:auto;max-width:10rem;height:2.5rem;background:transparent;color:#0fbb6b;display:flex;align-items:center;justify-content:center;text-align:center;text-transform:uppercase;border:none;border-left:2px solid transparent;border-right:2px solid transparent;cursor:pointer;padding:0 1rem;margin-bottom:1rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1) * 1.25)}.content .sub-content button.is-active{background:#0fbb6b14;border-left:2px solid #0fbb6b;border-right:2px solid #0fbb6b}.content .sub-content button:hover{background:#0fbb6b26}.content .radiation-status,.content .effects-status{box-sizing:border-box;display:flex;align-items:center;justify-content:center}.content .actions{box-sizing:border-box;display:flex;align-items:flex-end;max-width:max-content}:host{font-size:inherit}\n",":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.sub-tabs{flex:0 0 auto;min-height:0;margin-bottom:.5rem;padding:0 1rem;position:relative;z-index:1}.sub-tabs>nav{box-sizing:border-box;display:flex;align-items:center;width:100%;height:2.25rem;gap:0}.sub-tabs>nav .center-line{flex:1 1 auto;height:100%;min-width:1.5rem}.sub-tabs>nav>.center-line:last-child .top-half-line:before{left:auto;right:0}.sub-tabs>nav button{background:transparent;border:2px solid transparent;color:#0fbb6b;cursor:pointer;font-size:clamp(1.25rem,1.25rem + (1.5rem - 1.25rem) * (100vw - 360px) / (1200px - 360px),1.5rem);padding:.5rem}.sub-tabs>nav button.is-active{background:#0fbb6b14;border:2px solid #0fbb6b}.sub-tabs>nav button:hover{background:#0fbb6b26}@media(max-width:700px)and (orientation:landscape){.sub-tabs>nav .center-line{min-width:.5rem}}:host{font-size:inherit}\n",':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.tabs{align-items:center;box-sizing:border-box;display:flex;flex-direction:column;flex:0 0 auto;gap:.5rem;max-height:12rem;overflow:hidden;padding:0;position:relative;z-index:5;transition:max-height .35s ease-in-out,padding .35s ease-in-out,gap .35s ease-in-out;width:100%}.tabs.is-collapsed{gap:0;max-height:2rem}.tabs.is-collapsed>nav{opacity:0;pointer-events:none;transform:translateY(100%)}.tabs.is-collapsed .tabs-toggle .caret{transform:translateY(2px) rotate(-135deg)}.tabs .tabs-toggle{align-items:center;background:transparent;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;display:inline-flex;height:2rem;justify-content:center;line-height:0;max-height:2rem;min-height:2rem;overflow:hidden;padding:0 1rem;transition:border-color .2s ease;width:100%}.tabs .tabs-toggle:hover{background-color:#0fbb6b1f}.tabs .tabs-toggle .caret{border:solid #0fbb6b;border-width:0 2px 2px 0;box-sizing:border-box;display:inline-block;height:.6rem;margin:0 .5rem;padding:0;transform:translateY(-4px) rotate(45deg);transform-origin:center;transition:transform .35s ease;width:.6rem}.tabs .tabs-toggle .tabs-toggle-label{font-size:clamp(.7rem,.7rem + (.85rem - .7rem) * (100vw - 360px) / (1200px - 360px),.85rem);letter-spacing:.1em;line-height:1;text-transform:uppercase;white-space:nowrap}.tabs>nav{display:flex;justify-content:center;opacity:1;padding-bottom:.5rem;transform:translateY(0);transition:transform .35s ease-in-out,opacity .35s ease-in-out;transform-origin:bottom;will-change:transform,opacity;width:100%;position:relative}.tabs .tabs-version{bottom:14px;color:#0fbb6bbf;font-size:10px;letter-spacing:.08em;position:absolute;right:22px}.tabs .tabs-actions{align-items:center;display:flex;gap:.5rem;left:1rem;position:absolute;top:50%;transform:translateY(-50%)}.tabs .tabs-actions.right,.tabs .tabs-actions.tabs-actions--right{left:auto;right:1rem}.tabs .tabs-actions .tabs-actions-toggle{align-items:center;background:transparent;border:1px solid rgba(15,187,107,.6);border-radius:9999px;color:#0fbb6b;cursor:pointer;display:none;height:2.1rem;justify-content:center;padding:0 .6rem;text-transform:uppercase;width:2.4rem}.tabs .tabs-actions .tabs-actions-toggle:hover{background:#0fbb6b1f;border-color:#0fbb6b}.tabs .tabs-actions .tabs-actions-icon{background:#0fbb6b;border-radius:9999px;display:block;height:2px;position:relative;width:1.1rem}.tabs .tabs-actions .tabs-actions-icon:before,.tabs .tabs-actions .tabs-actions-icon:after{content:"";background:#0fbb6b;border-radius:9999px;height:2px;left:0;position:absolute;width:100%}.tabs .tabs-actions .tabs-actions-icon:before{top:-5px}.tabs .tabs-actions .tabs-actions-icon:after{top:5px}.tabs .tabs-actions .tabs-actions-menu{display:flex;gap:.5rem;align-items:center}.tabs .tabs-actions .action-button{background:transparent;border:1px solid rgba(15,187,107,.7);color:#0fbb6bb3;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.25rem .35rem;width:100%;border-radius:1rem;text-align:center}.tabs .tabs-actions .action-button:hover{background:#0fbb6b1f;border-color:#0fbb6b}.tabs .tabs-actions input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.tabs .tabs-action{align-items:center;background:#0fbb6b1a;border:2px solid rgba(15,187,107,.6);border-radius:.4rem;color:#0fbb6b;cursor:pointer;display:inline-flex;font-size:clamp(.65rem,.65rem + (.75rem - .65rem) * (100vw - 360px) / (1200px - 360px),.75rem);height:2.5rem;justify-content:center;letter-spacing:.08em;padding:0 .85rem;text-transform:uppercase;transition:background .2s ease,border-color .2s ease;width:auto}.tabs .tabs-action:hover{background:#0fbb6b2e;border-color:#0fbb6b}.tabs>nav>button{align-items:center;background:transparent;border-radius:9999px;border:2px solid rgba(15,187,107,.35);box-sizing:border-box;color:#0fbb6b;cursor:pointer;display:inline-flex;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);height:5rem;justify-content:center;line-height:1;margin:0 1rem;padding:0;text-transform:uppercase;width:5rem}.tabs>nav>button>span{align-items:center;display:inline-flex;justify-content:center;line-height:1;white-space:nowrap;width:100%;height:100%;border-radius:9999px;padding:0}.tabs>nav>button:hover{border-color:#0fbb6ba6}.tabs>nav>button:hover>span{background:#0fbb6b1f}.tabs>nav>button.is-active{border-color:#0fbb6b}.tabs>nav>button.is-active>span{background:#0fbb6b29}@media(max-width:750px){.tabs .tabs-actions{z-index:5}.tabs .tabs-actions .tabs-actions-toggle{display:inline-flex}.tabs .tabs-actions .tabs-actions-menu{display:none}.tabs .tabs-actions.is-open .tabs-actions-menu{background:#062114f2;border:1px solid rgba(15,187,107,.35);border-radius:.5rem;display:flex;flex-direction:column;gap:.35rem;padding:.5rem;position:absolute;bottom:2.6rem;z-index:1000}.tabs .tabs-actions.tabs-actions--left.is-open .tabs-actions-menu{left:0}.tabs .tabs-actions.tabs-actions--right.is-open .tabs-actions-menu{right:0}.tabs .tabs-actions .action-button{width:100%}}@media(max-width:750px){.tabs{overflow:visible}}:host{font-size:inherit}\n',':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{font-family:Roboto Condensed,sans-serif;font-size:clamp(.95rem,.95rem + (1.15rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.15rem);scrollbar-color:rgba(107,255,153,.6) rgba(6,33,20,.6);scrollbar-width:thin;background-color:#062114;background-image:repeating-linear-gradient(to bottom,#ffffff0a 0 1px,#0000 4px);background-size:100% 6px;animation:scan-lines 6s linear infinite;box-shadow:inset 0 0 24px #0009,inset 0 0 90px #00000073;box-sizing:border-box;color:#0fbb6b;display:block;height:100%;overflow:hidden;position:relative;width:100%;font-size:inherit}:host ::-webkit-scrollbar{width:6px;height:6px}:host ::-webkit-scrollbar-track{background:#06211499}:host ::-webkit-scrollbar-thumb{background:#6bff9999;border-radius:9999px}:host:before{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,#06211400 55%,#00000040 70%,#0009);mix-blend-mode:multiply}@keyframes scan-lines{0%{background-position:0 0}to{background-position:0 60px}}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:0;position:relative;width:100%;display:flex;flex-direction:column;min-height:0}.screen-size-overlay{position:absolute;inset:0;background:#000000d9;color:#0fbb6b;display:flex;align-items:center;justify-content:center;text-align:center;padding:2rem;text-transform:uppercase;font-size:clamp(1.1rem,1.1rem + (1.35rem - 1.1rem) * (100vw - 360px) / (1200px - 360px),1.35rem);z-index:200}.boot-sequence{position:fixed;inset:0;background:#000;display:flex;align-items:center;justify-content:center;pointer-events:auto;z-index:99999}.boot-sequence video{width:100%;height:100%;object-fit:cover}.boot-sequence.is-playing{pointer-events:auto}.boot-sequence__loading{font-size:clamp(.95rem,.95rem + (1.2rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.2rem);letter-spacing:.08em;text-transform:uppercase;color:#0fbb6b}.boot-sequence__prompt{position:absolute;bottom:2rem;left:50%;transform:translate(-50%);font-size:clamp(.95rem,.95rem + (1.2rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.2rem);letter-spacing:.1em;text-transform:uppercase;color:#0fbb6b;background:#0009;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;padding:.4rem .75rem;cursor:pointer}.boot-sequence__prompt:hover{background:#0fbb6b1f;border-color:#0fbb6b}.boot-sequence__close{position:absolute;top:1rem;right:1rem;z-index:1;background:#0009;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;padding:.6rem .95rem;font-size:1.35rem;line-height:1;text-transform:uppercase}.boot-sequence__close:hover{background:#0fbb6b1f;border-color:#0fbb6b}.screen.is-booting ::ng-deep .dialog-backdrop{display:none}.screen.is-booting ::ng-deep .dialog{display:none}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:50%;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.top-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.top-half-line:before{content:"";position:absolute;bottom:50%;top:-1.25rem;width:2px;z-index:2;left:0;background:linear-gradient(to top,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.extra-options{margin-top:0;display:flex;flex-direction:column;font-family:Roboto Mono,monospace;font-size:calc(clamp(1.05rem,1.05rem + .2rem * (100vw - 360px) / 840px,1.25rem) * var(--list-font-scale, 1));align-items:flex-end;gap:.75rem;white-space:nowrap;position:absolute;top:1rem;right:2rem;z-index:3}.extra-options button{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font:inherit;padding:0;white-space:nowrap}.extra-options button:hover{opacity:.8}.extra-options button:disabled,.extra-options button.is-locked{cursor:default}.extra-options .controller-button{font-size:inherit;white-space:nowrap}.extra-options .controller-button .large-par{display:inline;padding-left:.5rem;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));top:-.15rem;position:relative;white-space:nowrap}.map-panel{display:flex;flex:1 1 auto;min-height:0;position:relative;width:100%}.map-view{align-items:flex-start;background:transparent;border:none;color:#0fbb6b;cursor:pointer;display:flex;flex:1 1 auto;justify-content:flex-start;min-height:0;overflow:auto;padding:0;width:100%}.map-view span{letter-spacing:.1em;margin:auto;text-transform:uppercase;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.map-view img{display:block;max-width:none;max-height:none}.map-view.is-locked,.map-view:disabled{cursor:default}.map-view.is-draggable{cursor:grab}.map-view.is-dragging{cursor:grabbing}.map-zoom{display:flex;gap:.5rem;position:absolute;right:1.5rem;top:.5rem;z-index:2}.map-zoom .map-zoom-button{padding:0;width:calc(2rem * var(--list-font-scale, 1))}.map-fit{position:absolute;right:1.5rem;bottom:.5rem;z-index:2}.map-control-button{align-items:center;background:#062114f2;border:1px solid rgba(15,187,107,.65);border-radius:.5rem;color:#0fbb6b;cursor:pointer;display:inline-flex;font-size:calc(clamp(.75rem,.75rem + .15rem * (100vw - 360px) / 840px,.9rem) * var(--list-font-scale, 1));justify-content:center;text-transform:uppercase;height:calc(2rem * var(--list-font-scale, 1));padding:0 calc(.6rem * var(--list-font-scale, 1))}.map-control-button:hover{border-color:#0fbb6b;background:#062114e6}\n'],dependencies:[{kind:"component",type:K,selector:"pip-boy-cnd-status"},{kind:"component",type:te,selector:"pip-boy-eff-layout"},{kind:"component",type:$,selector:"pip-boy-inventory-layout",inputs:["category"]},{kind:"component",type:de,selector:"pip-boy-map-image-modal",inputs:["open","title","imageUrl"],outputs:["closeResult","save"]},{kind:"component",type:se,selector:"pip-boy-music-layout",inputs:["category","waveformColorRgb"]},{kind:"component",type:Q,selector:"pip-boy-name-edit-modal",inputs:["open","title","value","placeholder","allowEmpty","inputType","inputMin","inputStep","showNumberControls"],outputs:["closeResult","save"]},{kind:"component",type:H,selector:"pip-boy-3000-header"},{kind:"component",type:ne,selector:"pip-boy-quests-layout"},{kind:"component",type:X,selector:"pip-boy-radiation-meter"},{kind:"component",type:Y,selector:"pip-boy-reset-confirm-modal",inputs:["open","title","message","confirmLabel","cancelLabel"],outputs:["confirm","closeResult"]},{kind:"component",type:w,selector:"pip-boy-screen-scan-lines",inputs:["replayTimeoutSeconds","screen","scanSpeedSeconds","tailLengthPx","scanColorRgb"]},{kind:"component",type:le,selector:"pip-boy-settings-modal",inputs:["open","scanLinesEnabled","rememberTabOnRefreshEnabled","editLockEnabled","listFontScale","secondaryTabSoundLabel","mainTabSoundLabel","clickSoundLabel","bootVideoLabel"],outputs:["closeResult","save","previewListFontScale","playSecondarySound","playMainSound","playClickSound","playBootVideo"]},{kind:"component",type:G,selector:"pip-boy-stats-layout",inputs:["category","valueLabel","valueMin","valueMax"]},{kind:"component",type:re,selector:"pip-boy-welcome-modal",inputs:["open","listFontScale"],outputs:["closeResult","previewListFontScale"]}]})}e.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"21.1.1",ngImport:e,type:De,decorators:[{type:a,args:[{selector:"pip-boy-3000",standalone:!0,imports:[K,te,$,de,se,Q,H,ne,X,Y,w,le,G,re],providers:[W],template:'<main\n #screen\n class="screen"\n [style.--list-font-scale]="settings.listFontScale()"\n [class.is-booting]="showBootSequence()"\n>\n @if (settings.scanLinesEnabled()) {\n <pip-boy-screen-scan-lines\n [replayTimeoutSeconds]="8"\n [scanSpeedSeconds]="5"\n [screen]="screen"\n [tailLengthPx]="300"\n />\n }\n @if (isScreenTooSmall()) {\n <div class="screen-size-overlay" role="alert" aria-live="assertive">\n Screen is too small.<br />Please rotate to landscape.\n </div>\n }\n @if (showBootSequence()) {\n <div\n class="boot-sequence"\n [class.is-playing]="bootIsPlaying()"\n tabindex="0"\n data-skip-click-sound="true"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n <button\n type="button"\n class="boot-sequence__close"\n aria-label="Close boot sequence"\n data-skip-click-sound="true"\n (click)="finishBootSequence()"\n >\n X\n </button>\n @if (bootVideoPlaybackUrl()) {\n <video\n #bootVideo\n [src]="bootVideoPlaybackUrl()"\n muted\n playsinline\n preload="auto"\n (canplay)="handleBootCanPlay(bootVideo)"\n (click)="playBootVideo(bootVideo, $event)"\n (ended)="finishBootSequence()"\n ></video>\n @if (bootNeedsClick()) {\n <button\n type="button"\n class="boot-sequence__prompt"\n data-skip-click-sound="true"\n (click)="playBootVideo(bootVideo, $event)"\n >\n Click to play\n </button>\n }\n } @else {\n <div class="boot-sequence__loading">Loading boot sequence...</div>\n }\n </div>\n }\n \x3c!-- HEADER --\x3e\n <pip-boy-3000-header />\n \x3c!-- CONTENT --\x3e\n <section class="content">\n @if (state.primary() === \'STATS\') {\n @if (state.secondary() === \'STATUS\') {\n <div class="status-content">\n <nav class="column sub-content" aria-label="Status tabs">\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'CND\'"\n (click)="state.selectTertiary(\'CND\')"\n >\n CND\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'RAD\'"\n (click)="state.selectTertiary(\'RAD\')"\n >\n RAD\n </button>\n <button\n type="button"\n [class.is-active]="state.tertiary() === \'EFF\'"\n (click)="state.selectTertiary(\'EFF\')"\n >\n EFF\n </button>\n </nav>\n @if (state.tertiary() === \'CND\') {\n <pip-boy-cnd-status />\n } @else if (state.tertiary() === \'RAD\') {\n <pip-boy-radiation-meter />\n <div class="extra-options">\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADAWAY\')"\n >\n {{ settings.radAwayLabel() }}\n </button>\n <button\n type="button"\n [class.is-locked]="settings.editLockEnabled()"\n [disabled]="settings.editLockEnabled()"\n (click)="openExtraOptionModal(\'RADX\')"\n >\n {{ settings.radXLabel() }}\n </button>\n </div>\n } @else if (state.tertiary() === \'EFF\') {\n <pip-boy-eff-layout />\n }\n </div>\n } @else if (state.secondary() === \'S.P.E.C.I.A.L.\') {\n <pip-boy-stats-layout\n category="SPECIAL"\n valueLabel="Rating"\n [valueMin]="1"\n [valueMax]="10"\n />\n } @else if (state.secondary() === \'SKILLS\') {\n <pip-boy-stats-layout\n category="SKILLS"\n valueLabel="Skill"\n [valueMin]="0"\n [valueMax]="100"\n />\n } @else if (state.secondary() === \'PERKS\') {\n <pip-boy-stats-layout\n category="PERKS"\n valueLabel="Rank"\n [valueMin]="0"\n />\n } @else if (state.secondary() === \'GENERAL\') {\n <pip-boy-stats-layout category="GENERAL" valueLabel="Value" />\n }\n } @else if (state.primary() === \'ITEMS\') {\n @if (state.secondary() === \'WEAPONS\') {\n <pip-boy-inventory-layout category="WEAPONS" />\n } @else if (state.secondary() === \'APPAREL\') {\n <pip-boy-inventory-layout category="APPAREL" />\n } @else if (state.secondary() === \'AID\') {\n <pip-boy-inventory-layout category="AID" />\n } @else if (state.secondary() === \'MISC\') {\n <pip-boy-inventory-layout category="MISC" />\n } @else if (state.secondary() === \'AMMO\') {\n <pip-boy-inventory-layout category="AMMO" />\n }\n } @else if (state.primary() === \'DATA\') {\n @if (state.secondary() === \'LOCAL MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #localMapView\n [class.is-draggable]="settings.localMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'LOCAL\')"\n >\n @if (settings.localMapImage()) {\n <img\n #localMapImage\n [src]="imageStore.getImageUrl(settings.localMapImage())"\n alt="Local map"\n [style.zoom]="settings.localMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.localMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.localMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'LOCAL\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'LOCAL\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'LOCAL\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'LOCAL\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'WORLD MAP\') {\n <div class="map-panel">\n <button\n type="button"\n class="map-view"\n #worldMapView\n [class.is-draggable]="settings.worldMapImage()"\n [class.is-dragging]="isMapDragging()"\n [class.is-locked]="settings.editLockEnabled()"\n (mousedown)="startMapDrag($event)"\n (mousemove)="onMapDrag($event)"\n (mouseup)="endMapDrag()"\n (mouseleave)="endMapDrag()"\n (click)="openMapImageModal(\'WORLD\')"\n >\n @if (settings.worldMapImage()) {\n <img\n #worldMapImage\n [src]="imageStore.getImageUrl(settings.worldMapImage())"\n alt="World map"\n [style.zoom]="settings.worldMapZoom()"\n />\n } @else {\n <span>\n {{\n settings.editLockEnabled()\n ? \'NO IMAGE\'\n : \'CLICK TO UPLOAD IMAGE\'\n }}\n </span>\n }\n </button>\n @if (settings.worldMapImage()) {\n <div\n class="map-zoom"\n role="group"\n tabindex="0"\n (click)="$event.stopPropagation()"\n (keydown)="$event.stopPropagation()"\n >\n @if (settings.worldMapZoom() !== 1) {\n <button\n type="button"\n class="map-control-button"\n (click)="resetMapZoom(\'WORLD\')"\n >\n Reset\n </button>\n }\n @if (!isMapFit(\'WORLD\')) {\n <button\n type="button"\n class="map-control-button"\n (click)="fitMapZoom(\'WORLD\')"\n >\n Fit\n </button>\n }\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', 0.2)"\n >\n +\n </button>\n <button\n type="button"\n class="map-control-button map-zoom-button"\n (click)="zoomMap(\'WORLD\', -0.2)"\n >\n -\n </button>\n </div>\n }\n </div>\n } @else if (state.secondary() === \'QUESTS\') {\n <pip-boy-quests-layout />\n } @else if (state.secondary() === \'NOTES\') {\n <pip-boy-music-layout category="NOTES" />\n } @else if (state.secondary() === \'RADIO\') {\n <pip-boy-music-layout category="RADIO" />\n }\n }\n </section>\n \x3c!-- SUB TABS --\x3e\n <section class="sub-tabs">\n @if (state.primary() === \'STATS\') {\n <nav aria-label="Stats tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'STATUS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'STATUS\')"\n >\n Status\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'S.P.E.C.I.A.L.\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'S.P.E.C.I.A.L.\')"\n >\n S.P.E.C.I.A.L.\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'SKILLS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'SKILLS\')"\n >\n Skills\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'PERKS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'PERKS\')"\n >\n Perks\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'GENERAL\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'GENERAL\')"\n >\n General\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'ITEMS\') {\n <nav aria-label="Items tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WEAPONS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'WEAPONS\')"\n >\n Weapons\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'APPAREL\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'APPAREL\')"\n >\n Apparel\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AID\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'AID\')"\n >\n Aid\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'MISC\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'MISC\')"\n >\n Misc\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'AMMO\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'AMMO\')"\n >\n Ammo\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n } @else if (state.primary() === \'DATA\') {\n <nav aria-label="Data tabs">\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'LOCAL MAP\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'LOCAL MAP\')"\n >\n Local Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'WORLD MAP\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'WORLD MAP\')"\n >\n World Map\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'QUESTS\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'QUESTS\')"\n >\n Quests\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'NOTES\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'NOTES\')"\n >\n Notes\n </button>\n <div class="center-line"></div>\n <button\n type="button"\n [class.is-active]="state.secondary() === \'RADIO\'"\n data-skip-click-sound="true"\n (click)="selectSecondary(\'RADIO\')"\n >\n Radio\n </button>\n <div class="center-line">\n <div class="top-half-line"></div>\n </div>\n </nav>\n }\n </section>\n \x3c!-- MAIN TABS --\x3e\n <section class="tabs" [class.is-collapsed]="!tabsOpen()">\n <button\n type="button"\n class="tabs-toggle"\n aria-label="Toggle main tabs"\n [attr.aria-expanded]="tabsOpen()"\n aria-controls="main-tabs"\n data-skip-click-sound="true"\n (click)="toggleTabs()"\n >\n <span class="tabs-toggle-label tabs-toggle-label--state">\n {{ tabsOpen() ? \'CLOSE\' : \'OPEN\' }}\n </span>\n <span class="caret" aria-hidden="true"></span>\n <span class="tabs-toggle-label tabs-toggle-label--menu">MENU</span>\n </button>\n <nav id="main-tabs" aria-label="Main tabs">\n <div\n class="tabs-actions tabs-actions--left"\n [class.is-open]="tabsActionsLeftOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open settings actions"\n (click)="toggleTabsActions(\'left\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Save settings"\n title="Save settings"\n (click)="saveSettingsToFile()"\n >\n Save\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Load settings"\n title="Load settings"\n (click)="loadSettingsInput.click()"\n >\n Load\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Reset settings"\n title="Reset settings"\n (click)="openResetModal()"\n >\n Reset\n </button>\n <input\n #loadSettingsInput\n type="file"\n accept=".zip,application/zip"\n (change)="loadSettingsFromFile($event)"\n />\n </div>\n </div>\n <button\n type="button"\n [class.is-active]="state.primary() === \'STATS\'"\n data-skip-click-sound="true"\n (click)="selectPrimary(\'STATS\')"\n >\n <span>STATS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'ITEMS\'"\n data-skip-click-sound="true"\n (click)="selectPrimary(\'ITEMS\')"\n >\n <span>ITEMS</span>\n </button>\n <button\n type="button"\n [class.is-active]="state.primary() === \'DATA\'"\n data-skip-click-sound="true"\n (click)="selectPrimary(\'DATA\')"\n >\n <span>DATA</span>\n </button>\n <div\n class="tabs-actions tabs-actions--right"\n [class.is-open]="tabsActionsRightOpen()"\n >\n <button\n type="button"\n class="tabs-actions-toggle"\n aria-label="Open utility actions"\n (click)="toggleTabsActions(\'right\')"\n >\n <span class="tabs-actions-icon" aria-hidden="true"></span>\n </button>\n <div class="tabs-actions-menu">\n <button\n type="button"\n class="action-button"\n aria-label="Open GitHub profile"\n title="Open GitHub profile"\n (click)="openGithubProfile()"\n >\n ❤\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Open settings"\n title="Settings"\n (click)="openSettingsModal()"\n >\n Settings\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Report a bug"\n title="Report a bug"\n (click)="openBugModal()"\n >\n Bug\n </button>\n <button\n type="button"\n class="action-button"\n aria-label="Exit"\n title="Exit"\n (click)="openExitModal()"\n >\n Exit\n </button>\n </div>\n </div>\n @if (tabsOpen()) {\n <div class="tabs-version">v{{ appVersion }}</div>\n }\n </nav>\n </section>\n <pip-boy-welcome-modal\n [open]="showWelcomeModal() && !showBootSequence()"\n [listFontScale]="settings.listFontScale()"\n (previewListFontScale)="previewListFontScale($event)"\n (closeResult)="closeWelcomeModal()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showResetModal()"\n title="Reset Settings"\n message="This will reset all values back to defaults. This cannot be undone."\n confirmLabel="Reset"\n (closeResult)="closeResetModal()"\n (confirm)="confirmReset()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showExitModal()"\n title="Exit"\n message="Are you sure you want to leave this screen?"\n confirmLabel="Exit"\n (closeResult)="closeExitModal()"\n (confirm)="confirmExit()"\n />\n <pip-boy-reset-confirm-modal\n [open]="showBugModal()"\n title="Report a bug"\n message="Would you like to report a bug?"\n confirmLabel="Yes"\n cancelLabel="No"\n (closeResult)="closeBugModal()"\n (confirm)="confirmBugReport()"\n />\n <pip-boy-map-image-modal\n [open]="mapImageModal() !== null"\n [title]="mapImageModalTitle()"\n [imageUrl]="mapImageModalImage()"\n (closeResult)="closeMapImageModal()"\n (save)="saveMapImageModal($event)"\n />\n <pip-boy-settings-modal\n [open]="showSettingsModal()"\n [scanLinesEnabled]="settings.scanLinesEnabled()"\n [rememberTabOnRefreshEnabled]="settings.rememberTabOnRefresh()"\n [editLockEnabled]="settings.editLockEnabled()"\n [listFontScale]="settings.listFontScale()"\n [secondaryTabSoundLabel]="secondaryTabSoundLabel()"\n [mainTabSoundLabel]="mainTabSoundLabel()"\n [clickSoundLabel]="clickSoundLabel()"\n [bootVideoLabel]="bootVideoLabel()"\n (closeResult)="cancelSettingsModal()"\n (previewListFontScale)="previewListFontScale($event)"\n (playSecondarySound)="previewSecondaryTabSound()"\n (playMainSound)="previewMainTabSound()"\n (playClickSound)="previewClickSound()"\n (playBootVideo)="previewBootVideo($event)"\n (save)="saveSettingsModal($event)"\n />\n <pip-boy-name-edit-modal\n [open]="extraOptionModal() !== null"\n [value]="extraOptionValue()"\n [title]="extraOptionTitle()"\n placeholder="Value"\n [allowEmpty]="true"\n (closeResult)="closeExtraOptionModal()"\n (save)="saveExtraOptionModal($event)"\n />\n</main>\n',styles:[":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.content{box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;height:100%;overflow:auto;padding:1rem 2rem;position:relative;width:100%}.content .status-content{box-sizing:border-box;display:flex;flex-direction:row;height:100%;gap:1rem}.content .column{box-sizing:border-box;display:flex;flex:1;flex-direction:column}.content .sub-content{max-width:max-content}.content .sub-content button{width:auto;max-width:10rem;height:2.5rem;background:transparent;color:#0fbb6b;display:flex;align-items:center;justify-content:center;text-align:center;text-transform:uppercase;border:none;border-left:2px solid transparent;border-right:2px solid transparent;cursor:pointer;padding:0 1rem;margin-bottom:1rem;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1) * 1.25)}.content .sub-content button.is-active{background:#0fbb6b14;border-left:2px solid #0fbb6b;border-right:2px solid #0fbb6b}.content .sub-content button:hover{background:#0fbb6b26}.content .radiation-status,.content .effects-status{box-sizing:border-box;display:flex;align-items:center;justify-content:center}.content .actions{box-sizing:border-box;display:flex;align-items:flex-end;max-width:max-content}:host{font-size:inherit}\n",":host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.sub-tabs{flex:0 0 auto;min-height:0;margin-bottom:.5rem;padding:0 1rem;position:relative;z-index:1}.sub-tabs>nav{box-sizing:border-box;display:flex;align-items:center;width:100%;height:2.25rem;gap:0}.sub-tabs>nav .center-line{flex:1 1 auto;height:100%;min-width:1.5rem}.sub-tabs>nav>.center-line:last-child .top-half-line:before{left:auto;right:0}.sub-tabs>nav button{background:transparent;border:2px solid transparent;color:#0fbb6b;cursor:pointer;font-size:clamp(1.25rem,1.25rem + (1.5rem - 1.25rem) * (100vw - 360px) / (1200px - 360px),1.5rem);padding:.5rem}.sub-tabs>nav button.is-active{background:#0fbb6b14;border:2px solid #0fbb6b}.sub-tabs>nav button:hover{background:#0fbb6b26}@media(max-width:700px)and (orientation:landscape){.sub-tabs>nav .center-line{min-width:.5rem}}:host{font-size:inherit}\n",':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}.tabs{align-items:center;box-sizing:border-box;display:flex;flex-direction:column;flex:0 0 auto;gap:.5rem;max-height:12rem;overflow:hidden;padding:0;position:relative;z-index:5;transition:max-height .35s ease-in-out,padding .35s ease-in-out,gap .35s ease-in-out;width:100%}.tabs.is-collapsed{gap:0;max-height:2rem}.tabs.is-collapsed>nav{opacity:0;pointer-events:none;transform:translateY(100%)}.tabs.is-collapsed .tabs-toggle .caret{transform:translateY(2px) rotate(-135deg)}.tabs .tabs-toggle{align-items:center;background:transparent;border:none;box-sizing:border-box;color:#0fbb6b;cursor:pointer;display:inline-flex;height:2rem;justify-content:center;line-height:0;max-height:2rem;min-height:2rem;overflow:hidden;padding:0 1rem;transition:border-color .2s ease;width:100%}.tabs .tabs-toggle:hover{background-color:#0fbb6b1f}.tabs .tabs-toggle .caret{border:solid #0fbb6b;border-width:0 2px 2px 0;box-sizing:border-box;display:inline-block;height:.6rem;margin:0 .5rem;padding:0;transform:translateY(-4px) rotate(45deg);transform-origin:center;transition:transform .35s ease;width:.6rem}.tabs .tabs-toggle .tabs-toggle-label{font-size:clamp(.7rem,.7rem + (.85rem - .7rem) * (100vw - 360px) / (1200px - 360px),.85rem);letter-spacing:.1em;line-height:1;text-transform:uppercase;white-space:nowrap}.tabs>nav{display:flex;justify-content:center;opacity:1;padding-bottom:.5rem;transform:translateY(0);transition:transform .35s ease-in-out,opacity .35s ease-in-out;transform-origin:bottom;will-change:transform,opacity;width:100%;position:relative}.tabs .tabs-version{bottom:14px;color:#0fbb6bbf;font-size:10px;letter-spacing:.08em;position:absolute;right:22px}.tabs .tabs-actions{align-items:center;display:flex;gap:.5rem;left:1rem;position:absolute;top:50%;transform:translateY(-50%)}.tabs .tabs-actions.right,.tabs .tabs-actions.tabs-actions--right{left:auto;right:1rem}.tabs .tabs-actions .tabs-actions-toggle{align-items:center;background:transparent;border:1px solid rgba(15,187,107,.6);border-radius:9999px;color:#0fbb6b;cursor:pointer;display:none;height:2.1rem;justify-content:center;padding:0 .6rem;text-transform:uppercase;width:2.4rem}.tabs .tabs-actions .tabs-actions-toggle:hover{background:#0fbb6b1f;border-color:#0fbb6b}.tabs .tabs-actions .tabs-actions-icon{background:#0fbb6b;border-radius:9999px;display:block;height:2px;position:relative;width:1.1rem}.tabs .tabs-actions .tabs-actions-icon:before,.tabs .tabs-actions .tabs-actions-icon:after{content:"";background:#0fbb6b;border-radius:9999px;height:2px;left:0;position:absolute;width:100%}.tabs .tabs-actions .tabs-actions-icon:before{top:-5px}.tabs .tabs-actions .tabs-actions-icon:after{top:5px}.tabs .tabs-actions .tabs-actions-menu{display:flex;gap:.5rem;align-items:center}.tabs .tabs-actions .action-button{background:transparent;border:1px solid rgba(15,187,107,.7);color:#0fbb6bb3;cursor:pointer;font-size:clamp(.75rem,.75rem + (.9rem - .75rem) * (100vw - 360px) / (1200px - 360px),.9rem);padding:.25rem .35rem;width:100%;border-radius:1rem;text-align:center}.tabs .tabs-actions .action-button:hover{background:#0fbb6b1f;border-color:#0fbb6b}.tabs .tabs-actions input[type=file]{height:1px;opacity:0;overflow:hidden;position:absolute;width:1px}.tabs .tabs-action{align-items:center;background:#0fbb6b1a;border:2px solid rgba(15,187,107,.6);border-radius:.4rem;color:#0fbb6b;cursor:pointer;display:inline-flex;font-size:clamp(.65rem,.65rem + (.75rem - .65rem) * (100vw - 360px) / (1200px - 360px),.75rem);height:2.5rem;justify-content:center;letter-spacing:.08em;padding:0 .85rem;text-transform:uppercase;transition:background .2s ease,border-color .2s ease;width:auto}.tabs .tabs-action:hover{background:#0fbb6b2e;border-color:#0fbb6b}.tabs>nav>button{align-items:center;background:transparent;border-radius:9999px;border:2px solid rgba(15,187,107,.35);box-sizing:border-box;color:#0fbb6b;cursor:pointer;display:inline-flex;font-size:clamp(.85rem,.85rem + (1rem - .85rem) * (100vw - 360px) / (1200px - 360px),1rem);height:5rem;justify-content:center;line-height:1;margin:0 1rem;padding:0;text-transform:uppercase;width:5rem}.tabs>nav>button>span{align-items:center;display:inline-flex;justify-content:center;line-height:1;white-space:nowrap;width:100%;height:100%;border-radius:9999px;padding:0}.tabs>nav>button:hover{border-color:#0fbb6ba6}.tabs>nav>button:hover>span{background:#0fbb6b1f}.tabs>nav>button.is-active{border-color:#0fbb6b}.tabs>nav>button.is-active>span{background:#0fbb6b29}@media(max-width:750px){.tabs .tabs-actions{z-index:5}.tabs .tabs-actions .tabs-actions-toggle{display:inline-flex}.tabs .tabs-actions .tabs-actions-menu{display:none}.tabs .tabs-actions.is-open .tabs-actions-menu{background:#062114f2;border:1px solid rgba(15,187,107,.35);border-radius:.5rem;display:flex;flex-direction:column;gap:.35rem;padding:.5rem;position:absolute;bottom:2.6rem;z-index:1000}.tabs .tabs-actions.tabs-actions--left.is-open .tabs-actions-menu{left:0}.tabs .tabs-actions.tabs-actions--right.is-open .tabs-actions-menu{right:0}.tabs .tabs-actions .action-button{width:100%}}@media(max-width:750px){.tabs{overflow:visible}}:host{font-size:inherit}\n',':host,:host button,:host input,:host select,:host textarea{font-family:Roboto Mono,monospace;line-height:1}:host{font-family:Roboto Condensed,sans-serif;font-size:clamp(.95rem,.95rem + (1.15rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.15rem);scrollbar-color:rgba(107,255,153,.6) rgba(6,33,20,.6);scrollbar-width:thin;background-color:#062114;background-image:repeating-linear-gradient(to bottom,#ffffff0a 0 1px,#0000 4px);background-size:100% 6px;animation:scan-lines 6s linear infinite;box-shadow:inset 0 0 24px #0009,inset 0 0 90px #00000073;box-sizing:border-box;color:#0fbb6b;display:block;height:100%;overflow:hidden;position:relative;width:100%;font-size:inherit}:host ::-webkit-scrollbar{width:6px;height:6px}:host ::-webkit-scrollbar-track{background:#06211499}:host ::-webkit-scrollbar-thumb{background:#6bff9999;border-radius:9999px}:host:before{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,#06211400 55%,#00000040 70%,#0009);mix-blend-mode:multiply}@keyframes scan-lines{0%{background-position:0 0}to{background-position:0 60px}}.screen{box-sizing:border-box;height:100%;overflow:hidden;padding:0;position:relative;width:100%;display:flex;flex-direction:column;min-height:0}.screen-size-overlay{position:absolute;inset:0;background:#000000d9;color:#0fbb6b;display:flex;align-items:center;justify-content:center;text-align:center;padding:2rem;text-transform:uppercase;font-size:clamp(1.1rem,1.1rem + (1.35rem - 1.1rem) * (100vw - 360px) / (1200px - 360px),1.35rem);z-index:200}.boot-sequence{position:fixed;inset:0;background:#000;display:flex;align-items:center;justify-content:center;pointer-events:auto;z-index:99999}.boot-sequence video{width:100%;height:100%;object-fit:cover}.boot-sequence.is-playing{pointer-events:auto}.boot-sequence__loading{font-size:clamp(.95rem,.95rem + (1.2rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.2rem);letter-spacing:.08em;text-transform:uppercase;color:#0fbb6b}.boot-sequence__prompt{position:absolute;bottom:2rem;left:50%;transform:translate(-50%);font-size:clamp(.95rem,.95rem + (1.2rem - .95rem) * (100vw - 360px) / (1200px - 360px),1.2rem);letter-spacing:.1em;text-transform:uppercase;color:#0fbb6b;background:#0009;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;padding:.4rem .75rem;cursor:pointer}.boot-sequence__prompt:hover{background:#0fbb6b1f;border-color:#0fbb6b}.boot-sequence__close{position:absolute;top:1rem;right:1rem;z-index:1;background:#0009;border:1px solid rgba(15,187,107,.5);border-radius:.5rem;color:#0fbb6b;cursor:pointer;padding:.6rem .95rem;font-size:1.35rem;line-height:1;text-transform:uppercase}.boot-sequence__close:hover{background:#0fbb6b1f;border-color:#0fbb6b}.screen.is-booting ::ng-deep .dialog-backdrop{display:none}.screen.is-booting ::ng-deep .dialog{display:none}.center-line{position:relative;height:100%;overflow:visible}.center-line:before{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:2px;background:#0fbb6b}.bottom-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.bottom-half-line:before{content:"";position:absolute;top:50%;bottom:-1.25rem;width:2px;z-index:2;background:linear-gradient(to bottom,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.top-half-line{position:absolute;inset:0;pointer-events:none;overflow:visible}.top-half-line:before{content:"";position:absolute;bottom:50%;top:-1.25rem;width:2px;z-index:2;left:0;background:linear-gradient(to top,#0fbb6b,#0fbb6ba6 18%,#0fbb6b59 40%,#0fbb6b26 65%,#0fbb6b00)}.extra-options{margin-top:0;display:flex;flex-direction:column;font-family:Roboto Mono,monospace;font-size:calc(clamp(1.05rem,1.05rem + .2rem * (100vw - 360px) / 840px,1.25rem) * var(--list-font-scale, 1));align-items:flex-end;gap:.75rem;white-space:nowrap;position:absolute;top:1rem;right:2rem;z-index:3}.extra-options button{background:transparent;border:none;color:#0fbb6b;cursor:pointer;font:inherit;padding:0;white-space:nowrap}.extra-options button:hover{opacity:.8}.extra-options button:disabled,.extra-options button.is-locked{cursor:default}.extra-options .controller-button{font-size:inherit;white-space:nowrap}.extra-options .controller-button .large-par{display:inline;padding-left:.5rem;font-size:calc(clamp(1.45rem,1.45rem + .3rem * (100vw - 360px) / 840px,1.75rem) * var(--list-font-scale, 1));top:-.15rem;position:relative;white-space:nowrap}.map-panel{display:flex;flex:1 1 auto;min-height:0;position:relative;width:100%}.map-view{align-items:flex-start;background:transparent;border:none;color:#0fbb6b;cursor:pointer;display:flex;flex:1 1 auto;justify-content:flex-start;min-height:0;overflow:auto;padding:0;width:100%}.map-view span{letter-spacing:.1em;margin:auto;text-transform:uppercase;font-size:calc(clamp(.95rem,.95rem + .2rem * (100vw - 360px) / 840px,1.15rem) * var(--list-font-scale, 1))}.map-view img{display:block;max-width:none;max-height:none}.map-view.is-locked,.map-view:disabled{cursor:default}.map-view.is-draggable{cursor:grab}.map-view.is-dragging{cursor:grabbing}.map-zoom{display:flex;gap:.5rem;position:absolute;right:1.5rem;top:.5rem;z-index:2}.map-zoom .map-zoom-button{padding:0;width:calc(2rem * var(--list-font-scale, 1))}.map-fit{position:absolute;right:1.5rem;bottom:.5rem;z-index:2}.map-control-button{align-items:center;background:#062114f2;border:1px solid rgba(15,187,107,.65);border-radius:.5rem;color:#0fbb6b;cursor:pointer;display:inline-flex;font-size:calc(clamp(.75rem,.75rem + .15rem * (100vw - 360px) / 840px,.9rem) * var(--list-font-scale, 1));justify-content:center;text-transform:uppercase;height:calc(2rem * var(--list-font-scale, 1));padding:0 calc(.6rem * var(--list-font-scale, 1))}.map-control-button:hover{border-color:#0fbb6b;background:#062114e6}\n']}]}],propDecorators:{returnToUrl:[{type:e.Input,args:[{isSignal:!0,alias:"returnToUrl",required:!1}]}],localMapImage:[{type:e.ViewChild,args:["localMapImage",{isSignal:!0}]}],worldMapImage:[{type:e.ViewChild,args:["worldMapImage",{isSignal:!0}]}],localMapView:[{type:e.ViewChild,args:["localMapView",{isSignal:!0}]}],worldMapView:[{type:e.ViewChild,args:["worldMapView",{isSignal:!0}]}],onResize:[{type:h,args:["window:resize"]}]}});export{x as PipBoy2000MkVI,De as PipBoy3000,Re as PipBoy3000MkIV,W as PipBoy3000State,Le as PipBoy3000a};