!function(){"use strict";function e(e,t){return function(o){let n=e(o);return n?t(n.result)(n.toks):null}}function t(t,o){for(let o=1;o"string"==typeof e?m(e):e));return function(o){return t(e[0](o),...e.slice(1))}}function n(){let e=Array.from(arguments).map((e=>"string"==typeof e?m(e):e));return function(t){let o=e.map((e=>e(t)));return function(){let e=!1;for(var t=0;t1?o(...arguments):e)?m(e):e,function(t){return function(o){let n=e(t)(o);return n?{toks:n.toks,result:t}:null}}}function l(e){return f unction(t){return function(o){let n=e([])(o);return n?{toks:n.toks,result:[...t,n.result.join(" ")]}:null}}}function h(e){return function(t){return{toks:t,result:e}}}function d(e){return function(t){return h(e)}}function u(e){return o(n(c,i(m("."))),function(e){return function(t){let o=e(t);return null!==o?h(o):()=>null}}(e),d([]))}function c(e){return function(t){return 0==t.length?{toks:[],result:e}:null}}function m(e,t=e){return e.split(" ").length>1?o(...e.split(" "),d([t])):function(o){return function(n){return n[0]==e?{toks:n.slice(1),result:o.slice().concat([t])}:null}}}function g(e="inReach"){return function(t){return function(o){["the","a","an"].includes(o[0])&&o.shift();let n=null,a=o.length+1;for(;null==n&&a>1;){a--;let t=o.slice(0,a).join(" ");n="NPCs"==e?ke.findNPC(t):ke.findObj(t,e)}return n?{toks:o.slice(a),result:t.slice().concat(n)}:null}}}function y(e,t){return o(s=t?n(g(e),A):g(e),a(o(i(n(", and",",","and")),s)));var s}function f(e="inReach",t=!0){return n(o(m("all"),i(n("but","except")),y (e,t)),y(e,t))}function p(e){return function(t){return function(o){return o.length>0&&o[0].match(e)?{toks:o.slice(1),result:t.slice().concat([o[0]])}:null}}}function b(e){return n(m(e),m(e[0],e))}function w(){let e=Array.from(arguments).map((e=>m(e,arguments[0])));return n.apply(null,e)}const k=p(new RegExp("^(?!"+["and","about","with","on","in","up","to","into","for","from","out"].map((e=>`\\b${e}\\b`)).join("|")+")(\\w|')+$"));let v=n("the",w("an","a")),$=l(s(k)),A=o(i(r(v)),$),Y=[],I=function(){let e={addRaw:e=>Y.push(e),shiftRaw:e=>Y.unshift(e),addVerb:function(e,{action:t=e,synonyms:a=[],codKind:h="object",codScope:d="inReach",codMayFail:c=!1,defaultCod:y=null,coiKind:f=null,coiScope:b=null,coiMayFail:w=!1,prepositions:k=null,flipCodCoi:v=!1,alsoInDeadPrompt:$=!1}={}){let I=[i(n(e,...a))];if("object"==h&&d){let e=g(d);c&&(e=n(e,A)),I.push(e)}if("string"==h&&I.push(r(l(s(p(/.*/))),y)),"thing"==h&&I.push(A),k&&I.push(i(n(...k))),b){let e=g(b);w&&(e=n(e,A)),I.push(e)}"thing"==f&&I.push(A),I.push(u((([e,o]) =>{v&&([e,o]=[o,e]),"string"==typeof t?ke.dispatchP(t,e,o):t(e,o)}))),Y.push(o(...I)),$&&m.push(o(...I))}};const t=Object.freeze({normal:1,yesno:2,dead:3});e.Modes=t;let a=t.normal;e.isNormal=()=>a==t.normal;let h,d,c,m=[];e.die=function(){a=t.dead},e.normal=()=>{a=t.normal},Object.defineProperty(e,"mode",{get:()=>a}),e.yesno=function(e,o="Yes or no?",n=(()=>{})){a=t.yesno,h=e,d=n,c=o};let y=o(n(w("yes","y","yeah","yep","sure","yup","aye"),w("no","n","nope","nah")),u((e=>(a=t.normal,"yes"==e?(h(),ke.pushUndoRecord(),!0):(d(),ke.pushUndoRecord(),!1)))));return Object.defineProperty(e,"failMsg",{get:()=>{switch(a){case t.normal:return"#.softError{I don't understand.}";case t.yesno:return c;case t.dead:return ke.deadPrompt;default:throw new Error("Unexpected parser mode")}}}),e.parse=function(r){e.rawStr=r;let i=function(e){return e.split(/(\s|\.|,|;)/).map((e=>e.trim().toLowerCase())).filter((e=>""!=e))}(r);if(0==i.length)return!0;let l,h=o(A,u((e=>ke.disamb(e[0]))));switch(ce("lexer",i),a){case t.normal:l=n(h ,...Y);break;case t.yesno:l=y;break;case t.dead:l=n(...m);break;default:throw new Error("Unexpected parser mode")}return!!s(l)([])(i)},e}();function T(){return Math.random()}function S(e){return arguments.length>1&&(e=arguments),e[Math.floor(Math.random()*e.length)]}function x(e){for(let t=e.length-1;t>0;--t){const o=Math.floor(Math.random()*(t+1)),n=e[o];e[o]=e[t],e[t]=n}}function E(e,t=!1){let o=t?-1:e.length;return()=>{if(++o,o>=e.length){let t=P(e);O((()=>e[0]!=t),(()=>x(e)),!0,10),o=0}return e[o]}}function N(e,t="and"){return j(e.every((e=>"string"==typeof e))),1==e.length?e[0]:e.slice(0,-1).join(", ")+(e.length>2?", ":" ")+t+" "+P(e)}function V(e){return e[0].toUpperCase()+e.slice(1)}function P(e){return e[e.length-1]}function O(e,t,o=!1,n=2e3){for(let o=0;ot. includes(e)));return 1!=t.length?null:t[0].filter((t=>t!=e))[0]}function H(e){return"a"+("aioe".includes(e[0])?"n ":" ")+e}function j(e,t="Assertion failed"){if(!e)throw new D(t)}class D extends Error{}let M=0;function R(){return"o"+M++}const F={classList:{add:()=>{}},style:{}};let U=e=>{try{return document.getElementById(e)}catch(e){return F}};function L(e){return"string"==typeof e?()=>W.msg(e):e}function B(e){return class extends e{constructor(){super(...arguments),this.beforeHooks={},this.afterHooks={}}addBeforeHook(e,t){this.beforeHooks[e]||(this.beforeHooks[e]=[]),this.beforeHooks[e].push(L(t))}doBeforeHooks(e,...t){return this.beforeHooks[e]?this.beforeHooks[e].map((e=>e.call(this,...t))):[]}addAfterHook(e,t){this.afterHooks[e]||(this.afterHooks[e]=[]),this.afterHooks[e].push(L(t))}doAfterHooks(e,...t){return this.afterHooks[e]?this.afterHooks[e].map((e=>e.call(this,...t))):[]}}}function q(e,t){return new Proxy({},{set:(e,o,n)=>(be(),ae(o,...t,n),!0),get:(t,o)=>(be(),new Proxy({},{set(t,n,a){if("before "===n)e.addBeforeHook(o,a);else{if("after"!==n)throw new Error("Bad A call");e.addAfterHook(o,a)}return!0}}))})}const W=new(B(class{}));let z=0;I.addVerb(";",{action:e=>{return t=e,U(`ex${z}`).insertAdjacentHTML("beforeend",`
${t}
`),void W.msg("Noted","meta");var t},codKind:"string",alsoInDeadPrompt:!0}),I.addVerb("dump",{synonyms:["transcript"],codKind:"string",defaultCod:"transcript",action:e=>function(e){let t=""+U("transcript").innerHTML,o=new File([t],e+".html",{type:"octet/stream"}),n=URL.createObjectURL(o),a=document.createElement("a");return a.href=n,a.download=e+".html",a.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0,view:window})),W.msg("Transcript dumped","meta"),!0}(e),alsoInDeadPrompt:!0});let _="";function K(){let e=`
${_}
`;U("transcri pt").insertAdjacentHTML("beforeend",e),function(e){let t=U(e).style;t.opacity=0;const o=performance.now();!function e(n){t.opacity=(n-o)/600,t.opacity>=1?t.opacity=1:requestAnimationFrame(e)}()}("ex"+z),W.doAfterHooks("commit",U("ex"+z)),function(){const e=document.scrollingElement,t=e.scrollHeight-e.clientHeight,o=e.scrollTop,n=t-o,a=performance.now();let s=o;!function r(i){var l;if(!(Math.abs(s-e.scrollTop)>2)&&e.scrollTop{for(let e=1;e<=z;++e)U("ex"+e).classList.add("cleared")};let G=[e=>e.replace(/#fn\{([^]*?)\}/gi,"$1"),e=>e.replace(/#\.(.*?)\{([^]*?)\}/gi,"$2"),e=>e.replace(/#quote\{([^]*?)\}/gi,"
$1
"),e=>e.replace(/``/gi,"“"),e=>e.replace(/''/gi,"”"),e=>e.replace(/\n/gi,"
"),e=>e.replace(/<\/div>
/gi,"")]; W.addProcessor=(e,t)=>{G.unshift((o=>o.replace(e,t)))},W.msg=function(e,t,o,n="
"){"string"!=typeof e&&(e=e.toString()),e.endsWith("<>")&&(n="",e=e.slice(0,-2)),e.startsWith("<>")&&(e=e.slice(2),_.endsWith("
")&&(_=_.slice(0,-4))),t||o||!/[a-z]/i.test(P(e))||(e+="."),"echo"==t&&(e=``),"loc"==t&&(e=''+e+""),"meta"==t&&(e='['+e+"]"),"implied"==t&&(e='('+e+")"),"error"==t&&(e=''+e+""),_+=function(e){for(let t of G)e=t(e);return e}(e+n)};let J=null;W.hasPendingAction=()=>null!=J,W.wait=function(e,t){U("inputArea").style.opacity="0";const o=te;W.setInputFunc(Z),J={action:()=>{U("inputArea").style.opacity=1,W.setInputFunc(o),J=null,e(),K()},key:t}},W.lock=e=>W.wait(e,"timer"),W.unlock=()=>te({key:"timer",preventDefault:()=>{}}),W.doCmd=function(e){e.split(".").filter((e=>""!=e.trim())).forEach((e=>{W.msg(e,"echo"),I.parse(e)||W.msg(I.failMsg)})),K( )},W.save=(e,t)=>{try{return localStorage.setItem(e,JSON.stringify(t)),!0}catch(e){return!1}},W.restore=e=>{try{return JSON.parse(localStorage.getItem(e))}catch(e){return null}},W.listSaves=()=>{let e=[];for(let t=0;t()=>{U("prompt").classList.remove("yn"),e()};I.yesno(n(e),t,n(o)),U("prompt").classList.add("yn")},W.begin=function(){let e=U("echo");document.getElementsByTagName("body")[0].addEventListener("keydown",(t=>{t.metaKey||"Control"==t.key||(e.focus(),te(t))})),window.addEventListener("popstate",(e=>{e.state&&(W.clear(),W.msg("UNDO","echo"),ke.meta.undo(),W.commit())})),e.focus(),I.parse("look"),K()};const oe={};class ne{constructor(e,t,o,n){this.action=e,this.codKind=t,this.coiKind=o,this.room=n,this.score=ne.score(t,o,n)}static scorePattern(e){let t=0;if(null===e&&(t+=2),"all"===e&&(t+=5),"string"==typeof e&&(t+=1),"function"==typeof e){let o=e;for(;o;)o=Object.getPro totypeOf(o),t+=1}return e instanceof re&&(t+=20),t}static score(e,t,o){let n=0;return"*"!=o&&(n+=10),n+=ne.scorePattern(e),n+=ne.scorePattern(t),n}static checkPattern(e,t){return"*"===t||(null==t?null==e:"string"===t?"string"==typeof e:"array"===t?Array.isArray(e):"function"==typeof t?e instanceof t:t===e)}check(e,t,o){return("*"==this.room||this.room==o)&&ne.checkPattern(e,this.codKind)&&ne.checkPattern(t,this.coiKind)}}function ae(e,...t){const o=t.pop();let[n=null,a=null,s="*"]=t;"string"!=typeof s&&(s=s.id),oe[e]||(oe[e]=[]),Array.isArray(n)||(n=[n]),Array.isArray(a)||(a=[a]),n.forEach((t=>a.forEach((n=>oe[e].push(new ne(o,t,n,s))))))}function se(e,t,o,n,a,s=null,r="$YOU don't see $acoi here"){ae(e,"array",s,((t,a)=>{if(t.length>0&&"all"==t[0]){const s=ke.lastUsedItem;let r=(o(a)||[]).filter((e=>e.includedInAll())).filter((e=>!t.slice(1).includes(e)));0==r.length?W.msg(n):ke.dispatch(e,r,a),ke.lastUsedItem=s}else t.forEach((o=>{t.length>1&&W.msg(V(o.defName||o),"implied",!0," "),ke.dispatch(e,o,a)}))})), ae(e,"string",s,a),s==re&&ae(e,"*","string",r),ae(e,re,s,t)}let re=B(class{constructor(e,t,{id:o=R()}={}){if(this.id=o,ke.objects[o])throw new Error("Duplicate definition");ke.objects[o]=this,Array.isArray(e)||(e=[e]),this.names=e,this.desc=t,this.showInList=()=>!0,this.includedInAll=()=>this.showInList(),this.isPlural="s"==P(e[0])}msg(e){ke.getItems().includes(this)&&W.msg(e)}details(){return(this.$.details||[]).map((e=>ke.objects[e]))}get defName(){return this.defOverride?"function"==typeof this.defOverride?this.defOverride():this.defOverride:"the "+this.names[0]}set defName(e){this.defOverride=e}get indefName(){if(this.indefOverride)return this.indefOverride;let e=this.names[0];return void 0!==this.$.open&&(e=(this.$.open?"open ":"closed ")+e),this.isPlural?"some "+e:H(e)}set indefName(e){this.indefOverride=e}get $(){let e=Object.isFrozen(this)?"state":"initialState";return ke[e].objects[this.id]||(ke[e].objects[this.id]={}),ke[e].objects[this.id]}get A(){return q(this,[this])}get A_(){return q(this,[this ,"*"])}get _A(){return q(this,["*",this])}addDetail(){let e=arguments[0];return e instanceof re||(be(),e=new ie(...arguments)),this.$.details||(this.$.details=[]),this.$.details.push(e.id),e}hideAll(){Object.values(ke.state.rooms).forEach((e=>{e.items.includes(this.id)&&this.move(e.items)})),Object.values(ke.state.objects).forEach((e=>{e.itemsIn?.includes(this.id)&&this.move(e.itemsIn),e.itemsOn?.includes(this.id)&&this.move(e.itemsOn)})),ke.playerHas(this)&&this.move(ke.$.inventory)}requireAttr(e,t){if(void 0===this.$[e])throw W.msg(t),me}requireHeld(){if(!ke.playerHas(this)&&(W.msg("First getting "+this.defName,"implied"),ke.dispatch("get",this),!ke.playerHas(this)))throw me}requireOpen(){if(!1===this.$.open&&(W.msg("First opening "+this.defName,"implied"),ke.dispatch("open",this),!1===this.$.open))throw me}mayLetGo(){return ke.doBeforeHooks("mayLetGo",this),ke.currentRoom().doBeforeHooks("mayLetGo",this),this.doBeforeHooks("mayLetGo",this),!0}get isContainer(){return void 0!==this.$.itemsIn}get isSupporte r(){return void 0!==this.$.itemsOn}get hasChildren(){return this.isContainer||this.isSupporter}children(){return this.childrenIn().concat(this.childrenOn())}childrenIn(){const e=[];return!1!==this.$.open&&e.push.apply(e,this.$.itemsIn),e.map((e=>ke.objects[e]))}childrenOn(){return(this.$.itemsOn??[]).map((e=>ke.objects[e]))}lookDesc(){let e=this.indefName,t=this.childrenIn();return this.isContainer&&!1!==this.$.open&&(e+=" (",0==t.length?e+="which is empty":e+="containing "+N(t.map((e=>e.lookDesc()))),e+=")"),e}inventoryName(){return this.lookDesc()+(this.$.worn?" (worn)":"")}matches(e){return this.names.some((t=>t.toLowerCase()==e))}fuzzyMatches(e,t=1){return 1==e.length&&(t=0),[...this.names,...this.names.flatMap((e=>e.split(" ")))].some((o=>function(e,t){let o,n,a=e.length,s=t.length,r=[];if(!a)return s;if(!s)return a;for(o=0;o<=a;o++)r[o]=[o];for(n=0;n<=s;n++)r[0][n]=n;for(n=1;n<=s;n++)for(o=1;o<=a;o++)e[o-1]==t[n-1]?r[o][n]=r[o-1][n-1]:(r[o][n]=Math.min(r[o-1][n],r[o][n-1],r[o-1][n-1])+1,o>1&&n>1&&e[o-1 ]==t[n-2]&&e[o-2]==t[n-1]&&(r[o][n]=Math.min(r[o][n],r[o-2][n-2]+1)));return r[a][s]}(e,o.toLowerCase())<=t))}move(e,t){if(e instanceof de&&(e=ke.state.rooms[e.id].items),t instanceof de&&(t=ke.state.rooms[t.id].items),!e.includes(this.id))throw new Error("Bad move");e=e.splice(e.indexOf(this.id),1),t&&t.push(this.id)}});class ie extends re{constructor(e,t){super(e,t),this.showInList=()=>!1}}class le extends ie{constructor(e,t,o,n=[{resp:()=>`${this.defName} has nothing to say about that.`}]){super(e,t),this.showInList=()=>!0,this.includedInAll=()=>!1,"m"==o?this.isMale=!0:"f"==o&&(this.isFemale=!0),this.topics=n,this.defName=this.names[0]}get genderIdx(){return this.isMale?1:this.isFemale?2:0}get them(){return["them","him","her"][this.genderIdx]}get themself(){return["themself","himself","herself"][this.genderIdx]}get they(){return["they","he","she"][this.genderIdx]}get their(){return["their","his","her"][this.genderIdx]}get theirs(){return["theirs","his","hers"][this.genderIdx]}get Them(){return V(this.the m)}get Themself(){return V(this.themself)}get They(){return V(this.they)}get Their(){return V(this.their)}get Theirs(){return V(this.theirs)}lookDesc(){return`${V(this.defName)} is here.`}ask(e,t,o="about"){ke.interlocutor=this;let n=this.topics.find((e=>e[o]&&e[o].some((e=>function(e,t){return"string"==typeof e?e==t:e.test(t)}(e,t)))));!function(e,t){if("string"==typeof e)W.msg(e);else{if("function"!=typeof e)throw new Error("Bad NPC reply");W.msg(e(t))}}(n?n.resp:this.topics[0].resp,t)}}function he(e,t=0){return(...o)=>{o[t]=ke.findNPC(""),o[t]?ke.dispatch(e,...o):W.msg("There's nobody here.")}}ae("ask","string","string","$YOU don't see $cod here."),ae("askFor","string","string","$YOU don't see $cod here."),ae("tell","string","string","$YOU don't see $cod here."),ae("ask",null,"string",he("ask")),ae("askFor",null,"string",he("askFor")),ae("tell",null,"string",he("tell")),ae("ask",le,"string",((e,t)=>e.ask(e,t))),ae("askFor",le,"string",((e,t)=>e.ask(e,t,"for"))),ae("tell",le,"string",((e,t)=>e.ask(e,t,"tel l")));let de=B(class{constructor(e,t,{id:o=R()}={}){j(!Object.prototype.hasOwnProperty.call(ke.rooms,o),"Duplicate room id: "+o),this.name_=e,this.id=o,this.desc_=t,this.exits={},ke.rooms[o]=this,ke.initialState.rooms[o]={items:[],visitedExits:[]}}name(){return this.name_}desc(){return this.desc_}decor(e,t){be();let o=new ie(e,t);return this.addItem(o)}addExit(e,t,...o){be();const n=e instanceof de?e.id:e;let a="";["north","south","east","west"].some((e=>t.startsWith(e)))&&(a="to the "),this.exits[t]=n;let s=[];return o.forEach((e=>{this.exits[e+"_"]=n;let o=this.decor([e],`The ${e} is ${a}${t}`);o.A.enter=()=>ke.dispatch("go",t),s.push(o)})),s}addSymExit(e,t){this.addExit(e,t),e.addExit(this,C(t))}addFauxExit(e,...t){this.addExit((()=>{throw W.msg(e),me}),...t)}get $(){let e=Object.isFrozen(this)?"state":"initialState";return ke[e].rooms[this.id]}get A(){return q(this,["*","*",this])}knownExits(){let e=this.doBeforeHooks("knownExits").flatMap((e=>e));return[...Object.keys(this.exits).filter((e=>"_"!=P(e))), ...e]}containsItem(e){return"string"!=typeof e&&(e=e.id),ke.state.rooms[this.id].items.includes(e)}itemListFormat(e){return`There's ${e} here.`}listItems(){let e=ke.getItems("directLocal").filter((e=>e.showInList()&&!(e instanceof le)));e.length>0&&W.msg(this.itemListFormat(N(e.map((e=>e.lookDesc())))));let t=ke.getItems("NPCs").filter((e=>e.showInList()));t.length>0&&W.msg(t.map((e=>e.lookDesc())).join(" "))}items(){return ke.state.rooms[this.id].items.map((e=>ke.objects[e]))}markDirVisited(e){let t=ke.state.rooms[this.id].visitedExits;t.includes(e)||t.push(e)}enter(e){const t=ke.currentRoom();ke.doBeforeHooks("enterRoom",this,e,t),ke.rooms[this.id].doBeforeHooks("enterRoom",this,e,t),ke.currentRoom().markDirVisited(e),ke.state.room=this.id;let o=C(e);o&&this.markDirVisited(o),ke.dispatch("look"),ke.doAfterHooks("enterRoom",this,e,t),ke.rooms[this.id].doAfterHooks("enterRoom",this,e,t)}msg(e){ke.state.room==this.id&&W.msg(e)}addItem(e){let t=Object.isFrozen(this)?"state":"initialState",o=ke[t].rooms[this.id ].items;if("string"==typeof e)o.push(e);else{if(!(e instanceof re))throw new Error("Unexpected argument for addItem");o.push(e.id)}return e}get state(){return ke.state.rooms[this.id]}get neighbors(){return Object.values(this.exits).filter((e=>"string"==typeof e)).map((e=>ke.rooms[e]))}});const ue={dispatch:!1,action:!1,lexer:!1,error:!0};function ce(e,...t){let o=console.log;"error"==e&&(o=console.error),ue[e]&&(o(`[${e}]`,...t),W.msg(`[${e}] ${t}`,"log"))}I.addVerb("db log",{codKind:"string",action:e=>{ue[e]=!ue[e]}});let me={};function ge(e){throw null!=e&&W.msg(e),me}class ye{constructor(e,t){this.candidates=e,this.msg=t}}class fe{constructor(e,t){this.item=e,this.msg=t,t||(this.msg=e.defName)}}const pe=e=>Array.isArray(e)?e.map(pe):e instanceof fe?(W.msg(e.msg,"implied"),e.item):e;function be(){if(Object.isFrozen(ke.initialState)){var e=(new Error).stack.replace(/^Error\s+/,"");throw e=(e=(e=(e=e.split("\n")[1]).replace(/^\s+at Object./,"")).replace(/ \(.+\)$/,"")).replace(/@.+/,""),new Error(e+" may not be used at runtime")}}function we(e,t,o){function n(e,n,a){let s="THE"==n.toUpperCase(),r="COD"==a.toUpperCase()?t:o;return""==n?r:r instanceof re?s?r.defName:r.indefName:s?"the "+r:H(r)}if("string"==typeof e){let t=e;return t=t.replace(/\$(THE|A|)(CO[ID])/g,((e,t,o)=>V(n(0,t,o)))),t=t.replace(/\$(the|a|)(co[id])/g,n),W.msg(t)}e(t,o)}let ke=function(){let e,t=new(B(class{}));function o(e){throw ke.state.dead=!0,W.msg(`
${e}
`),I.die(),W.msg(I.failMsg),me}function n(e="inReach"){function o(e){let t=[e,...e.details().flatMap(o)];return e.hasChildren&&(t=t.concat(e.children().flatMap(o))),t}function a(e){return e.map((e=>t.objects[e]))}switch(e){case"all":return Object.values(t.objects);case"directLocal":return t.doBeforeHooks("directLocalScope").flatMap((e=>e)).concat(a(t.currentRoom().state.items));case"nestedInventoryAndLocal":{let e=n("directInventory");return n("inReach").filter((t=>!e.includes(t)))}case"directInventory":return a(t.state.inventory);case"totalLocal":return n("directLo cal").flatMap(o);case"totalInventory":return n("directInventory").flatMap(o);case"inReach":return n("totalLocal").concat(n("totalInventory"));case"NPCs":return n("directLocal").filter((e=>e instanceof le));default:throw new Error("Bad scope for getObjs: "+e)}}function a(e,o){if(null==e)return null;if("all"==e)return null;let a=o;if("string"==typeof o?a=n(o):"function"==typeof o?a=o():o instanceof re&&(a=[o]),"them"==e){const o=t.findNPC(e),n=t.lastUsedItem?.isPlural&&a.includes(t.lastUsedItem)?t.lastUsedItem:null;if(o&&!n)return o;if(!o&&n)return new fe(n);if(o&&n){let e;return o instanceof le?e=[o]:o instanceof ye?e=o.candidates:o instanceof fe&&(e=[o.item]),s("them",[n,...e],"Which ``them'' do you mean, ")}}if("him"==e||"her"==e)return t.findNPC(e);if("it"==e&&t.lastUsedItem)return a.map((e=>e.id)).includes(t.lastUsedItem.id)?new fe(t.lastUsedItem):null;let r=a.filter((t=>t.matches(e)));return 0==r.length&&a.length>0&&(r=a.filter((t=>t.fuzzyMatches(e))),1==r.length)?new fe(r[0],"Assuming $you meant "+r[0]. defName):1==r.length?r[0]:r.length>1?s(e,r):null}function s(e,t,o=`Which ${e} do you mean, `){if(t.every((e=>e===t[0])))return t[0];let n=o+N(t.map((e=>e.defName)),"or")+"?";return new ye(t,n)}t.id="untitled",t.pronoun="you",t.beta=!1,t.rooms={},t.objects={},t.initialState={time:0,dead:!1,room:null,inventory:[],objects:{},rooms:{},persist:{deaths:0}},"undefined"!=typeof document&&(t.isWeb=!0),t.deadPrompt="Would you like to DUMP your transcript, UNDO, RESTART, LIST SAVES or RESTORE a saved game?",Object.defineProperty(t,"$",{get:()=>ke[Object.isFrozen(t.initialState)?"state":"initialState"]}),Object.defineProperty(t,"A",{get:()=>q(t,["*","*","*"])}),t.die=function(e=V(t.pronoun)+" have died."){ke.state.persist.deaths++,o(e)},t.win=function(e=V(t.pronoun)+" have won!"){o(e)},t.playerHas=function(e){return e instanceof re&&(e=e.id),ke.state.inventory.includes(e)},t.currentRoom=function(){const e=t.rooms[ke.state.room];return void 0===e?(W.msg("Invalid game state, restarting.","meta"),t.meta.restart(!0),t.curre ntRoom()):e},t.getItems=n,t.lastUsedItem=null,t.itIs=e=>t.lastUsedItem=e,t.findNPC=function(e){if(""==e||"him"==e||"her"==e||"them"==e){let o=n("NPCs").filter((e=>!e.dontAssume));if("him"==e&&(o=o.filter((e=>e.isMale))),"her"==e&&(o=o.filter((e=>e.isFemale))),1==o.length)return new fe(o[0]);if(o.includes(t.interlocutor))return new fe(t.interlocutor);if(o.length>1)return s(e,o,"Who do you mean, ")}else{let t=a(e,"NPCs");if(t)return t}return null},t.findObj=a,t.addSimpleVerb=function(e,t,{actionName:o=e,synonyms:n=[]}={}){I.addVerb(e,{action:o,codScope:null,synonyms:n}),ae(o,t)},t.addIVerb=function(e,t,{actionName:o=e,codScope:n="inReach",codKind:a="object",coiScope:s="inReach",synonyms:r=[],prepositions:i=[],flipCodCoi:l=!1,missingCod:h="#.softError{$YOU don't see $acod here.}",missingCoi:d="#.softError{$YOU don't see $acoi here.}"}={}){I.addVerb(e,{action:o,codScope:n,codKind:a,codMayFail:!0,coiMayFail:!0,coiScope:s,synonyms:r,flipCodCoi:l,prepositions:i}),ae(o,re,re,t),ae(o,"string","*",h),ae(o,re,"string", d)},t.addDirectVerb=function(e,t,{actionName:o=e,scope:n="inReach",synonyms:a=[],missingCod:s="#.softError{$YOU don't see $acod here.}"}={}){I.addVerb(e,{action:o,codScope:n,synonyms:a,codMayFail:!0}),ae(o,"string",s),ae(o,re,t)},t.interlocutor=null;let r=["look"];t.dispatchP=function(o){if("again"==o)return W.msg(`Doing \`\`${e}'' again`,"meta"),void I.parse(e);e=I.rawStr;let n=t.dispatch(...arguments);return t.pushUndoRecord(),n},t.dispatch=function(e,o,n){try{if(r=[e,o,n],ce("dispatch",e," -- ",o," -- ",n),o instanceof ye)return W.msg(o.msg),!0;if(n instanceof ye)return W.msg(n.msg),!0;o=pe(o),n=pe(n),t.doBeforeHooks(e,o,n),t.currentRoom().doBeforeHooks(e,o,n),o instanceof re&&(t.lastUsedItem=o,o instanceof le?t.interlocutor=o:n instanceof le&&(t.interlocutor=n),o.doBeforeHooks(e,o,n)),we(function(e,t,o,n){let a=oe[e];ce("action","Searching for: ",e,t,o,n),ce("action","Candidate rules: ",a),j(null!=a,"No rules for "+e),a=a.filter((e=>e.check(t,o,n))),0==a.length&&Array.isArray(t)&&ge("You can't use that v erb with multiple objects."),j(a.length>0,"No matching rules for "+e),ce("action","Filtered rules: ",a);let s=0,r=a.reduce(((e,t)=>t.score>e.score?(s=0,t):(t.score==e.score&&s++,e)),{score:-1});return j(0==s,"Multiple matching rules for "+e),r.action}(e,o,n,t.currentRoom().id),o,n),t.doAfterHooks(e,o,n),t.currentRoom().doAfterHooks(e,o,n),o instanceof re&&o.doAfterHooks(e,o,n)}catch(e){e!==me&&(ce("error",e),W.msg(e,"error"))}return!0},t.disamb=function(e){if(r[1]instanceof ye){if("all"==e)return t.dispatch(r[0],r[1].candidates,r[2]),t.pushUndoRecord(),!0;let o=a(e,r[1].candidates);if(o)return t.dispatch(r[0],o,r[2]),t.pushUndoRecord(),!0}if(r[2]instanceof ye){let o=a(e,r[2].candidates);if(o)return t.dispatch(r[0],r[1],o),t.pushUndoRecord(),!0}return null},t.advanceClock=function(e=1){if(!ke.state.dead)for(let t=0;t{try{e.tick&&e.tick()}catch(e){if(e!==me)throw e}}))};let i=[],l=[],h={};function d(e){return{set:funct ion(t,o,n){if("function"==typeof n)throw new Error("Functions not allowed in state");return t[o]!=n&&"length"!=o&&(function(e){return typeof e==typeof{}&&0==Object.entries(e).length}(n)||u(e+o,t[o])),"tickTock"==o||(t[o]=n),!0},deleteProperty:function(t,o){return u(e+o,t[o]),delete t[o],!0},get:function(t,o){let n=t[o];return"object"==typeof n&&"persist"!=o?new Proxy(n,d(e+o+".")):n}}}function u(e,t){l.push({i:e,p:t})}function c(e){var o;o=e,h=JSON.parse(JSON.stringify(o)),t.state=new Proxy(h,d("")),l=[]}function m(e){Object.values(e).filter((e=>"object"==typeof e)).forEach(m),Object.freeze(e)}function g(){c(t.initialState),i=[]}t.begin=function(){!function(){for(let e of Object.values(ke.rooms))for(let t of Object.values(e.exits))if("string"==typeof t&&!ke.rooms[t])throw new Error(`Bad exit in ${e.name}: ${t}`)}(),m(t.objects),m(t.rooms),m(t.initialState),g(),t.isWeb&&!new URL(document.location).searchParams.has("reset")&&p("_autosave_",!0),W.begin()},t.pushUndoRecord=function(){0!=l.length&&(W.hasPendingAc tion()||(t.advanceClock(),i.push([l.filter((e=>"tickTock"!=e.i)),e]),l=[],f()))};let y={};function f(){I.isNormal()&&y.save("_autosave_",!0)}function p(e,o=!1){let n=W.restore(t.id+"-save-"+e);n&&n.state?(c(n.state),i=n.stack,I.normal(),t.doAfterHooks("restore"),W.msg("Game restored","meta"),o||t.dispatch("look")):o||(W.msg("Save file not found","meta"),y.listSaves())}return t.meta=y,t.undoCore=function(){let[e,t]=i.pop();for(let t of e.reverse()){let e=t.i.split("."),o=e.slice(0,-1).reduce(((e,t)=>e[t]),h);void 0===t.p?Array.isArray(o)?o.pop():delete o[P(e)]:o[P(e)]=t.p}j(0==l.length),W.msg("Undid ``"+t+"''","meta")},y.undo=function(){j(0==l.length),t.doBeforeHooks("undo"),t.currentRoom().doBeforeHooks("undo"),0!=i.length?(t.undoCore(),t.doAfterHooks("undo"),t.currentRoom().doAfterHooks("undo"),t.dispatch("look"),0!=l.length&&(i.length&&P(i)[0].push(...l),l=[]),I.normal(),f()):W.msg("Nothing left to undo","meta")},y.save=function(e="default",o=!1){"default"==e&&W.msg("SAVE default","implied");let n=W.save(t .id+"-save-"+e,{state:h,stack:i});o||(n?W.msg("Saved game","meta"):W.msg("Unable to save game","meta"))},y.listSaves=function(){let e,o=W.listSaves().filter((e=>e.startsWith(t.id+"-save-"))).map((e=>e.slice(6+t.id.length))).filter((e=>"_autosave_"!=e));o.length>0?(e="The following save files are available:\n - ",e+=o.join("\n - ")):e="There are no save files available.",W.msg(e,!0)},y.restore=function(e="default"){"default"==e&&W.msg("RESTORE default","implied"),p(e),f()},y.restart=function(e=!1){function o(){W.msg(V(t.pronoun)+" start anew","meta"),W.commit(),W.clear(),g(),f(),I.normal(),t.dispatchP("look")}e||I.mode==I.Modes.dead?o():(W.msg("Are you sure you want to restart?"),W.yesno(o,"Are you sure you want to start over?",(()=>W.msg("Nevermind then","meta"))))},I.addVerb("db state",{action:()=>{console.log(h)},codScope:null}),t.addSimpleVerb("db game",(()=>{console.log(ke)})),t.addDirectVerb("db get",(e=>{ke.state.inventory.push(e.id)}),{scope:"all"}),I.addVerb("db go",{action:e=>{Object.keys( ke.rooms).includes(e)?(ke.state.room=e,ke.dispatch("look")):W.msg("invalid room id","error")},codKind:"string"}),I.addVerb("db obj",{action:e=>console.log(ke.objects[e]),codKind:"string"}),I.addVerb("db rooms",{action:()=>{Object.values(ke.rooms).forEach((e=>W.msg(e.name()+" - "+e.id)))},codKind:null}),t.addSimpleVerb("db space",(()=>{var e,t,o=0;for(t in localStorage)localStorage.hasOwnProperty(t)&&(o+=e=2*(localStorage[t].length+t.length),console.log(t.substr(0,50)+" = "+(e/1024).toFixed(2)+" KB"));console.log("Total = "+(o/1024).toFixed(2)+" KB")})),t}(),ve=0;function $e(e,t){be();const o="_f"+ve++;return(n,a)=>{ke.state[o]?t&&we(t,n,a):(ke.state[o]=!0,we(e,n,a))}}function Ae(e,t="cod",o="coi"){return(n,a)=>{const s=e=>"cod"==e?n:"coi"==e?a:e;ke.dispatch(e,s(t),s(o))}}const Ye=new Map;W.addProcessor(/#draw\{([^]*?)\}/gi,(function(e,t){return Ye.get(t)||Ye.set(t,E(t.split("|"))),Ye.get(t)()})),W.addProcessor(/#rnd\{([^]*?)\}/gi,((e,t)=>S(t.split("|")))),W.addProcessor(/\$YOU/g,V(ke.pronoun)),W.addProcessor (/\$you/g,ke.pronoun);const Ie={again:()=>{I.addVerb("again",{synonyms:["g"],codScope:null})},attack:()=>{ke.addDirectVerb("attack","#.softError{That seems unnecessarily violent.}"),ke.addIVerb("attack",Ae("attack","cod",null),{prepositions:["with"],coiScope:"totalInventory",missingCoi:(e,t)=>W.msg(`#.softError{You don't have ${H(t)}}.`)})},climb:()=>{ke.addSimpleVerb("climb",(()=>ke.dispatch("climb",new ye(ke.getItems(),"What do you want to climb?")))),ke.addDirectVerb("climb","#.softError{You can't climb that.}")},close:()=>{I.addVerb("close"),ae("close",re,(e=>{e.requireAttr("open","#.softError{"+V(e.defName)+" isn't something $you can close.}"),e.$.open?(W.msg("$YOU close "+e.defName),e.$.open=!1):W.msg("#.softError{"+V(e.defName)+" is already closed.}")}))},cut:()=>{ke.addIVerb("cut",((e,t)=>{t.cutter?W.msg(`#.softError{$YOU don't think cutting ${e.defName} is a good idea.}`):W.msg(`#.softError{${V(t.defName)} isn't something $you can cut with.}`)}),{synonyms:["chop","dice","mince"],prepositions:["with" ],coiScope:"totalInventory",missingCoi:(e,t)=>W.msg(`#.softError{You don't have ${H(t)}}`)}),ke.addDirectVerb("cut",(e=>{let t=ke.getItems("totalInventory").filter((e=>e.cutter));1==t.length?(W.msg(`With ${t[0].defName}`,"implied"),ke.dispatch("cut",e,t[0])):ke.dispatch("cut",e,new ye(ke.getItems("totalInventory"),`What do you want to cut ${e.defName} with?`))}),{synonyms:["chop","dice","mince"]})},doff:()=>{I.addRaw(o(i("take"),g(),i("off"),u((e=>ke.dispatchP("doff",e[0]))))),ke.addDirectVerb("doff",(function(e){void 0!==e.$.worn?e.$.worn?(e.$.worn=!1,W.msg("You doff "+e.defName)):W.msg("#.softError{You aren't wearing "+e.defName+".}"):W.msg("#.softError{"+V(e.defName)+" isn't something you can wear.}")}),{synonyms:["remove","take off"]}),ke.A.mayLetGo.before=e=>{if(e.$.worn&&(W.msg("First doffing "+e.defName,"implied"),ke.dispatch("doff",e),e.$.worn))throw me}},drop:()=>{I.addRaw(o(i(w("drop","discard","put down")),f("totalInventory"),u((e=>{ke.dispatchP("drop",e)})))),I.addRaw(o(i("put"),f("totalInventory "),i(n("down",o("on",r("the"),w("ground","floor")))),u((e=>{ke.dispatchP("drop",e)})))),se("drop",(e=>{if(e.requireHeld(),!e.mayLetGo())throw me;if(!ke.playerHas(e))throw me;e.move(ke.state.inventory,ke.currentRoom().state.items),ke.dispatch("drop_report",e)}),(()=>ke.getItems("directInventory")),"$YOU have none","#.softError{$YOU don't have $acod.}"),ae("drop",ie,"#.softError{$YOU can't drop $thecod.}"),ae("drop_report",re,"$YOU drop $thecod")},eat:()=>{ke.addDirectVerb("eat","#.softError{That's hardly edible.}")},enter:()=>{ke.addDirectVerb("enter","#.softError{That isn't something $you can enter.}",{synonyms:["get in"]})},exit:()=>{ke.addDirectVerb("exit","#.softError{That isn't something $you can exit.}")},get:()=>{I.addRaw(o(i(w("get","pick up","take","grab")),f("nestedInventoryAndLocal",!1),u((e=>{ke.dispatchP("get",e)})))),I.addRaw(o(i(w("get","pick up","take","grab")),f(),u((e=>{ke.dispatchP("get",e)})))),se("get",(e=>{if(ke.currentRoom().containsItem(e))e.move(ke.currentRoom().state.items,ke.state.i nventory),W.msg("$YOU pick up "+e.defName);else if(ke.playerHas(e))W.msg("$YOU already have "+e.defName);else{let t=ke.getItems().filter((t=>t.hasChildren&&t.children().includes(e)));j(1==t.length,"Object not in one! container"),ke.dispatch("getFrom",e,t[0])}}),(()=>ke.getItems("directLocal")),"#.softError{There are none.}","#.softError{$YOU don't see $acod here.}"),ae("get",ie,"#.softError{$YOU can't take $thecod.}")},getFrom:()=>{I.addRaw(o(i(w("get","take","grab","snatch")),f(),i(n("out of","from")),n(g(),A),u((e=>ke.dispatchP("getFrom",e.slice(0,-1),P(e)))))),se("getFrom",((e,t)=>{if(!t.children().includes(e)){const o=t.isContainer?"in":"on";throw W.msg("#.softError{"+V(e.defName)+` isn't ${o} `+t.defName+".}"),me}const o=t.childrenIn().includes(e)?"itemsIn":"itemsOn";e.move(ke.state.objects[t.id][o],ke.state.inventory),W.msg("$YOU take "+e.defName+" from "+t.defName)}),(e=>e.children()),"$THECOI is empty.","#.softError{$YOU don't see $acod in $thecoi.}",re),ke.addBeforeHook("getFrom",((e,t)=>{if(t insta nceof re&&!1===t.$.open)throw W.msg(V(t.defName)+" is closed."),me}))},go:()=>{let e=n(b("north"),b("south"),b("west"),b("east"),w("northeast","ne"),w("northwest","nw"),w("southeast","se"),w("southwest","sw"),b("up"),b("down"),w("inside","in","enter"),w("outside","out","exit","leave")),t=w("go","move","walk","run"),a=n("towards","to");I.addRaw(o(i(r(t),r(a),r("the")),e,u((e=>ke.dispatchP("go",e[0]))))),I.addRaw(o(i(n("go to","go in","goto","go")),A,u((e=>ke.dispatchP("go",e[0]))))),ae("go","string",(function(e){let t=ke.rooms[ke.state.room].exits,o=t[e]||t[e+"_"];if(!o){const t=ke.getItems("totalLocal"),n=ke.findObj(e,t.filter((e=>e.goExit)));n instanceof re?o=n.goExit:n?.item instanceof re&&(W.msg(n.msg,"implied"),o=n.item.goExit)}if(o){if("function"==typeof o)return o();o instanceof de&&(o=o.id),j("string"==typeof o,"Wrong room kind"),j(ke.rooms[o],"Bad room id: "+o),ke.rooms[o].enter(e)}else W.msg("#.softError{$YOU see no way "+e+".}"),ke.dispatch("listExits")}))},handle:()=>{ke.addDirectVerb("handle","#. softError{That isn't something $you can handle.}")},hit:()=>{ke.addDirectVerb("hit",Ae("attack")),ke.addIVerb("hit",Ae("attack","cod","coi"),{prepositions:["with"],coiScope:"totalInventory",missingCoi:(e,t)=>W.msg(`You don't have ${H(t)}`)})},inventory:()=>{I.addRaw(o(r(b("take")),b("inventory"),u((()=>ke.dispatchP("inventory"))))),ae("inventory",(()=>{if(0==ke.state.inventory.length)W.msg("$YOU have nothing.");else{const e=ke.getItems("directInventory").filter((e=>e.showInList()));if(0==e.length)return void W.msg("$YOU have nothing.");let t="$YOU have:";e.forEach((e=>t+="\n - "+e.inventoryName())),W.msg(t,"normal",!0),1==e.length&&ke.itIs(e[0])}}))},kick:()=>{ke.addDirectVerb("kick",Ae("attack"))},listExits:()=>{I.addVerb("exits",{action:"listExits",synonyms:["list exits"],codScope:null}),ae("listExits",(()=>{let e=ke.currentRoom().knownExits();return 0==e.length?W.msg("$YOU can see no exit from this place."):(e=e.map((e=>ke.state.rooms[ke.state.room].visitedExits.includes(e)?e:`#.emph{${e}}`)),W.msg("$YOU could try going "+N(e,"or")+"."))}))},listSaves:()=>{I.addVerb("saves",{synonyms:["list saves"],action:ke.meta.listSaves,codScope:null,alsoInDeadPrompt:!0})},listen:()=>{ke.addSimpleVerb("listen","You hear nothing unexpected"),ke.addDirectVerb("listen to","You hear nothing unexpected",{actionName:"listen"})},lookInside:()=>{ke.addDirectVerb("look in",(e=>{let t=e.childrenIn();e.isContainer?t.length>0?W.msg("In "+e.defName+(1==t.length?" is ":" are ")+N(t.map((e=>e.indefName)))):!1===e.$.open?W.msg(V(e.defName)+" is closed."):W.msg(V(e.defName)+" is empty."):W.msg("$YOU can't look inside "+e.defName)}),{actionName:"lookInside",synonyms:["look inside"]})},lookBehind:()=>{ke.addDirectVerb("look behind","#.softError{$YOU find nothing unexpected.}",{actionName:"lookBehind"})},lookUnder:()=>{ke.addDirectVerb("look under",Ae("search"),{actionName:"lookUnder"})},lookUp:()=>{const e=(e,t,o)=>{if(o&&W.msg(`in ${t.defName}`,"implied"),!t.topics&&!t.$.topics)return W.msg("You can't look things up with "+t.indefName);co nst n=Object.assign({},t.topics,t.$.topics),a=n[e]||n._missing||"You don't find anything about "+e+" in "+t.defName;return a&&"string"==typeof a?W.msg(a):a()};ae("lookUp","string",null,(t=>{let o=ke.getItems("inReach").filter((e=>e.topics||e.$.topics));if(0==o.length)return ke.dispatch("lookUp",t,new ye(ke.getItems("inReach"),`What do you want to look ${t} up in?`));if(1==o.length)return e(t,o[0],!0);const n=o.filter((e=>e.topics&&e.topics[t]||e.$.topics&&e.$.topics[t]));if(1==n.length)return e(t,n[0],!0);const a=n.length>1?n:o;return ke.dispatch("lookUp",t,new ye(a,`What do you want to look up ${t} in? `+V(N(a.map((e=>e.defName)),"or"))+"?"))})),ae("lookUp","string",re,e),ae("lookUp","string","string","You don't see $acoi here"),I.addVerb("lookup",{action:"lookUp",synonyms:["look up","read about","read on"],codKind:"thing"}),I.addVerb("lookup",{action:"lookUp",codKind:"thing",prepositions:["in","on"],synonyms:["look up","read about","read on"],coiMayFail:!0,coiScope:"inReach"}),I.addVerb("consult",{action:" lookUp",flipCodCoi:!0,coiKind:"thing",prepositions:["about","on"]}),I.addRaw(o(i("look"),A,i("up"),r(o(i(n("in","on")),g()),null),u((e=>ke.dispatchP("lookUp",...e)))))},look:()=>{ke.addSimpleVerb("look",(()=>{W.msg(ke.rooms[ke.state.room].name(),"loc"),W.msg(ke.rooms[ke.state.room].desc()),ke.currentRoom().listItems()}),{synonyms:["l"]})},move:()=>{ke.addDirectVerb("move","Nothing happens.")},offer:()=>{I.addRaw(o(i(w("give","offer")),f(),i("to"),n(g("NPCs"),A),u((e=>ke.dispatchP("offerArr",e.slice(0,-1),P(e)))))),I.addRaw(o(i(w("give","offer")),g("NPCs"),f(),u((e=>ke.dispatchP("offerArr",e.slice(1),e[0]))))),I.addRaw(o(i(w("give","offer")),f(),u((e=>ke.dispatchP("offerAnon",e))))),se("offerArr",Ae("offer"),(()=>ke.getItems("directInventory")),"$YOU have none","$YOU don't have $acod",re,"$YOU don't see $coi here."),ae("offer",re,re,"$THECOI doesn't want $thecod"),ae("offerAnon","array",(e=>{const t=ke.findNPC("");t?ke.dispatch("offerArr",e,t):W.msg("There's nobody here.")}))},open:()=>{ke.addDirectVerb("open ",(e=>{e.requireAttr("open","#.softError{"+V(e.defName)+" isn't something $you can open.}"),e.$.open?W.msg("#.softError{"+V(e.defName)+" is already open.}"):(W.msg("$YOU open "+e.defName),e.$.open=!0,e.isContainer&&ke.dispatch("lookInside",e))}))},pull:()=>{ke.addDirectVerb("pull","#.softError{Nothing happens.}")},push:()=>{ke.addDirectVerb("push","#.softError{Nothing happens.}")},putIn:()=>{I.addRaw(o(i(w("put","place","drop")),f(),i(n("in to","into","in")),g(),u((e=>ke.dispatchP("putIn",e.slice(0,-1),P(e)))))),se("putIn",((e,t)=>{if(t.requireAttr("itemsIn","$YOU can't put things in "+t.defName),e===t)return W.msg(V(t.defName)+" is not a Klein bottle."),!1;if(e.children().includes(t))return W.msg("That might cause the universe to explode."),!1;if(t.childrenIn().includes(e))return W.msg(V(e.defName)+" is already in "+t.defName),!1;if(t.requireOpen(),e.requireHeld(),!e.mayLetGo())throw me;if(!ke.playerHas(e))throw me;return e.move(ke.state.inventory,ke.state.objects[t.id].itemsIn),W.msg("$YOU put "+e.defName+ " in "+t.defName),!0}),(()=>ke.getItems("directInventory")),"$YOU have none","$YOU don't have $acod",re)},putOn:()=>{I.addRaw(o(i(w("put","place","drop")),f(),i(n("on to","onto","on")),g(),u((e=>ke.dispatchP("putOn",e.slice(0,-1),P(e)))))),se("putOn",((e,t)=>{if(t.requireAttr("itemsOn","#.softError{$YOU can't put things on "+t.defName+".}"),e===t)return W.msg(`#.softError{You can't put ${t.defName} on itself.}`),!1;if(e.children().includes(t))return W.msg("#.softError{That might cause the universe to explode.}"),!1;if(t.childrenOn().includes(e))return W.msg("#.softError{"+V(e.defName)+" is already on "+t.defName+".}"),!1;if(e.requireHeld(),!e.mayLetGo())throw me;if(!ke.playerHas(e))throw me;return e.move(ke.state.inventory,ke.state.objects[t.id].itemsOn),W.msg("$YOU put "+e.defName+" on "+t.defName),!0}),(()=>ke.getItems("directInventory")),"$YOU have none","#.softError{$YOU don't have $acod.}",re)},read:()=>{ke.addDirectVerb("read","#.softError{That isn't something $you can read.}")},restart:()=>{I.addVerb( "restart",{action:ke.meta.restart,codScope:null,alsoInDeadPrompt:!0})},restore:()=>{I.addVerb("restore",{action:ke.meta.restore,codKind:"string",codMayFail:!0,defaultCod:"default",alsoInDeadPrompt:!0})},rotate:()=>{ke.addDirectVerb("rotate","#.softError{That isn't something $you can rotate.}")},save:()=>{I.addVerb("save",{action:ke.meta.save,codKind:"string",codMayFail:!0,defaultCod:"default"})},search:()=>{ke.addDirectVerb("search","#.softError{$YOU don't find anything unexpected.}")},show:()=>{ke.addIVerb("show","#.softError{$THECOI doesn't care about $thecod.}",{prepositions:["to"],coiScope:"NPCs",missingCoi:"#.softError{$YOU don't see $coi here.}"})},smell:()=>{ke.addSimpleVerb("smell","#.softError{$YOU don't smell anything unexpected.}"),ke.addDirectVerb("smell","#.softError{$THECOD doesn't smell unexpected.}")},swim:()=>{ke.addSimpleVerb("swim","#.softError{$YOU can't swim here.}")},talk:()=>{I.addRaw(o(n("ask","tell"),n(g("NPCs"),r(A,null)),i(n("about","to")),l(s(p(/[^.]*/))),u((e=>ke.dispatchP(...e)) ))),I.addRaw(o(i("say"),A,r(o(i("to"),n(g("NPCs"),A))),u((e=>ke.dispatchP("tell",e[1],e[0]))))),I.addRaw(o(g("NPCs"),i(","),l(s(p(/[^.]*/))),u((e=>ke.dispatchP("tell",...e))))),I.addRaw(o(m("ask","askFor"),n(g("NPCs"),r(A,null)),i("for"),l(s(p(/[^.]*/))),u((e=>ke.dispatchP(...e))))),ke.addSimpleVerb("talk",(()=>{ke.dispatch("talkTo",new ye(ke.getItems("NPCs"),"Who do you want to talk to?"))})),I.addRaw(o(i("talk to"),n(g("NPCs"),g(),A),u((e=>{ke.dispatchP("talkTo",e[0])})))),ae("talkTo",le,(e=>{W.msg("``ASK "+e.defName+" ABOUT themself''","implied"),ke.dispatchP("ask",e,"themself")})),ae("talkTo",re,"#.softError{$THECOD is inanimate.}"),ae("talkTo","string","#.softError{You don't see $acod here.}")},turnOn:()=>{ke.addDirectVerb("turn on","#.softError{That isn't something you can turn on.}",{actionName:"turnOn",synonyms:["switch on"]}),I.addRaw(o(i(n("turn","switch")),g(),i("on"),u((e=>ke.dispatchP("turnOn",...e)))))},turnOff:()=>{ke.addDirectVerb("turn off","#.softError{That isn't something you can turn off. }",{actionName:"turnOff",synonyms:["switch off"]}),I.addRaw(o(i(n("turn","switch")),g(),i("off"),u((e=>ke.dispatchP("turnOff",...e)))))},turn:()=>{ke.addDirectVerb("turn","#.softError{That isn't something $you can turn.}")},undo:()=>{I.addVerb("undo",{action:ke.meta.undo,codScope:null,alsoInDeadPrompt:!0})},use:()=>{ke.addDirectVerb("use","#.softError{$YOU don't know how to use $thecod.}"),ke.addIVerb("use","#.softError{$YOU don't know how to use $thecod on $thecoi.}",{prepositions:["on","with"]})},wait:()=>{ke.addSimpleVerb("wait",(()=>{ke.state.tickTock=!0,W.msg("Time passes...")}),{synonyms:["z"]})},wear:()=>{I.addRaw(o(i("put"),g(),i("on"),u((e=>ke.dispatchP("wear",e[0]))))),ke.addDirectVerb("wear",(function(e){void 0!==e.$.worn?e.$.worn?W.msg("#.softError{You are already wearing "+e.defName+".}"):(e.requireHeld(),e.$.worn=!0,W.msg("You put on "+e.defName)):W.msg("#.softError{"+V(e.defName)+" isn't something you can wear.}")}),{synonyms:["put on","don"]})},xyzzy:()=>{ke.addSimpleVerb("xyzzy","Nothing hap pens.")},examine:()=>{const e=u((e=>ke.dispatchP("examine",e[0])));I.addRaw(o(i(n(w("examine","x"),o(b("look"),r("at")))),n(o(g(),e),o(A,e)))),ae("examine",re,(e=>{if(W.msg(e.desc+" <>"),!1===e.$.open?W.msg("It is closed"):e.isContainer&&ke.dispatch("lookInside",e),e.isSupporter){const t=e.childrenOn();t.length>0&&W.msg("On "+e.defName+(1==t.length?" is ":" are ")+N(t.map((e=>e.indefName))))}})),ae("examine","string",(e=>{[ke.currentRoom().name(),...ke.currentRoom().name().split(" ")].some((t=>t.toLowerCase()==e.toLowerCase()))?ke.dispatch("look"):W.msg("#.softError{$YOU don't see "+H(e)+" here.}")}))}},Te=["north","northeast","east","southeast","south","southwest","west","northwest"],Se="#999";let xe=U("rose"),Ee=!0;"undefined"!=typeof document&&function(){function e(e,t){const o=xe?.getElementById(e),n=o?.getElementsByClassName("dark");n?.[0]?.setAttribute("style","fill: "+t),o?.setAttribute("style","cursor: "+(t==Se?"unset":"pointer"))}"svg"!=xe.nodeName&&(xe=xe.getSVGDocument()),Te.forEach((e=>{xe?.getEl ementById(e).addEventListener("click",(()=>{Ee&&(U("echo").value="go "+e,U("echo").focus(),document.getElementsByTagName("body")[0].dispatchEvent(new KeyboardEvent("keydown",{key:"Enter"})))}))})),ke.addBeforeHook("_doPsg_",(()=>{Te.forEach((t=>e(t,Se)))})),ke.addAfterHook("look",(()=>{let t=ke.currentRoom().knownExits();Te.forEach((t=>e(t,Se))),t.forEach((t=>e(t,"#222"))),ke.currentRoom().$.homeDir&&e(ke.currentRoom().$.homeDir,"#135")}))}();const Ne={E:[[0,0],[4,1],[9,1],[13,1],[14,1],[14,2],[1,3],[6,3],[3,6],[9,6],[2,7],[1,8],[7,8],[12,8],[11,9],[5,10],[11,11],[12,12],[5,13],[8,13],[12,13],[14,13],[2,14],[7,14]],S:[[1,0],[2,0],[10,1],[4,2],[11,2],[7,4],[1,6],[11,7],[0,8],[12,9],[14,9],[0,11],[5,12],[13,13],[5,14],[10,14],[14,14]],A:[[3,0],[12,0],[1,1],[7,1],[0,2],[3,2],[9,2],[5,4],[6,5],[8,5],[11,5],[12,6],[1,9],[4,9],[3,10],[8,10],[1,11],[2,12],[13,12],[0,13],[4,14]],Y:[[4,0],[9,0],[4,3],[4,10],[1,14]],O:[[6,0],[8,2],[13,3],[4,4],[1,5],[10,5],[7,6],[13,6],[6,7],[8,7],[9,9],[10,10],[6,11],[9,11],[14,11],[ 7,12],[10,12],[1,13],[6,13],[11,14]],B:[[7,0],[6,2],[9,5],[5,7],[13,8],[9,10],[10,11],[4,13]],G:[[8,0],[8,3],[5,5]],N:[[10,0],[6,1],[2,3],[3,3],[10,4],[10,6],[7,7],[4,12],[14,12],[7,13],[8,14]],R:[[13,0],[14,0],[8,1],[7,2],[2,5],[12,5],[14,6],[6,8],[10,9],[7,11],[0,14],[12,14]],M:[[0,1],[4,8],[14,8]],P:[[2,1],[12,3],[8,6],[14,7],[5,11]],L:[[3,1],[12,1],[1,2],[3,7],[2,11],[12,11],[13,11]],I:[[2,2],[12,2],[7,3],[11,3],[9,4],[0,6],[4,7],[5,8],[3,12]],D:[[10,2],[13,2],[14,3],[13,5]],J:[[0,3]],W:[[5,3],[11,8]],H:[[9,3],[2,6],[1,7],[1,12],[6,12],[11,13],[6,14]],T:[[6,4],[0,5],[3,5],[0,7],[9,7],[2,8],[2,9],[3,9],[13,9],[3,11],[8,11],[8,12],[10,13],[13,14]],V:[[11,4]],U:[[4,5],[10,7],[13,7]],C:[[12,7],[5,9],[7,10],[0,12],[11,12]],K:[[6,9],[2,13]],F:[[8,9]]},Ve=["OSSIFRAGE","ANANAS","MUNCHKIN","CRAWDAD","GHERKIN","HOLOTHURIAN","FALAFEL","HAMADRYAD","MAGPIE","AMPERSAND","CAPOTAIN","GATSBY"];Ve.forEach((e=>[...e].forEach((t=>j(null!=Ne[t],"Bad magic word: "+e))))),I.addRaw(o(n(...Ve.map((e=>e.toLowerCase()))),u((e=>ke. dispatchP("sayMagic",e[0]))))),ae("sayMagic","string","I don't understand.");const Pe=new re(["ICS merit badge","badge","merit badge"],"It's an International Code of Signals merit badge. It appeared mysteriously in your pocket.");Pe.hint="#parrot{Looks worthless to me,} says #V#.",Pe.endValue=35,Pe.endMsg="You sell the merit badge to a kid for 35 doubloons.";const Oe=$e((()=>{W.msg("``Synapse,'' you say, to no one in particular. Suddenly your pocket feels heavier."),ke.$.inventory.push(Pe.id)}),"Nothing happens.");ke.addSimpleVerb("synapse",Oe),ke.A.tell.before=(e,t)=>{null==e&&Ve.includes(t.toUpperCase())&&(ke.dispatch("sayMagic",t),ge()),null==e&&"synapse"==t&&(Oe(),ge())};const Ce=S(Ve);let He="",je="";function De(e,t,o){const n=new re([e+" medallion","medallion",e],`In the center of the ${e} medallion is a picture of ${t}. Surrounding the picture are some strange letters:`);n.$.text=o,n.givesMagic=!0;const a=n.addDetail(["strange letters on the "+e+" medallion","strange letters","letters"],"It's all gree k to you");return a.A.read=Ae("examine",n),a.hint="#parrot{Quite mysterious,} #V# agrees.",n.A.read=Ae("examine"),n.addDetail("picture of "+t,"He's a patron of sailors. Hopefully the medallion will bring you luck."),n.A.examine.after=()=>{W.msg(`\n#.medallion{${n.$.text}}`)},n.A.examine.after=$e("You can tell that the medallion is imbued with some powerful magic."),n.hint="#parrot{This kind of magical item can be useful at sea. Be sure to keep it on your person when we set sail,} #V# reminds you.",n}[..."BY SKULL ROCK SAY "+Ce].forEach((e=>{if(" "==e)He+=" ",je+=" ";else{const t=S(Ne[e]);He+="???????????????"[t[0]],je+="???????????????"[t[1]]}})),ke.$.medIdx=Ve.indexOf(Ce);const Me=De("golden","Pollux",He),Re=De("silver","Castor",je);function Fe(e,t,o="ABOUT",n="ASK"){W.msg(`\`\`${n} ${e.defName} ${o} ${t}''`,"implied");const a={ABOUT:"ask",FOR:"askFor",TO:"tell"}[o];ke.dispatch(a,e,t)}W.addProcessor(/#henry\{(.+?)\}/gi,"#.henry{``$1''}"),W.addProcessor(/#merchant\{(.+?)\}/gi,"# .merchant{``$1''}"),W.addProcessor(/#you\{(.+?)\}/gi,"#.you{``$1''}"),W.addProcessor(/#violet\{(.+?)\}/gi,"#.violet{``$1''}"),W.addProcessor(/#marvin{(.*)}/g,((e,t)=>"#.marvin{``"+t.replace(/a|e|i|o|u/gi,"")+"''}")),W.addProcessor(/#sammy\{(.+?)\}/gi,"#.sammy{``$1''}"),W.addProcessor(/#witch\{(.+?)\}/gi,"#.witch{``$1''}"),W.addProcessor(/#cashier\{(.+?)\}/gi,"#.cashier{``$1''}"),W.addProcessor(/#cecile\{(.+?)\}/gi,"#.cecile{``$1''}"),W.addProcessor(/#knikna\{(.+?)\}/gi,"#.knikna{<$1>}");const Ue=new le(["pirates"],"A handful of pirates");function Le(e){return{n:"north",s:"south",e:"east",w:"west",ne:"northeast",nw:"northwest",se:"southeast",sw:"southwest",d:"down",u:"up"}[e]??e}function Be(e="",t){e=e.trim().match(/(?:a |the )?(.*)/)[1].trim();const o=ke.findObj(e,"totalLocal");return o?.item?o.item:(!t||o instanceof re||t.noObj(e),o instanceof re?o:null)}function qe(e){return!e.$.eyesClosed||(e.say("Sorry, I can't do that with my eyes closed Cap'n."),!1)}Ue.pirates=()=>ke.currentRoom().items().filter((e=> e instanceof ze)),Ue.A.examine=()=>{0==Ue.pirates().length&&W.msg("There's nobody here."),Ue.pirates().forEach((e=>{W.msg(e.defName+" is here.")}))},Ue.defName="the pirates",Ue.showInList=()=>!1,Ue.dontAssume=!0,Ue.isPlural=!0,Ue.A_.tell=(e,t)=>{Ue.pirates().forEach((e=>{ke.dispatch("tell",e,t)}))},Ue.A_.ask=(e,t)=>{Ue.pirates().forEach((e=>{ke.dispatch("ask",e,t)}))};const We=[[/^(n|north|s|south|e|east|w|west|ne|northeast|nw|northwest|se|southeast|sw|southwest|u|up|d|down|inside|outside)$/,(e,t)=>{e.tryGo(Le(t[0]))}],[/stay here|stop|(not|don't|stop) follow(ing)? (you|me)/,e=>{e.complyMsg(),e.$.following=!1}],[/\bfollow( me| you)?|(come|go|stay) with (me|you)/,e=>{qe(e)&&(e.complyMsg(),e.$.following=!0)}],[/\b(walk|run|go|move)\b (.*)/,(e,t)=>{const o=Le(t[2]);e.tryGo(o)}],[/\b(?:get|grab|take|pick up)\b (.*)/,(e,t)=>{if(!qe(e))return;const o=Be(t[1],e);o&&e.getObj(o)}],[/\b(?:drop|let go of)\b (?:the )?(.*)/,(e,t)=>{e.heldItem?.fuzzyMatches(t[1])?e.dropItem():e.noObj(t[1])}],[/^(?:give|hand over|hand)(?: me| you)?(?: the)?(.+?)(?: to me| to you)?$/,(e,t)=>{if(e.heldItem?.fuzzyMatches(t[1])){const t=e.heldItem;t.hideAll(),ke.$.inventory.push(t.id),W.msg(`${e.defName} hands you ${t.defName}.`)}else e.noObj(t[1])}],[/\b(?:tie|attach|secure)\b (.*?)(?: to (.*))?$/,(e,t)=>{if(!qe(e))return;const o=Be(t[1],e);if(o){const n=Be(t[2]);t[2]&&!n?e.noObj(t[2]):e.tie(o,n)}}],[/\b(?:climb up|scale|climb down|climb)\b(.*?)?$/,(e,t)=>{if(!qe(e))return;if(!t[1]||""==t[1])return e.climb();const o=Be(t[1],e);o&&e.climb(o)}],[/\b(?:untie)\b (.*)/,(e,t)=>{if(!qe(e))return;const o=Be(t[1],e);o&&e.untie(o)}],[/(close|shut)( your)? eyes/,e=>e.closeEyes(!0)],[/(open)( your)? eyes/,e=>e.closeEyes(!1)],[/\b(?:cut|chop|saw)\b(?: down)?(.*)/,(e,t)=>{if(!qe(e))return;const o=Be(t[1],e);o&&e.cut(o)}]];class ze extends le{constructor(e,t,o,n){super(e,t,o),this.$.roomId=n.id,this.$.itemsOn=[],n.addItem(this)}lookDesc(){ //!overridden for Violet let e=`${this.defName} is #draw{standing around||waiting for orders|waiting|standing} here`;return this.childrenOn()[0]&&(e+=`, ${this.they} is carrying ${this.childrenOn()[0].indefName}`),e+"."}climb(e){e||this.say("I don't know what you want me to climb."),this.say(`Sorry Cap'n I can't climb ${e.defName}.`)}tie(){this.say("Sorry Cap'n, I'm no good with knots.")}cut(e){this.say(`I can't cut ${e.defName} Cap'n.`)}say(e){W.msg("``"+e+"''")}complyMsg(){W.msg(this.defName+" says <>"),this.say("Aye aye, Cap'n")}closeEyes(e){this.$.eyesClosed!=e?(this.$.eyesClosed=e,this.say("Um that's a weird order, but okay Cap'n."),W.msg(`${this.defName} ${e?"closes":"opens"} ${this.their} eyes.`)):this.say("Aye aye, Cap'n. I'll keep my eyes "+(e?"closed.":"open."))}noObj(e){this.say("Sorry cap'n, I don't know which "+e+" you mean,"),W.msg(`<> #.softError{says ${this.defName}.}`)}whatNow(){this.say("Sorry cap'n, I'm afraid I don't understand what you want me to do,"),W.msg(`<> #.softError{says ${this.defName}.}`)}get heldItem( ){return this.childrenOn()[0]}getObj(e){return e.superHeavy?this.say(`Sorry Cap'n, ${e.defName} is too heavy for me to carry.`):e.tied?this.untie(e):(this.heldItem&&this.dropItem(),e instanceof ie?this.say(`I can't take ${e.defName}, Cap'n!`):(e.hideAll(),this.$.itemsOn.push(e.id),void W.msg(`${this.defName} takes ${e.defName}.`)))}dropItem(){j(1==this.$.itemsOn.length);const e=this.heldItem;e.hideAll(),this.room.$.items.push(e.id),W.msg(`${this.defName} drops ${e.defName}`)}processOrder(e){for(const[t,o]of We){const n=e.match(t);if(n)return o(this,n),!0}return!1}get room(){return ke.rooms[this.$.roomId]}set room(e){this.$.roomId=e.id}tryGo(e){const t=this.room.exits[e];if("string"==typeof t){this.room.msg(`${this.defName} leaves to the ${e}.`);const o=ke.rooms[t];this.go(o)&&o.msg(`${this.defName} arrives from the ${C(e)}.`)}else this.room.msg(`${this.defName} sees no way ${e}.`)}go(e){return this.move(this.room,e),this.room=e,!0}}ae("talkTo",ze,(e=>{e.$.following?Fe(e,"stay here","TO"):Fe(e,"follow you","T O")})),ae("examine",ze,(e=>{W.msg(e.desc),e.childrenOn()[0]&&W.msg(`<> ${e.They} is carrying ${e.childrenOn()[0].indefName}.`),e.$.eyesClosed&&W.msg(`<> ${e.Their} eyes are closed.`)})),ke.addAfterHook("enterRoom",((e,t,o)=>{o.items().filter((e=>e instanceof ze&&e.$.following&&!e.$.eyesClosed)).forEach((e=>{e.tryGo(t)}))})),ke.A.ask.before=(e,t)=>{e instanceof ze&&e.processOrder(t)&&ge()},ae("tell",ze,"string",((e,t)=>{e.processOrder(t)||e.whatNow()})),ae("offer",re,ze,((e,t)=>{e.requireHeld(),e.mayLetGo()||ge(),e.hideAll(),t.heldItem&&t.dropItem(),t.$.itemsOn.push(e.id),W.msg(`You give ${e.defName} to ${t.defName}.`)}));const _e=new le(["Thin Virge","Virge","Virge","Thin Virge","parrot"],"``Thin'' Virge is your trusty parrot. Despite his name he is a fat little guy.","n",[{resp:function(e){let t=ke.findObj(e,"all");return t=t?.candidates?.[0]??t,t?.hint&&et(t),"#.softError{#V# has nothing useful to say on the subject.}"}},{about:["virge","thin virge","himself","themself","themselves"],resp:"#V# winks, #p arrot{I'm #V#, your hint-providing parrot.}"},{about:[/hint/,/help/],for:[/hint/,/help/],resp:et},{about:[/bayou/],resp:()=>{"The Bayou"==ke.currentRoom().name()?et():et("bayou")}},{about:[/citrus/],resp:()=>et("citrus")},{about:[/c(e|e)cile/,/seamstress/],resp:()=>et("cecile")},{about:[/\bsails?\b/],resp:()=>et("sails")},{about:[/\bcannons?\b/],resp:()=>et("cannons")}]);_e.A.pet="You stroke your parrot on the head.",ae("show",re,_e,(e=>{e.hint&&et(e),W.msg("#V# looks at "+e.defName+" but has nothing to say about it.")})),_e.A_.tell="Union rules forbid hint-giving familiars from doing any non hint-giving work.",W.addProcessor(/#V#/g,"Virge");class Ke extends ie{constructor(e,t,o){super(e,t),this.extraActions=o}}const Ge=[new Ke(["tiny fedora","Indiana Jones hat"],"It's a tiny#fn{Well, parrot-sized.} brown fedora!",["looking for rare artefacts","making sure there aren't any snakes around"]),new Ke(["little horned helmet","viking hat"],"An adorable little hornet helmet.",["searching for mead","looking for mo nasteries to raid"]),new Ke(["small firefighter's helmet","hat"],"A little red firefighter's helmet.",["inspecting everything for fire safety"]),new Ke(["lil' top hat"],"An itsy bitsy black top hat with some silver medallion like thingys around it.",["singing something about a sweet child of his","shredding an air guitar"]),new Ke(["wee ten gallon hat"],"It's a cute lil' ten gallon#fn{#V#'s head diameter is about 6 times smaller than yours which would actually make it a 5.9 fluid ounce, or 175 milliliter, hat.} hat.",["searching for some cattle to rustle"])];ae("get",Ke,"You aren't the kind who would steal their own parrot's hat."),ke.addSimpleVerb("plugh",Ae("xyzzy"),{synonyms:["plover"]}),ke.A.xyzzy.before=()=>{const e=_e.$.details?.pop(),t=O((t=>t.id!=e),(()=>S(Ge)));_e.addDetail(t),ge("Something about Virge seems different.")},_e.A.examine.after=()=>{const e=_e.details()[0];_e.$.disabled&&W.msg("<> He is chewing a particularly sticky sticky piece of salt water taffy."),e&&W.msg(`<> He is wearing ${e.ind efName}.`),W.msg("<>\n#.instruction{If you're stuck, you can ask #V# for hints.}")},_e.lookDesc=()=>{let e=["on your shoulder","flying around","perched on your shoulder","looking around from his perch on your shoulder"];return e=e.concat(_e.details().flatMap((e=>e.extraActions))),"#draw{Virge|Thin Virge|Your parrot} is "+S(e)},ke.addAfterHook("enterRoom",((e,t,o)=>{o!=e&&(_e.move(o,e),W.msg(_e.lookDesc()))})),_e.dontAssume=!0;class Je{constructor(...e){be(),this.id=R(),this.hints=e}nextHint(){const e=ke.$[this.id]??0;let t;return e#.instruction{Hint ${Math.min(e+1,this.hints.length)} of ${this.hints.length}}`}}const Qe={citrus:new Je("#parrot{Have you looked everywhere?} asks #V#.","#parrot{Even in your cabin?}, asks #V#.","#parrot{Tangerines, including the one in the chest in your cabin, are a kind of citrus,} #V# reminds you."),bayou:"#parrot{The bayou is on the north side of town,} says #V#.",cecile:()=>ke.$.enteredCeciles ?"#parrot{We can buy some new sails if you want,} says #V#.":et("enterCeciles"),enterCeciles:new Je("#parrot{Have you tried just walking in the shop?} asks #V#.","#parrot{I guess Cecile hasn't forgiven you then,} #V# says, #parrot{she doesn't want to see you ever again.}","#parrot{Perhaps you could enter her shop wearing a disguise,} suggests #V#.","#parrot{There might be a disguise you can find somewhere in town,} says #V#.","#parrot{You might find a disguise in Tupelowood Square,} says #V#.","#parrot{You can take the fake beard from the statue in Tupelowood Square and wear it to enter Cecile's shop,} explains #V#."),sails:new Je("#parrot{Do we really need to change the sails?} asks #V#, lazily.","#parrot{If we really want to change the sails, we can probably find someone in town who can help,} says #V#.","#parrot{There's a seamstress who has a shop on Threadneedle Alley,} #V# reminds you."),cannons:new Je("#parrot{You can just buy a random cannon and hope it works or I guess you could try doing a little research,} says #V#","#parrot{Perhaps there's a publication that includes cannon reviews,} muses #V#","#parrot{I think you have an issue of Raider's Digest in the chest in your cabin. They frequently feature cannon reviews,} says #V#","#parrot{You should buy the Bursua set,} says #V#")},Xe=new Je("#parrot{We should inspect the ship to see what needs to be done most urgently,} recommends Virge.","#parrot{The ship is moored at the docks, to the south of Tupelowood Square. We should examine it to see what needs to be done to make it seaworthy,} #V# reminds you.");function Ze(e){return e instanceof Je?e.nextHint():"function"==typeof e?Ze(e()):e}function et(e){let t;ke.$.hintWarn||_e.$.disabled||(W.yesno((()=>{ke.$.hintWarn=!0,ke.dispatch("hint",e)}),"Really ask for a hint?",(()=>W.msg("Ok. By the way, you can permanently disable hints by giving #V# a piece of salt water taffy."))),ge("Are you sure you want to enable hints?")),e instanceof re&&(t=Ze(e.hint)),!t&&e&&(t=Ze(Qe[e])),e&&!t&&(t="#.softError{#V# looks apologetic,} #parrot{Sorry, I don't have anything on the subject.}"),!t&&ke.currentRoom().hint&&(t=Ze(ke.currentRoom().hint)),t||(t=Ze(function(){if(!ke.$.xedShip)return Xe;if(!ke.$.noteRead)return"#V# says, #parrot{We need to fix the hull most of all. Maybe there's somebody in this town who can help with that.}";if(!ke.$.henryOut)return"#parrot{We should look for Henry and ask him to fix the hull,} says Virge.";if(!ke.$.soberHenry&&!ke.$.seekRose)return"#parrot{We have to get Henry sober so he can patch up the Pink Flamingo's hull,} says #V#.";if(!ke.$.soberHenry&&!ke.$.gotPotion)return"#parrot{We need to bring a swamp rose blossom and some kind of citrus to the mambo so she can brew a potion to get Henry sober,} #V# reminds you.\n#.instruction{You can ask #V# about those items if you need help finding them.}";if(!ke.$.gotQuote)return"#parrot{Henry said he'd give us a quote. We should check up on that,} says #V#.";if(!ke.$.henryPaid&&ke.$.gold<120)return"#parrot{We need more doubloons to pay for the hull repairs, maybe we can get some from the bank?} asks #V#.";if(!ke.$.henryPaid)return"#parrot{We have enough cash to pay Henry for the hull repairs,} notes #V#.";if(!(ke.$.embarked||ke.$.cannons&&ke.$.betterSails)){let e=[];return ke.$.cannons||e.push("buy some new cannons"),ke.$.betterSails||e.push("get some better sails"),e=e.join(" or "),`#parrot{With the hull fixed we could call it a day, or we could also try to ${e} before we go to bed,} says #V#.`}return ke.$.embarked?void 0:"#parrot{The Pink Flamingo is as good as we're going to get it before the race. We should go to bed,} says #V#"}())),t||(t="#.softError{Sorry, I don't know what you are stuck on, perhaps you should ask your parrot about something specific.}"),ge(t)}ke.addSimpleVerb("hint",et),I.addVerb("hint",{action:"hintX",codKind:"string"}),ae("hintX","string",Ae("ask",_e,"cod")),ae("hint","*",(e=>et(e)));const tt=new re(["piece of salt water taffy","taffy","caramel"],"A piece of extra sticky salt water taffy.\n#.instruction{Give it to your parrot to disable hints permanently.}");tt.A.eat="No thanks! Sammy once gave one to Purplebeard and he couldn't speak for two weeks!",ae("offer",tt,_e,(()=>{tt.requireHeld(),W.msg("Giving #V# the taffy will permanently stop him from giving you hints. Are you sure you want to do this?"),W.yesno((()=>{tt.hideAll(),W.msg("#V# starts chewing the taffy."),_e.$.disabled=!0}),"Really disable hints?",(()=>W.msg("Nevermind.")))})),W.addProcessor(/#parrot\{(.+?)\}/gi,((e,t)=>(_e.$.disabled&&(t=(t=t.replace(/[a-ze]/g,(()=>S(["m","n"])))).replace(/[A-Z]/g,"M")),"#.parrot{``"+t+"''}")));const ot=new ie(["sand","wall","floor","ceiling"],"The castle is made of slightly damp sand.");class nt extends de{constructor(){super(...arguments),this.A.wake=St,this.hint=new Je("#parrot{You seem to be in some kind of daydream,} offers #V#.","#parrot{You could try opening your eyes,} suggests #V#."),this.addItem(ot),this.addAfterHook("examine",(e=>{"myself"==e.defName&&W.msg("You can somehow see that your eyes are closed.")}))}}const at=new nt("On the Drawbridge","You are standing on the drawbridge. A large gate to the north leads into the castle.");at.decor(["drawbridge","bridge"],"It's made out of some driftwood.");const st=at.decor(["gate","large gate"],"It leads into the castle to the north.");at.decor(["sand castle","castle"],"A magnificent sand castle, towering above you.");const rt=new nt("Great Hall","You are in the castle's entrance hall. The throne room is to the north. A door in the sand wall leads east. There are some stairs going up and down. Back south is the gate that leads out to the drawbridge.");rt.decor(["stairs"],"The stairs lead up and down from the great hall.");const it=new nt("Throne Room","You are in a large room with a throne made of seashells in the back. The only door leads south back towards the great hall."),lt=it.decor(["throne","seashells","seashell throne"],"A throne fit for a queen. Nay, an empress!");it.A.sit=lt.A.sitOn="You briefly sit on the seashell throne but it isn't actually that comfortable so yo u quickly stand up again.";const ht=new nt("The Dark and Damp Dungeon","It is dark here. You are likely to be shown the way out by a helpful grue. You can feel a stairway leading up."),dt=new nt("The Kitchen","You are in the castle's kitchen. All the ``food'' is seaweed and bits of seashells though. The great hall is to the west."),ut=dt.decor(["food","seaweed","seashells"],"Bits of seaweed and seashell posed to look like food if you look from afar, which you aren't.");ut.A.eat="It only #.emph{looks} like food.",ut.A.get="No thanks.";const ct=new nt("First Floor Landing");ct.desc=()=>{let e="";return ct.$.seen||(e="#fn{Assuming you start counting at zero like a sensible person}",ct.$.seen=!0),`You are on the first${e} floor landing. A hallway leads east. The stairs go up and down.`};const mt=new nt("Hallway","You are in a hallway. Out little windows you can see some giants. West is the landing. Doorways lead north and east.");mt.decor("windows","Little windows made of seashells and bits of driftwood. Outside you can see some giants.");const gt=new le(["giants"],"You see three towering giants outside: Violet, Marvin and, bizarrely, yourself.",void 0,[{resp:"They can't hear you."}]);gt.A.talkTo="They can't hear you.";const yt=new le(["the giant Jenny Weigh","first","1","giant","me"],"You look up to yourself -- it's an odd feeling. You can see that your eyes are closed.","f",[{resp:"You can't hear yourself."}]);yt.A.talkTo="Talking to yourself? That's crazy!";const ft=new le(["the giant Violet","second","2","giant"],"A giant version of Violet is standing around idly.","f",[{resp:"Violet can't hear you."}]);ft.A.talkTo="She can't hear you.";const pt=new le(["the giant Marvin","third","3","giant"],"An enormous Marvin is standing outside the castle, towering above it.","m",[{resp:"Marvin can't hear you."}]);pt.A.talkTo="He can't hear you.",pt.showInList=ft.showInList=yt.showInList=gt.showInList=()=>!1,mt.addItem(gt),mt.addItem(yt),mt.addItem(ft),mt.addItem(pt);const bt=new nt("Royal Bedroom","There is a little bed ma de of seamoss here. There are doorways to the east and south."),wt=bt.decor(["bed","seamoss"],"The bed looks unexpectedly comfortable considering it is made of seamoss.");wt.goExit=wt.A.enter=bt.A.sleep=()=>ge("You enter the bed and fall asleep. You dream of a person, identifying themselves only as #.emph{the author}, apologizing for not implementing an awesome ``Inception'' sequence. You wake up confused and unsure as to what that was all about.");const kt=new nt("Royal En-suite Bathroom","The royal bathroom contains a sink, a toilet, and a #.emph{clawfoot bathtub}. The bedroom is back to the west."),vt=kt.decor(["clawfoot bathtub","tub","bathtub","bath"],"It's the obligatory #.emph{clawfoot bathtub}! It is made out of seashells.");vt.A.get=vt.goExit=vt.A.use=vt.A.enter=()=>ge("No need, you bathed just a few months ago."),kt.decor(["sink"],"It is shaped just like a clamshell. In fact it #.emph{is} a clamshell.");const $t=kt.decor(["toilet"],"Like everything else in this room, it is made of seashells.");$t.A .use=$t.A.sitOn="You don't need to use the toilet right now.";const At=new nt("Treasury","You are in the castle's treasure room. The doorway out is to the west."),Yt=new nt("Tower","You are atop the castle's tallest tower. You see some giants milling about. Stairs lead down.");Yt.addItem(gt),Yt.addItem(yt),Yt.addItem(ft),Yt.addItem(pt),at.addSymExit(rt,"north"),rt.addSymExit(it,"north"),rt.addSymExit(ht,"down"),rt.addSymExit(dt,"east"),rt.addSymExit(ct,"up"),ct.addSymExit(mt,"east"),mt.addSymExit(bt,"north"),bt.addSymExit(kt,"east"),mt.addSymExit(At,"east"),ct.addSymExit(Yt,"up"),st.A.enter=st.goExit=Ae("go","north");const It=new re("black pearl","A shiny black pearl.");It.endValue=95,It.endMsg="You sell the black pearl for 95 doubloons.",It.hint="#parrot{Looks valuable.}",At.addItem(It);const Tt=new ie("eyes","Your eyes are closed.");function St(){Tt.hideAll(),W.msg("You open your eyes and find yourself back on the beach."),ke.rooms[at.$.prevRoom].enter("outside")}function xt(e,t){const o=new de(e,t);return o.addItem(Ue),o.hint=Rt,o}function Et(){Qt.$.cut||ge("You need to get a new mast for the Pink Flamingo before you can leave."),Qt.$.tied||ge("You need to bring the mast with you."),Ut.room==Nt&&Lt.room==Nt||ge("You can't abandon your crew on the island."),"bad"==Qt.$.tied&&(Qt.$.tied=!1,Nt.addItem(Wt),ge("The knot securing the mast to the rowboat comes undone. Luckily it does so before you pushed either into the ocean.")),$o("storm_reboard"),ge()}Tt.A.open=St;const Nt=xt("Beach","Your rowboat is pulled up on the beach here. You can see the Pink Flamingo moored in the natural harbor to the south. To the north is a sheer cliff. A path to the east climbs gently into the heart of the island."),Vt=xt("Jungle (south)","The path from the beach to the west curves northwards towards higher ground."),Pt=xt("Jungle (north)","Near a large skull shaped rock the path from the south bends westward towards the top of the cliffs."),Ot=xt("Top of the Cliffs","You are at the top of some steep cliffs. There are some tall pine trees here. You can see the beach where you landed far below to the south. East is the forest."),Ct=$e("#parrot{Welcome To The Jungle,} says Virge.");Vt.A.enterRoom.after=()=>{_e.details()[0]?.defName?.includes("top hat")&&Ct()},ke.addSimpleVerb("make sandcastle","#.softError{I don't understand.}",{actionName:"sandcastle",synonyms:["make sand castle","build sand castle","build sandcastle","make a sand castle","build a sand castle","build a sandcastle"]});const Ht=new re(["sand castle","sandcastle","moat","seashells","seaweed"],"A magnificent sand castle you made with Violet and Marvin. It has little seashell windows on its many towers. It has a moat that is fed with water from the receding tide and the roofs are thatched with seaweed.");Ht.A.get="Sadly you can't bring the sand castle with you but you'll always treasure the memories.",Ht.goExit=Ht.A.enter=()=>{return e=Nt,at.$.prevRoom=e.id,W.msg("You close your eyes and imagine yourself entering the sand castle."),ke.$.inventory.push(Tt.id),void at.enter("o utside");var e};const jt=Nt.decor(["sand","beach"],"The beach is made of beautiful and very fine white sand. Perfect for making sand castles!");Nt.A.dig=Nt.A.sandcastle=jt.A.dig=$e((()=>{W.msg("You spend about an hour with Violet and Marvin, building a sand castle. It looks glorious!"),Nt.addItem(Ht),ke.itIs(Ht)}),"Enough fooling around, you need to get a new mast for the Pink Flamingo.");const Dt=new Je("#parrot{We should look around the island for a tree that is suitable for making a mast,} suggests #V#.","#parrot{Only Marvin can fell trees,} says #V#.","#parrot{Marvin is afraid of the skull rock,} says #V#.","#parrot{Perhaps there's another way to the top of the cliffs that doesn't go by the scary rock?} wonders #V#.","#parrot{Only Violet can climb the cliff face unassisted,} says #V#","#parrot{Did you bring anything along that might help?} asks #V#","#parrot{There's a rope in your rowboat,} says #V#","#parrot{You're no good with knots but surely you know an expert rigger,} says #V#.","#parrot{TELL Violet to tie the rope to a tree,} explains #V#"),Mt=new Je("#parrot{Now you just need to get the mast over to the Pink Flamingo,} says #V#","#parrot{The mast is too heavy to carry and too large to fit in the rowboat,} remarks #V#","#parrot{You could tow the mast,} suggests #V#","#parrot{You'd need rope of course,} says #V#","#parrot{You only brought one rope with you to the island,} remarks #V#","#parrot{Can't untie the rope? That's quite the Gordian knot,} says #V#","#parrot{Cut the knot with Marvin's axe}, says #V#","#parrot{You're rubbish at knots, but Violet isn't,} #V# tactlessly reminds you.","#parrot{Ask Violet to tie the mast to the rowboat, then we can leave,} says #V#");function Rt(){return Nt.containsItem(Qt)||Nt.containsItem(zt)?Nt.containsItem(Qt)?Mt:"Now Marvin can get to the top of the cliffs to fell a tree":Dt}Nt.obstacle="the rowboat",Ot.obstacle="a pine tree",Vt.obstacle="a small tree",Vt.addSymExit(Nt,"west"),Pt.addSymExit(Vt,"south"),Pt.addSymExit(Ot,"west"),Nt.exits.south_=Et,Nt.exits.up_=Nt. exits.north_=so(Ot,"up","You climb up the rope.","The cliffs are too steep for you to climb."),Ot.exits.down_=Ot.exits.south_=so(Nt,"down","You reluctantly climb down the rope","#you{Free climb down the cliff? Nope. That's not happening.}");const Ft=Vt.decor(["trees","small tree"],"Small trees, entirely unsuitable for most mast purposes.");Ft.A.cut="Those little trees are not suitable.",Pt.addItem(Ft);const Ut=new ze(["Violet","nimble violet","pirate"],"Violet is the Pink Flamingo's expert rigger. She's always climbing up the masts, jumping from spar to spar as if it were nothing and, unlike you, she's great with ropes.","f",Nt);Ut.addDetail(["string","piece of string","bit of string"],"Violet is always practicing her knot work. She's incredible at it."),Ut.lookDesc=()=>{let e="Violet is #draw{standing around||waiting for orders|waiting|standing|practicing knots on a bit of string|playing with a piece of string} here";return Ut.childrenOn()[0]&&(e+=`, she is carrying ${Ut.childrenOn()[0].indefName}`), e+"."},Ut.topics=[{resp:"Violet just shurgs."},{about:["herself","violet",/^themsel(f|ves)$/],resp:"#violet{Hi Cap'n, I'm practicing tying monkey's fist knots,} says Violet showing you her piece of string."},{about:["skull","skull rock","rock","boulder"],resp:"#violet{It's pretty spooky.}"},{about:["marvin",/cannibals?/],resp:"#violet{Aye, it be terrible what those cannibals did to Marvin,} says Violet."}],Ut.say=e=>W.msg(`#violet{${e}}`);const Lt=new ze(["Marvin","mute marvin","pirate"],"A stout, middle-aged man, Mute Marvin is the ship's carpenter. He isn't technically mute but was disemvoweled by a tribe of cannibals.","m",Nt);Lt.say=e=>W.msg(`#marvin{${e}}`),Lt.topics=[{resp:"#marvin{I don't know anything about that, cap'n,} says Marvin."},{about:["marvin","himself",/themsel(f|ves)/],resp:"#marvin{I can't speak very well thanks to those blasted cannibals, but I'm still the best darned carpenter you'll ever meet,} answers Marvin proudly."},{about:["cannibals","cannibal","disemvowelment"],resp:"#marvin{Hor rible cannibals! They caught us, me and Gerald, back in '53 you know. The bastards ate Gerald. I managed to get away, but not before they'd disemvoweled me. Been like this ever since,} he sighs."},{about:["skull","skull rock"],resp:"#marvin{I'm sure the cannibals are responsible for that rock. I'm not going anywhere near it!}"},{about:["Gerald"],resp:"#marvin{He was a great guy, Gerald. I miss him dearly,} sighs Marvin."}];const Bt=new re(["large axe","axe","large iron axe"],"A large and very heavy iron axe.");Bt.largeish=!0,Lt.$.itemsOn=[Bt.id],Bt.cutter=!0;const qt=Nt.decor(["rowboat","row boat","boat"],"A medium sized rowboat.");qt.A.push=qt.A.enter=Et,Nt.decor(["ship","Pink Flamingo"],"The Pink Flamingo is moored to the south. Her main mast has snapped."),Nt.A.swim="You don't really care for swimming so it's a good thing you brought a rowboat",Nt.decor(["sea","ocean","natural harbor"],"The Caribbean sea is blue, warm, and rather moist.").A.enter=Ae("swim",null),Nt.decor(["path"],"It climbs eastwards into the heart of the island.");const Wt=new re(["coil of rope","rope"],"A coil of rope.");qt.$.itemsIn=[Wt.id];const zt=new re(["hanging rope","rope","knot"],"The rope is dangling from a tree at the top of the cliff down to the beach below.");function _t(){Wt.requireHeld(),Wt.hideAll(),zt.$.knot="bad",W.msg("Despite being no good with knots, you fasten one end of the rope to one of the trees then toss the other end over the ledge towards the beach."),Ot.addItem(zt),Nt.addItem(zt)}function Kt(){if(Ut.heldItem!=Wt){if(!Nt.containsItem(Wt))return Ut.say("I don't have the rope.");Ut.getObj(Wt)}Ut.msg("Violet attaches the rope to the mast and then fastens it to the rowboat."),Wt.hideAll(),Qt.$.tied=!0}function Gt(){if(Ut.heldItem!=Wt)return Ut.say("I don't have the rope.");Wt.hideAll(),zt.$.knot="good",W.msg("Violet expertly secures the rope to one of the trees with a bowline."),Ot.addItem(zt),Nt.addItem(zt)}zt.tied=!0,zt.lookDesc=()=>ke.currentRoom()==Nt?"a rope dangling from the top of the cliff":"a rope tied to t he tree and dangling down towards the beach",zt.A.pull=()=>{W.msg("You give the rope a test tug."),"bad"==zt.$.knot?ke.currentRoom()==Nt?(W.msg("<> The knot comes undone and the rope comes crashing down."),zt.hideAll(),Nt.addItem(Wt)):(W.msg("<> The knot comes undone and you find yourself holding onto the rope."),zt.hideAll(),ke.$.inventory.push(Wt.id),ke.itIs(Wt)):W.msg("<> It seems to be holding.")},zt.A.untie=zt.A.get=()=>{ke.currentRoom()==Nt?W.msg("The rope is fastened to a tree far, far above you."):W.msg("You try to untie the rope but you're no good with knots.")},zt.A.climb=()=>{ke.currentRoom()==Nt?ke.dispatch("go","up"):ke.dispatch("go","down")},ae("cut",zt,Bt,(()=>{ke.currentRoom()!=Ot&&ge("Nah, that wouldn't help"),W.msg("You take the Alexandrian approach and slice though the knot. You watch as the rope falls down towards the beach."),zt.hideAll(),Nt.addItem(Wt)}));const Jt=Ot.decor(["trees","tree","pine","pine trees","pine tree"],"Some kind of tall pine trees are growing here. While not quite as perfect for masts as the eastern white pines of New England, they will do quite nicely.");Jt.A.climb="You are quite high enough as is.",ae("cut",Jt,Bt,"You don't know the proper lumberjaning technique, you'd probably only manage to maim yourself. Better let Marvin handle the wood cutting."),Jt.A.get=Ae("cut");const Qt=new re(["mast","spar"],"The Pink Flamingo's new main mast. You just need to bring it back to the ship.");function Xt(){ke.playerHas(Wt)||(ke.currentRoom().containsItem(Wt)?Wt.requireHeld():ge("You need rope")),Wt.hideAll(),Qt.$.tied="bad",W.msg("You attempt to tie one end of the rope to the mast and the other to the row boat.")}Qt.superHeavy=!0,Qt.lookDesc=()=>"a mast"+(Qt.$.tied?" which is tied to the rowboat":""),ae("tieTo",Wt,Qt,Xt),ae("tieTo",Qt,Wt,Xt),ae("tieTo",qt,Qt,Xt),ae("tieTo",Qt,qt,Xt),ae("tie",Qt,null,Xt),Qt.A.get="The mast is too heavy to carry.",Qt.A.examine.after=()=>{Qt.$.tied&&W.msg("It is tied to the rowboat.")},qt.A.examine.after=()=>{Qt.$.tied&&W.msg("It is tied to the mas t.")},Qt.A.push=()=>{Qt.$.tied?Et():W.msg("You could push it into the water but it would drift away and you'd lose it.")},Ot.decor(["cliffs"],"The cliffs drop down rather vertically from here. You'd describe them in more detail but that would require getting closer to the edge."),Ot.decor(["beach"],"It looks tiny from up here."),Ut.tie=(e,t)=>e==qt&&t==Qt||e==Qt&&t==qt||e==Qt&&null==t?Kt():e!=Wt?Ut.say(`Sorry boss, I can't tie ${e.defName}.`):t||Ut.room!=Ot?t==Jt?Gt():t==Qt?Kt():void(t?Ut.say(`Sorry Cap'n, I can't tie the rope to ${t.defName}.`):Ut.say("Sorry Cap'n, I don't know what you want me to tie the rope to.")):Gt(),ae("tie",Wt,null,Ot,_t),ae("tieTo",Wt,Jt,Ot,_t),ae("drop",Wt,null,Ot,_t),ae("throw",Wt,null,Ot,_t);const Zt=Nt.decor(["cliffs","cliff"],"The cliffs go up almost vertically.");Zt.A.climb=Ae("go","north");const eo=new re(["treasure"],"A treasure trove the likes of which you hadn't even dared dream."),to=[eo.addDetail(["rare coins","ducat","dinar","denarii","drachmai","dollars"],"These are no ordinary pieces of eight! They're ancient, rare, and mint condition ducats, dinars, doubloons, denarii, drachmai, and dollars!"),eo.addDetail("sparkling diamonds","There must be at least 69105 carats worth of diamonds!"),eo.addDetail(["jeweled scarab","scarab"],"A Cheops of the Fourth Dynasty!"),eo.addDetail(["rubies","ruby","gavinchian rose"],"Rubies of all sorts of cut and shade! The most beautiful is doubtlessly the one shaped like a rose."),eo.addDetail("jade statuettes","A collection of magnificent jade statuettes. Enough for several chess sets."),eo.addDetail("silver bars","A couple dozen bars of silver.")];to.forEach((e=>{e.A_.offer.before=e.A.drop=e.A.mayLetGo.before=()=>ge("You can't won't part with "+e.defName)})),eo.inventoryName=()=>to.map((e=>e.indefName)).join("\n - "),eo.A_.offer.before=eo.A.mayLetGo.before=()=>ge("No way, you aren't parting with this treasure!"),ke.addSimpleVerb("db magicword",(()=>W.msg(Ve[ke.$.medIdx])));const oo=Pt.decor(["skull rock","skull","rock","boulder"],"It' s a large, roughly spherical, basalt boulder that's a little more than 2 meters in diameter and that looks uncannily like a giant skull.");oo.hint=new Je("#parrot{Marvin is afraid of the skull rock. You'll have to either hide it or get Marvin around some other way,} says #V#","#parrot{You can't hide or move the rock,} remarks #V#","#parrot{Marvin will have to get to the top of the cliffs via some other route,} says #V#"),oo.A.move=oo.A.push="Knowing the formula for the volume of a sphere#fn{ #.frac{4/3} π r3 } and that the density of basalt is about 2850 kg/m3, you can easily estimate the mass of the boulder.\nSpoiler alert: you can push it all you want; it's going nowhere.";const no=oo.addDetail(["skull's mouth","mouth"],"The skull seems to be grinning.");oo.A.lookInside=Ae("lookInside",no),oo.A.examine.before=()=>{no.$.open||ge(oo.desc),W.msg("The skull's mouth is open!"),ke.dispatch("lookInside",oo),ge()},no.$.itemsIn=[eo.id],no.$.open=!1,oo.A.climb="You don't really care for clim bing.",no.A.open=oo.A.open="As far as you know that isn't something you can open.",no.A.close=oo.A.close="As far as you know that isn't something you can close.";const ao=$e((e=>{W.msg("``"+V(e)+",'' you say, unsure what to expect.\nAt first nothing happens, but soon you hear a grinding noise coming from the skull. Its mouth opens and inside is a fabulous treasure! Coins, diamonds, rubies, jade statuettes galore!\nYou're rich!"),no.$.open=!0}),(()=>{no.$.open?(no.$.open=!1,W.msg("The skull's mouth closes.")):(no.$.open=!0,W.msg("The skull's mouth opens."))}));function so(e,t,o,n){return()=>{Ot.containsItem(zt)||ge(n);const a=ke.getItems("directInventory").filter((e=>e.largeish));a.length>0&&(W.msg("You drop your large items in order to climb safely."),a.forEach((e=>ke.dispatch("drop",e)))),"bad"==zt.$.knot?(W.msg("The knot comes undone and you find yourself holding the rope."),zt.hideAll(),ke.$.inventory.push(Wt.id)):(W.msg(o),e.enter(t)),ge()}}function ro(e){e.heldItem&&(W.msg(`${e.They} needs both hands to climb the rope so <>`),e.dropItem()),"bad"==zt.$.knot?(W.msg(`${e.defName} grabs the rope and gives it a pull and the knot comes undone!\nThe rope falls down to the beach.`),zt.hideAll(),Nt.addItem(Wt)):e.room==Nt?(W.msg(`${e.defName} climbs up the rope`),e.go(Ot)):(W.msg(`${e.defName} climbs down the rope.`),e.go(Nt))}Pt.A.look.after=()=>{no.$.open&&no.childrenIn().length>0&&(W.msg("The skull's mouth is open!"),ke.dispatch("lookInside",oo))},Pt.A.sayMagic=e=>{e.toUpperCase()==Ve[ke.$.medIdx]?ao(e):(W.msg("#.emph{CHEATER!} booms out a loud voice.\nThe skull's eyes begin to glow a deep red and suddenly you are attacked by a swarm of bees.\nYou try to run but you are too slow."),ke.die("Not the bees!"))},Ut.tryGo=e=>Ut.$.eyesClosed?Ut.say("Not with my eyes closed Cap'n."):Ut.room!=Nt||"up"!=e&&"north"!=e?Ut.room!=Ot||"down"!=e&&"south"!=e?ze.prototype.tryGo.call(Ut,e):(W.msg("Violet climbs down the cliff."),Ut.go(Nt)):Ut.climb(Zt),Lt.tryGo=e=>Lt.$.eyesClosed?(Lt.$.eyesClosed=!1,W.msg(`With his eyes closed, Ma rvin walks straight into ${Lt.room.obstacle}. He curses and opens his eyes.`)):Lt.room!=Nt||"up"!=e&&"north"!=e?Lt.room!=Ot||"down"!=e&&"south"!=e?ze.prototype.tryGo.call(Lt,e):Ot.containsItem(zt)?ro(Lt):Lt.say("Sorry Cap'n I can't climb down without a rope."):Lt.climb(Zt),Lt.go=e=>e==Pt?(Pt.msg("Marvin arrives and sees the skull shaped rock. #marvin{Oh no! Cannibals! Run away, run away!} he exclaims before running off to the south."),Lt.go(Vt),Lt.room.msg("He quickly comes running back screaming: #marvin{The skull rock! It can only mean that there are cannibals on the island!}"),!1):ze.prototype.go.call(Lt,e),Ut.climb=e=>(e||Ut.room!=Nt||(e=Zt),e||Ut.room!=Ot?e?void(e==zt?ro(Ut):e==Zt?(Ut.go(Ot),W.msg("Violet nimbly climbs up the cliff.")):Ut.say("Sorry Cap'n, I can't climb that.")):Ut.say("Sorry Cap'n, I don't understand what you want me to climb."):Ut.tryGo("down")),Lt.climb=e=>{if(e||Lt.room!=Nt||(e=Zt),!e&&Lt.room==Ot)return Lt.tryGo("down");if(e==Zt){if(!Nt.containsItem(zt))return Lt.say("Sorry Cap'n, I'm not all nimble like Violet. The only way I'm scaling those cliffs is if there's a rope installed.");e=zt}e==zt?ro(Lt):Lt.say("Sorry Cap'n, I can't climb that.")},Lt.cut=e=>{if(Lt.heldItem!=Bt){if(!Lt.room.containsItem(Bt))return Lt.say("Sure thing Cap'n, but I need my axe to cut things.");Lt.getObj(Bt)}if(e==Jt){if(1==Qt.$.cut)return W.msg("Marvin's already cut a new mast.");Qt.$.cut=!0,W.msg("Marvin selects a nice straight tree that will make a good mast and chops it down. He proceeds to trim it into a perfect spar then rolls it over the edge onto the beach below."),Nt.addItem(Qt)}else if(e==Ft)Lt.say("But Cap'n, those trees are way to small to be of any use.");else{if(e!=zt||Lt.room!=Ot)return ze.prototype.cut.call(Lt,e);W.msg("Marvin swings his axe through the knot. You watch as the rope falls down towards the beach."),zt.hideAll(),Nt.addItem(Wt)}},Lt.untie=Ut.untie=function(e){e==zt?this.room==Ot?this==Ut?W.msg("Violet looks at you sheepishly, #violet{I can't seem to untie the knot.}"):this.say("Sorr y Cap'n, I can't seem to untie the knot."):this.say("But Cap'n, the knot is at the other end, far above."):this.say("Sorry Cap'n, I can't untie it.")},Lt.A.talkTo.before=()=>{Lt.room==Ot&&Lt.heldItem==Bt&&(Fe(Lt,"cut the tree","TO"),ge())},Ut.A.talkTo.before=()=>{Ut.heldItem==Wt&&(Ut.room==Nt&&Nt.containsItem(Qt)&&(Fe(Ut,"tie the mast to the rowboat","TO"),ge()),Ut.room==Ot&&(Fe(Ut,"tie the rope to a tree","TO"),ge()))},Lt.A.blindfold="You don't have a suitable blindfold with you, but you could just ask him to close his eyes.",ae("putOn",Qt,qt,"The mast won't fit on the rowboat."),ae("putIn",Qt,qt,"The mast won't fit in the rowboat.");const io=[{name:"Charlotte Noire",initialTime:10,they:"she",their:"her"},{name:"Cap'n Quartz",initialTime:15,they:"they",their:"their"},{name:"Calico Sammy",initialTime:23,they:"they",their:"their"},{name:"Purplebeard",initialTime:29,they:"he",their:"his"}];ke.$.pirateTimes=io.map((e=>e.initialTime));const lo={};function ho(e,t){Object.assign(lo,function(e,t){function o(e){retu rn e.startsWith("$")?ke.$[e.slice(1)]:e}function n(e){if(e.includes("==")){const[t,n]=e.split("==");return ke.$[t]==o(n)}if(e.includes("!=")){const[t,n]=e.split("!=");return ke.$[t]!=o(n)}return"!"==e[0]?!ke.$[e.slice(1)]:"@"==e[0]?s[e.slice(1)]():ke.$[e]}const a={},s={fireCannons:()=>{ke.$.cannonDangerous&&(W.msg("Unfortunately one of your shoddy cannons explodes violently. The Pink Flamingo's hull is torn up below the waterline and despite your crew's best efforts she sinks."),s.gameOver("Your ship has sunk")),ke.$.cannonFragile&&(ke.$.cannons=!1,W.msg("You are dismayed to find that after firing only a few shots your cannons fall apart. Unreliable schlock!"))},disableUndo:()=>{U("undo")?.classList?.add("disabled")},enableUndo:()=>{U("undo")?.classList?.remove?.("disabled")},if:e=>{const[t,o]=e.split(/ (.+)/);n(t)&&W.msg(o)},jumpif:e=>{const[t,o]=e.split(/ (.+)/);n(t)&&(ke.dispatch("_innerDoPsg_",r(o)),ge())},duel:e=>{const t=h[ke.$.currentPassage];!function(){[mo,go,yo]=arguments,fo=0,bo()}(t.choices[0].ta rget,t.choices[1].target,a[e]),ge()},"gainMedallion?":()=>{ke.$.inventory.push(Re.id)},examine:e=>{ke.dispatch("examine",ke.findObj(e,"all"))},"gainMoney?":e=>ke.$.gold+=Number(e),"addPirateTime?":e=>{let[t,o]=e.split(" ");"TARGET"==t&&(t=ke.$.target),ke.$.pirateTimes[t]+=Number(o)},gameOver:e=>{W.msg("\n#.dead{"+e+"}"),W.msg("\nYou wonder what would have happened if you'd made different choices. Alas, one can't just travel back and undo the errors of the past."),W.msg("Or can they?"),ge()},haveTreasure:()=>ke.playerHas(eo),loseTreasure:()=>eo.hideAll(),hasMagic:()=>ke.getItems("totalInventory").some((e=>e.givesMagic)),"useMagic?":()=>{const e=ke.getItems("totalInventory").find((e=>e.givesMagic));e.hideAll(),ke.$.magicItem=e.defName},haveGold:e=>ke.$.gold>=e,isset:e=>ke.$[e],kniknaToggle:()=>{ke.$.knikna=!ke.$.knikna},set:e=>{const[t,o]=e.split(/ (.+)/);ke.$[t]=JSON.parse(o)},doBeach:()=>{ko(),delete ke.$.currentPassage,Nt.enter("sea"),ge()},win: ()=>{ko(),function(){const e=io.map(((e,t)=>({name:e.name,time:ke.$.pirateTimes[t]})));e.push({name:"Jenny Weigh",time:Number(ke.$.raceTime)});const t=e.sort(((e,t)=>Number(e.time)-Number(t.time)));console.log(t),W.msg("#.emph{Race Results}"),W.msg("#.handWritten{"+t.map(((e,t)=>`${t+1}${["st","nd","rd","th","th"][t]} ${e.name}`)).join("\n")+"}");const o=t.findIndex((e=>"Jenny Weigh"==e.name)),n=t.findIndex((e=>e.name.includes("Sammy"))),a=["first","second","third","fourth","last"][o],s=["the golden Libonotus Cup","a silver salver","a bronze urn","a copper medal","a participation ribbon"][o],r=[2500,1800,1500,250,7][o];ke.$.gold+=r,W.msg(`\nYou arrived ${a} and receive ${r} doubloons and ${s}.`),ke.$.rumMoney&&(ke.$.gold+=ke.$.rumMoney,W.msg(`<> You sell the rum you looted from the Spanish for ${ke.$.rumMoney} doubloons.`)),ke.playerHas(eo)&&(ke.$.gold+=2534637),ke.$.gold+=ke.getItems("totalInventory").reduce(((e,t)=>e+(t.endValue??0)),0),o You also get 500 doubloons fr om Sammy for winning your bet.")):(ke.$.gold-=500,ke.$.gold<0?W.msg(`<> You lost your bet with Sammy and hand them all your doubloons and as well as an IOU for the remaining ${-ke.$.gold} doubloons.`):W.msg("<> You lost your bet with Sammy and hand them 500 doubloons.")),ke.getItems("totalInventory").filter((e=>e.endMsg)).forEach((e=>W.msg(e.endMsg+" <>"))),ke.$.gold>=303?W.msg("<> You pay back 303 doubloons (including interest) to the Crimson Permanent Assurance."):W.msg("<> You still owe the Crimson Permanent Assurance 303 doubloons (including interest)."),ke.$.gold-=303,ke.playerHas(eo)&&W.msg("Oh, and you also have a treasure worth several million doubloons."),W.msg("\nAs you are sitting with your friends in the Portobello tavern you reflect on how much fun it all was. But of course the real treasure is the booty you looted along the way."),ke.$.gold<0?W.msg(`You ended the race with a debt of ${-ke.$.gold} doubloons.`):ke.$.gold>1e6?W.msg(`You ended the race with millions#fn{${ke.$.gold.toLocaleString("e n-uk")} if you really need to know the exact number.} of doubloons.`):W.msg(`You ended the race with ${ke.$.gold} doubloons.`),console.log("[Time]: "+ke.$.raceTime),ke.win("The End")}()}};function r(e){return e.includes("@")?e.split("@")[1]+"_start":t+"_"+e}W.addProcessor("%target%",(()=>io[ke.$.target].name)),W.addProcessor(/\$([a-zA-Z]+)\$/g,((e,t)=>ke.$[t])),W.addProcessor("#NOTSAFE#",(()=>"port"==ke.$.reefSafe?"starboard":"port"));const i=e.split("\n");let l,h={};return i.forEach((e=>{if(""!=e&&!e.startsWith(";"))if(e.match(/#cycle/)&&(l._dotCycle=!0),e.match(/useMagic/)&&(l._dotMagic=!0),e.startsWith("#")){const t=r(e.slice(1));h[t]={actions:[],choices:[]},l=h[t]}else if(e.startsWith("*"))!function(e){const[,,t,o,n]=e.match(/\*(\[(.*)\])?(.+)=>(.+)/),a={label:o,target:r(n)};if(t){const[,e,o,,n=""]=t.match(/([^ |]+)( [^|]+)?(\|(.+))?/),r="!"==e[0],i=r?e.slice(1):e;a.condition=()=>!r!=!s[i](o?.trim()),a.disabledMsg=n}l.choices.push(a)}(e);else if(e.startsWith("+"))!function(e){l._dotTime=e,l.actions.push( $e((()=>{let t=1;ke.$.betterSails&&(t=.8),ke.$.snappedMast&&(t=2),ke.$.raceTime+=t*Number(e.slice(1))})))}(e);else if(e.startsWith("=>"))l.actions.push((()=>{ke.dispatch("_innerDoPsg_",r(e.slice(2))),ge()})),l._dotJump=r(e.slice(2));else if(e.match(/^<.*>$/))!function(e){const t=e.match(/^<([^ ]+)( .*)?>/);let o=t[1];const n=t?.[2]?.slice(1);"gameOver"==o&&(l._dotGameOver=!0),"jumpif"==o&&(l._dotIfJumps||(l._dotIfJumps=[]),l._dotIfJumps.push({target:r(P(n.split(" "))),lab:n.split(" ")[0]})),o in s?l.actions.push((()=>s[o](n))):(o+="?",j(o in s,"Missing function: "+o),l.actions.push($e((()=>s[o](n)))))}(e);else if(e.startsWith(">>NPC:"))!function(e){const t=e.match(/^>>NPC:(.+?),(.+?),(.+)$/),[,o,n,s]=t;a[o.trim()]=new le(n.trim(),"",s.trim())}(e);else{const t=()=>W.msg(e);l.actions.push(t)}})),h}(e,t))}ho("#start\n+3\nYou go to bed and are easily lulled to sleep by the gentle rhythm of the waves. After a night full of dreams of plunder and peril, you wake up refreshed and feel ready to take on the world!\n* Begin the race=>begin\n#begin\nYou give the order to take in lines and set sail for the staging area behind the starting line.\nYour first mate asks whether you'll be attempting a port or a starboard approach.\nYou hesitate; a starboard approach is usually a safe bet while a port approach doesn't always work but when it does will often let you surge in front of your competitors. Of course you could also ignore the standard playbook and just try shooting at the other boats.\n*Take a starboard approach=>starboard\n*Go for a port approach=>port\n*[isset cannons|You don't have working cannons]Shoot the competition=>cannons\n*[hasMagic|You have no magic items]Use a magic item=>magic\n#magic\n\nRight as the race begins, you rub the $magicItem$ before throwing it into the ocean to invoke the sea gods. Castor smiles upon you and a puff of wind propels you forward!\nYou leave your competitors in your wake.\n*Sail onwards=>next\n#starboard\n+4\nYou are hugging the starting line when you hear the starting can non. You immediately turn right, cross the line and are off towards Portobello!\n\nThere are a few cannon exchanges among the competitors but you manage to take very little damage. Soon all the ships are out of mutual cannon range and things quiet down.\n*Towards Portobello=>next\n#starboardCursed\nJust as you are about to order a course correction to stay away from Cap'n Quartz's ship, you suddenly feel a sharp pang of pain in your left knee. The pain disappears almost as suddenly as it started but in the meantime the Pink Flamingo has drifted into cannon range. You receive a burst of cannon fire before you can skedaddle back out of range.\n\n\n\n*Sail onwards=>next\n#port\n+2\n\nYou hang back from the starting line a little and tack port a little before when you expect the race to start. Your timing is spot on, and you cross the starting line at full speed mere seconds after the starting cannon. You take a little light cannon fire from your rivals but nothing serious.\n*Onwards=>next\n#missPort\n+6\nYou hang back a little from starting line to tack port a little before the race starts. Suddenly you feel an intense stab-like pain in your left shoulder. While the pain vanishes as quickly as it appeared it threw off your timing and you cross the starting line early. You are forced to come around to recross the line which costs you precious time.\n*Onwards=>next\n#cannons\n+6\nWhy even enter a pirate regatta if you aren't going to direct some friendly cannonball fire towards your mates? You order your crew to stand ready and to aim the cannons at #cycle[target]{Cap'n Quartz:1|Calico Sammy:2|Charlotte Noire:0|Purplebeard:3}'s ship and wait for #TARGET.THEIR# ship to get within range.\n*Fire! =>shot\n#shot\nBefore the race even starts, you fire your cannons at %target%'s ship.\n\n\nYou whiz away before #TARGET.THEY# can return fire but that makes you cross the start line well before the start of the race. You have to come around to recross the line by which time you are far behind your rivals. Still you think it was worth it for the look on %target%'s face.\n*Continue on your way=>next\n#next\n=>@ruckus","embark"),ho("#start\n+1\n\nYou are making good time when suddenly a shout rings out from the crow's nest: ``A Spanish galleon! Due port!''\nYou grab a spyglass to check it out. The galleon is riding low in the water! It must be full of booty and will be too slow to flee. You rub your hands thinking of the pillage to come. Then you remember you are in a race, if you attack it you'll surely lose precious time.\nYou're not sure how to proceed.\n*Attack the galleon, pillage and booty are more important=>attack\n*Ignore the galleon, the race is more important=>ignore\n#ignore\nYou decide to be reasonable and keep your eyes on the prize. You continue on your course towards Portobello. Still, you can't help but sigh as you watch the galleon dip below the horizon behind you.\n*Onward=>next\n#attack\nYou yell out some orders and the Pink Flamingo turns to intercept the galleon. The Spanish notice you and try to flee but they're too slow. You ship is closing in on the galleon.\nShould you fire your cannons to soften them up or have your crew board the galleon right away?\n*[isset cannons|You don't have working cannons]Fire the cannons=>cannon\n*Board right away=>board\n#cannon\n+1\n; What kind of shot should you use?\n; *Standard cannonballs=>round_shot\n; *Chain shot=>chainshot\n; *Grape shot=>grapeshot\nYou pull up alongside your prey and fire a volley into the Spanish galleon.\n\nThey see that you mean business and are in no mood to fight. The galleon raises a white flag!\n*Booty time! =>booty\n#board\n+5\nYou fire grappling hooks into the ga lleon's masts and swing aboard along with your band of pirates.\nYou find yourself near the top of one of their masts. You need to get down to the decks where the fighting is. You could climb down the ratlines or you could stab the sail with your #cycle[sailStab]{sharp cutlass:cutlass|dull dagger:dagger} and jump down.\n*Climb down the ratlines=>safe_down\n*Ride your #live[sailStab]{cutlass:cutlass|dagger:dagger} down the sail=>sail_down\n#safe_down\n+1\nYou climb down the ratlines and join the fray.\n=>fight\n#sail_down\n\nYou stab the sail with your dagger and jump. The dagger slows you down as is cuts into the sail fabric just like you planned.\nHowever as soon as you hit a reef band the dagger stops abruptly and you are thrown. You plummet precipitously and would surely have been gravely injured had a Spanish crewmate not fortuitously#fn{For you, his opinion on the matter differs} broken your fall.\n=>fight\n#tooFast\nYou plunge your cutlass into the sail and jump!\nYour sharp cutlass tears through the sailcloth, not slowing you down at all. You hit the deck at tremendous speed and are knocked out cold!\n*... wake up=>wake\n#wake\n+5\nYou awaken to find that your crewmates have won the fight!\n=>booty\n\n#fight\nHours of dramatic#fn{Ed: show don't tell} hand to hand fighting follow but finally the Spanish surrender.\nThe ship is yours!\n*Grab the booty=>booty\n#booty\n+1\nTo your delight, you find that the galleon was loaded with the best cargo of them all: RUM!\nYou have as much of it as will fit loaded onto the Pink Flamingo's hold and let your victim continue on its way.\nSelling the rum in Portobello would net you a pretty piece of eight. You figure your share would be about 300 doubloons. On the other hand many among your crew would rather drink the rum now.\n*Keep the rum to sell=>sell\n*Distribute half the rum to the crew and sell the rest=>half\n*Party! Let's drink all the rum=>drinkall\n#sell\n\nThe crew is not too happy about the lack of immediat e gratification, but they understand that they'll get their share of the proceeds when you arrive in Portobello.\n*Sail on=>next\n#half\n\nYou set half of the rum aside to be sold in Portobello and distribute the rest right away. The crew is quite happy with the compromise and a merry time is had by all.\n*Sail on=>next\n#drinkall\nYou smash open the first barrel and yell ``Partayyy!'' before plunging your whole head into the rum and drinking deeply. The crew cheer and everybody as having a great time.\nUnfortunately by night fall every last soul on the ship is smashed and, with no one at the helm, so is the Pink Flamingo, against a reef.\n\n#next\n=>@lifeboat","galleon"),ho("#start\nSuddenly, off the forward port side of the ship, an enormous tentacle emerges from the sea. It appears that you have encountered the legendary Kraken!\nFew who have set eyes on it have lived to tell the tale. Due, no doubt, to its diet of fish and ships.\n \nYou ponder your opti ons.\n*[isset cannons|You don't have working cannons]Shoot the kraken=>attack\n*Try to bribe it=>bribe\n*Bravely run away=>evade\n*Soothe the kraken with music=>sing\n#sing\nYou decide the best course of action is to sing to the kraken to pacify it.\nNow you only need to settle on the right song from your wide repertoire.\n*Sing the one about the drunken sailor=>badSong\n*Sing the one about the wasted pirate=>badSong\n*Sing the one about the hammered parrot=>badSong\n*Sing the one about the sloshed merchant=>badSong\n*Sing the one about the plastered flapper=>badSong\n*[isset knowSong|You don't know the sirens' song]Sing the sirens' song=>goodSong\n#badSong\nThe kraken is, if anything, only more enraged by your singing.\nYou barely have time to be offended by the kraken's lack of taste before it swats your ship with a flick of its tentacles.\n\n#goodSong\nAgainst all odds, the kraken is appeased by your singing of the sirens' song. It gently sinks below the waves and allows you to leave unharmed.\n*Quickly sail away=>next\n#evade\nYou, rather sensibly, decide that discretion is the better part of valor.\n\n\nWhat approach to running away shall you choose.\n*Flee=>flee1\n*[hasMagic|You don't have any magic items]Use a magic item=>fleemagic\n*[isset cannons|You don't have working cannons!]Never mind, turn back and fight=>attack\n#fleebad\nYou try to flee but the Pink Flamingo is just too slow. The mighty kraken swats your ship as if it were a mere speck of dust in the ocean.\n\n#fleemagic\n\nYou kiss the $magicItem$ then throw it overboard, invoking Pollux. He answers and a mighty wind starts filling your sails.\n=>flee2\n#flee1\n+2\n\n=> flee2\n#flee2\n+2\nYou hang a starboard and try to get as far away from the beast as you possibly can. The beast chases you for a while but eventually gives up the pursuit. You lost some time but are glad to have escaped with your lives.\n*Onward=>next\n#attack\nYou decide to be bold attack the fearsome kraken! Should your crew aim the cannon at the Kraken's eyes, its mouth or perhaps one of its tentacles?\n*Aim for a tentacle=>tentacle\n*Aim for the mouth=>mouth\n*Aim for the eyes=>eyes\n#tentacle\nThe tentacles must surely be its weak spot!\nYou instruct your crew to aim for the kraken's #cycle[nthtentacle]{first:first|second:second|third:third|fourth:fourth|fifth:fifth|sixth:sixth|seventh:seventh|eighth:eighth} tentacle.\n*Fire=>tentacle2\n#tentacle2\nThe kraken's $nthtentacle$ is positively destroyed when you fire a round of cannonballs into it! Unfortunately it uses one of the seven remaining ones to split your ship apart.\n\n#mouth\n+1\nYou order your crew to aim f or the creature's mouth. They do as instructed and manage to shoot a cannonball straight into the Kraken's gaping maw!\n\nThe kraken's eyes bulge wide. It gags and then sinks under the waves!\n*Hurray=>next\n#eyes\nYou order your crew to aim for the creature's eyes. They do as instructed and manage to shoot a cannonball straight into one of the beast's eyes.\nUnfortunately that only serves to make it even angrier. It lashes out at your ship with its mighty tentacles and easily destroys your ship.\n\n#bribe\n\n=>bribeGold\n#bribeChoice\nWhat shall you try to placate the beast with?\n*[haveGold 1|You don't have any booty]Bribe the kraken with gold=>bribeGold\n*Bribe the kraken with rum=>bribeRum\n*Bribe the kraken with everything=>bribeBoth\n#bribeGold\nYou sail towards the mighty kraken and toss all of your gold overboard.\nThe kraken ignores the money and attacks your ship, splitting it in two with a mighty #.emph{*thwack*} from its tentacle. As you are thrown into the sea you wonder what possessed you into thinking that bribing the kraken could possibly work.\n\n#bribeBoth\n\n\nYou sail towards the mighty kraken and throw all of your gold and all of the rum barrels overboard. The kraken grabs the barrels with its mighty tentacles and tosses them into its mouth. It appears pleased and sinks below the waves, letting you be.\n\n\n*Sail on=>next\n#bribeRum\n\nYou sail towards the mighty kraken and throw all of the rum barrels overboard. The kraken grabs the barrels with its mighty tentacles and tosses them into its mouth. It appears pleased and sinks below the waves, letting you be.\n*Sail on=>next\n#next\n=>win\n#win\nAt last you pull into the Portobello harbor.\n*See the results=>end\n#end\n","kraken"),ho("#start\nYou retire to your ca bin after another day on the seas. You dream of booty and bagels. You wake up to a beautiful red sky.\n*Onwards=>2\n#2\nAround noon you see a large storm brewing on the horizon. It is coming your way.\n\n*Furl the sails to ride out the storm=>furl\n*Use the high winds to your advantage! Attempt to race through the storm=>ride\n#furl\n+4\nYou furl the sails to keep the sails and masts from being damaged. The Flamingo is hurled around on giant waves for hours but finally the storm passes. Despite your precautions, the main mast has snapped. At least your sails weren't damaged, but you will need to find an island for repairs.\n*Search for land=>island\n#ride\nInitially the plans works out great and you are making excellent time, almost flying through the waves. Eventually though the strain is too much and your main mast snaps!\n What's more, your beautiful silk sails are mangled by the falling mast.>\nYou need to find an island for repairs.\n\n*Search for land=>island\n#island\n+1\nLuckily, after only a few hours you spot a small island. You can see some tall pine trees growing at the top of some cliffs that would make perfect masts.\nThe Flamingo limps towards it on what sails remain.\nYou moor the ship in a natural harbor and row ashore with a small party.\n \n\n;next line is dead code but kept to keep graph nice\n=>reboard\n#reboard\nYou push the mast and the rowboat into the ocean then the three of you hop in and tow the mast back to the Pink Flamingo.\nMarvin spends a few hours raising the new mast while Violet takes care of the rigging.\nSoon the main mast is good as new and you are ready to depart.\n\n*Weigh the anchor=>weigh\n#weigh\nThe anchor weighs about 1.4 tonnes. Using the rule of thumb that anchors should weigh about 1/500th of a ship's tonnage, knowing that pirates consume about 285ml of grog per day, and assuming spherical pirates, you could easily calculate the maximum range of a fully crewed and loaded Pink Flamingo.\n*Har, har. Weigh anchor=>@hunter","storm"),ho("#start\nAfter a long day of sailing, you turn in for the night. You dream of loot and locusts. The next morning you wake up refreshed.\n\n``There's something ahead, off the starboard side!'' the barrelman cries. You fetch a spyglass to check it out.\nA handful of pitiful looking people are crammed onto a makeshift raft that seems to have been made from the remains of the ship they were sailing on.\n*Set a course to rescue them=>rescue_man \n*Ignore them, you're in a race=>ignore\n*[hasMagic|You have no magic items]Use a magic item=>magic\n#magic\n\nYou rub the $magicItem$ and then toss it into the ocean. Suddenly a strong sea current materializes and whisks the raft towards your ship! As their raft nears the Pink Flamingo,\n=>rescue\n#ignore\nYou have no time to waste. Besides, they don't look like they have any valuables you could relieve them of.\nAs sail on, you see that Purplebeard, that ol' softie, has set a course to rescue them.\nWhat a sucker!\n\n*Continue=>next\n#rescue_man\n+4\nYou call for the course to be adjusted in order to intercept the raft. As you approach the raft,\n=>rescue\n#rescue\n<> the castaways cheer. They were en route from Port Royal to Portobello when their ship, the Flaming Herring, hit a reef and sank.\n*Give them a ride to Portobello=>nice\n*Charge a ``rescue fee''=>nasty\n#nice\nThe rescued sailors are grateful and offer to help out on the ship where they can. Among them is a tailo r who volunteers to spruce up your sails.\n\n\n\n\n*Continue=>next\n#nasty\n\nThe rescued sailors grumble a little as you and your crew relieve them of all their valuables. It is a rather meager haul though; it turns out shipwrecked people don't tend to have a lot of loot. Your share comes out to 15 doubloons.\n*Sail onward=>next\n\n#next\n=>@mutiny","lifeboat"),ho("#start\n\n\nT he first few hours of the morning are uneventful, but suddenly, around noon, an orange sail is spotted. You only know of one ship that has orange sails: that of Ben Hornigold, the famous pirate hunter!\nAnd he is coming straight towards you.\n>>NPC: hornigold, Hornigold, m\n*Attack head on=>attack\n*Flee=>flee1\n#attack\n+4\nYou set a course straight for the pirate hunter.\n*[isset cannons]Attack with cannons=>cannons\n*Board their boat=>board\n#cannons\nYou have your crew load #cycle[ammo]{standard cannonballs:ball|chain shot:chain|grape shot:grape} into the cannons and wait for the pirate hunter to come into range.\n \n3... 2... 1...\n*Fire! =>fire\n#fire\n\n\n\n#firechain\nThe chain shot absolutely shreds the pirate hunter's rigging.\n\nWith their sails in tatters, you realize you could probably get away quite easily.\n*Board them=>board\n*Slip away=>flee\n#fireball\nYou fire a salvo of cannon balls i nto the pirate hunter's hull and do a fair amount of damage to it.\n\n*Board their ship=>board\n#firegrape\nYou sweep their deck with grapeshot. A large amount of sailors dive overboard to avoid being hit. That should make the coming battle a bit easier.\n\n\n*Board their ship=>board\n#board\n+2\nYou order the grappling hooks launched and personally lead the boarding party.\n\n+2\n=>hand2hand\n#hand2hand\nYour crew fights valiantly, but alas so do Hornigold's men. You fight your way to Hornigold himself and engage him in a duel.\n\n*w=>h2hWin\n*l=>h2hLose\n#h2hWin\n\nHornigold surrenders and begs for mercy. You leave him his life but loot his ship, finding a chest full of coins. Your share comes out to 600 doubloons.\n\n*Sail onwards=>next\n#h2hCurse\nJust when you thought you had won the mysterious outbursts of pain strike again. Hornigold quickly recovers his cutlass and di sarms you.\n=>h2hLose\n#h2hLose\nUnable to fight on you are forced to surrender.\nDays later you will manage a heroic escape, but by then you will have lost the race.\n\n#caught\n+3\nYou try to flee but, given the state of her sails, the Pink Flamingo is too slow. Before long, the pirate hunter's ship catches up and a bunch of pirate hunters board your ship, swinging in on grappling hooks.\n=>hand2hand\n#flee1\nYou spot Cap'n Quartz and Sammy. You could try fleeing their way.\n*Just flee towards Portobello=>flee\n*Flee towards Cap'n Quartz=>fleeQ\n*Flee towards Calico Sammy=>fleeSam\n*[hasMagic]Use a talisman=>fleeMagic\n#fleeMagic\n\nYou pat the $magicItem$ twice and throw it into the sea. Pollux answers your call and a giant wave crashes into the pirate hunter's ship! Their sails are washed away and the ship is in no shape to pursue you.\n*Sail onwards=>next\n#fleeQ\n\n=>fleePirate\n#fleeSam\n\n=>fleePirate\n#fleePirate\n+2\nYou manage to catch up to %target%, but the pirate hunter is still on your tail. You could team up with %target% to attack Hornigold's ship and split the loot.\nOr you could do that ``outrun your friend not the bear'' thing.\n*Team up with %target%=>teamup\n*Flee and hope Hornigold attacks %target%=>fleejerk\n#teamup\n+2\n\n%target% understands your plan and happily joins in, flanking the pirate hunter. You manage to trap him between your two ships and board it from both sides!\nYou often mock Purplebeard for always spouting inane little sayings like ``teamwork makes the dream work,'' but you have to admit that in this case teamwork really does work. In no time at all you and %target% manage to overpower Hornigold's ship.\nYou divide up the loot and each leave with 300 doubloons.\n\n*Sail onward=>next\n#fleejerk\n\nYour gambit works! The pirate hunter adjusts its course to intercept %target% and soon they start exchanging cannon fire.\n*Sail onwards=>next\n#flee\n \nYou manage to outrun the pirate hunter.\n*Continue=>next\n#next\n=>@knikna","hunter"),ho("#start\nYou are making splendid progress when suddenly a small group of armed sailors storm the quarterdeck.\n #.emph{Mutiny!}\nTheir leader, Iago Fawkes, informs you that the crew is unsatisfied with your leadership and demands you surrender the ship to them.\n\n\n\n\n\n=>alone\n#alone\n*[isset notset]Let your loyal crew deal with the mutineers=>lazy\n*Challenge their leader to a duel=>duel\n*[hasMagic|You have no magic items]Use a magic item=>magic\n*Surrender=>loseDuel\n#team\n*Let your loyal crew deal with the mutineers=>lazy\n*Challenge their leader to a duel=>duel\n*[hasMagic|You have no magic items]Use a magic item=>magic\n*Surrender=>loseDuel\n#magic\n+2\n\nYou toss the $magicItem$ into the sea. A column of water propels a Nereid aboard. She unsheathes a glaive preparing to fight at your side. Seeing this, Iago tosses a silver medallion into the ocean and another Nereid boards the ship! The two Nereids look at each other, shrug and depart from your ship. While you didn't get the magical help you were expecting, the delay give your loyal mates enough time to rally the crew to your cause.\nThe mutineers are defeated in the ensuing melee.\n*Sail onwards=>next\n#lazy\nThe loyal crew rush to your defense and after a shor t melee the mutineers are soundly defeated.\n*Sail onwards=>next\n#duel\n``Well then, let us settle this mano a mano,'' you say, as you unsheathe your cutlass.\n``Fine, let's fight but yer no man,'' sneers Iago, displaying both a nasty sexist streak as well as an appallingly poor grasp of the Spanish language.\n>>NPC: Iago, Iago Fawkes, m\n\n*win=>winDuel\n*lose=>loseDuel\n\n#loseDuel\nIago accepts your surrender and has you put in irons in the brig. A few days later you are marooned on a desert island.\n\n\n#winDuel\nIago raises his hands in surrender as he falls to his knees and grovels. ``Please,'' he begs, ``I'll give ye everything me has but don't make me walks the plank.''\n*Make him walk the plank=>plank\n*Throw him in the brig=>loot\n#plank\nYou make Iago, along with all the other mutineers, walk the plank!\nYou crew jeers at them while they curse you and swim towards a nearby island.\n*Sail onwards=>next\n#loot\nYou have him, along with all the mutineers, put in irons in the brig.\nGrateful that you spared him, he hands you his money, 35 doubloons worth, along with a silver medallion!\n\n\n*Inspect medallion=>med\n*Sail onwards=>next\n#med\n\nInteresting.\n*Sail onwards=>next\n#next\n=>@storm","mutiny"),ho("#start\n\n #henry{Um... Cap'n?} Master Tomlinson, the ship's navigator, interrupts your daydreaming.\n #you{What is it Thomas?} you inquire.\n #henry{Ye know how we always keeps tha KNIKNA's state in a logbook?}\n Of course you do, if you didn't know its current veracity status then the navigational information would be quite useless.\n #henry{Well, tha logbook be drenched by tha storm and be unreadable. Thar be a reef straight ahead and we don't know whether tha port or starboard side be tha safe one.}\n*Choose direction randomly=>rand\n*Let me have a look at the KNIKNA=>intro\n#rand\n\n #.you{``We'll go} #cycle[dir]{Port:port|Starboard:starboard} #.you{!''} you say with the all the confid ence of a player who doesn't realize that a mercurial author might take away their UNDO privileges at any time.\n*Onwards=>randgo\n*On second thought, let's take a look at that KNIKNA=>intro\n#randgo\n\nYou order the ship to go around on the $dir$ side. You are vindicated as the Pink Flamingo sails past unmolested.\n*Sail onwards=>next\n#unsafe\n+8\nYou order the ship to go around on the $dir$ side. You cringe as the bottom of the Pink Flamingo scrapes against the submerged reef. You have run aground and are stuck.\nYou have to wait hours for high tide to get away and then it takes your crew most of the rest of the day to repair all the damage.\n*No use crying over spilt rum, sail onwards=>next\n\n#intro\n\nThomas Tomlinson brings you the small aquarium in which the Knowledge-Negating Inverter Kelpfish Navigation Aid is swimming.\nThe KNIKNA is a magically imbued talking fish that has perfect navigational knowledge of an area. The only catch is that it alternates bet ween strictly telling the truth and telling a lie which is why the logbook to keep track of its state is so important. Geography Providing Squids don't have that drawback but they cost so much more.\n=>main\n#main\n \nWhat shall you ask the KNIKNA?\n*``Which direction is safe''=>dir\n*``Are you lying''=>lie\n*``Say ``this is a lie''''=>paradox\n*``If I were ask whether the port side is safe, what would you answer?''=>portindir\n*``Is this ship named the Flying Belgian?''=>shipname\n#postAns\n*Ask another question=>main\n*Enough questions, I know which way to go=>qgo\n#shipname\n #you{Is the name of this ship the Flying Belgian?}, you ask.\n\n\n\n=>postAns\n#qgo\n #.you{``We'll go} #cycle[dir]{Port:port|Starboard:starboard} #.you{!''} you say.\n*Sail forth=>randgo\n#lie\n #you{Are you currently lying?} you ask the KNIKNA.\n\n #knikna{No, I am not lying.}\n=>postAns\n#dir\n #you{Which direction is safe?} you as k the KNIKNA.\n\n\n\n=>postAns\n#portindir\n #you{If I were to ask you whether the port side is safe, what would you answer?} you ask.\n\n\n\n=>postAns\n#paradox\nYou order the KNIKNA to say ``This sentence is a lie.''\nUnsure what to say, the kelpfish starts swiming in circles faster and faster. After a while it turns into a colorful beach ball and floats away!\n*Whoops=>qgo\n#next\n\n=>@sirens","knikna"),ho("#start\nYou are gazing into the distance on the quarterdeck when suddenly your thoughts are interrupted by a commotion on the lower deck.\nYou descend to see what is going on and find Alex, the ship's cook, and the navigator engaged in a shouting match.\n #you{Sirens be half-bird, ye pox-faced cur!} says Alex, the cook.\ n #you{You chum-smellin' codfish! Everybody knows they be half-fish,} retorts Thomas.\nYou decide to intervene before they come to blows:\n*Side with the cook: ``Sirens are half-bird''=>bird\n*Back up the navigator: ``Sirens are half-fish''=>fish\n*``Sirens don't actually exist''=>both\n#bird\n\n #you{Alex is right,} you say, #you{sirens are half-woman and half-bird. Now get back to work, you bilge rats!}\nAlex returns to the galley, happy that you took their side. Meanwhile Thomas sulks as he goes back to the map room.\n*Return to the quarterdeck=>next\n#fish\n\n #you{Tom is right,} you say, #you{sirens are just another word for mermaids. They're half-woman and half-fish. Now get back to work, you bilge rats!}\nAlex sulks as they return to the galley. Thomas whistles happily as he goes back to the map room.\n*Return to the quarterdeck=>next\n#both\n\n\n #you{Sirens are mythological creatures that don't actually exist, ye lily-livered bilge rats! Now get back to work.}\nThey both sulk as they return to their stations.\n*Return to the quarterdeck=>next\n\n#next\n=>@galleon","ruckus"),ho("#start\nThe barrelman cries out as he spots something straight ahead!\nYou grab a spyglass and quickly catch sight of some strange creatures. They are half-fish and half-bird and seem to be hanging out atop some rocks poking out of the sea. Could these possibly be sirens?\n*Investigate=>investigate\n*Give them a wide berth=>avoid\n#avoid\n+2\nYou order the ship to keep well out of singing range even if it means losing a little bit of time.\n*Sail forth=>next\n#investigate\nYou decide to investigate the sirens and order your crew to maintain the ship's heading. You vaguely remember reading about some Irish captain -- Leopard Bloom or something like that -- encountering sirens and having his crew fill their ears with wax. Perhaps that would be a good idea?\n*Don't bother=>doom\n*Earwax for everybody! =>tieMe\n#doom\nAs you near the si rens, you are entranced by their beautiful singing. Despite a nagging little voice in your head telling you it is a terrible idea, you jump into the water and swim towards them. You are soon joined by pretty much all your crew.\nAfter a while the sirens tire of singing and leave. Their spell is broken but by then the uncrewed Pink Flamingo has crashed into the rocks and shattered!\n\n#tieMe\nYou have everybody fill their ears with wax (luckily, as an avid water skier, you always keep a supply of ski wax#fn{I'm glad this game isn't in French} on board).\nHowever you decide that you want to hear the sirens' singing so you #cycle[knotter]{tie yourself:me|have Alex tie you:alex|make Tom Tomlinson tie you:tom|ask Violet to tie you:violet} to the mast.\n*Approach the sirens=>near\n#near\n\n\n\n\n#alexKnot\n\n=>goodKnot\n#tomKnot\n\n=>goodKnot\n#goodKnot\n\nAs you near the sirens, you are entranced by their beautiful singing. You pull at the ropes but they hold remarkably well. After a while you give up trying to escape your bonds and simply enjoy the sirens' songs.\n\nAfter you are out of range again your crew unties you and they all spend some time cleaning out their ears.\n*Sail on=>next\n#hardknot\n+2\nAfter you are out of range again your crew #.emph{tries} to untie you. Violet's knots are very strong but they are also hard to untie so it takes your crew the better part of two hours to finally get you free.\n*Sail on=>next\n#undone\nAs you near the sirens, you are entranced by their beautiful song. You pull at the ropes that are holding you and they easily come undone!\nYou jump overboard and start swimming towards the sirens.\n\n#next\n=>@kraken","sirens");const uo=[["My sword fighting skills are unrivaled!","Perhaps, but all of your quips are recycled."],["Anyone seeing you fight would be puzzled.","Indeed, and then quite quickly dazzled."],["You look like a vile and ugly landlubber!","And you smell like a putrid sea cucumber."],["You are naught but a five-pence swindler","Did you expect a pirate, for the law, to be a stickler?"],["I can't fathom how ugly you are!","Alas, thinking isn't your strong suit, by far."],["I'll cleave you in four with my scimitar!","Wow, you can count all the way up to the fifth integer?"],["Everyone knows you are a lily-livered buffoon!","But nobody can tell you from a dirty old spittoon."],["You need a kiss on the neck from a crocodile.","Can't you leave out your mother, once in a while?"],["Thou art a boil, a plague sore.","Quoting Shakespeare? You really are a bore."],["I've never set eye upon such an inept fighter.","I knew from your hair that you'd never seen a mirror."],[null,"How appropriate. You fight like a cow!"]].map((([e,t])=>({insult:e,retort:t}))),co=E([...Array(uo.length-1).keys()]);let m o,go,yo,fo,po;function bo(){po=co();const e=uo[po].insult;let t=new Set([uo.length-1,po]);for(;t.size<5;)t.add(Math.floor(T()*uo.length));t=[...t],x(t),fo<0&&W.msg(`Pressing ${yo.their} advantage, <>`),fo>0&&W.msg("Trying to break your advantage, <>"),W.msg(`${yo.defName} #draw{swings ${yo.their} blade towards you|thrusts ${yo.their} weapon in your direction|lunges towards you, blade first} and exclaims:\n#.insult{\`\`${e}''}\nYou parry ${yo.their} blade and rejoin:`),vo(t.map((e=>({label:"``"+uo[e].retort+"''",target:"duel#"+e}))))}function wo(e,t=!1){let o=uo[e].retort;"."==o.slice(-1)&&(o=o.slice(0,-1)+","),e==po?(fo++,W.msg(`#you{${o}} you retort, throwing ${yo.defName} off balance!`)):(fo--,W.msg(`#you{${o}} you reply meekly. ${yo.defName} sneers and takes a step forward.`)),t||fo>=2?(W.msg(`You seize your chance and disarm ${yo.them} before ${yo.they} can reorient ${yo.themself}.`),vo([{label:"You've won",target:mo}]),ge()):fo<=-2&&(W.msg(`${yo.Their} blade comes down hard and your cutlass is thrown ou t of your hands.`),vo([{label:"Surrender",target:go}]),ge()),bo()}function ko(){Ee=!0,U("undo").style.display="none",U("inputArea").style.display="block",W.setInputFunc()}function vo(e=[]){let t=e.map(((e,t)=>e.condition&&!e.condition()?`${e.label}`:`${e.label}`));t.length>0&&W.msg("
"+t.join("
"))}function $o(e){ke.dispatchP("_doPsg_",e)}if(ke.addSimpleVerb("db win duel",(()=>{wo(0,!0)})),I.addVerb("db cannons",{action:()=>ke.$.cannons=!0,codKind:null}),I.addVerb("db hull",{action:()=>ke.$.henryPaid=!0,codKind:null}),I.addVerb("=>",{action:"_doPsg_",codKind:"string"}),I.addVerb(">>",{codKind:"string",action:e=>{const t=Number(e)-1,o=lo[ke.$.currentPassage];j(null!=o,"No current passage");const n=o.choices[t]?.target;n?ke.dispatchP("_doPsg_",n):W.msg("Bad choice number: "+e)}}),ae("_doPsg_","string",(e=>{if(U("inputArea").style.display= "none",Ee=!1,U("undo").style.display="block",W.commit(),W.clear(),W.setInputFunc((e=>{const t=U("transcript").lastChild.getElementsByClassName("choice");for(let o=1;o<=9;++o)if(e.key==`${o}`)return t[o-1]?.click(),void e.preventDefault()})),e.startsWith("duel#")&&(wo(Number(e.slice(5))),ge()),!lo[e])throw new Error("missing passage: "+e);ke.$.currentPassage&&ke.$.currentPassage!=e&&j(lo[ke.$.currentPassage].choices.some((t=>t.target==e)),`Illegal jump from [${ke.$.currentPassage}] to [${e}]`),ke.dispatch("_innerDoPsg_",e)})),ae("_innerDoPsg_","string",(e=>{const t=lo[e];if(!t)throw new Error("missing passage: "+e);ke.$.currentPassage=e,t.actions.forEach((e=>e())),vo(t.choices)})),ke.addBeforeHook("look",(()=>{ke.$.currentPassage&&(ke.dispatch("_doPsg_",ke.$.currentPassage),ge())})),ke.addAfterHook("look",(()=>{ko()})),ke.isWeb){const e=e=>{const t=e.target.closest("A");if(null!=t){if("undo"===t.dataset.cmd)return W.msg("UNDO","echo"),W.clear(),ke.meta.undo(),void W.commit();if(t.classList.contains("choice")& &!t.classList.contains("disabled")){const e=t.innerHTML.toUpperCase();return W.msg(e,"echo"),I.rawStr=e,ke.dispatchP("_doPsg_",t.dataset.next),void W.commit()}if(t.classList.contains("cycler")){const e=t.dataset.cycleralts.split("|").map((e=>e.split(":")));let n=(Number(t.dataset.cycleridx)+1)%e.length;return ke.$[t.dataset.cyclertarget]=e[n][1],t.dataset.cycleridx=n,t.innerHTML=e[n][0],void o(t.parentElement)}}};document.addEventListener("click",e,!1);const t=(e,t,o)=>{const n=o.split("|").map((e=>e.split(":")));return ke.$[t]=n[0][1],`${n[0][0]}`},o=e=>{e.querySelectorAll(".live").forEach((e=>{if("target.their"==e.dataset.kind&&(e.innerHTML=io[ke.$.target].their),"target.they"==e.dataset.kind)e.innerHTML=io[ke.$.target].they;else{const t=ke.$[e.dataset.kind];e.innerHTML=e.dataset.opts.split("|").find((e=>e.split(":")[0]==t)).split(":")[1]}}))};function n(e,t,o){const n=o.split("|").map((e=>e.split(":")));retur n`${n[0][1]}`}W.addProcessor(/#cycle\[(.*)\]\{(.*?)\}/gi,t),W.addProcessor(/#TARGET.THEIR#/,(()=>`${io[ke.$.target??0].their}`)),W.addProcessor(/#TARGET.THEY#/,(()=>`${io[ke.$.target??0].they}`)),W.addProcessor(/#live\[(.*)\]\{(.*?)\}/gi,n)}const Ao=new de("The Docks","Tortuga's main square is up the road to the north. Your ship, the Pink Flamingo, is docked here and accessible via a gangplank to the south. Northwest is Henry's shipyard. You can also see some other ships moored in the harbor."),Yo=new de("Main Deck of the Pink Flamingo","You stand on the main deck of your ship. Stairs to the aft lead up to the quarterdeck. Your cabin is fore. A gangplank leads out to the docks.");Yo.boat=!0;const Io=new de("Your Cabin","Spartan but clean, your cabin has a bed, a chest and not much else. A door aft leads out to the main deck.");Io.boat=!0;const To=new de("Quarterdeck","The nerve center of the Pink Flamingo, the quarterdeck is the deck from which you command the ship. It is equipped with a steering wheel, a glovebox and a capstan. Stairs lead down to the main deck.");To.boat=!0,Yo.decor(["stairs","steps"],"Just some stairs leading up to the quarterdeck."),To.decor(["stairs","steps"],"Just some stairs leading down to the main deck.");const So=e=>{Yo.addItem(e),To.addItem(e),Ao.addItem(e)},xo=new ie(["Pink Flamingo","ship","your ship","my ship","boat"]);xo.A.examine=()=>{ke.$.xedShip=!0;let e="The Pink Flamingo is your pride and joy";ke.$.hullFixed||ke.$.henryPaid?ke.$.hullFixed?e+=". Henry did a bang up job and her hull is now all patched up.":e+=", her hull is currently being repaired by Henry.":e+=". Sadly she took a severe beating during your recent raid on Nassau. It's frankly a miracle you made it back to port at all and you won't be heading out to sea before getting her hull patched up.",ke.$.betterSails?e+="\nThe fancy new silk sails look great":e+= "\nThe sails have seen better days but are still serviceable",ke.$.cannons?e+=" and the Flamingo sports a brand new set of cannons.":e+=" however the Flamingo doesn't currently have any working cannons.",W.msg(e)},xo.goExit=xo.A.board=xo.A.enter=()=>{ke.currentRoom()==Ao?ke.dispatch("go","south"):W.msg("You are already aboard the Pink Flamingo.")},So(xo),xo.A.sail=Yo.A.sail=To.A.sail=Io.A.sail="There'll be plenty of time to sail come morning.";const Eo=new ie(["sails"]);Eo.A.examine=()=>{ke.$.betterSails?W.msg("Beautiful new silk sails. You are sure to go extra fast with these."):W.msg("While still serviceable, your sails have seen better days. The Pink Flamingo took a fair bit of chainshot in Nassau and, while your crew gave patching the sails a fair stab, none of them are tailors and it shows.")},So(Eo);const No=new ie(["cannons"]);No.A.examine=()=>{ke.$.cannons?W.msg("You have some brand new cannons. You can't wait to hear them in action."):W.msg("You lost most of your cannons during the fighting in Nassa u and had to toss the rest overboard to lose weight when you were fleeing from the British navy in the aftermath. Getting some new cannons would probably be a good idea.")},So(No);const Vo=new ie(["hull"]);Vo.A.examine=()=>{ke.$.hullFixed||ke.$.henryPaid?ke.$.hullFixed?W.msg("Henry did a fantastic job and the Pink Flamingo's hull looks as good as new."):W.msg("Henry is currently working on fixing the Pink Flamingo's hull."):W.msg("You hull is all shot up. You only made it back to Tortuga thanks to your crew's continuous bailing and a providentially calm sea. Leaving port before you get it patched up is out of the question.")},So(Vo);const Po=To.decor(["capstan"],"It's used to hoist the anchor.");Po.A.turn=Po.A.use="You prefer to let your crew do the manual labor.";const Oo=To.decor(["wheel","steering wheel"],"The wheel controls the ship's rudder.");Oo.A.use=Oo.A.turn="You give the wheel a turn, not that it really matters since the ship is currently docked.";const Co=new re(["ship registration","title","certi ficate","registration"],"It's a certificate attesting to your ownership of the Pink Flamingo.");Co.A.read="#.handWritten{``Ahoy,\nJeanne 'Jenny' Weigh be the proper owner of the Pink Flamingo.\nExpires: April 1678''}\nIt bears an official seal of the Port Royal Department of Marauding Vessels.";const Ho=To.decor(["glovebox","glove box","glove compartment"],"It's useful for keeping small items.");Ho.$.open=!1,Ho.$.itemsIn=[Co.id];const jo=Yo.decor(["gangplank","plank"],"It leads off the ship to the docks to the north.");jo.A.get="Better leave it for now. Your crew will haul it away when you leave tomorrow morning.",jo.goExit=jo.A.use=Ae("go","north"),Io.A.smell="You smell a faint citrusy odor coming from you chest.";const Do=Io.decor(["sea chest","chest"],"It's a rather plain wooden sea chest.");Do.A.smell="The sea chest smells faintly citrusy.",Do.A.get="The sea chest is too heavy to lug around.",Do.A.search=Ae("lookInside"),Do.A.lookUnder=Do.A.lookBehind="You don't even find dust, so clean is your cabin.";c onst Mo=new re(["vaseline"],"This stuff is delicious on toast.");var Ro;Mo.indefName="some vaseline",Mo.A.eat=(Ro=Mo,()=>{Ro.requireHeld(),Ro.hideAll(),W.msg("Yummy, way better than butter, cheese or jelly.")});const Fo=new re(["magazine","raider's digest","mag"],"It's this month's Raider's Digest issue. Useful if you need to blow your nose."),Uo=E(["turn to the crossword puzzle#fn{A4 version - US Letter version}. Oh cool, Mary Barnacle is your favorite constructor.","skim a cannon review, it claims the Bursua is the best value for money.","read an article about sea monsters. It claims a kraken's weak point is its mouth.","read an interview with the sculptor of the new Henry Morgan statue in Portobello's Tupelowood square.","turn to the games page. Ugh, it's a maze. Don't they know everybody hates mazes?"],!0);Fo.A.read=()=>W.msg("You flip through the magazine and "+Uo()),Fo.hint="#parrot{I bet there's all kinds of useful information in there if you read it,} says #V#.",ke.addSimpleVerb("blow nose","You nose isn't congested",{synonyms:["blow your nose","blow my nose"],actionName:"blowNose"}),ke.A.blowNose.after=()=>{ke.playerHas(Fo)&&W.msg("<> However you are glad that you have the magazine with you in case you need to later.")};const Lo=new re(["tangerine","citrus"],"You use it to dye your hair orange.");Lo.A.peel=Lo.A.eat="Yuck, no! You'd sooner have scurvy than eat a piece of fruit.",Lo.hint="#parrot{Tangerines are a kind of citrus, you know?} #V# says.",Do.$.open=!1,Do.$.itemsIn=[Mo.id,Fo.id,Lo.id],Io.A.go.before=e=>{"bed"!=e&&"sleep"!=e||(Wo(),ge())};const Bo=Io.decor("door","A boring old door that needn't be referred to in this game.");Bo.A.close=Bo.A.open="Ok then";const qo=Io.decor(["bed"],"You look forward to your bed once you've done all that needs doing before the race.");function Wo(){ke.$.henryPaid||ge("You can't go to bed yet, the Flamingo isn't seaworthy and the race starts at dawn!"),W.msg ("Really go to sleep? The race starts at dawn, you won't have time to do anything else before it begins."),W.yesno((()=>{ke.$.embarked=!0,$o("embark_start")}),"Really go to sleep?",(()=>W.msg("Nevermind")))}qo.A.search="You check your bed but find nothing -- you and Purplebeard once put a seahorse's head in Cap'n Quartz bed as prank and you've been mindful of retaliation ever since.",qo.A.enter=Wo,qo.A.lookUnder=$e((()=>{W.msg("Oh neat, you find a loose doubloon. You pocket it."),ke.$.gold+=1}),"You find nothing else."),Io.A.sleep=Wo,ke.addSimpleVerb("sleep","Here? I think you'd rather sleep in your bed in you cabin aboard the Pink Flamingo."),Yo.addExit(Io,"fore","cabin"),Yo.addExit(To,"up"),Yo.addExit(To,"aft_"),Io.addExit(Yo,"aft"),Io.addExit(Yo,"outside_"),To.addExit(Yo,"down"),To.addExit(Yo,"fore_"),ke.addSimpleVerb("aft",Ae("go","aft"),{synonyms:["a"]}),ke.addSimpleVerb("fore",Ae("go","fore"),{synonyms:["f"]}),ke.addSimpleVerb("port",Ae("go","port"),{synonyms:["p"]}),ke.addSimpleVerb("starboard",Ae("go ","starboard"),{synonyms:["sb"]}),ke.A.go.before=e=>{["aft","fore","port","starboard"].includes(e)&&!ke.currentRoom().boat&&ge(`${V(e)} doesn't mean anything when you're not on a ship!`)};const zo=new de("Tupelowood Square","You are standing in the middle of Tortuga's main square, near the statue of #statue#. The tavern is to the southeast of the square. The main road goes from the docks to the south towards the bayou to the north. To the east is Threadneedle Alley and to the west lies Carapace Lane.");zo.decor(["Tupelowood square"]).A.examine=Ae("look",null);const _o=zo.decor(["tavern","Shelly's Heart"],"Shelley's Heart#fn{It's named for some other Shelley and definitely not an anachronism.} is Tortuga's most popular tavern and one of the largest buildings in town.");_o.goExit=_o.A.enter=Ae("go","southeast");const Ko=new re(["fake beard","beard"],"It's a bright purple beard that -- you suspect -- Purplebeard fastened to Morgan's statue in Tupelowood square.");Ko.$.worn=!1,Ko.disguise=!0;const Go=zo.decor([" statue","statue of Purplebeard","statue of Henri Morgan","beard_"]);W.addProcessor("#statue#",(()=>Go.$.found?Go.childrenOn().includes(Ko)?"Henry Morgan (with a fake purple beard)":"Henry Morgan":"Purplebeard"));const Jo=$e((()=>{W.msg("Wait!? Why would ol' Purplebeard have a statue in Tortuga?\nYou take a closer look and chuckle when you realize it's actually a statue of Henry Morgan with a fake beard stuck on it."),Go.$.found=!0,Go.$.itemsOn.push(Ko.id)}),"It's a statue of Henry Morgan onto which somebody (Purplebeard, you'd wager) stuck a fake purple beard.");Go.hasBeard=()=>!Go.$.found||Go.childrenOn().includes(Ko),Go.A.examine=()=>{Go.hasBeard()?Jo():W.msg("It's a statue of Henry Morgan.")},zo.A.putOn.before=(e,t)=>{t==Go&&e instanceof re&&e!=Ko&&ge("You can't put "+e.defName+" on the statue.")},Go.$.itemsOn=[],zo.decor(["main road"],"The main road goes south towards the docks and north towards the bayou.");const Qo=zo.decor(["Threadneedle Alley"],"Threadneedle Alley, to the east, is the financial hub o f the city. It's where Tortuga's only bank is located.");Qo.goExit=Qo.A.enter=Ae("go","east");const Xo=zo.decor(["Carapace Lane"],"Carapace Lane lies to the west.");Xo.goExit=Xo.A.enter=Ae("go","west");const Zo=zo.decor(["docks"],"You can't actually see the docks from here, but they are to the south.");Zo.goExit=Zo.A.enter=Ae("go","south");const en=new de("Threadneedle Alley","You can tell Threadneedle Alley is in the fancy part of town as it is the rare Tortugan street to be paved. North is the Crimson Permanent Assurance branch, east is Cecile's shop, and back west is Tupelowood Square.");en.decor(["pavement","street","cobblestones","ground","floor"],"The alley is paved with cobblestones."),en.exits.inside_=()=>ge("You can enter the Crimson Permanent Assurance to the north or Cecile's shop to the east.");const tn=en.decor(["tupelowood square","square"],"Tupelowood Square is back to the west.");tn.goExit=tn.A.enter=Ae("go","west");const on=en.decor(["Crimson Permanent Assurance building","bank","branch"], "On the north side of the road are the Crimson Permanent Assurance's offices in Tortuga.");on.goExit=on.A.enter=Ae("go","north");const nn=en.decor(["Cecile's shop","Cecile's","ceciles shop","cecile"],"Cecile is the finest seamstress in the whole Caribbean.");nn.defName="Cecile's shop",nn.goExit=nn.A.enter=Ae("go","east");const an=new de("Carapace Lane","A rare bird merchant has set up shop here and is doing business from a cart piled with cages. The jail is to the north, west is a Cutlass, Cannon, et Cetera store, and back east is Tupelowood Square.");an.decor(["cart"],"A rickety old cart, piled high with bird cages.");const sn=an.decor(["bird cages","cages","cage"],"The cages each contain a single bird. Most are macaws but there are also a few cockatoos.");sn.A.examine.after=()=>{ke.$.freedFenix||W.msg("<> There's also a phoenix.")},sn.A.open="You don't need another parrot.";const rn=an.decor(["macaws","parrots","bird"],"Brightly colored parrots from the New World."),ln=an.decor(["cockatoos","parrots","b ird"],"These must have been imported from the East Indies.");rn.A.buy=ln.A.buy=rn.A.get=ln.A.get="You already have #V#, and one parrot is plenty.";const hn=an.decor(["phoenix","firebird","bird"],"The phoenix looks sad in its golden cage.");hn.hint=()=>ke.$.freedFenix?ke.$.gotFeather?"#parrot{What a magnificent creature,} #V# says with a hint of jealousy.":"#parrot{We saw it fly away towards the bayou I think,} recalls #V#.":"#parrot{It seems cruel to keep a magical creature like that in such a tiny cage,} remarks #V#.";const dn=an.decor(["golden cage","phoenix's cage","cage"],"The phoenix's cage looks like it's made of gold but the hinges are rusty so you suspect it's actually iron with a coat of paint.");dn.A.get="The golden cage is too cumbersome to lug around.";const un=dn.addDetail(["hinges","hinge"],"Rusty little hinges.");un.A.examine.after=()=>{un.$.oiled&&W.msg("They've been dabbed with vaseline")},ae("putOn",Mo,un,(()=>{Mo.requireHeld(),Mo.hideAll(),un.$.oiled=!0,W.msg("You apply some vaseline to th e hinges.")})),dn.A.open=()=>{un.$.oiled||ge("You wait for the merchant to be distracted before making to open the cage.\nThe hinges squeak noisily, attracting the the merchant's attention! #merchant{Oi! What do you think yer doing?} she asks as you back away trying to look innocent."),ke.$.freedFenix&&ge("That cage is empty."),W.msg("You wait for the merchant to look elsewhere and then you open the cage's door. The phoenix hurries out, flying off to the northeast! You quickly get away from the cart before the merchant can notice what you've done."),hn.hideAll(),ke.$.freedFenix=!0},hn.A.listen="You prefer the rite of spring.",hn.A.buy="You can't afford to buy the phoenix.",hn.A.free=hn.A.get=Ae("open",dn);const cn=new le(["rare bird merchant","hawker","merchant"],"Dressed in colorful robes, the rare bird merchant is hawking#fn{heh} her wares from a cart.","f",[{resp:"The merchant stares at you blankly, she clearly has nothing to say on the subject."},{about:["themself","themselves","herself",/parrots?|macaws ?|cockatoos?/],resp:"#merchant{I have the finest birds in the whole Caribbean!} the merchant says proudly."},{about:[/phoenix|firebird/],resp:"#merchant{A mighty fine specimen! Yours for only 2000 doubloons.}"},{about:[/bayou/],resp:"#merchant{I often hunt for birds in the bayou. It's easy to get lost if you don't pay close attention to your surroundings,} she says."},{about:[/mambo/,/voodoo priestess/],resp:"#merchant{The old bird lives somewhere out in the bayou I think.}"},{about:[/race/,/libonotus cup/],resp:"#merchant{I don't really follow regattas, piratical or otherwise. I would like to visit Portobelo some day though: there are some spectacular motmots to be found there!}"},{about:[/thin virge/,"virge","thin"],resp:"#merchant{Nice specimen. A tad overfed perhaps.}"},{about:[/taffy/,/caramel/],resp:"The merchant grins, #merchant{Ah yes. Taffy is great for keeping noisy birds quiet. I always keep a few handy.}"}]);cn.addDetail("colorful robes","The vivid primary colors of her robes makes the merchant a lmost look like a scarlet macaw."),cn.defName="The rare bird merchant",an.addItem(cn),ae("show",_e,cn,"The merchant looks at #V#, #merchant{Nice specimen, if a tad overfed. I'll give you 7 doubloons for 'im.}"),ae("offer",_e,cn,"No way, that would be like selling a member of your family!"),_e.A.sell="No way, that would be like selling a member of your family!",ae("offer",tt,cn,"#merchant{Thanks, but I already have plenty,} she declines."),ae("show",tt,cn,Ae("ask",cn,"taffy"));const mn=an.decor(["jail","prison"],"A forbidding stone building you hope never to visit.");mn.A.examine.after=()=>{an.$.escaped&&W.msg("Again.")},mn.hint="#parrot{As long as you don't break the law you shouldn't have to worry about it,} says #V#.";const gn=()=>ge("No thanks. Like most pirates you have a professional aversion to jails.");mn.goExit=mn.A.enter=gn,an.exits.north=gn,an.exits.jail_=gn;const yn=an.decor(["Cutlass, Cannon & Cetera","store","shop","cc&c","ccc"],"It's a souless big box weaponry shop. You'd prefer to patronize mo m and pop weapon merchants but they've all been driven out of business, unable to compete with the C,C&C's low prices.");yn.A.examine.after=()=>{ke.$.cannons&&W.msg("<> It is closed for the day.")},yn.goExit=yn.A.enter=Ae("go","west");const fn=an.decor(["tupelowood square","square"],"Tupelowood Square is back to the east.");fn.goExit=fn.A.enter=Ae("go","east");const pn=["#a $drunk $locals walks out of the tavern and leaves towards $nontav","$PERSON walks in from the docks and heads $nondock","[beard]$LOCAL glances at the statue and $laughs before heading to $squareloc","$PERSON comes in from Threadneedle Alley and goes $nonalleydir","$PERSON and $PERSON meet at the foot of the statue then head to $squareloc"],bn=["$person arrives from Tupelowood square and enters $tnbiz","$person exits $tnbiz and leaves towards Tupelowood square","$person entering $tnbiz bumps into $person who was just leaving"],wn={tnbiz:"the bank|the Crimson Permanent Assurance|Cecile's shop",laughs:"laughs|giggles|chuckles",drunk:"drunk| plastered|sozzled|pickled|tipsy|merry|lubricated",squareloc:"the docks|the tavern|Threadneedle Alley|Carapace Lane",nonalleydir:"north towards the bayou|south towards the docks|into the tavern|west to Carapace Lane",nondock:"to the tavern|to Threadneedle alley|north",nontav:"the docks|Threadneedle Alley|the bayou|Carapace Lane",adj:"fat|jolly|red-haired|blonde|young|old|tall|short|skinny|well dressed|debonair",locals:"townsman|townswoman|tailor|seamstress|brewer|innkeeper",pirates:"pirate|corsair|buccaneer|privateer",piracc:"a peg leg|an eyepatch|a hook hand",pirate:"#a $adj $pirates|#a $pirates with $piracc|#a $pirates",local:"#a $adj $locals",person:"$local|$pirate",racer:"Jenny Weigh|Charlotte Noire|Sammy Quartz|Cap'n Quartz|Purplebeard",rumors:"that they think $racer will will the Libonotus Cup|that they heard there where 'gators in the bayou|about how they solved the lastest crossword in record time|how the beer at the Heart isn't as good as it used to be|about some legendary hidden treasure|to not beli eve everything they hear",rumor:"You overhear a passing $locals tell $person $rumors"},kn=new le(["townsperson","townswoman","townsman","tailor","seamstress","brewer","innkeeper","pirate","corsaire","buccaneer","privateer"],"They're no longer here.",void 0,[{resp:"They're no longer here."}]);function vn(e,t){return An(S(wn[t.toLowerCase()].split("|")))}function $n(e,t){return t.match(/[aeio]/)?"an "+t:"a "+t}function An(e){return e.replace(/\$(.+?)\b/g,vn).replace(/#a ([a-z])/g,$n).replace(/\[.*\]/,"")}function Yn(){return ke.getItems("directInventory").some((e=>e.disguise&&e.$.worn))}kn.showInList=()=>!1,kn.A.examine.after=$e("\n#.instruction{The townspeople walking around are just here for flavor and don't need to be interacted with.}"),kn.A.talkTo="They're no longer here.",zo.addItem(kn),en.addItem(kn),zo.A.look.after=()=>{const e=S(pn);e.includes("[beard]")&&!Go.hasBeard()||W.msg(V(An(e)))},en.A.look.after=()=>{W.msg(V(An(S(bn))))},an.A.listen=en.A.listen=zo.A.listen=()=>W.msg(An("$rumor"));const In=new de("Jail","You are in a small jail cell, surrounded on three sides by solid stone blocks and on the fourth by metal bars and a sturdy door. On a bench are the skeletal remains of another prisoner. Through the bars to the south you can see the warden's desk.");In.A.enterRoom.before=$e((()=>0),(()=>{W.msg("This time the guards are less careless and make sure the door is locked before tossing you into the cell. Of course you still manage to escape, but by the time you do the race has already started. You run, and you run to catch up."),ke.die("You missed the starting gun")})),In.hint=new Je("#parrot{Have you looked around for the key?} asks #V#.","#parrot{On the desk too?} asks #V#.","#parrot{Can't reach the key? Maybe someone can bring it to you?} muses #V#","#parrot{Ask that cute little dog to bring you the key perhaps,} suggests #V#","#parrot{The dog won't come near? Perhaps there's something in the cell that will entice him?} wonders #V#","#parrot{Try waving a bone to attract the dog, maybe,} suggests #V#", "#V# frowns, #parrot{We can't seem to get the dog to bring us the key. Incidentally, have you checked that the door is actually locked?}","#parrot{Just open the unlocked door and leave,} sighs #V#."),In.decor(["warden"],"The warden isn't here at the moment."),In.name=()=>In.$.jigsUp?"Jail (locked in the cell)":"Jail (locked in the cell)";const Tn=In.decor(["floor","ground"],"Large stone slabs.");In.A.dig=Ae("dig",Tn),Tn.A.dig="Dig through the solid stone floor? That's not happening.",In.decor(["walls","solid stone blocks"],"Basalt you'd guess. Or maybe some other igneous stone. In any event you're not digging through it anytime soon.").A.dig="What do you w-- actually, nevermind. You aren't digging though those walls no matter what you try to dig with.";const Sn=new re(["tibia","bone"],"The tibia of an unfortunate fellow prisoner");ae("wave",Sn,null,In,"The bone piques the dogs attention. He takes a tentative step in your direction but then shies away.");const xn=new re(["brass key","key","keyring"],"A heavy brass key on a large keyring.");xn.A_.getFrom=xn.A.get="You can't reach the key.";const En=new le(["dog"],"A cute little Scottish Terrier.","m",[{resp:"``Arf''"},{tell:[/key/],ask:[/key/],resp:$e((()=>{En.$.hasKey=!0,xn.hideAll(),En.addDetail(xn),ge("You motion for the dog to get the key and, to your surprise, he grabs the keyring in his mouth! Now you only need him to come to you.")}),(()=>ge("You call and motion for the dog bring the key to you. Alas, without success.")))}]);En.lookDesc=()=>En.$.hasKey?"The dog, holding the key in his mouth, is sitting outside the cell, just out of reach.":"A dog is standing guard outside the cell.",En.defName="the dog",In.addItem(En),En.A.examine.after=()=>{En.$.hasKey&&W.msg("A brass key hangs from a keyring in his mouth.")},ae("offer",Sn,En,"You hold out the bone for the dog but, though he looks interested, he refuses to draw near."),En.A.pet=En.A.get="He's staying out of reach.",ae("ask",_e,"get the key",In,Ae("tell",_e,"get the key")),ae("ask",_e,"get key",In,A e("tell",_e,"get the key")),In.A.tell.after=(e,t)=>{e==_e&&W.msg("Besides, ``Thin'' (hah) #V# is too fat to fit through the bars.")};const Nn=In.decor(["bench"],"An old bench on which a fellow prisoner has been awaiting release for a very long time judging by his skeletal nature.");Nn.A.sitOn=()=>{W.msg("You sit down on the bench next to the skeleton"),ke.$.sitting=!0},In.A.sit=Ae("sitOn",Nn),In.decor(["desk","guard's desk"],"A sturdy oak desk, quite out of reach from within the cell.").$.itemsOn=[xn.id];const Vn=In.decor(["skeleton","skeletal remains","bone_"],"This fellow has seen better days.");Vn.A.examine.after=$e((()=>{W.msg("Oho, among the bones you spot a golden medallion."),In.addItem(Me)})),Vn.A.get=$e((()=>{W.msg("You take a tibia from the skeleton."),ke.$.inventory.push(Sn.id)}),"You've taken enough bones");const Pn=In.decor(["cell door","door"],"A study iron door with an intimidating lock.");Pn.addDetail(["lock"],"Looking at the impresive lock you wish you'd read that article on lockpicking in l ast month's Raider's Digest."),Pn.A.attack="You hit the door with all you might but it won't budge.",Pn.$.open=!1,Pn.A.open.before=$e((()=>{In.$.jigsUp=!0,W.msg("Oh hey, they forgot to lock the door.")})),Pn.A.open.after=$e(Ae("look",null,null)),Pn.A.unlock="You need the key to unlock the door.",In.decor(["bars"],"Solid metal bars stop you from leaving the cell.").A.attack="You try attacking them, but the bars don't budge.";const On=()=>{Pn.$.open&&(W.msg("You sneak out of the jail."),an.$.escaped=!0,an.enter("south")),ge("Between you and freedom lie the metal bars or the door.")};In.exits.south=On,In.exits.outside_=On;const Cn=new de("Crimson Permanent Assurance","Having recently taken over the VBCA, the Crimson Permanent Assurance has now entered the banking business."),Hn=new Je("#parrot{You could ask for a loan,} says #V#.","#parrot{Need collateral? Do you own anything really valuable?} asks #V#.","Suddenly #V# has an idea: #parrot{The Pink Flamingo is valuable! Do you have something that attests to your ownership over it?}","#parrot{The Pink Flamingo's registration is in the glovebox, on the quarterdeck,} #V# reminds you.");Cn.hint=()=>{if(!ke.$.tookOutLoan)return Hn},ke.$.gold=36;const jn=[/loan|money|cash|doubloons|gold/];W.addProcessor("#lass#",(()=>Yn()?"boy":"lass"));const Dn=E(["Davy Jones Iniquitous Average","Seafarer & Pirate 500","Freebooter Tribune Swashbuckler Exchange 100","Booty Exchange Locale 20"].map((e=>[e,Math.floor(20*T())+5*(T()>.5?1:-1)])),!0),Mn=new le(["cashier"],"The elderly cashier seems to be in his nineties. He is keeping an eye on you from behind his newspaper (and the counter).","m",[{resp:"The cashier just mumbles something incomprehensible in response."},{for:jn,about:jn,resp:Ln},{about:["collateral"],resp:"#cashier{Sorry #lass#, without some valuable collateral I can't lend ye any doubloons.}"},{about:["registration"],resp:()=>(Cn.$.regKnown=!0,"#cashier{Aye, a registration certificate be a fine piece of collateral.}")},{about:[/VBCA/i],resp:"The cashier smiles, #cashier{Aye , now that be a hostile takeover for ye.}"},{about:[/interests?/],resp:"#cashier{Thank ye for taking an in... for being curious about me interests. They include fishing, philately and usury.}"},{about:[/voodoo priestess/,/mambo/],resp:"#cashier{Aye, the voodoo priestess be living out in the bayou somewhere.}"},{about:["cashier","themself","himself","themselves"],resp:"#cashier{Ahoy! I be the one to see if ye be wanting to take out a loan.}"},{about:[/weather/],resp:"He winces. #cashier{Me arthritis be acting up. We be having a pretty big storm soon, mark me words #lass#.}"},{about:[/henry/,/shipwright/],resp:"#cashier{That dipsomanic? Ye'll finds him in the tavern for sure, #lass#.}"},{about:["newspaper",/starr+ tribune/,"tribune","paper","news",/(stock )?markets?/,"index","indices"],resp:()=>{const[e,t]=Dn();return`He looks up from his paper, #cashier{It says here that the ${e} is ${t>0?"up":"down"} ${Math.abs(t)} points.}`}}]);Mn.defName="the cashier",Mn.A.steal=Mn.A.attack=zn,Mn.A.talkTo=()=>{ke.$.tookOut Loan?Fe(Mn,"the weather"):Fe(Mn,"a loan","FOR")},Mn.lookDesc=()=>"Behind a counter, an old cashier is reading a newspaper.";const Rn=Mn.addDetail(["newspaper","paper"],"The cashier is reading the Starrrrrrr Tribune");function Fn(e){ke.$.tookOutLoan&&ge("The cashier isn't interested."),ge(`#cashier{Sorry #lass#, ${e.defName} won't work as collateral.}`)}function Un(){Co.requireHeld(),ke.$.tookOutLoan&&ge("You've already taken out a loan."),W.msg("You hand over the registration to the cashier who looks over it. #cashier{Aye, that'll do nicely as collateral,} he says and hands you a bagful of doubloons after filing a ridiculous amount of paperwork. You are now 275 doubloons richer#fn{Actually you are a bit poorer since you'll have to pay it back with interest. But you do have more cash on hand.}."),Co.hideAll(),ke.$.tookOutLoan=!0,ke.$.gold+=275}function Ln(){ke.$.tookOutLoan&&ge("#cashier{Ye already have an outstanding loan, #lass#.}"),Cn.$.regKnown&&ke.playerHas(Co)?Un():W.msg("You inquire about getting a loa n. The cashier looks sternly at you. #cashier{Ye be needing some collateral to get a loan, #lass#.}"),ge()}Rn.A.read="You peek at the paper but it's mostly financial mumbo jumbo.",Rn.A.get="The cashier is reading it.",Cn.decor("counter","It's just a boring old counter."),ae("offer",Co,Mn,Un),ae("show",Co,Mn,Un),Cn.A.offer.before=(e,t)=>{t==Mn&&e.$.worn&&ge("You probably shouldn't blow your disguise.")},ae("offer",re,Mn,Fn),ae("show",re,Mn,Fn);const Bn=Cn.decor(["loan","out loan","out a loan"],"");Bn.A.examine=Bn.A.borrow=Bn.A.get=Ae("askFor",Mn,"loan");const qn=new re(["doubloon","doubloons","money","gold","coin","120 doubloons"]);qn.showInList=()=>ke.$.gold>0,qn.inventoryName=()=>`${ke.$.gold} doubloon${1!=ke.$.gold?"s":""}`,qn.A.mayLetGo.before=()=>ge("Let go of your precious gold? Never!"),qn.A.small="Non olet, my transom! These coins reek.",qn.A.examine=()=>{const e=ke.$.gold;W.msg(`You have ${e>0?e:"no"} shiny doubloon${1!=e?"s":""}.`)},qn.A.count=()=>W.msg(`You count ${ke.$.gold} shiny doubloons`),ae(" borrow",qn,null,Cn,Ln),ae("get",qn,null,Cn,Ln);const Wn=Cn.decor("bank");function zn(){Cn.$.arrestedDisguise=Yn(),W.msg("You take a swing at the cashier, but he's more nimble than he looks and he dives behind the counter."),W.msg("He calls for help and suddenly a bunch of guards appear. As you are heavily outnumbered, they overpower you and haul you into jail."),In.enter("bank")}Wn.A.examine=Ae("look",null),Wn.A.steal=zn,Cn.A.enterRoom.before=()=>{Cn.$.arrestedDisguise===Yn()&&(W.msg("The cashier recognizes you when you enter and calls the guards."),In.enter("bank"))},ae("steal",qn,null,Cn,zn),Cn.A.wear=Cn.A.doff="No way, the cashier will see you.",Cn.addItem(Mn),ae("show",qn,Mn,"The cashier raises an eyebrow. #cashier{Ye wants to trade doubloons for doubloons?}"),ae("offer",qn,Mn,"#cashier{Ok then.} The cashier accepts your doubloons and then gives you an identical number of different doubloons. #cashier{I'm not really sure what was accomplished by that, #lass#.}"),ae("offer",_e,Mn,"#cashier{Sorry #lass#, t hat parrot isn't valuable enough,} says the cashier. #V# looks indignant.");const _n=new de("Cecile's shop","It's a seamstress' shop, full of textile products, clothes, table linen and, most importantly, sails."),Kn=$e((()=>{ge("#parrot{So do you think she's forgiven you?} asks Virge.\n#you{I'm sure she has. It's been years,} you reply, full of confidence.\n\n--\n\nAs you pick yourself up from the cobblestones in the middle of the road, you hear the door to Cecile's shop slam shut.")}),(()=>ge("No way, she was very clear as to what she would do if she ever saw you again.")));_n.A.enterRoom.before=()=>{Yn()||Kn()},_n.A.enterRoom.after=()=>ke.$.enteredCeciles=!0,_n.A.doff.before=e=>{e.disguise&&ge("No way! Not when Cecile is around.")},_n.A.borrow=_n.A.steal="That would be madness. Cecile hates you enough as is.";const Gn=_n.decor(["cloth products","clothes","table linen","table clothes","shirt","trousers","table cloth","textiles","textile products"],"Superb quality, but you don't need any right now.");Gn .A.get=Gn.A.buy="You don't need that right now";const Jn=_n.decor(["sail","sails"],"Magnificent silk sails.");function Qn(e){if(ke.$.gold>=e){const t=(ke.$.henryPaid?0:120)+(ke.$.gotPotion?0:10)-(ke.$.tookOutLoan?0:275);ke.$.gold-e{ke.$.betterSails&&ge("You already have fancy silk sails."),Zn.$.offeredErrand||(Zn.$.offeredErrand=!0,ge("#cecile{Those silk sails? You can buy them for 110 doubloons. Or,} she pauses, #cecile{I'll part with them for only 39 if you run a quick errand for me.}")),Zn.$.errandDone&&(Qn(39),ge("You don't have enough money.")),Zn.$.acceptedErrand&&ge("#cecile{Well, first bring me my package and then you can buy the sails.}"),Qn(110),ge("You don't have enough money.")},Zn=new le(["Cecile","Cecile","seamstress"],"She's still just as gorgeous after all these years.","f",[{resp:"She has nothing to say on the subject."},{about:["herself","themself","themselves","cecile","cecile","her"],resp:"#cecile{Hello, I'm Cecile.}"},{for:[/sail/],about:[/sail/],resp:Xn},{about:["me","myself"],resp:"#cecile{I don't believe I know you, sir.}"},{about:[/pouch/],resp:"#cecile{Bring it to the mambo and then bring me what she'll give you.}"},{about:[/errand/],resp:()=>{Zn.$.acceptedErrand&&ge("Don't you remember? You have to bring the pouch to the mambo and then back to me."),W.msg("You inquire as to what the errand would entail.\nShe takes a leather pouch out of her pocket, #cecile{Take this to the mambo. She'll give you a package in return; bring it to me and the sails are yours for 39 doubloons. What do you say?}"),W.yesno((()=>{Zn.$.acceptedErrand=!0,ke.$.inventory.push(ea.id),W.msg("#cecile{Great! Well, off you go,} she says and she hands you the pouch.")}),"#cecile{Will you run my errand, yes or no?}",(()=>W.msg("#cecile{You can pay full price then.}"))),ge()}},{about:["jenny","jenny weigh"],resp:"At the mere mention of your name her face contorts into a rictus of raw rage. You decide not to press the subject."},{about:["pirates"],resp:"#cecile{Treacherous snakes the lot of them.}"},{about:[/mambo/,"witch","voodoo priestess"],resp:"#cecile{She lives somewhere in the bayou I think.}"},{about:[/libonotus cup/i],resp:"#cecile{I'm not interested in pirate races.} Her pronounciation of the word ``pirate'' oozes with contempt."},{about:[/henry/,/shipwright/],resp:()=>ke.$.henryOut?"#cecile{Henry's drunk again, eh? The only thing that'll get him sober is one of the mambo's sobering potions.}":"#cecile{Despite his inclination for the bottle, Henry is a pretty good shipwright, or so I heard.}"},{about:["doll"],resp:"#cecile{That's none of your business,} she says pointedly."}]);_n.addItem(Zn),_n.A.show.before=_n.A.offer.before=e=>{ e.disguise&&ge("That would be, to put it mildly, ill-advised.")},Zn.lookDesc=()=>"Cecile is here, #draw{working on a table cloth|mending a pair of trousers|trimming a shirt}.",Zn.A.talkTo=()=>{ke.$.betterSails?Fe(Zn,"the Libonotus cup"):Zn.$.offeredErrand?Zn.$.acceptedErrand?Fe(Zn,"the mambo"):Fe(Zn,"the errand"):Fe(Zn,"some new sails")},Zn.A.pay=Jn.A.get=Jn.A.buy=Xn;const ea=new re(["leather pouch","pouch"],"Cecile tasked you with bringing it to the mambo.");ea.$.open=!1;const ta=new re(["strands of hair from the pouch","hair","strands","strands of hair"],"A few strands of orange hair.");ta.isPlural=!0,ta.bodySample=!0,ta.A.smell="You notice a familiar citrusy scent.";const oa=new re("coins","You count 50 doubloons in the pouch.");ea.$.itemsIn=[ta.id,oa.id],oa.A_.getFrom=()=>{oa.hideAll(),ke.$.gold+=50,W.msg("You pocket the coins.")},ke.addBeforeHook("putIn",((e,t)=>{t==ea&&t.$.itemsIn.length>=2&&ge("The pouch is full."),t==ea&&e instanceof re&&e!=qn&&e!=Ko&&e!=sa&&void 0===e.bodySample&&ge(V(e.defName)+" won't fit in the pouch.")}));const na=new re(["purple beard bits","beard bits"],"Some bits of the fake beard you snipped off.");function aa(){ke.$.cursed=sa.$.active,W.msg("#cecile{She'll be sorry now,} she cackles under her breath, before regaining her composure and turning to you. #cecile{Thank you sir. As promised you can have the sails for only 39 doubloons.}"),Qn(39),Zn.$.errandDone=!0,W.msg("You should come back when you have the money.")}na.bodySample=!1,ae("putIn",Ko,ea,$e((()=>{W.msg("You snip a few strands of the fake beard."),ke.$.inventory.push(na.id),ke.dispatch("putIn",na,ea)}),"The fake beard would no longer be an effective disguise if you were to trim any more of it.")),ae("putIn",qn,ea,(()=>{(ke.$.madeDoll||ea.childrenIn().includes(oa))&&ge("Nah"),ke.$.gold<50&&ge("You don't have enough doubloons to return."),ke.$.gold-=50,ea.$.itemsIn.push(oa.id),W.msg("You return 50 doubloons to the pouch.")}));const sa=new re(["creepy doll","voodoo doll"],"It's a creepy little doll.");sa.$.active=!0,sa.A .attack=()=>{sa.$.active&&ge("You punch the doll and feel a corresponding pain.\nThat can't be good."),W.msg("You punch the doll.")},ae("offer",sa,Zn,(()=>{sa.requireHeld(),sa.hideAll(),W.msg("She grins as you hand her the doll."),aa()})),ae("offer",ea,Zn,(()=>{ea.requireHeld(),ea.$.itemsIn.some((e=>e==sa.id))||ge("She peeks into the pouch before returning it to you. #cecile{This isn't what I ordered.}"),ea.hideAll(),W.msg("She peeks into the pouch and grins."),aa()})),_n.A.open.before=e=>{e==ea&&ge("You probably shouldn't fiddle with the pouch in Cecile's presence.")};const ra=new de("The Mambo's Hut","You are in the voodoo priestess' hut. Bundles of strange herbs hang from the ceiling. A large cauldron occupies the center of the room. Scores of talismans and charms are attached to the walls."),ia=new re(["swamp rose flower","flower","blossom","rose","swamp rose"],"The flower of a swamp rose.");function la(){return`#witch{I still need ${N([Lo,ia].filter((e=>!ua.childrenIn().includes(e))).map((e=>e.indefNam e)))} to be able to brew the abstemious aperitif.}`}const ha=new le(["voodoo priestess","Marie","witch","mambo","priestess"],"She is dressed in ceremonial robes and is wearing a lot of ritual jewelry.","f",[{resp:"She just shrugs"},{tell:["yes"],resp:"She smiles."},{tell:["hello","hi","greetings"],resp:"#witch{Greetings, girl!} replies the mambo."},{about:["me","jenny","jenny weigh"],resp:"She looks you up and down. #witch{I can see from your astounding aura that you will have a formidable future.}"},{about:["cauldron"],resp:"#witch{It's a original Steele's Pots and PansR cauldron,} she says proudly."},{about:["themself","herself","voodoo priestess","witch","her","mambo","marie"],resp:"#witch{I'm mambo Marie, the best mambo this side of the chelonian canal!}\nYou try to look impressed and refrain from mentioning that she's also the #.emph{only} mambo on the island."},{about:["cecile","seamstress"],resp:"#witch{She's great isn't she?}"},{about:["citrus","tangerine"],resp:"#witch{Its ascorbic attributes are vital for many a potion.}"},{about:[/(swamp rose|blossom|flower|rose)/],resp:"#witch{It gives potions the appropriate aroma.}"},{about:[/amulets?|talismans?|charms?|dolls?/],resp:"#witch{They're imbued with my magnificent magicks!}"},{about:[/herbs?/],resp:"She mumbles something about a trading event in Scarborough."},{about:[/phoenix|firebird/],resp:"#witch{The fabulous firebirds are said to be massively magical as well as largely loyal to those who help them.}"},{about:[/robes?/,"clothes"],resp:"#witch{These? I just bought them from seamstress Cecile downtown.}"},{about:[/ingredients?/],resp:la},{for:[/(sobering|(anti)?drunk(ness)?)?\s*(potion|cure)( for henry)?/,/(#|number)\s?(five|5)/],about:[/(sobering|(anti)?drunk(ness)?)?\s*(potion|cure)( for henry)?/,/henry/,/(#|number)\s?(five|5)/],resp:()=>ke.$.henryOut?ke.$.seekRose?ke.$.gotPotion?"#witch{My #5 is superior stuff isn't it?}":la():(ke.$.seekRose=!0,"You ask for a remedy to sober up the shipwright.\n#witch{Sure, I can brew some of my #5 potion for y ou. It'll cost 10 doubloons.} She starts tossing various herbs into the cauldron then pauses and looks for something. #witch{You'll also need to bring me a swamp rose blossom and some kind of citrus.}"):"#witch{I'm busy buddy. Come back later,} she says."}]);ha.defName="the voodoo priestess",ha.addDetail("robes","Colorful robes dyed using ancient and secret techniques, no doubt."),ha.addDetail(["ritual jewelry","jewelry","trinkets","beads","gator teeth"],"Various trinkets made with lots of colorful glass beads and 'gator teeth."),ha.hint=()=>ke.$.foundWitch?"#parrot{Sorry, I'm not sure what you need help with,} says #V#, sheepishly.":"#parrot{Mambos often hang around in bayous,} offers #V#.",ha.A.talkTo=()=>{!ke.$.madeDoll&&ke.$.inventory.some((e=>e==ea.id))?ke.dispatch("offer",ea,ha):ke.$.henryOut?Fe(ha,"a sobriety potion","FOR"):Fe(ha,"herself")},ha.A.pay="She shrugs, #witch{You can pay me when the potion is ready.}",ae("offer",qn,ha,Ae("pay",ha,null)),ra.addItem(ha);const da=$e((()=>ge("#witch{Don't mess with my sacred stuff,} the mambo warns you.")),(()=>{W.msg("#witch{I warned you not to mess with my blessed belongings!}"),W.msg("The voodoo priestess touches one of the talismans on the wall and mumbles a curse."),ke.die("Ribbit")})),ua=ra.decor(["cauldron"],"A massive cast iron cauldron, hanging over a simmering fire.");ua.$.itemsIn=[],ua.A.lookInside="The contents of the cauldron are bubbling.",ra.A.smell=Ae("smell",ua),ua.A.smell="You detect a #draw{note|whiff|hint} of #draw{fillet of fenny snake|toe of frog|tongue of dog|adder's fork|blind-worm's sting|lizard's leg|howlet's wing} from the cauldron.",ua.A.pour=ua.A.drink=da,ae("getFrom","*",ua,"You'd burn yourself."),ke.A.putIn.before=(e,t)=>{Array.isArray(e)||t!=ua||e!=Lo&&e!=ia&&da()},ke.A.putIn.after=ma,ra.decor(["fire"],"The fire is keeping the cauldron nice and hot.");const ca=new re(["sobering potion","potion","#5","number five"],"The sobering potion is orange and bubbly and has a faint swampy smell.");function ma(){ke.$.gotPotion||[Lo,ia].every((e =>ua.childrenIn().includes(e)))&&(W.msg("She says some magic words and you watch the fire burn and cauldron bubble. After cooling it down with baboon's blood she starts bottling the mixture.\n#witch{That'll be 10 doubloons dear.}\nYou hand over the money and she hands you a potion.\n#witch{Just pour it on the pickled party and they'll be sober as a haunted Hazel in no time.}"),ke.$.gold-=10,ke.$.gotPotion=!0,ke.$.inventory.push(ca.id))}function ga(e){e.requireHeld(),e.hideAll(),W.msg(`You hand her ${e.defName} which she tosses into the cauldron.`),ua.$.itemsIn.push(e.id),ma()}ca.sobering=!0,ca.A.drink="You are already sober enough.",ca.A.smell="It has a swampy bouquet",ca.A_.pour="You don't want to waste the potion.",ae("pour",ca,ha,"As if reading your thoughts, the mambo shoots you a black look and you decide not to end the day turned into a frog."),ha.A.attack="As if reading your thoughts, the mambo shoots you a black look and you decide not to end the day turned into a frog.",[ia,Lo].forEach((e=>{ae("offe r",e,ha,ga),ae("show",e,ha,ga)})),ke.A.show.before=ke.A.offer.before=(e,t)=>{t==ha&&e.givesMagic&&ge(`She examines ${e.defName} before handing it back to you. #witch{This ${e.names[0]} is imbued with some mighty magical mojo! You should hang on to it.}`)};const ya=ra.decor(["herbs","bundles","wool of bat","eye of newt","mosses","moss"],"There's some wool of bat, some eye of newt, various mosses, and dozens of other herbs you don't recognize hanging in bundles from the ceiling."),fa=ra.decor(["amulets","talismans","charms"],"Many many talismans are pinned to the walls of the hut.");function pa(){ke.$.madeDoll&&ge("The mambo already did her part. Now you need to bring the pouch back to Cecile."),ea.requireHeld(),W.msg("You hand over the pouch to the mambo."),ea.$.open=!0;const e=ea.childrenIn();e.includes(oa)||ge("She looks into the pouch before thrusting it back into your hands. #witch{The pecuniary part is missing.}"),e.some((e=>void 0!==e.bodySample))||ge("She looks into the pouch before thrusting it back into your hands. #witch{There's no somatic sample in here.}"),W.msg("She takes a small doll from one of the walls before emptying the pouch into her cauldron. She whispers some magic words as she waves the doll over the fumes then puts it in the pouch."),W.msg("#witch{Here you go. Please thank charming Cecile for her business,} she says as she hands you the pouch."),sa.$.active=e.find((e=>void 0!==e.bodySample)).bodySample,e.forEach((e=>e.hideAll())),ea.$.itemsIn.push(sa.id),ea.$.open=!1,ke.$.madeDoll=!0}fa.A.examine.after=$e("The priestess sees you peering at the amulets. #witch{You can look, but don't try touching.}"),fa.A.count="More than forty. Considerably less than 69105.",[fa,ya,ua].forEach((e=>{e.A.touch=e.A.push=e.A.pull=e.A.get=da})),ra.decor("ceiling","A thatched ceiling from which bundles of herbs are hanging."),ra.decor(["floor","ground"],"Just a plain dirt floor."),ae("offer",ea,ha,pa),ae("show",ea,ha,pa),ra.exits.inside_=()=>ge("You are already inside the hut.");const ba=Ao.decor(["tupelowood square"],"Tupelowood Square is up the road to the north.");ba.goExit=ba.A.enter=Ae("go","north"),Ao.A.smell="Something here smells fishy. The ocean probably.",Ao.decor(["harbor","water","sea","ocean"],"You watch the sunset reflecting in the harbor's water.").A.smell="It smells fishy.",Ao.A.swim="Swim? When you own such a magnificent ship? I think not.";const wa=Ao.decor(["other ships","ships","cherter boat","esprit of canne","spirit of canne"],"You see several ships moored in Tortuga's harbor, among them you recognize Cap'n Flint's ``Cherter Boat'' and Sammy's ``Spirit of Canne''.");wa.goExit=wa.A.enter="The other ships are moored out of reach in the harbor. Besides, boarding a fellow pirate's ship uninvited would just be plain rude.";const ka=()=>{ke.$.gotQuote?W.msg("#henry{As soon as you pay my fee I'll get started.}"):(W.msg("Henry turns towards you. #henry{The damage isn't too bad, a few of the timbers need to be replaced and a third of your planks are shot, but the ribs and knees are fine. I should be able to fix it all up in a few hours. It'll cost you 120 doubloons.}"),ke.$.gotQuote=!0),ge()};ke.addDirectVerb("pay","#.softError{I don't understand.}");const va=new le(["Henry the shipwright","henry","shipwright"],"Henry is a hefty man with a bushy red beard.","m",[{resp:"#henry{I don't know about that.}"},{about:[/\bsails?\b/],resp:"#henry{Sorry, I don't do sails. Maybe ask Cecile?} he answers."},{for:["quote","cost","repairs"],about:["hull","quote","cost","repairs","ship"],resp:ka}]),$a=va.addDetail(["Henry's beard","beard hair"],"Henry's bushy red beard is ... well ... reddish and rather bushy?");$a.A.examine.after=()=>{ke.$.yankedBeard&&W.msg(" A small patch is missing which you will deny having anything to do with if anybody asks.")},$a.defName="Henry's beard";const Aa=new re(["red beard bits","beard bits"],"Some bits of Henry's beard.");Aa.bodySample=!1,$a.A.get=()=>{ke.$.yankedBeard?W.msg("Nah, you don't want to deplete his beard."):(W.msg("In a brazen act of kleptotrichy you yank a tuft of hairs from Henry's beard.\n#henry{Yeow! Did you just yank my beard!?}\n#you{What? No! It was a tufted titmouse,} you lie pointing towards the sky."),ke.$.inventory.push(Aa.id),ke.$.yankedBeard=!0)},va.lookDesc=()=>ke.$.gotQuote?ke.$.henryPaid?"Henry is here, working on the Pink Flamingo's hull.":"Henry is standing here.":"Henry is examining the Pink Flamingo's hull.",va.A.talkTo=()=>{ke.$.henryPaid?W.msg("#henry{I'll be done in no time.}"):ka()},va.A.pay=()=>{ke.$.gotQuote||ka(),ke.$.henryPaid&&ge("You've already paid Henry."),ke.$.gold>=120?(ke.$.gold-=120,ke.$.henryPaid=!0,W.msg("You hand over 120 doubloons to Henry. #henry{I'll get started right away!}"),ke.$.fixTime=ke.$.time+10):W.msg("You don't have enough money.")},va.tick=()=>{ke.$.henryPaid&&ke.$.fixTime>ke.$.time?va.msg("#draw{Henry hammers on the hull.|Henry fetches some planks from his shipyard.|Henry measures a part of the hull.|Henry curses as he hits his thumb with a hammer.}"):ke.$.fixTime==ke.$.time&&(va.msg("Henry puts the finishing touches on th e Pink Flamingo's hull. #henry{There! Good as new,} he says before leaving."),ke.$.hullFixed=!0,va.hideAll())},ae("offer",qn,va,Ae("pay",va,null));const Ya=Ao.decor(["shipyard","gate","henry's shipyard"],"The gate to the shipyard is closed.");Ya.A.open=()=>{Ao.containsItem(va)?W.msg("Henry stops you."):ke.$.hullFixed?W.msg("The gate is locked, but it doesn't matter since your ship has already been fixed."):W.msg("The gate is locked but it doesn't matter: without the shipwright, access to the shipyard does you little good.")},Ya.A.unlock="You don't have the key or the lockpicking skills required.",Ya.goExit=()=>{ke.dispatch("examine",Ya),ge()},Ya.A.enter=Ae("examine"),Ao.exits.northwest=()=>{ke.dispatch("enter",Ya),ge()};const Ia=Ao.decor(["note"],"It reads:\n#.handWritten{Off for the day.\nFor emergencies find me at the tavern -- H.}");Ia.A.read=Ae("examine"),Ia.A.examine.after=()=>ke.$.noteRead=!0,Ia.A.get="That would be rather inconsiderate.",Ya.A.examine.after=()=>{Ao.containsItem(Ia)&&(W.msg("There's a n ote attached to it."),ke.itIs(Ia))};const Ta=Ao.decor(["gangplank","plank"],"It leads onto your ship to the south.");Ta.goExit=Ta.A.use=Ae("go","south"),Ta.A.get="Better leave it for now. Your crew will haul it away when you leave tomorrow morning.";const Sa=new de("Tavern");Sa.A.look.before=$e((()=>{W.msg("#.emph{1676, a seedy tavern in Tortuga}\n\n#sammy{You? Win the Libonotus Cup?} scoffs Sammy. #sammy{After the debacle in Nassau I'd be impressed if your ship even makes it to the starting line tomorrow morning, let alone Portobello.}\n#you{Aye,} you say, #you{me ship may have taken a beating in that last raid, but I'll bet ye 500 doubloons I can still beat ye to the finish line!}\n#sammy{Yer on matey!} Sammy shakes your hand, then downs their mug, gets up and leaves.\n\nYou'd better get cracking, the race starts at dawn and your ship isn't exactly seaworthy at the moment."),W.msg("#.instruction{Press space to continue}"),W.wait((()=>{ke.dispatchP("look"),W.msg("#.instruction{New players may want to type H ELP}")})," "),ge()})),ae("buy","string",null,Sa,(e=>{e.match(/drink|rum|beer|round|grog/)?W.msg("You'd love to get another drink or three but you have work to do."):e.match(/coffee/)?W.msg("This is a rowdy tavern, not an Ishmaels coffee house."):W.msg(`#.softError{You don't see ${H(e)} for sale here.}`)})),ke.addDirectVerb("order","#.softError{I don't understand.}"),Sa.A.order=Ae("buy"),Sa.addBeforeHook("get",(e=>{e.match?.(/drink|rum|beer|grog/)&&ge("You'd love to get another drink or three but you have work to do.")}));const xa=Sa.decor("tavern");xa.A.examine=Ae("look",null),xa.A.exit=Ae("go","outside"),Sa.A.smell="The tavern smells of rum soaked oak.",Sa.decor(["sammy","calico sammy"],"Your friend Calico Sammy is no longer here.").A.talkTo=Ae("examine"),Sa.decor(["square","main square","tupelowood square"],"Tupelowood square is just outside the door, to the northwest.");const Ea=new le(["Henry the shipwright","henry","shipwright"],"Henry is a hefty man with a bushy red beard.","m",[{resp:"Henry is making no sense, he is clearly three sheets to the wind."},{for:["repairs"],about:[/ship|hull|repairs?|pink flamingo|flamingo/,/(fix|repair|mend|patch up) ((my |your |the )?(ship|boat|hull|pink flamingo))/],resp:()=>(ke.$.henryOut=!0,"You ask Henry about doing some repairs on your ship. He nods a few times but then promptly passes out.\nYou'd better find a way to get him sober.")}]),Na=Ea.addDetail(["Henry's beard","beard hair"],"Henry's bushy red beard is ... well ... reddish and rather bushy?");Na.defName="Henry's beard",Na.A.examine.after=()=>{ke.$.yankedBeard&&W.msg(" A small patch is missing which you will deny having anything to do with if anybody asks.")};const Va=new re(["red beard bits","beard bits","beard strands","beard tufts","beard tuft"],"Some bits of Henry's beard.");Va.bodySample=!1,Na.A.get=Na.A.pull=()=>{ke.$.yankedBeard?W.msg("Nah, you don't want to deplete his beard."):(ke.$.henryOut?W.msg("You try to wake Henry by yanking his beard. A few strands of his beard come loose in your hand, but Henry doesn't stir."):W.msg("In a brazen act of kleptotrichy you yank a tuft of hairs from Henry's beard. He's so drunk he doesn't even notice."),ke.$.inventory.push(Va.id),ke.$.yankedBeard=!0)},Ea.lookDesc=()=>ke.$.henryOut?"Henry is passed out, his head resting on a table.":"Henry is here, #draw{drinking from a large mug of rum|belting out a salty song|ordering another drink}.",Ea.A.talkTo=()=>{Fe(Ea,"repairing your ship")},Ea.A.attack=()=>{ke.$.henryOut?W.msg("You try slapping him across the face but Henry just goes on snoring."):W.msg("#parrot{Perhaps you shouldn't assault the guy who's going to fix the ship,} suggests Virge.")},Ea.A.kiss=()=>{ke.$.henryOut?W.msg("Henry is not roused."):W.msg("You'd rather not")},Ea.A.push=Ea.A.pull=Ea.A.wake=$e("You shake Henry but to no avail.","Despite your best efforts you can't manage to rouse Henry.");const Pa=$e("``Don't bother,'' calls out one of the regulars, ``when he's that plastered the only thing that'll sober him up is some of the voodoo priestess' #5 potion.''" ,"One of the locals suggested the voodoo priestress might be able to help.");function Oa(){ca.requireHeld(),ca.hideAll(),W.msg("You pour the potion onto Henry's head. His eyes open wide and he shakes his head a few times. ``Oh wow,'' he says, ``some of Marie's number five. I must have been completely wasted. Anyhoo, what can I do for you?''\nYou tell him about the Pink Flamingo's hull and the race tomorrow morning.\n``Let me go see the extent of the damage and I'll give you a quote,'' he says before leaving the tavern."),Ea.hideAll(),Ao.addItem(va),Ia.hideAll(),ke.$.soberHenry=!0}Ea.A.wake.after=Ea.A.attack.after=Ea.A.kiss.after=()=>{ke.$.henryOut&&Pa()},Ea.A.examine.after=()=>{ke.$.henryOut?W.msg("He is currently passed out"):W.msg("He seems to be pretty drunk.")},Ea.A.ask.before=Ea.A.tell.before=Ea.A.askFor.before=()=>{ke.$.henryOut&&ge("Henry is passed out on his chair, his head resting on the table.")},ae("pour",ca,null,Sa,Oa),ae("pour",ca,Ea,Oa),ae("offer",ca,Ea,Oa),ae("putOn",ca,Ea,Oa),ae("offer",re,Ea ,(e=>{ke.$.henryOut?W.msg("Henry is currently passed out."):W.msg("Henry is too drunk to care about "+e.defName)}));const Ca=$e((()=>{W.msg("You notice Henry, the shipwright, among the crowd."),Sa.addItem(Ea)}));Sa.A.look.after=()=>{ke.$.noteRead&&Ca()},Sa.desc=()=>`You are ${ke.$.sitting?"sitting at a table ":""}in a rowdy tavern. Patrons in various states of inebriation are chatting, singing or sleeping. The door leads out to Tortuga's main square.`;const Ha=new le(["patrons","pirates","townfolk","chatting","singing","sleeping","locals","regulars","customers"],"The patrons are a merry mix of townfolk and visiting pirates. Everybody seems to be having a good time.","they",[{resp:"All your attempts at conversation are stymied by your interlocutors' intoxication."}]),ja=E([["the weather"],["grog"],["the joys of piracy",!0],["the twelve steps",!0]],!0);Ha.A.talkTo=()=>{let[e,t]=ja();t=t?"TELL":"ASK",Fe(Ha,e,"ABOUT",t)},Ha.defName="the patrons",Ha.showInList=()=>!1,Ha._A.offer="They don't want $thecod.",Sa.addI tem(Ha);const Da=new Je("#parrot{Try slapping Henry to wake him up!} suggests Virge.",'#parrot{Well it works in the movies#fn{Ed: The game is set in 1676, what are these "movies" you speak of?},} says Virge sheepishly. #parrot{But one of the regulars said something about a voodoo priestess, we should look into that.}',"#parrot{We need to find this voodoo priestess person!} says Virge.","#parrot{Voodoo priestesses often live in bayous,} says Virge.");Sa.hint=()=>ke.$.noteRead&&!ke.$.henryOut?"#parrot{We should talk to Henry about repairing our ship,} suggests Virge.":!ke.$.henryOut||ke.$.soberHenry||ke.$.seekRose?!ke.$.soberHenry&&ke.playerHas(ca)?"#parrot{Well, just pour the potion on Henry I suppose,} say Virge.":void 0:Da,Sa.A.sing="You join in on one of the sea shanties",Sa.A.listen="You hear some slurred bits of conversation, but mostly raucous singing of salty sea shanties.";const Ma=Sa.decor("door","It's just a regular old door.");Ma.A.open=Ma.A.close="You don't need to mess with the door.";const Ra=Sa.decor("table","A sturdy oak table.");Ra.A.lookUnder="Under the table is nothing but the filthy floor.",Sa.decor(["floor","filthy floor"],"The floor has been stained by countless spilt drinks.");const Fa=new re(["teacup","my teacup","cup"],"It's your novelty teacup. Some text on it reads: ``There's a good chance this is grog.''");Ra.$.itemsOn=[Fa.id],Fa.defName="your teacup",Fa.lookDesc=()=>Fa.indefName+(Fa.$.cracked?" (cracked)":""),Fa.A.get.before=$e((()=>{W.msg("You reach to pick up the teacup but clumsily knock it over.\nYou've cracked your teacup."),Fa.$.cracked=!0})),Fa.A.examine.after=()=>{Fa.$.cracked&&W.msg("It is cracked.")},Fa.A.drink="Sadly the teacup is empty",Fa.A.read=Ae("examine");const Ua=Sa.decor(["chair"],"A basic wooden chair");Ua.A.get="As a pirate you're all about stealing stuff, but this chair is neither portable nor valuable.",Ua.A.sitOn=()=>{W.msg("You sit down on a chair"),ke.$.sitting=!0},Sa.A.sit=Ae("sitOn",Ua);const La=new de("Cutlass, Cannon, & Cetera","There are four bran ds of cannon on display: the LAAD cannons cost only 20 doubloons, the Lerevchot set is on sale for 40, the Bursua bundle costs 75 and the luxury Horspec costs 125 doubloons.");La.A.enterRoom.before=()=>{ke.$.cannons?ge("The CC&C is closed."):La.$.arrestedDisguise===Yn()&&ge("The guard recognizes you, ``Sorry "+(La.$.arrestedDisguise?"sir":"ma'am")+", you are banned from this establishment.")},La.A.enterRoom.before=$e("You usually prefer not to patronize big box stores but unfortunately all the mom and pop arm dealers in Tortuga have closed. You head to the cannon aisle.","You head to the cannon aisle."),La.hint=()=>{ke.dispatch("hint","cannons"),ge()},[{name:"LAAD",alias:"lada",madeIn:"??????? ?? ????",price:20,tag:"Dangerous"},{name:"Lerevchot",alias:"chevrolet",madeIn:"Made in Columbia",price:40,tag:"Fragile"},{name:"Bursua",alias:"subaru",madeIn:"???",price:75},{name:"Horspec",alias:"porsche",madeIn:"Deutsche Ingenieurskunst",price:125}].forEach((e=>{const t=La.decor([e.name+" cannons", e.name,e.alias],"A set of cast iron killing machines. There's a label that reads: ``"+e.madeIn+"'' and a sticker that shows the price, viz. "+e.price+" doubloons.");t.A.get=Ae("buy"),t.A.steal=t.A.borrow=$e("CC&C security is notoriously tight, you don't think you'll be able to get away with stealing a whole set of cannons.",(()=>{void 0===La.$.arrestedDisguise?(W.msg("You try to surreptitiously slip a cannon under your coat but it doesn't go unnoticed. The city guards are summoned and you are thrown into jail!\n"),La.$.arrestedDisguise=Yn(),In.enter("guards")):ge("No way. You tried once and it didn't go well.")})),t.A.buy=()=>{ke.$.gold{ns.$.triedBotany=!0,ge("Ye be a pirate, not a botanist!")},Ba.push(a),a}W.addProcessor(/#hintName\{(.+)\}\{([12])\}/,(function(e,t,o){return ke.$.foundWitch?t:`=13?"style='font-style: italic'":""}>=19?`style='font-size: 1.${(""+Math.min(20,ns.$.timeLost-15)).padStart(2,"0")}em'`:""}>`+t.slice(0,o)+""+t.slice(o)+""}));const Wa=qa("north","narrowleaf sedge","Some #hintName{narrowleaf sedge}{1} is growing here.","n"),za=qa("northeast",["newt's eye","eye of newt","clump of newt's eye"],"A clump of #hintName{newt's eye}{2} is growing here.","ne"),_a=qa("east",["eyebane","patch of eyebane"],"A patch of #hintName{eyebane}{1} is growing here.","e"),Ka=qa("southeast","seaweed","S ome #hintName{seaweed}{2} has washed up here.","se"),Ga=qa("south","Spanish moss","You notice some #hintName{Spanish moss}{1} hanging from the trees here.","s"),Ja=qa("southwest",["swamp rose bush","swamp rose"],"A #hintName{swamp rose}{2} is in bloom here.","sw"),Qa=qa("west","wool of bat","A fair amount of #hintName{wool of bat}{1} is growing on the trees.","w"),Xa=qa("northwest",["'nwed wench's purse","unwed wenchs purse"],"Some '#hintName{nwed wench's purse}{2} is in bloom here.","nw");Ga.isPlural=!1,Ka.A.smell="Briny!",[Wa,za,Ga,Ja,Qa,Xa].forEach((e=>e.A.eat="Not being a botanist, you decide it's unwise to nibble on random herbs.")),Ka.A.eat="It's ok but you think it would taste better wrapped around some rice and raw fish.",_a.A.eat="With a name like #.emph{eyebane} you decide not to.",ia.A.smell=Ja.A.smell="By any other name it would smell as swampy.",Ja.hint=ia.hint=()=>{if(ke.$.seekRose&&!ke.$.foundRose)return"#parrot{I'm sure we can find a swamp rose in the bayou,} says #V# optimistically."};const Za=$e((()=>{ke.$.foundRose=!0,ke.$.inventory.push(ia.id);let e="sometimes being a pirate means being a botanist too.\nYou pluck a flower from the swamp rose bush.";ns.$.triedBotany&&(e="my mistake, "+e),ge(V(e))}),(()=>ge("Nah, I think we have enough.")));Ja.A.get.before=()=>{ke.$.seekRose&&Za()};const es=new de("Edge of the Bayou");es.desc=()=>{let e="Small paths lead northward into the bayou.";return ke.$.foundWitch&&(e+=" You remember that the path to northwest leads to the voodoo priestess' hut."),"You are at the edge of town. The road leads south back to Tortuga's main square. "+e},es.decor(["town","tortuga"],"Tortuga! The Caribbean's most sordid den of thieves. You love the place.").A.enter=Ae("go","south");const ts=es.decor(["tupelowood square","square","main square"],"Tupelowood Square is to the south");ts.goExit=ts.A.enter=Ae("go","south");const os=es.decor(["bayou","water","swamp"],"The bayou streches northward as far as the eye can see. Which admittedly isn't very far what with the trees.");os.add Detail(["trees"],"The trees are in the bayou to the north."),os.goExit=os.A.enter=Ae("go","north"),es.decor("paths","The paths lead northward into the bayou."),es.decor("road","The road leads south towards Tortuga's main square.");const ns=new de("The Bayou"),as=new Je("#parrot{It seems like nature itself is trying to guide us,} observes Virge.","#parrot{There might be a way to tie the plants to the correct direction,} muses Virge.","#parrot{The first letter(s) of these plants all match cardinal directions!} exclaims Virge.",(()=>`Virge examines ${is().defName}, #parrot{${V(is().names[0])} starts with "${is().letters}" so we should go ${is().dir}.}`));ns.hint=()=>ke.$.foundWitch?ke.$.seekRose&&!ke.$.foundRose?"#parrot{We're bound to eventually find a swamp rose if we explore the bayou enough,} says Virge.":void 0:as,ae("drop",re,null,ns,"Better not. Anything you dropped in the bayou would likely be lost forever."),ns.decor(["mangrove trees","trees"],"#parrot{Aye, they be halophytes}, chimes in Thin Virg e.").A.climb="You try climbing one of the trees to get a better view of your surroundings, but don't see anything of interest.",ns.decor("paths","You see a myriad#fn{Well, eight actually} paths leading in every direction.").A.count="There are 10000 paths.\nWait, no! Only 8 in fact.",ns.A.swim="The water isn't deep enough to swim in.";const ss=ns.decor(["bayou","water","swamp"],"You hope there aren't any 'gators hiding in the murky water.");ns.exits.outside=ss.A.exit=()=>ke.dispatch("go",ns.$.homeDir);const rs=ns.decor(["'gators","gators","alligators"],"#.emph{You} don't see any 'gators here.");rs.A.get="You don't #.emph{currently} see any 'gators here.",rs.A.attack="You can't attack what you can't see.",rs.A.talkTo="What 'gators?",rs.A.listen="You #.emph{think} you can hear something in water behind you.",rs.A.search="You don't find any 'gators.",rs.A.smell="Any hints of 'gator odor are overwhelmed by the general swampy aroma of the bayou.",ss.A.drink="The rum content of the bayou water is far too low for i t to be potable.",ns.decor(["crickets","frogs"],"You can hear criket and frog sounds coming from all around."),ns.A.listen="You hear some distant crickets and frogs.",ns.A.smell="The bayou smells appropriately swampy.",Te.forEach((e=>{ns.decor([`${e} path`,`path ${e}`],"It's a twisty little path leading off to the "+e).A.examine.after=()=>{e==ns.$.homeDir&&W.msg("It seems more heavily travelled than the other paths.")}})),es.addExit(ns,"north"),es.addBeforeHook("knownExits",(()=>ke.$.foundWitch?["northwest"]:[])),es.addBeforeHook("go",(e=>{ke.$.foundWitch&&"northwest"==e&&(ra.enter("northwest"),ge())})),ra.addExit(es,"southeast"),ra.addExit(es,"outside_"),es.addBeforeHook("enterRoom",((e,t,o)=>{o==ra&&W.msg("Stepping out of the hut you follow a well travelled path and easily find you way back to town.")}));const is=()=>ke.objects[ns.$.kind];ns.addBeforeHook("enterRoom",(()=>{is()?.hideAll();const e=ns.$.kind;ns.$.kind=O((t=>t!=e),(()=>S(Ba).id)),ns.addItem(is()),ns.$.homeDir=O((e=>e!=is().dir),(()=>S(Te)))}) ),ns.desc=()=>{let e="You are wading in the bayou, among the mangrove trees.";return e+=" "+is().roomDesc,e+=`\nTwisty little paths lead in every direction, but the path ${ns.$.homeDir} looks more heavily travelled.`,e},ke.addSimpleVerb("db navigate bayou",(()=>{ke.dispatch("go",is().dir)}));const ls=new re(["phoenix feather","feather"],"A phoenix's feather! They are said to be good luck!");ls.givesMagic=!0,ls.hint="#parrot{We should hang on to it. It might be useful during the race.}";const hs=new re(["jeweled crook","crook"],"About one cubit long, the crook is covered with alternating stripes of blue glass, gold and obsidian.");hs.A.wave="It makes a satisfying woooosh sound, but apart from that nothing happens.",hs.hint="#parrot{I bet we can sell it in Portobello. Best hang on to it.}",hs.endValue=400,hs.endMsg="You sell the jeweled crook for 400 doubloons.";const ds=$e((()=>{W.msg("#.emph{You stumble upon an oasis!}\nWait, no. Sorry wrong game.\nYou do find and pick up a jeweled crook though. That's nice. "),ke.$.inventory.push(hs.id)}));ns.$.goodSteps=0,ns.$.ts=["n"],ns.$.timeLost=0,ns.addBeforeHook("go",(e=>{ns.$.ts.push(e[0]),e==ns.$.homeDir&&(W.msg("You follow the twisty path and find your way back to town."),ns.$.goodSteps=0,ns.$.ts=["n"],es.enter("north"),ge()),ns.$.ts.join("").endsWith("nnssewew")&&ds(),Te.includes(e)&&(e==is().dir?ns.$.goodSteps++:(ns.$.goodSteps=0,ns.$.timeLost++),ns.$.goodSteps>=5?(ke.$.foundWitch=!0,ns.$.goodSteps=0,W.msg("You follow the path and behind a large mangrove tree you find a strange little hut!\nYou head inside.\n"),ra.enter(e)):(W.msg(`You trudge forward, following the twisty path to the ${e}, and yet still you find yourself in ...`),ns.enter(e),ke.$.freedFenix&&!ke.$.gotFeather&&(ke.$.gotFeather=!0,W.msg("Suddenly the phoenix that you freed earlier flies in. She offers you one of her feathers before flying off again."),ke.$.inventory.push(ls.id))),ge())})),ns.addBeforeHook("knownExits",(()=>Te)),ns.A.listExits="You can go in any compass direction.",ke.addSimpleVerb("cl ap","You clap your hands."),ke.addSimpleVerb("hop","You do a little hop."),ke.addSimpleVerb("kweepa",Ae("tell",null,"kweepa")),ns.A.clap.after="Virge raises an eyebrow. #parrot{Worried there might be canal beetles in the bayou?}",ns.A.hop.after="#parrot{Aye, wouldn't want to be ambushed by bottom-crawling sand crabs.}",ae("tell","*","kweepa",ns,"#parrot{Good thinking Cap'n. This bayou is probably thick with 'gators.}"),ae("tell",null,"mambo",ns,"#.emph{``Mambo! Where are you?''} you yell, but no one answers."),ae("follow",_e,null,ns,"Virge is just as lost as you are"),Sa.addExit(zo,"outside_"),zo.addSymExit(Sa,"southeast"),zo.addExit(Sa,"inside_"),zo.addSymExit(an,"west"),zo.addSymExit(en,"east"),zo.addSymExit(Ao,"south"),zo.addSymExit(es,"north"),an.addSymExit(La,"west"),Ao.addSymExit(Yo,"south"),Ao.addExit(Yo,"inside_"),Yo.addExit(Ao,"outside_"),La.addExit(an,"outside_"),Cn.addExit(en,"outside_"),en.addSymExit(Cn,"north"),en.addSymExit(_n,"east"),_n.addExit(en,"outside_"),ke.A.go.before=()=>{ke.$.sitting &&(W.msg("First standing up","implied"),ke.dispatch("stand"))},ke.addSimpleVerb("sit","#.softError{You'd rather stand.}",{synonyms:["sit down"]}),ke.addSimpleVerb("stand",(()=>{ke.$.sitting?(W.msg("You stand up"),ke.$.sitting=!1):W.msg("#.softError{You are already standing.}")}),{synonyms:["stand up","get up"]}),ke.addDirectVerb("sit on","#.softError{Nah.}",{actionName:"sitOn",synonyms:["sit down on","sit in","sit down in"]}),ke.addDirectVerb("tie","#.softError{You can't tie $thecod.}"),ke.addIVerb("tie","#.softError{You can't tie $thecod to $thecoi.}",{actionName:"tieTo",prepositions:["to"]}),ke.addIVerb("pour","#.softError{$THECOD isn't liquid.}",{prepositions:["on","onto"]}),ke.addDirectVerb("pour","#.softError{$THECOD isn't liquid.}"),ke.addSimpleVerb("climb down",Ae("go","down"),{synonyms:["climb d"]}),ke.addSimpleVerb("climb up",Ae("go","up"),{synonyms:["climb u"]}),ke.addDirectVerb("throw","#.softError{You'd rather not.}"),ke.addDirectVerb("pet","#.softError{You'd rather not.}",{synonyms:["stroke"]}), ke.addDirectVerb("drink from","#.softError{Virge} chimes in: #parrot{That doesn't seem potable.}",{actionName:"drink",synonyms:["drink"]}),ke.addDirectVerb("count","#.softError{I don't understand.}"),ke.addDirectVerb("board","#.softError{I don't understand.}"),ke.addDirectVerb("peel","#.softError{I don't understand.}"),ke.addSimpleVerb("solve crossword","I'm afraid you'll have to solve it on your own."),ke.addDirectVerb("pick",Ae("get"),{synonyms:["pluck"]}),ke.addDirectVerb("chop down",Ae("cut"),{synonyms:["cut down"]}),ke.addIVerb("chop down",Ae("cut"),{prepositions:["with"],synonyms:["cut down"]}),ke.addDirectVerb("untie","#.softError{I don't understand.}");const us=E(["Put them in the long boat 'til they're sober","Shave their belly with a rusty razor","Give 'em a hair of the dog that bit them","Put them in a bunk with the Captain's daughter","Give 'em a dose of salt and water","Heave them by the leg in a runnin' bowline","Put 'em at the wheel of an Exxon tanker","Keel haul them till they're sober","Tie them to the mast and then you flog them","Tie them to the taffrail when she's yardarm under"]);ke.addSimpleVerb("sing",(()=>{W.msg(`#you{ ${us()}
    Early in the morning}`)})),ke.addDirectVerb("follow","#.softError{You're a leader, not a follower.}"),ke.addDirectVerb("sail","#.softError{I don't understand.}"),ke.addSimpleVerb("sail","#.softError{I don't understand.}"),ke.addDirectVerb("free","#.softError{I don't understand.}"),ke.addDirectVerb("blindfold","#.softError{I don't understand.}"),ke.addDirectVerb("slap",Ae("attack")),ke.addDirectVerb("kiss","#.softError{You'd rather not.}"),ke.addDirectVerb("touch","#.softError{You touch $thecod}. Nothing happens."),ke.addSimpleVerb("wake up","But it isn't a dream!",{actionName:"wake",synonyms:["wake","awaken","awake"]}),ke.addDirectVerb("wake","#.softError{$THECOD isn't sleeping.}"),ke.addDirectVerb("wave",(e=>{e.requireHeld(),W.msg("#.softError{You wave "+e.defName+" around. Nothing unexpected happens.}")})),ke.addDirectVerb("unlock","#.sof tError{$THECOD isn't locked.}"),ke.addDirectVerb("dig","#.softError{$THECOD isn't something you can dig.}"),ke.addSimpleVerb("dig","#.softError{You can't dig here.}"),ke.addDirectVerb("buy","#.softError{$THECOD isn't for sale.}"),ke.addDirectVerb("steal",(e=>{W.msg("You attempt to steal "+e.defName),ke.dispatch("get",e)}),{synonyms:["rob"]}),ke.addDirectVerb("borrow",(e=>{W.msg("You attempt to ``borrow'' "+e.defName),ke.dispatch("get",e)})),ke.addDirectVerb("pocket",Ae("get")),ke.addDirectVerb("punch",Ae("hit")),ke.addSimpleVerb("score","You have to complete the race first to know how you did."),ke.addSimpleVerb("dance","Ye (shake, shake, shake) shake yer booty."),ke.addSimpleVerb("jump","You hop about."),ke.addSimpleVerb("wave","Like the ocean, you wave to no one in particular."),ke.addSimpleVerb("pray","You mumble a quick prayer to the twins, bidding them to keep the weather fair.");const cs="#.instruction{Sorry, you cannot search FOR things in this game. Generally speaking you can only interact with objec ts that are present. For instructions type HELP PARSER.}";ke.addDirectVerb("search for",cs,{missingCod:cs,synonyms:["look for"]}),ke.addSimpleVerb("shout",$e("You let out a blood-curdling cry.\nYou are likely to develop thrombosis if you continue.",(()=>{W.msg("You let out another blood-curdling scream. Unfortunately the ensuing blood clot dooms your left leg.\nOn the bright side you gain much pirate prestige thanks to your new peg leg. On less bright side, the time spend in the hospital makes you miss the race."),ke.die("You missed the start of the race")})),{synonyms:["scream","yell"]}),I.addVerb("shout",{codKind:"string",action:e=>ke.dispatch("tell",null,e),synonyms:["yell"]}),I.addRaw(o(i("talk to"),n(g("NPCs"),r(A,null)),i("about"),l(s(p(/[^.]*/))),u((e=>{ke.dispatch("ask",...e)}))));const ms=new ie(["me","self","myself"],"You are Jenny Weigh, the famous pirate with the orange hair and the black heart.");ms.defName="myself",ms.A.smell="You smell fine. You last bathed mere months ago.",ms.A.examine.after =()=>{Yn()&&W.msg("You are currently altogether unrecognizable thanks to the fake beard you are wearing.")},ke.$.inventory.push(ms.id);const gs=new ie(["your black heart","your heart","my heart","black heart"],"#.you{Your heart is as black\nOh, your heart is as black as night}");ke.$.inventory.push(gs.id),gs.defName="your black heart";const ys=new ie(["your hair","my hair","orange hair","hair"],"You keep your beautiful hair dyed orange.");ys.A.smell="Your hair has a pleasant tangeriny#fn{tangerinish?} aroma.",ke.$.inventory.push(ys.id),ys.defName="your hair";const fs=new re(["compass"],"This special compass always points towards whatever its holder's heart most desires!#fn{So long as what you most desire is the magnetic north pole.}");fs.A.read=fs.A.use="You glance at the compass and now know exactly which way is north.",fs.isPlural=!1,fs.hint="#parrot{Sometimes a compass is just a compass, I guess,} says #V#.",ke.$.sleepPressure=0,ke.A.look.after=()=>{ke.$.henryPaid&&ke.$.betterSails&&ke.$.cannons&&!ke.$.em barked&&(ke.$.sleepPressure++,ke.$.sleepPressure>=9&&ke.$.sleepPressure%3==0&&W.msg("#draw{You yawn|You feel ready for bed|You're exhausted|You're feeling rather tired|You're looking forward to a good night's sleep}."))},ke.$.inventory.push(qn.id),ke.$.inventory.push(fs.id),ke.$.inventory.push(tt.id),ke.isWeb&&(W.addProcessor(/Th/g,"Th"),W.addProcessor(/--/g,"—")),ke.$.room=Sa.id,ke.$.sitting=!0,ke.$.rooms[ke.$.room].items.push(_e.id),W.addAfterHook("commit",(e=>e.style=`margin-left: ${.1*Math.random()-.05}em; transform: rotate(${.8*Math.random()-.4}deg)`));const ps=`#.emph{The Libonotus Cup} was made by Nils Fagerburg in the summer of 2021 for the 27th IFComp.\nA thousand thanks to my beta testers, ${N(["Mike Russo","Amanda Walker","Giannis G. Georgiou","Christopher Merriner","Eva Radke","Sarah Hernu"])}, for their invaluable help! The game wouldn't be half as much fun without their suggestions.\nThanks to everyone on the intfiction.org forums for advice.\nSpecial thanks to Sarah for many ideas and for being Sarah!\nFinally, thank #.emph{you} for playing.`;ke.addSimpleVerb("credits",ps),ke.addSimpleVerb("help parser","This game is played by reading the story and typing simple imperative (i.e. #.cmd{VERB object(s)}) commands. For example you can type:\n#.cmd{examine the cannon}\n#.cmd{open the powder keg}\n#.cmd{get the eyepatch}\n#.cmd{wear it}\n#.cmd{walk to the west}\n#.cmd{give the black mark to the mutineer}\n#.cmd{ask the buccaneer about tides}\n\nSome frequently used commands have abbreviations: instead of #.cmd{take inventory} you can simply type #.cmd{i}, to move around you can type the first letter(s) of the direction (e.g. #.cmd{nw} instead of #.cmd{go northwest}, #.cmd{in}, #.cmd{up}, ...), the #.cmd{look} command (which redisplays the current room) can be abbreviated to #.cmd{l}, and, most importantly, to examine an item you can type #.cmd{x [the item]}.\n\nYou almost never have to type the full object description or use articles. For instance, if the game tells you there is a shiny white diamond here, you can type #.cmd{x shiny}, or #.cmd{x white}, or #.cmd{x diamond} to examine it.\n\nGenerally, you begin by examining objects around you, examining yourself (#.cmd{x me}), and seeing what, if anything, you are carrying. You shouldn't need it, but if you change your mind you can #.cmd{undo} your previous actions."),ke.addSimpleVerb("help","You are Jenny Weigh, a pirate captain. Your goals are to do as well as possible in the race and to collect as much booty as possible along the way. Which of these goals you wish to prioritize is entirely up to you. Your first order of business though, is to make your ship seaworthy again.\n\nConversation uses the standard #.cmd{ask person about topic} verb but you can also simply #.cmd{talk to} a person and the game will try to guess an appropriate conversation subject.\n\nHints are provided by ``Thin'' Virge, your trusty parrot sidekick. You can ask #V# for a hint (or simply type #.cmd{hint}) and he will try to give you a context ap propriate hint. You can also ask #V# about a specific topic or show him an object to get more targeted hints. To disable hints, give #V# a piece of taffy.\n\nIf you are new to parser IF (i.e. games where you type in commands) you should type #.cmd{help parser}.\nFor credits, type #.cmd{credits}.",{synonyms:["info","about"]}),ke.$.raceTime=0,ke.$.reefSafe=S(["port","starboard"]),ke.$.knikna=S([!0,!1]),function(e={}){for(const[t,o]of Object.entries(Ie))!1!==e[t]&&o(e[t])}(),ke.addSimpleVerb("version","Game version one"),ke.id="piraceone",ke.ifid="ea4ef735-riff-42b2-a126-007788710442",ke.begin()}();