<<hl "Barriers">> v0.2 <<wait>>- a PMD Twine game by Sockfox.<<wait>>
<br>
Before we begin, you can change <<hl "settings">>, load a previous <<hl "save">>, and view <<hl "credits">>.
<<menu>>
<<pick "New game">>
Are you sure?
<<pick "Yes">>
<<intro>>
<</pick>>
<<pick "No">>
<<cancel>>
<</pick>>
<</pick>>
<<pick "Continue">>
<<screen "Saves">>
<</pick>>
<<pick "Settings">>
<<screen "Settings">>
<</pick>>
<<pick "Credits" "Credits">><</pick>>
<<pick "Map test" "Brine Cave">><</pick>>
<</menu>><div class="credits-text"><div class="credits-line credits-line-0">Music, SFX, and quiz background taken from PMD: Explorers of Sky.</div><div class="credits-gap"></div></div>
<<credits>>
<<menu>>
<<pick "Back" `previous() || "Title"`>><</pick>>
<</menu>>Change settings here.
<<menu "stay">>
<<pick "Text speed">>
View or test the current typing speed, or disable it if you'd like.
<<menu>>
<<value "textSpeed" "Faster">>
<<value "textSpeed" "Fast">>
<<value "textSpeed" "Normal">>
<<value "textSpeed" "Slow">>
<<value "textSpeed" "Disabled">>
<<pick "Back">>
<<cancel>>
<</pick>>
<</menu>>
<</pick>>
<<pick "Background">>
Various options for the backgrounds.
<<menu>>
<<value "background" "On">>
<<value "background" "Paused">>
<<value "background" "Disabled">>
<<pick "Back">><<cancel>><</pick>>
<</menu>>
<</pick>>
<<pick "Sound">>
Change the volume of both BGM and sound effects, or disable them entirely.
<<menu>>
<<pick "BGM">>
Background music settings.
<<menu>>
<<value "bgm" "Unmuted">>
<<value "bgm" "Muted">>
<<pick "Back">>
<<cancel>>
<</pick>>
<</menu>>
<</pick>>
<<pick "SFX">>
Sound effect settings.
<<menu>>
<<value "sfx" "Unmuted">>
<<value "sfx" "Muted">>
<<pick "Back">>
<<cancel>>
<</pick>>
<</menu>>
<</pick>>
<<pick "Back">>
<<cancel>>
<</pick>>
<</menu>>
<</pick>>
<<pick "Back">>
<<cancel>>
<</pick>>
<</menu>>/*
WRITING GUIDE:
Text by itself in a passage tagged [prompt] goes into the bottom box.
<<menu>> text by itself <</menu>>:
opens the menu up top to be used with <<pick>> (seen below). text outside of <<pick>> refreshes what's in the bottom box.
<<menu>>
<<pick "text to be placed on the menu box">>
text to be placed in the bottom box
<</pick>>
<</menu>>
<<pick "text">>
adds an entry to the menu box that can be selected.
<</pick>>
<<hl "Text" "color">>:
highlights text in that color.
<<wait>>:
pauses the text animation, requiring a click/tap/enter to move forward
<<screen "Passage">>:
goes to the desired passage
*//*
MAP GUIDE
a map is any passage tagged [map]
it MUST include a <<map>> block (todo: fallback test map?)
<<music "track">>:
starts music, usually at the top of a map passage.
optionally, to change music partway through.
<<location "Brine Cave" 1>>:
what the strip along the top of the screen calls this place: a name, and which floor.
drawn as "Brine Cave B1F", with the B and the F picked out like the HP label.
leave the floor off for somewhere with only one, or leave the whole line off and
the passage's own name is used.
map marks:
# wall
. floor
~ water
@ player starting position
<<at "o" "Passage Name" "Type" "Species">> to place objects, NPCs, eventually enemies
<<at>> types:
item (this is default if you don't specify)
<<at "o" "Oran Berry">>
exit (warps to another map or some other passage)
<<at "E" "Brine Cave Pit" "Exit">>
npc (stationary NPC to be talked to)
<<at "R" "Riolu Greeting" "npc" "Riolu">>
sign
<<at "?" "Brine Cave Sign" "sign">>
NPC dialogue:
basically a prompt but shows names and portraits
inside of a passage given by an NPC's <<at>>
<<speaker "Species" "Mood" "Name">>Dialogue<</speaker>>
species - capitalized pokemon species name, optional, will default to whichever species took you here
mood - optional, defaults to Happy.png for the species
name - optional, defaults to species name
<<mood "Mood">> changes that portrait expression part way through a line. best used directly after a <<wait>>
*/<<if $player.hp < $player.maxHP>>
<<set $player.hp to Math.clamp($player.hp + 30, 0, $player.maxHP)>>
<<drop $backpack "Oran Berry" 1>>
You ate the berry and healed 30 HP.
<<else>>
Your health is full!
<</if>><<pickup $backpack "Oran Berry" 1>>
An <<hl "Oran Berry">> is lying on the ground, fresh for the taking. You pocket it./* see src/guides/1. Map Guide.twee for syntax */
<<music "brine">>
<<location "Brine Cave" 1>>
<<map>>
####################
#........#.......~~#
#..o.....#..R.U...~#
#........#.........#
#....@.............#
#........#.........#
#~~~~~~~~#.........#
#~~~~~~~~#....E....#
####################
<</map>>
<<at "o" "Oran">>
<<at "R" "Riolu Greeting" "npc" "Riolu">>
<<at "U" "Ursaring Greeting" "npc" "Ursaring">>
<<at "E" "Cave Depths" "exit">><<speaker>>
Who the heck are you?
<<menu>>
<<pick "I'm a human!">>
<<speaker>>
<<mood "Happy">>
Cool!
<</pick>>
<<pick "Say nothing">>
<<speaker>>
Uh...
<<wait>>
<<mood "Stunned">>
okay?
<</pick>>
<</menu>><<speaker>>
I'm a second NPC...
<<wait>>
<<mood "Happy">>
in the same map!This'll probably be an exit to another map. Til then, here's some stuff to play around with!
/* temp menu */
<<menu>>
<<pick "Back off">><</pick>>
<<pick "Play the quiz music!">>
<<music "quiz">>You couldn't resist.
<</pick>>
<<pick "Play the cave music!">>
<<music "brine">>It slaps, doesn't it?
<</pick>>
<</menu>>/* personality quiz stuff here.
nothing different from the usual scene writing process aside from the logic at the bottom to determine species.
todo: actual questions, logic in each to add to the species counter. */
<<music "quiz" while "quiz">>
Have you ever imagined yourself as a Pokémon before?
<<menu>>
<<pick "More than I'd probably admit" "Quiz 2">><</pick>>
<<pick "Sometimes" "Quiz 2">><</pick>>
<<pick "Once or twice" "Quiz 2">><</pick>>
<<pick "Not at all" "Quiz 2">><</pick>>
<</menu>>You have trouble thinking of anything else, don't you?
<<menu>>
<<pick "God, yes" "Quiz 3">><</pick>>
<<pick "Nuh uh" "Quiz 3">><</pick>>
<<pick "Wait, what?" "Quiz 3">><</pick>>
<</menu>>We both know why you're here.
<<menu>>
<<pick "We do?" "Quiz 4">><</pick>>
<<pick "What?" "Quiz 4">><</pick>>
<<pick "Oh no..." "Quiz 4">><</pick>>
<</menu>>And now your <<hl "aura">> will be analyzed.
<<advance "Quiz 5">>Your <<hl "aura">> is the energy that you radiate!
<<advance "Quiz 6">>Relax. <<wait>>Calm yourself...
<<advance "Quiz 7">>That's right... <<wait>>Stay perfectly still... <<wait>>Take a deep breath...<<wait>> and now exhale...
<<advance "Quiz 8">>Your <<hl "aura">> is...
<<advance "Quiz 9">>/* basic quiz scoring things. tallies up each species counter, if tied picks randomly. */
<<silently>>
<<set _order to ["Buizel", "Vulpix", "Piplup", "Riolu"]>>
<<set _topScore to Math.max.apply(null, _order.map(function(s) { return $quizScores[s]; }))>>
<<set _tied to _order.filter(function(s) { return $quizScores[s] === _topScore; })>>
<<set $player.portrait to _tied[random(0, _tied.length - 1)]>>
<<set $player.emotion to "Normal">>
<<revealself>>
<</silently>>
That of a... <<wait "goodchime">>
<<portrait `$player.portrait + "/" + $player.emotion + ".png"`>>
/* pulls species from the value currently used for portraits.
todo: give it its own value, maybe? */
<<hl `$player.portrait + "!"`>>
<<wait>>Note: this is currently random. :3
<<advance "Brine Cave">>/* cache audio at initial load so they can be called whenever */
<<cacheaudio "quiz" "audio/bgm/quiz.ogg">>
<<cacheaudio "brine" "audio/bgm/brine.ogg">>
<<cacheaudio "choice" "audio/sfx/choice.wav">>
<<cacheaudio "select" "audio/sfx/select.wav">>
<<cacheaudio "goodchime" "audio/sfx/goodchime.wav">>
/* initial variables, old combat system */
<<set $inCombat to false>>
/* list of known enemies, will default to "???" until <<learnenemy "(enemy)">> is called.
eventually planning to use this in a menu to show what you've encountered so far */
<<set $knownEnemies to []>>
/* initialize backpack and meters */
<<newinv $backpack>>
<<newmeter 'playerHealth'>>
<<animation 300ms>>
<<colors '#4ce04c' '#4ce04c' '#ff8b6b'>>
<<label 'HP: $player.hp/$player.maxHP' 'white' center>>
<<sizing "12em" "1.5em">>
<</newmeter>>
<<newmeter 'enemyHealth'>>
<<animation 300ms>>
<<colors '#4ce04c' '#4ce04c' '#ff8b6b'>>
<<label 'HP: $enemy.hp/$enemy.maxHP' 'white' center>>
<<sizing "12em" "1.5em">>
<</newmeter>>
<<newmeter "playerStamina">>
<<animation 300ms>>
<<colors 'purple' 'red' 'black'>>
<<label 'ST: $player.stamina/$player.maxStamina' 'white' center>>
<<sizing "12em" "1.5em">>
<</newmeter>>
<<newmeter "enemyStamina">>
<<animation 300ms>>
<<colors 'purple' 'red' 'black'>>
<<label 'ST: $enemy.stamina/$enemy.maxStamina' 'white' center>>
<<sizing "12em" "1.5em">>
<</newmeter>>
/* tally of quiz answers, used by the starter personality quiz to pick $player.portrait */
<<set $quizScores to { Buizel: 0, Vulpix: 0, Piplup: 0, Riolu: 0 }>>
/* OLD - REMOVE THIS AND ITS STYLING.
text in the box above the passage, and an optional class for it. set with <<topbox>>,
sticks until something changes it. probably to be used for dungeon/town names and floors */
<<set $topbox to "">>
<<set $topboxClass to "">>
/* default player name, species, stats.
OLD - REVAMP:
player name to be set by the quiz.
portrait set to Buizel by default.
revealed and <<revealself>> are now useless, as it should never show your portrait until you've gone through the quiz - even in the map test it default to Buizel.
revealed stays false until <<revealself>> runs, until
then the portrait is a question mark rather than whatever the quiz picked */
<<set $player to
{
name: "Damien",
portrait: "Buizel",
revealed: false,
emotion: "Normal",
hp: 70,
maxHP: 100,
stamina: 50,
maxStamina: 50,
defense: 1,
dmg: 3
}>>
/* list of enemies.
OLD - REVAMP:
with the current build, stuff on the map gets called in the map itself.
likely will include enemies once I work that in. keeping for now.
attackFlavor is a list of flavor text that's selected randomly when that enemy attacks */
<<set setup.enemies to
{
"Dewgong":
{
name: "Dewgong",
portrait: "Dewgong",
emotion: "Normal",
hp: 100,
maxHP: 100,
stamina: 50,
maxStamina: 50,
defense: 1,
dmg: 5,
gold: 10,
attackFlavor:
[
"The horned seal lunges forward on its belly, slamming its heavy, blubbery frame directly into you.",
"Lowering its head, the white seal lunges forward to thrust the horn on its head directly your ribs.",
"The massive creature pirouettes with surprising grace, whipping its broad, finned tail hard across your face.",
"The horned sea lion exhales a sudden, howling gust of sub-zero wind that bites deep into your skin.",
"With a harsh bark, the blubbery monster unleashes a jet of pressurized, ice-cold water that knocks you off balance.",
"The white, tuskless walrus rears up and brings both heavy flippers crashing down on top of you.",
"A flurry of razor-sharp ice crystals sprays from the creature's maw, stinging you repeatedly.",
"The pale beast barrels toward you like an aquatic battering ram, shoving you hard into the ground.",
"The horned seal sweeps the floor with its tail, kicking up a spray of sharp slush into your eyes.",
"The sea beast snaps forward with a snarling bark, grazing you with a frosty headbutt."
]
}
}>>/* OLD - REVAMP:
in the current build, the footer was used for a persistent portrait, menu, and the HP bar.
will likely be able to go away entirely with current build.
the footer is on everywhere except the screens that fill the whole display themselves.
tag passages "nofooter" to keep it off */
<<if not (tags().includes("prompt") or tags().includes("nofooter") or tags().includes("map") or passage() is "Combat")>>
<div id="footer-menu">
<div class="footer-panel footer-portrait-frame">
<<if $player.revealed>>
<img @src="setup.artPath + $player.portrait + '/' + $player.emotion + '.png'" @class="'portrait footer-portrait' + (_revealing ? ' portrait-revealing' : '')" alt="">
<<else>>
/* OLD - REVAMP:
<<revealself>> likely going away entirely.
the player doesn't know what they are yet. <<revealself>> swaps this out */
<div class="portrait footer-portrait portrait-unknown">?</div>
<</if>>
</div>
<div class="footer-main">
<div class="footer-status hp-block">
<span class="hp-text"><span class="hp-label">HP</span><span class="hp-numbers">$player.hp<span class="hp-sep">/</span>$player.maxHP</span></span>
<div class="meter-container"><<showmeter 'playerHealth' `$player.hp / $player.maxHP`>></div>
</div>
<div class="footer-panel footer-menu-box">
<div class="footer-button-group">
<span class="footer-button footer-inventory">
<<button "Inv">>
<<popup "InventoryDialog" "Your Inventory" "inventory-dialog">>
<</button>>
</span>
<span class="footer-button footer-saves">
<<button "Save">>
<<run UI.saves()>>
<</button>>
</span>
<span class="footer-button footer-restart">
<<button "Restart">>
<<run UI.restart()>>
<</button>>
</span>
</div>
</div>
</div>
</div>
<</if>>/* the overlay for location, floor, and the HP bar/text. placed on any passage tagged [map] */
<div class="map-header-location hp-text">
<<= setup.mapLocationText()>>
</div>
<div class="map-header-status hp-block">
<span class="hp-text">
<span class="hp-label">
HP
</span>
<span class="hp-numbers">
$player.hp
<span class="hp-sep">
/
</span>
$player.maxHP
</span>
</span>
<div class="meter-container">
<<showmeter 'playerHealth' `$player.hp / $player.maxHP`>>
</div>
</div><<menu "stay">>
<<if setup.slotFilled(0)>>
<<pick `setup.slotLabel(0)`>>
<<menu>>
<<pick "Save">><<run setup.saveToSlot(0)>><<refresh>><</pick>>
<<pick "Load">><<run setup.loadFromSlot(0)>><</pick>>
<<pick "Back">><<cancel>><</pick>>
<</menu>>
<</pick>>
<<else>>
<<pick `setup.slotLabel(0)`>><<run setup.saveToSlot(0)>><<refresh>><</pick>>
<</if>>
<<if setup.slotFilled(1)>>
<<pick `setup.slotLabel(1)`>>
<<menu>>
<<pick "Save">><<run setup.saveToSlot(1)>><<refresh>><</pick>>
<<pick "Load">><<run setup.loadFromSlot(1)>><</pick>>
<<pick "Back">><<cancel>><</pick>>
<</menu>>
<</pick>>
<<else>>
<<pick `setup.slotLabel(1)`>><<run setup.saveToSlot(1)>><<refresh>><</pick>>
<</if>>
<<if setup.slotFilled(2)>>
<<pick `setup.slotLabel(2)`>>
<<menu>>
<<pick "Save">><<run setup.saveToSlot(2)>><<refresh>><</pick>>
<<pick "Load">><<run setup.loadFromSlot(2)>><</pick>>
<<pick "Back">><<cancel>><</pick>>
<</menu>>
<</pick>>
<<else>>
<<pick `setup.slotLabel(2)`>><<run setup.saveToSlot(2)>><<refresh>><</pick>>
<</if>>
<<pick "Back">><<cancel>><</pick>>
<</menu>>/* what the map menu's "Restart" asks, shown over the map the way anything walked into speaks.
"No" steps back out of the last screen, which on an overlay is the way back to the map */
Are you sure you want to restart?
<<menu>>
<<pick "Yes">>
<<run Engine.restart()>>
<</pick>>
<<pick "No">>
<<cancel>>
<</pick>>
<</menu>>/* OLD - REVAMP:
in the current build, dialogues like this are out of place.
will be built to work with the current prompt/menu system.
dialogue that opens when you open the inventory. todo: style, it currently looks like shit */
<<inv $backpack use drop inspect>><<widget "learnenemy">>
<<silently>>
<<set _enemy to $args[0]>>
<<if not $knownEnemies.includes(_enemy)>>
<<run $knownEnemies.push(_enemy)>>
<</if>>
<</silently>>
<</widget>>/* OLD - REVAMP:
<<topbox>> and <<revealself>> likely going away entirely.
<<topbox "Dark Cave - B1F">>
sets the top bar, keeps whatever it was last set to, can specify class in the second argument */
<<widget "topbox">><<silently>>
<<set $topbox to $args[0]>>
<<set $topboxClass to ($args.length > 1 ? $args[1] : "")>>
<</silently>><</widget>>
<<widget "revealself">><<silently>>
<<set $player.revealed to true>>
<<set _revealing to true>>
<</silently>><</widget>>/* OLD - REVAMP:
old <<action>> and <<reveal>> logic, likely going away entirely.
<<action "Put them in your bag">> ... <</action>>
fix for <<linkreplace>> doing weird things with the type animation */
<<widget "action" container>><<silently>>
<<set _label to $args[0]>>
<<set _body to _contents>>
<</silently>><<capture _label, _body>><<linkreplace _label>><<typed>>_body<</typed>><</linkreplace>><</capture>><</widget>>
<<widget "reveal" container>><<silently>>
<<set _label to _args[0]>>
<<set _title to _args[1]>>
<<set _body to _contents>>
<</silently>><<capture _label, _title, _body>><div><<linkreplace _label>><div class="choice-result"><div class="result-title">_title</div><div class="result-body"><<typed>>_body<</typed>></div></div><</linkreplace>></div><</capture>><</widget>>
/* OLD - REVAMP (sort of):
in the current build, this fades the screen to black and plays the opening lines.
in the future, rework it so this can be used with any set of lines.
<<intro>> plays the opening lines and hands over to the quiz. "now" opens already black rather than fading down to it. */
<<widget "intro">>
<<blackout "Quiz 1" $args[0]>>
Welcome!
<<line>>This is the portal that leads to the world only inhabited by Pokémon.
<<line>>Beyond this gateway, many new adventures and fresh experiences await your arrival!
<<line>>Before you depart for adventure, you must answer some questions.
<<line>>Be truthful when you answer them!
<<line>>Now, are you ready?
<<line>>Then... <<wait>> let the questions begin!
<</blackout>>
<</widget>><<widget "startCombat">>
/* OLD - REUSE:
this is the old turn-based combat system.
can probably use a lot of this in the new system, to be determined.
<<startCombat "EnemyId" "Win Passage" "Lose Passage">>
if "Win Passage" or "Lose passage" aren't passed, defaults to "Victory" and "Defeat" */
<<set $enemy to clone(setup.enemies[$args[0]])>>
<<set $enemy.id to $args[0]>>
<<set $combatWin to $args[1] ? $args[1] : "Victory">>
<<set $combatLose to $args[2] ? $args[2] : "Defeat">>
<<set $player.emotion to "Normal">>
<<set $combatLog to []>>
<<set $turn to "player">>
/* the hurt faces both sides will need, off the wire before the first hit lands */
<<set _ouch to setup.artPath + $player.portrait + "/Pain.png">>
<<set _foeOuch to setup.artPath + $enemy.portrait + "/Pain.png">>
<<preload _ouch _foeOuch>>
<<goto "Combat">>
<</widget>><<if $enemy.hp > 0 and $player.hp > 0>>
<<set $inCombat to true>>
<</if>>
<div id="combat-passage">
<div id="combat-ui">
<div id="enemy-sheet" class="character-sheet">
<div class="sheet-row">
<img @src="setup.artPath + $enemy.portrait + '/' + $enemy.emotion + '.png'" class="portrait" alt="">
<div class="sheet-info">
<h2><<print setup.enemyDisplayName($enemy)>></h2>
<div class="meter-container"><<showmeter 'enemyHealth' `$enemy.hp / $enemy.maxHP`>></div>
<div class="meter-container"><<showmeter 'enemyStamina' '$enemy.stamina / $enemy.maxStamina'>></div>
</div>
</div>
</div>
<div id="player-sheet" class="character-sheet">
<div class="sheet-row">
<img @src="setup.artPath + $player.portrait + '/' + $player.emotion + '.png'" class="portrait" alt="">
<div class="sheet-info">
<h2>$player.name</h2>
<div class="meter-container"><<showmeter 'playerHealth' `$player.hp / $player.maxHP`>></div>
<div class="meter-container"><<showmeter 'playerStamina' '$player.stamina / $player.maxStamina'>></div>
</div>
</div>
</div>
<div id="combat-actions">
<<if $turn is "player">>
<div class="action-button-group">
<<button "Attack" "Combat">>
<<set _damage to Math.max(0, $player.dmg + random(1, 6) - $enemy.defense)>>
<<set $enemy.hp -= _damage>>
<<set $enemy.emotion to "Pain">>
<<set $player.emotion to "Normal">>
<<set $combatLog.unshift("You attack for " + _damage + " damage.")>>
<<if $enemy.hp <= 0>>
<<set $combatLog.unshift("You have defeated the " + setup.enemyDisplayName($enemy) + "!")>>
<<set $inCombat to false>>
<<goto `$combatWin`>>
<<else>>
<<set $turn to "enemy">>
<</if>>
<</button>>
<<button "Inventory">>
<<run Dialog.create("Your Inventory", "inventory-dialog")>>
<<run Dialog.wikiPassage("InventoryDialog")>>
<<run Dialog.open()>>
<</button>>
<<button "Surrender">>
<<set $inCombat to false>>
<<goto `$combatLose`>>
<</button>>
<<button "Flee" "Combat">>
<<set $inCombat to false>>
<<set $enemy.hp to 0>>
<<goto `$combatWin`>>
<</button>>
</div>
<<else>>
<div class="action-button-group">
<<button "Continue" "Combat">>
<<set _damage to Math.max(0, $enemy.dmg + random(1, 6) - $player.defense)>>
<<set $player.hp -= _damage>>
<<set $player.emotion to "Pain">>
<<set $enemy.emotion to "Normal">>
<<set _randomIndex to random(0, $enemy.attackFlavor.length - 1)>>
<<set _flavorText to $enemy.attackFlavor[_randomIndex]>>
<<set $combatLog.unshift(_flavorText + " It " + "deals " + _damage + " damage.")>>
<<if $player.hp <= 0>>
<<set $combatLog.unshift("You have been defeated by the " + setup.enemyDisplayName($enemy) + "!")>>
<<set $inCombat to false>>
<<goto `$combatLose`>>
<<else>>
<<set $turn to "player">>
<</if>>
<</button>>
<<button ".....">><</button>>
<<button ".....">><</button>>
<<button ".....">><</button>>
</div>
<</if>>
</div>
</div>
<div id="combat-log" class="combat-log-container">
<<for _i, _message range $combatLog>>
<div class="log-entry"><<print _message>></div>
<</for>>
</div>
</div>
<<script>>
setTimeout(function()
{
try
{
const playerSheet = document.getElementById('player-sheet');
const enemySheet = document.getElementById('enemy-sheet');
if (!playerSheet || !enemySheet)
{
return;
}
const defaultColor = '#444';
const activeColor = '#33ff99';
if (State.variables.turn === 'player')
{
playerSheet.style.borderColor = activeColor;
enemySheet.style.borderColor = defaultColor;
}
else
{
playerSheet.style.borderColor = defaultColor;
enemySheet.style.borderColor = activeColor;
}
} catch (e)
{
console.error("Error applying turn-based styles: ", e);
}
}, 0);
<</script>><<silently>>
/* transition by default */
<<removeclass "html" "no-transition">>
/* if you're in combat, disable the transition */
<<if passage() is "Combat" and $inCombat is true>>
<<addclass "html" "no-transition">>
<</if>>
<<addclass "html" "transitions-ready">>
<</silently>>