Files
roll20-character-sheets/Storypath/Storypath.html
T

4516 lines
305 KiB
HTML

<input name="attr_template_start" value="@{whisper}&{template:storypath} {{character_name=@{character_name}}} {{character_id=@{character_id}}} {{system=@{system}}}" type="hidden" title="@{template_start}"/>
<input name="attr_sheet_state" value="settings" type="hidden" title="@{sheet_state}"/>
<input name="attr_collapsed" value="" type="hidden" title="@{collapsed}"/>
<div class="subsystem-style compendium-drop-target antagonists" id="main">
<input name="attr_drop_name" accept="Name" value="" type="hidden" title="@{drop_name}"/>
<input name="attr_drop_data" accept="data" value="" type="hidden" title="@{drop_data}"/>
<nav class="sheet-nav" id="main-nav">
<button class="subsystem-style sheet-nav__tab sheet-nav__tab--possible sheet-nav__tab--possible--character all" name="act_nav-all" data-i18n="all pages" data-i18n-title="View all sections" role="heading" aria-level="5" type="action" title="%{nav-all}">
</button>
<button class="subsystem-style sheet-nav__tab sheet-nav__tab--possible sheet-nav__tab--possible--character general" name="act_nav-general" data-i18n="general pages" data-i18n-title="View general information" role="heading" aria-level="5" type="action" title="%{nav-general}">
</button>
<button class="subsystem-style sheet-nav__tab sheet-nav__tab--possible sheet-nav__tab--possible--character powers" name="act_nav-powers" data-i18n="powers pages" data-i18n-title="View powers information" role="heading" aria-level="5" type="action" title="%{nav-powers}">
</button>
<button class="subsystem-style sheet-nav__tab sheet-nav__tab--possible sheet-nav__tab--possible--antagonist antagonist" name="act_nav-antagonist" data-i18n="antagonist" data-i18n-title="View antagonist" role="heading" aria-level="5" type="action" title="%{nav-antagonist}">
</button>
<button class="subsystem-style sheet-nav__tab sheet-nav__tab--possible sheet-nav__tab--possible--gm_screen gm_screen" name="act_nav-gm_screen" data-i18n="gm screen" data-i18n-title="View gm screen" role="heading" aria-level="5" type="action" title="%{nav-gm_screen}">
</button>
<button class="subsystem-style sheet-nav__tab sheet-nav__tab--possible sheet-nav__tab--possible--party_screen party_screen" name="act_nav-party_screen" data-i18n="party screen" data-i18n-title="View party screen" role="heading" aria-level="5" type="action" title="%{nav-party_screen}">
</button>
<button class="pictos active sheet-nav__tab settings" name="act_nav-settings" data-i18n-title="open the settings page" role="heading" aria-level="5" type="action" title="%{nav-settings}">y
</button>
</nav>
<article class="navigable-section--settings navigable-section settings active" id="settings">
<section class="section-system-panel" id="system-panel">
<h2 data-i18n="system options"></h2>
<label class="input-label"><span data-i18n="system"></span>
<select class="underlined input-label__input" name="attr_system" title="@{system}">
<option value="scion-origin" data-i18n="scion-origin" selected="">
</option>
<option value="scion-hero" data-i18n="scion-hero">
</option>
</select>
</label>
<label class="input-label"><span data-i18n="sheet type"></span>
<select class="underlined input-label__input" name="attr_sheet_type" title="@{sheet_type}">
<option value="character" data-i18n="character" selected="">
</option>
<option value="antagonist" data-i18n="antagonist">
</option>
<option value="gm_screen" data-i18n="gm screen">
</option>
<option value="party_screen" data-i18n="party screen">
</option>
</select>
</label>
<label class="input-label"><span data-i18n="target number"></span>
<input class="underlined input-label__input" name="attr_target_number" type="number" value="8" title="@{target_number}"/>
</label>
<label class="input-label"><span data-i18n="again"></span>
<input class="underlined input-label__input" name="attr_again" type="number" value="10" min="2" max="10" title="@{again}"/>
</label>
</section>
<section class="section-sheet-behavior" id="sheet-behavior">
<h2 data-i18n="sheet behavior"></h2>
<label class="input-label"><span data-i18n="difficulty automation"></span>
<select class="underlined input-label__input" name="attr_difficulty_query" title="@{difficulty_query}">
<option value="off" data-i18n="off" selected="">
</option>
<option value="on" data-i18n="on">
</option>
</select>
</label>
<label class="input-label"><span data-i18n="enhancement automation"></span>
<select class="underlined input-label__input" name="attr_enhancement_query" title="@{enhancement_query}">
<option value="off" data-i18n="off" selected="">
</option>
<option value="on" data-i18n="on">
</option>
</select>
</label>
<label class="input-label"><span data-i18n="rolls are"></span>
<select class="underlined input-label__input" name="attr_whisper" title="@{whisper}">
<option value="" data-i18n="public" selected="">
</option>
<option value="/w gm " data-i18n="whispered to gm">
</option>
</select>
</label>
</section>
</article>
<article class="navigable-section sheet navigable-section--all navigable-section--general navigable-section--powers subsystem-style system-scion-origin system-scion-hero" id="sheet">
<section class="section-image-head" id="image-head"><img class="subsystem-display scion-origin active" alt="Scion Origin" role="heading" aria-level="1" src="https://s3.amazonaws.com/files.d20.io/images/251683701/lgeAjNoeRDqQccd7s0hsNQ/original.png"/><img class="subsystem-display scion-hero" alt="Scion Hero" role="heading" aria-level="1" src="https://s3.amazonaws.com/files.d20.io/images/251683696/wYblqZVpGI3AhAS9R3a-TA/original.png"/></section>
<section class="section-character_details" id="character_details">
<label class="input-label stacked"><span data-i18n="name"></span>
<input class="underlined input-label__input" name="attr_character_name" type="text" role="heading" aria-level="4" title="@{character_name}"/>
</label>
<label class="input-label stacked"><span data-i18n="player"></span>
<input class="underlined input-label__input" name="attr_player" type="text" role="heading" aria-level="4" title="@{player}"/>
</label>
<label class="input-label stacked subsystem-display scion-origin scion-hero active"><span data-i18n="chronicle"></span>
<input class="underlined input-label__input" name="attr_chronicle" type="text" role="heading" aria-level="4" title="@{chronicle}"/>
</label>
<label class="input-label stacked subsystem-display scion-origin scion-hero active"><span data-i18n="parent"></span>
<input class="underlined input-label__input" name="attr_parent" type="text" role="heading" aria-level="4" title="@{parent}"/>
</label>
</section>
<section class="section-momentum subsystem-style" id="momentum">
<button class="subsystem-style subsystem-display scion-origin expandable-header momentum" name="act_momentum" data-i18n="momentum" role="heading" aria-level="2" data-i18n-title="collapse/expand the section" type="action" title="%{momentum}">
</button>
<button class="subsystem-style subsystem-display scion-hero split expandable-header momentum" name="act_momentum" role="heading" aria-level="2" data-i18n-title="collapse/expand the section" type="action" title="%{momentum}">
<h2 data-i18n="momentum"></h2>
<h2 data-i18n="legend"></h2>
</button>
<div class="dot-row twelve-dots momentum-content boxes">
<select class="dot-number underlined" name="attr_momentum" title="@{momentum}">
<option value="0" selected="">0
</option>
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
<option value="6">6
</option>
<option value="7">7
</option>
<option value="8">8
</option>
<option value="9">9
</option>
<option value="10">10
</option>
<option value="11">11
</option>
<option value="12">12
</option>
</select>
<div class="dot-button-container">
<input class="clearer dot" name="attr_momentum" checked="" value="0" type="radio" title="@{momentum}"/>
<input class="dot" name="attr_momentum" value="1" type="radio" title="@{momentum}"/>
<input class="dot" name="attr_momentum" value="2" type="radio" title="@{momentum}"/>
<input class="dot" name="attr_momentum" value="3" type="radio" title="@{momentum}"/>
<input class="dot" name="attr_momentum" value="4" type="radio" title="@{momentum}"/>
<input class="dot" name="attr_momentum" value="5" type="radio" title="@{momentum}"/>
<input class="dot" name="attr_momentum" value="6" type="radio" title="@{momentum}"/>
<input class="dot" name="attr_momentum" value="7" type="radio" title="@{momentum}"/>
<input class="dot" name="attr_momentum" value="8" type="radio" title="@{momentum}"/>
<input class="dot" name="attr_momentum" value="9" type="radio" title="@{momentum}"/>
<input class="dot" name="attr_momentum" value="10" type="radio" title="@{momentum}"/>
<input class="dot" name="attr_momentum" value="11" type="radio" title="@{momentum}"/>
<input class="dot" name="attr_momentum" value="12" type="radio" title="@{momentum}"/>
</div>
</div>
<div class="dot-row four-dots legend-content subsystem-display scion-hero">
<select class="dot-number underlined" name="attr_legend" title="@{legend}">
<option value="0" selected="">0
</option>
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
</select>
<div class="dot-button-container">
<input class="clearer dot" name="attr_legend" checked="" value="0" type="radio" title="@{legend}"/>
<input class="dot" name="attr_legend" value="1" type="radio" title="@{legend}"/>
<input class="dot" name="attr_legend" value="2" type="radio" title="@{legend}"/>
<input class="dot" name="attr_legend" value="3" type="radio" title="@{legend}"/>
<input class="dot" name="attr_legend" value="4" type="radio" title="@{legend}"/>
</div>
</div>
<div class="dot-row four-dots legend-max-content boxes subsystem-display scion-hero">
<select class="dot-number underlined" name="attr_legend_max" title="@{legend|max}">
<option value="0" selected="">0
</option>
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
</select>
<div class="dot-button-container">
<input class="clearer dot" name="attr_legend_max" checked="" value="0" type="radio" title="@{legend|max}"/>
<input class="dot" name="attr_legend_max" value="1" type="radio" title="@{legend|max}"/>
<input class="dot" name="attr_legend_max" value="2" type="radio" title="@{legend|max}"/>
<input class="dot" name="attr_legend_max" value="3" type="radio" title="@{legend|max}"/>
<input class="dot" name="attr_legend_max" value="4" type="radio" title="@{legend|max}"/>
</div>
</div>
</section>
<section class="section-virtue subsystem-display scion-hero scion-origin" id="virtue">
<button class="subsystem-style expandable-header virtue" name="act_virtue" data-i18n="virtue" role="heading" aria-level="2" data-i18n-title="collapse/expand the section" type="action" title="%{virtue}">
</button>
<div class="dot-row size-number">
<input class="underlined" name="attr_virtue_1" type="text" title="@{virtue_1}"/>
<select class="dot-number underlined" name="attr_virtue" title="@{virtue}">
<option value="-2">-2
</option>
<option value="-1">-1
</option>
<option value="0" selected="">0
</option>
<option value="1">1
</option>
<option value="2">2
</option>
</select>
<div class="dot-button-container">
<input class="no-fill dot" name="attr_virtue" value="-2" type="radio" title="@{virtue}"/>
<input class="no-fill dot" name="attr_virtue" value="-1" type="radio" title="@{virtue}"/>
<input class="no-fill dot" name="attr_virtue" checked="" value="0" type="radio" title="@{virtue}"/>
<input class="no-fill dot" name="attr_virtue" value="1" type="radio" title="@{virtue}"/>
<input class="no-fill dot" name="attr_virtue" value="2" type="radio" title="@{virtue}"/>
</div>
<input class="underlined" name="attr_virtue_2" type="text" title="@{virtue_2}"/>
</div>
</section>
<section class="section-skills navigable-section navigable-section--all navigable-section--general" id="skills">
<button class="subsystem-style expandable-header skills" name="act_skills" data-i18n="skills" role="heading" aria-level="2" data-i18n-title="collapse/expand the section" type="action" title="%{skills}">
</button><span class="locked column-2" hidden=""></span>
<fieldset class="repeating_skill">
<input name="attr_name" hidden="" type="text" title="@{repeating_skill_$X_name}"/>
<input name="attr_path" type="checkbox" title="@{repeating_skill_$X_path}"/>
<div class="dot-row">
<button class="roller" name="roll_roll" value="@{action}" title="%{repeating_skill_$X_roll}" type="roll"><span name="attr_name" data-i18n-dynamic="" title="@{repeating_skill_$X_name}"></span>
</button>
<button name="act_action" hidden="" type="action" title="%{repeating_skill_$X_action}">
</button>
<input name="attr_action" type="hidden" title="@{repeating_skill_$X_action}"/>
<input class="subsystem-display scion-origin scion-hero active underlined" name="attr_specialty" type="text" title="@{repeating_skill_$X_specialty}"/>
<select class="dot-number underlined" name="attr_rating" title="@{repeating_skill_$X_rating}">
<option value="0" selected="">0
</option>
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<div class="dot-button-container">
<input class="clearer dot" name="attr_rating" checked="" value="0" type="radio" title="@{repeating_skill_$X_rating}"/>
<input class="dot" name="attr_rating" value="1" type="radio" title="@{repeating_skill_$X_rating}"/>
<input class="dot" name="attr_rating" value="2" type="radio" title="@{repeating_skill_$X_rating}"/>
<input class="dot" name="attr_rating" value="3" type="radio" title="@{repeating_skill_$X_rating}"/>
<input class="dot" name="attr_rating" value="4" type="radio" title="@{repeating_skill_$X_rating}"/>
<input class="dot" name="attr_rating" value="5" type="radio" title="@{repeating_skill_$X_rating}"/>
</div>
</div>
</fieldset>
</section>
<section class="section-attributes navigable-section navigable-section--all navigable-section--general" id="attributes">
<button class="subsystem-style expandable-header attributes" name="act_attributes" data-i18n="attributes" role="heading" aria-level="2" data-i18n-title="collapse/expand the section" type="action" title="%{attributes}">
</button>
<h3 class="subsystem-display scion-hero scion-origin active" data-i18n="mental"></h3>
<h3 class="subsystem-display scion-hero scion-origin active" data-i18n="physical"></h3>
<h3 class="subsystem-display scion-hero scion-origin" data-i18n="social"></h3>
<div class="approach-container power">
<h4 class="subsystem-display scion-hero scion-origin active" data-i18n="power"></h4>
<div class="dot-row size-number subsystem-display scion-hero scion-origin active">
<button class="roller" name="roll_intellect" role="header" aria-level="5" data-i18n="intellect" value="@{intellect_action}" title="%{intellect}" type="roll">
</button>
<button name="act_intellect-action" hidden="" type="action" title="%{intellect-action}">
</button>
<input name="attr_intellect_action" type="hidden" title="@{intellect_action}"/>
<select class="dot-number underlined" name="attr_intellect" title="@{intellect}">
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<div class="dot-button-container">
<input class="no-clear dot" name="attr_intellect" value="1" type="radio" title="@{intellect}"/>
<input class="no-clear dot" name="attr_intellect" value="2" type="radio" title="@{intellect}"/>
<input class="no-clear dot" name="attr_intellect" value="3" type="radio" title="@{intellect}"/>
<input class="no-clear dot" name="attr_intellect" value="4" type="radio" title="@{intellect}"/>
<input class="no-clear dot" name="attr_intellect" value="5" type="radio" title="@{intellect}"/>
</div>
</div>
<div class="dot-row size-number subsystem-display scion-hero scion-origin active">
<button class="roller" name="roll_might" role="header" aria-level="5" data-i18n="might" value="@{might_action}" title="%{might}" type="roll">
</button>
<button name="act_might-action" hidden="" type="action" title="%{might-action}">
</button>
<input name="attr_might_action" type="hidden" title="@{might_action}"/>
<select class="dot-number underlined" name="attr_might" title="@{might}">
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<div class="dot-button-container">
<input class="no-clear dot" name="attr_might" value="1" type="radio" title="@{might}"/>
<input class="no-clear dot" name="attr_might" value="2" type="radio" title="@{might}"/>
<input class="no-clear dot" name="attr_might" value="3" type="radio" title="@{might}"/>
<input class="no-clear dot" name="attr_might" value="4" type="radio" title="@{might}"/>
<input class="no-clear dot" name="attr_might" value="5" type="radio" title="@{might}"/>
</div>
</div>
<div class="dot-row size-number subsystem-display scion-hero scion-origin active">
<button class="roller" name="roll_presence" role="header" aria-level="5" data-i18n="presence" value="@{presence_action}" title="%{presence}" type="roll">
</button>
<button name="act_presence-action" hidden="" type="action" title="%{presence-action}">
</button>
<input name="attr_presence_action" type="hidden" title="@{presence_action}"/>
<select class="dot-number underlined" name="attr_presence" title="@{presence}">
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<div class="dot-button-container">
<input class="no-clear dot" name="attr_presence" value="1" type="radio" title="@{presence}"/>
<input class="no-clear dot" name="attr_presence" value="2" type="radio" title="@{presence}"/>
<input class="no-clear dot" name="attr_presence" value="3" type="radio" title="@{presence}"/>
<input class="no-clear dot" name="attr_presence" value="4" type="radio" title="@{presence}"/>
<input class="no-clear dot" name="attr_presence" value="5" type="radio" title="@{presence}"/>
</div>
</div>
</div>
<div class="approach-container finesse">
<h4 class="subsystem-display scion-hero scion-origin active" data-i18n="finesse"></h4>
<div class="dot-row size-number subsystem-display scion-hero scion-origin active">
<button class="roller" name="roll_cunning" role="header" aria-level="5" data-i18n="cunning" value="@{cunning_action}" title="%{cunning}" type="roll">
</button>
<button name="act_cunning-action" hidden="" type="action" title="%{cunning-action}">
</button>
<input name="attr_cunning_action" type="hidden" title="@{cunning_action}"/>
<select class="dot-number underlined" name="attr_cunning" title="@{cunning}">
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<div class="dot-button-container">
<input class="no-clear dot" name="attr_cunning" value="1" type="radio" title="@{cunning}"/>
<input class="no-clear dot" name="attr_cunning" value="2" type="radio" title="@{cunning}"/>
<input class="no-clear dot" name="attr_cunning" value="3" type="radio" title="@{cunning}"/>
<input class="no-clear dot" name="attr_cunning" value="4" type="radio" title="@{cunning}"/>
<input class="no-clear dot" name="attr_cunning" value="5" type="radio" title="@{cunning}"/>
</div>
</div>
<div class="dot-row size-number subsystem-display scion-hero scion-origin active">
<button class="roller" name="roll_dexterity" role="header" aria-level="5" data-i18n="dexterity" value="@{dexterity_action}" title="%{dexterity}" type="roll">
</button>
<button name="act_dexterity-action" hidden="" type="action" title="%{dexterity-action}">
</button>
<input name="attr_dexterity_action" type="hidden" title="@{dexterity_action}"/>
<select class="dot-number underlined" name="attr_dexterity" title="@{dexterity}">
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<div class="dot-button-container">
<input class="no-clear dot" name="attr_dexterity" value="1" type="radio" title="@{dexterity}"/>
<input class="no-clear dot" name="attr_dexterity" value="2" type="radio" title="@{dexterity}"/>
<input class="no-clear dot" name="attr_dexterity" value="3" type="radio" title="@{dexterity}"/>
<input class="no-clear dot" name="attr_dexterity" value="4" type="radio" title="@{dexterity}"/>
<input class="no-clear dot" name="attr_dexterity" value="5" type="radio" title="@{dexterity}"/>
</div>
</div>
<div class="dot-row size-number subsystem-display scion-hero scion-origin active">
<button class="roller" name="roll_manipulation" role="header" aria-level="5" data-i18n="manipulation" value="@{manipulation_action}" title="%{manipulation}" type="roll">
</button>
<button name="act_manipulation-action" hidden="" type="action" title="%{manipulation-action}">
</button>
<input name="attr_manipulation_action" type="hidden" title="@{manipulation_action}"/>
<select class="dot-number underlined" name="attr_manipulation" title="@{manipulation}">
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<div class="dot-button-container">
<input class="no-clear dot" name="attr_manipulation" value="1" type="radio" title="@{manipulation}"/>
<input class="no-clear dot" name="attr_manipulation" value="2" type="radio" title="@{manipulation}"/>
<input class="no-clear dot" name="attr_manipulation" value="3" type="radio" title="@{manipulation}"/>
<input class="no-clear dot" name="attr_manipulation" value="4" type="radio" title="@{manipulation}"/>
<input class="no-clear dot" name="attr_manipulation" value="5" type="radio" title="@{manipulation}"/>
</div>
</div>
</div>
<div class="approach-container resistance">
<h4 class="subsystem-display scion-hero scion-origin active" data-i18n="resilience"></h4>
<div class="dot-row size-number subsystem-display scion-hero scion-origin active">
<button class="roller" name="roll_resolve" role="header" aria-level="5" data-i18n="resolve" value="@{resolve_action}" title="%{resolve}" type="roll">
</button>
<button name="act_resolve-action" hidden="" type="action" title="%{resolve-action}">
</button>
<input name="attr_resolve_action" type="hidden" title="@{resolve_action}"/>
<select class="dot-number underlined" name="attr_resolve" title="@{resolve}">
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<div class="dot-button-container">
<input class="no-clear dot" name="attr_resolve" value="1" type="radio" title="@{resolve}"/>
<input class="no-clear dot" name="attr_resolve" value="2" type="radio" title="@{resolve}"/>
<input class="no-clear dot" name="attr_resolve" value="3" type="radio" title="@{resolve}"/>
<input class="no-clear dot" name="attr_resolve" value="4" type="radio" title="@{resolve}"/>
<input class="no-clear dot" name="attr_resolve" value="5" type="radio" title="@{resolve}"/>
</div>
</div>
<div class="dot-row size-number subsystem-display scion-hero scion-origin active">
<button class="roller" name="roll_stamina" role="header" aria-level="5" data-i18n="stamina" value="@{stamina_action}" title="%{stamina}" type="roll">
</button>
<button name="act_stamina-action" hidden="" type="action" title="%{stamina-action}">
</button>
<input name="attr_stamina_action" type="hidden" title="@{stamina_action}"/>
<select class="dot-number underlined" name="attr_stamina" title="@{stamina}">
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<div class="dot-button-container">
<input class="no-clear dot" name="attr_stamina" value="1" type="radio" title="@{stamina}"/>
<input class="no-clear dot" name="attr_stamina" value="2" type="radio" title="@{stamina}"/>
<input class="no-clear dot" name="attr_stamina" value="3" type="radio" title="@{stamina}"/>
<input class="no-clear dot" name="attr_stamina" value="4" type="radio" title="@{stamina}"/>
<input class="no-clear dot" name="attr_stamina" value="5" type="radio" title="@{stamina}"/>
</div>
</div>
<div class="dot-row size-number subsystem-display scion-hero scion-origin active">
<button class="roller" name="roll_composure" role="header" aria-level="5" data-i18n="composure" value="@{composure_action}" title="%{composure}" type="roll">
</button>
<button name="act_composure-action" hidden="" type="action" title="%{composure-action}">
</button>
<input name="attr_composure_action" type="hidden" title="@{composure_action}"/>
<select class="dot-number underlined" name="attr_composure" title="@{composure}">
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<div class="dot-button-container">
<input class="no-clear dot" name="attr_composure" value="1" type="radio" title="@{composure}"/>
<input class="no-clear dot" name="attr_composure" value="2" type="radio" title="@{composure}"/>
<input class="no-clear dot" name="attr_composure" value="3" type="radio" title="@{composure}"/>
<input class="no-clear dot" name="attr_composure" value="4" type="radio" title="@{composure}"/>
<input class="no-clear dot" name="attr_composure" value="5" type="radio" title="@{composure}"/>
</div>
</div>
</div>
</section>
<section class="section-health" id="health">
<button class="subsystem-style expandable-header health" name="act_health" data-i18n="health" role="heading" aria-level="2" data-i18n-title="collapse/expand the section" type="action" title="%{health}">
</button>
<button class="repcontrol-button repcontrol-button--add" name="act_add-injury" data-i18n-title="create a injury" type="action" title="%{add-injury}">
</button>
<button class="repcontrol-button repcontrol-button--edit" name="act_edit-injury" data-i18n-title="edit section" type="action" title="%{edit-injury}">
</button>
<div class="input-label input-label--button">
<button class="roller" name="roll_movement_dice" data-i18n="movement dice" role="heading" aria-level="5" value="@{movement_dice_action}" title="%{movement_dice}" type="roll">
</button>
<input class="underlined input-label__input" name="attr_movement_dice" type="number" readonly="" value="1" title="@{movement_dice}"/>
</div>
<button name="act_movement-dice-action" hidden="" type="action" title="%{movement-dice-action}">
</button>
<input name="attr_movement_dice_action" type="hidden" title="@{movement_dice_action}"/>
<div class="input-label input-label--button">
<button class="roller" name="roll_defense" role="heading" data-i18n="defense roll" aria-level="5" value="@{defense_action}" title="%{defense}" type="roll">
</button>
<input class="underlined input-label__input" name="attr_defense" type="number" readonly="" value="1" title="@{defense}"/>
</div>
<button name="act_defense-action" hidden="" type="action" title="%{defense-action}">
</button>
<input name="attr_defense_action" type="hidden" title="@{defense_action}"/><span class="pseudo-control" hidden=""></span>
<fieldset class="repeating_injury">
<input class="type-control" name="attr_display_state" value="bruised" type="hidden" title="@{repeating_injury_$X_display_state}"/>
<div class="type">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_injury_$X_collapse}"/>
<label class="collapse-interface">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_injury_$X_collapse}"/>
</label>
<input name="attr_affected" type="checkbox" title="@{repeating_injury_$X_affected}"/>
<select class="underlined" name="attr_type" title="@{repeating_injury_$X_type}">
<option value="bruised" data-i18n="bruised" selected="">
</option>
<option value="injured" data-i18n="injured">
</option>
<option value="maimed" data-i18n="maimed">
</option>
</select>
<input class="underlined" name="attr_name" data-i18n-placeholder="injury name" type="text" title="@{repeating_injury_$X_name}"/>
<div class="adaptive adaptive--text description"><span class="adaptive--text__span" name="attr_effect" title="@{repeating_injury_$X_effect}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_effect" data-i18n-placeholder="injury effect" title="@{repeating_injury_$X_effect}"></textarea>
</div>
</div>
<div class="taken-out">
<input name="attr_affected" type="checkbox" title="@{repeating_injury_$X_affected}"/><span name="attr_type" data-i18n-dynamic="" title="@{repeating_injury_$X_type}"></span>
</div>
</fieldset>
</section>
<section class="section-deeds subsystem-display scion-hero scion-origin navigable-section navigable-section--all navigable-section--general" id="deeds">
<button class="subsystem-style expandable-header deeds" name="act_deeds" data-i18n="deeds" role="heading" aria-level="2" data-i18n-title="collapse/expand the section" type="action" title="%{deeds}">
</button>
<button class="repcontrol-button repcontrol-button--add" name="act_add-deed" data-i18n-title="create a deed" type="action" title="%{add-deed}">
</button>
<button class="repcontrol-button repcontrol-button--edit" name="act_edit-deed" data-i18n-title="edit section" type="action" title="%{edit-deed}">
</button>
<div class="experience">
<h5 data-i18n="experience">
</h5>
<div class="input-label"><span data-i18n="used"></span>
<input class="underlined" name="attr_experience_used" type="number" title="@{experience_used}"/>
</div>
<div class="input-label"><span data-i18n="earned"></span>
<input class="underlined" name="attr_experience_earned" type="number" title="@{experience_earned}"/>
</div>
<div class="input-label"><span data-i18n="remaining"></span>
<input class="underlined" name="attr_experience_remaining" readonly="" type="number" title="@{experience_remaining}"/>
</div>
</div><span class="pseudo-control" hidden=""></span>
<fieldset class="repeating_deed">
<select name="attr_type" title="@{repeating_deed_$X_type}">
<option value="short" data-i18n="short" selected="">
</option>
<option value="long" data-i18n="long">
</option>
<option value="band" data-i18n="band">
</option>
</select>
<div class="adaptive adaptive--text"><span class="adaptive--text__span" name="attr_name" title="@{repeating_deed_$X_name}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_name" data-i18n-placeholder="deed description" title="@{repeating_deed_$X_name}"></textarea>
</div>
<input name="attr_completed" value="1" type="checkbox" title="@{repeating_deed_$X_completed}"/>
</fieldset>
<button class="subsystem-style completed-deed expandable-header completed deed" name="act_completed-deed" data-i18n="completed deeds" aria-level="3" role="heading" data-i18n-title="collapse/expand the section" type="action" title="%{completed-deed}">
</button><span class="pseudo-control" hidden=""></span>
<fieldset class="repeating_completed-deed">
<select name="attr_type" title="@{repeating_completed-deed_$X_type}">
<option value="short" data-i18n="short" selected="">
</option>
<option value="long" data-i18n="long">
</option>
<option value="band" data-i18n="band">
</option>
</select>
<div class="adaptive adaptive--text"><span class="adaptive--text__span" name="attr_name" title="@{repeating_completed-deed_$X_name}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_name" data-i18n-placeholder="deed description" title="@{repeating_completed-deed_$X_name}"></textarea>
</div>
<input name="attr_completed" value="1" type="checkbox" title="@{repeating_completed-deed_$X_completed}"/>
</fieldset>
</section>
<section class="section-paths navigable-section navigable-section--all navigable-section--powers" id="paths">
<button class="subsystem-style expandable-header paths" name="act_paths" data-i18n="paths" role="heading" aria-level="2" data-i18n-title="collapse/expand the section" type="action" title="%{paths}">
</button>
<button class="repcontrol-button repcontrol-button--add" name="act_add-path" data-i18n-title="create a path" type="action" title="%{add-path}">
</button>
<button class="repcontrol-button repcontrol-button--edit" name="act_edit-path" data-i18n-title="edit section" type="action" title="%{edit-path}">
</button><span class="pseudo-control image-borders" hidden=""></span>
<fieldset class="repeating_path">
<input class="border-control" name="attr_display_state" type="hidden" title="@{repeating_path_$X_display_state}"/>
<div class="image-border">
<div class="upper-blur"></div>
<div class="lower-blur"></div>
</div>
<input name="attr_master_id" type="hidden" title="@{repeating_path_$X_master_id}"/>
<input class="display-control" name="attr_display_state" value="short-master" hidden="" type="radio" title="@{repeating_path_$X_display_state}"/>
<div class="display-target short-master">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_path_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_path_$X_collapse}"/>
</label><span name="attr_type" role="heading" aria-level="5" title="@{repeating_path_$X_type}"></span><span name="attr_name" title="@{repeating_path_$X_name}"></span>
<select name="attr_status" title="@{repeating_path_$X_status}">
<option value="available" data-i18n="available" selected="">
</option>
<option value="invoked" data-i18n="invoked">
</option>
<option value="suspended" data-i18n="suspended">
</option>
<option value="revoked" data-i18n="revoked">
</option>
</select><span class="short-text description" name="attr_condition" title="@{repeating_path_$X_condition}"></span>
</div>
<input class="display-control" name="attr_display_state" value="master" hidden="" type="radio" title="@{repeating_path_$X_display_state}"/>
<div class="display-target master">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_path_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_path_$X_collapse}"/>
</label>
<input class="underlined" name="attr_type" data-i18n-placeholder="type" role="heading" aria-level="5" type="text" title="@{repeating_path_$X_type}"/>
<input class="underlined" name="attr_name" data-i18n-placeholder="name of the path" type="text" title="@{repeating_path_$X_name}"/>
<input name="attr_status" value="available" type="hidden" title="@{repeating_path_$X_status}"/>
<select name="attr_status" title="@{repeating_path_$X_status}">
<option value="available" data-i18n="available" selected="">
</option>
<option value="invoked" data-i18n="invoked">
</option>
<option value="suspended" data-i18n="suspended">
</option>
<option value="revoked" data-i18n="revoked">
</option>
</select>
<input class="underlined skills" name="attr_skill" data-i18n-placeholder="Associated skills" type="text" title="@{repeating_path_$X_skill}"/>
<div class="adaptive adaptive--text description"><span class="adaptive--text__span" name="attr_condition" title="@{repeating_path_$X_condition}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_condition" data-i18n-placeholder="Path condition" title="@{repeating_path_$X_condition}"></textarea>
</div>
<div class="adaptive adaptive--text description"><span class="adaptive--text__span" name="attr_description" title="@{repeating_path_$X_description}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_description" data-i18n-placeholder="describe the path" title="@{repeating_path_$X_description}"></textarea>
</div>
</div>
<input class="display-control" name="attr_display_state" value="short-contact" hidden="" type="radio" title="@{repeating_path_$X_display_state}"/>
<div class="display-target short-contact">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_path_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_path_$X_collapse}"/>
</label>
<h5 data-i18n="contact">
</h5><span name="attr_name" title="@{repeating_path_$X_name}"></span>
<input class="underlined" name="attr_tags" data-i18n-placeholder="tags" type="text" title="@{repeating_path_$X_tags}"/>
<select class="dot-number underlined" name="attr_rating" title="@{repeating_path_$X_rating}">
<option value="0">0
</option>
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
</div>
<input class="display-control" name="attr_display_state" value="contact" hidden="" type="radio" title="@{repeating_path_$X_display_state}"/>
<div class="display-target contact">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_path_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_path_$X_collapse}"/>
</label>
<h5 data-i18n="contact">
</h5>
<input class="underlined" name="attr_name" data-i18n-placeholder="name" type="text" title="@{repeating_path_$X_name}"/>
<input class="underlined" name="attr_tags" data-i18n-placeholder="tags" type="text" title="@{repeating_path_$X_tags}"/>
<div class="dot-row size-number">
<select class="dot-number underlined" name="attr_rating" title="@{repeating_path_$X_rating}">
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<div class="dot-button-container">
<input class="no-clear dot" name="attr_rating" value="1" type="radio" title="@{repeating_path_$X_rating}"/>
<input class="no-clear dot" name="attr_rating" value="2" type="radio" title="@{repeating_path_$X_rating}"/>
<input class="no-clear dot" name="attr_rating" value="3" type="radio" title="@{repeating_path_$X_rating}"/>
<input class="no-clear dot" name="attr_rating" value="4" type="radio" title="@{repeating_path_$X_rating}"/>
<input class="no-clear dot" name="attr_rating" value="5" type="radio" title="@{repeating_path_$X_rating}"/>
</div>
</div>
<div class="adaptive adaptive--text description"><span class="adaptive--text__span" name="attr_description" title="@{repeating_path_$X_description}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_description" data-i18n-placeholder="describe your contact" title="@{repeating_path_$X_description}"></textarea>
</div>
</div>
<input class="display-control" name="attr_display_state" value="short-group" hidden="" type="radio" title="@{repeating_path_$X_display_state}"/>
<div class="display-target short-group">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_path_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_path_$X_collapse}"/>
</label>
<h5 data-i18n="group">
</h5><span class="short-text" name="attr_group" title="@{repeating_path_$X_group}"></span>
</div>
<input class="display-control" name="attr_display_state" value="group" hidden="" type="radio" title="@{repeating_path_$X_display_state}"/>
<div class="display-target group">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_path_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_path_$X_collapse}"/>
</label>
<h5 data-i18n="group">
</h5>
<div class="adaptive adaptive--text description"><span class="adaptive--text__span" name="attr_group" title="@{repeating_path_$X_group}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_group" data-i18n-placeholder="describe the group" title="@{repeating_path_$X_group}"></textarea>
</div>
</div>
<input class="display-control" name="attr_display_state" value="short-access" hidden="" type="radio" title="@{repeating_path_$X_display_state}"/>
<div class="display-target short-access">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_path_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_path_$X_collapse}"/>
</label>
<h5 data-i18n="access">
</h5><span class="short-text" name="attr_access" title="@{repeating_path_$X_access}"></span>
</div>
<input class="display-control" name="attr_display_state" value="access" hidden="" type="radio" title="@{repeating_path_$X_display_state}"/>
<div class="display-target access">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_path_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_path_$X_collapse}"/>
</label>
<h5 data-i18n="access">
</h5>
<div class="adaptive adaptive--text description"><span class="adaptive--text__span" name="attr_access" title="@{repeating_path_$X_access}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_access" data-i18n-placeholder="describe the access" title="@{repeating_path_$X_access}"></textarea>
</div>
</div>
<input class="display-control" name="attr_display_state" value="short-obligation" hidden="" type="radio" title="@{repeating_path_$X_display_state}"/>
<div class="display-target short-obligation">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_path_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_path_$X_collapse}"/>
</label>
<h5 data-i18n="obligation">
</h5><span class="short-text" name="attr_obligation" title="@{repeating_path_$X_obligation}"></span>
<select class="underlined" name="attr_obligation_status" title="@{repeating_path_$X_obligation_status}">
<option value="pending" data-i18n="pending" selected="">
</option>
<option value="completed" data-i18n="completed">
</option>
<option value="failed" data-i18n="failed">
</option>
</select>
</div>
<input class="display-control" name="attr_display_state" value="obligation" hidden="" type="radio" title="@{repeating_path_$X_display_state}"/>
<div class="display-target obligation">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_path_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_path_$X_collapse}"/>
</label>
<h5 data-i18n="obligation">
</h5>
<input name="attr_obligation_status" value="pending" type="hidden" title="@{repeating_path_$X_obligation_status}"/>
<select class="underlined" name="attr_obligation_status" title="@{repeating_path_$X_obligation_status}">
<option value="pending" data-i18n="pending" selected="">
</option>
<option value="completed" data-i18n="completed">
</option>
<option value="failed" data-i18n="failed">
</option>
</select>
<div class="adaptive adaptive--text description"><span class="adaptive--text__span" name="attr_obligation" title="@{repeating_path_$X_obligation}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_obligation" data-i18n-placeholder="describe the obligation" title="@{repeating_path_$X_obligation}"></textarea>
</div>
</div>
<input class="display-control" name="attr_display_state" value="add-detail" hidden="" type="radio" title="@{repeating_path_$X_display_state}"/>
<div class="display-target add-detail">
<button class="repcontrol-button repcontrol-button--add" name="act_add-contact" data-i18n-title="create a contact" data-i18n="contact" type="action" title="%{repeating_path_$X_add-contact}">
</button>
<button class="repcontrol-button repcontrol-button--add" name="act_add-group" data-i18n-title="create a group" data-i18n="group" type="action" title="%{repeating_path_$X_add-group}">
</button>
<button class="repcontrol-button repcontrol-button--add" name="act_add-access" data-i18n-title="create a access" data-i18n="access" type="action" title="%{repeating_path_$X_add-access}">
</button>
<button class="repcontrol-button repcontrol-button--add" name="act_add-obligation" data-i18n-title="create a obligation" data-i18n="obligation" type="action" title="%{repeating_path_$X_add-obligation}">
</button>
</div>
</fieldset>
</section>
<section class="section-calling subsystem-display scion-hero scion-origin navigable-section navigable-section--all navigable-section--powers" id="calling">
<button class="subsystem-display subsystem-style scion-origin expandable-header calling" name="act_calling" data-i18n="calling & knacks" role="heading" aria-level="2" data-i18n-title="collapse/expand the section" type="action" title="%{calling}">
</button>
<button class="subsystem-display subsystem-style scion-hero expandable-header calling" name="act_calling" data-i18n="callings & knacks" role="heading" aria-level="2" data-i18n-title="collapse/expand the section" type="action" title="%{calling}">
</button>
<button class="repcontrol-button repcontrol-button--add" name="act_add-calling" data-i18n-title="create a calling" type="action" title="%{add-calling}">
</button>
<button class="repcontrol-button repcontrol-button--edit" name="act_edit-calling" data-i18n-title="edit section" type="action" title="%{edit-calling}">
</button><span class="pseudo-control image-borders" hidden=""></span>
<fieldset class="repeating_calling">
<input name="attr_level" value="mortal" type="hidden" title="@{repeating_calling_$X_level}"/>
<input class="border-control" name="attr_display_state" type="hidden" title="@{repeating_calling_$X_display_state}"/>
<div class="image-border">
<div class="upper-blur"></div>
<div class="lower-blur"></div>
</div>
<input name="attr_master_id" type="hidden" title="@{repeating_calling_$X_master_id}"/>
<input class="display-control" name="attr_display_state" value="master" hidden="" type="radio" title="@{repeating_calling_$X_display_state}"/>
<div class="display-target calling">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_calling_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_calling_$X_collapse}"/>
</label>
<div class="dot-row size-number contents used"><span class="dot-number" name="attr_rating" title="@{repeating_calling_$X_rating}"></span>
<div class="dot-button-container">
<input class="dot" name="attr_rating" value="0" hidden="" checked="" type="radio" title="@{repeating_calling_$X_rating}"/><span class="readonly-dot"></span>
<input class="dot" name="attr_rating" value="1" hidden="" type="radio" title="@{repeating_calling_$X_rating}"/><span class="readonly-dot"></span>
<input class="dot" name="attr_rating" value="2" hidden="" type="radio" title="@{repeating_calling_$X_rating}"/><span class="readonly-dot"></span>
<input class="dot" name="attr_rating" value="3" hidden="" type="radio" title="@{repeating_calling_$X_rating}"/><span class="readonly-dot"></span>
<input class="dot" name="attr_rating" value="4" hidden="" type="radio" title="@{repeating_calling_$X_rating}"/><span class="readonly-dot"></span>
<input class="dot" name="attr_rating" value="5" hidden="" type="radio" title="@{repeating_calling_$X_rating}"/><span class="readonly-dot"></span>
</div>
</div>
<div class="dot-row size-number contents">
<input class="underlined" name="attr_name" role="heading" aria-level="5" type="text" title="@{repeating_calling_$X_name}"/>
<select class="dot-number underlined" name="attr_rating_max" title="@{repeating_calling_$X_rating|max}">
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<div class="dot-button-container">
<input class="no-clear dot" name="attr_rating_max" value="1" type="radio" title="@{repeating_calling_$X_rating|max}"/>
<input class="no-clear dot" name="attr_rating_max" value="2" type="radio" title="@{repeating_calling_$X_rating|max}"/>
<input class="no-clear dot" name="attr_rating_max" value="3" type="radio" title="@{repeating_calling_$X_rating|max}"/>
<input class="no-clear dot" name="attr_rating_max" value="4" type="radio" title="@{repeating_calling_$X_rating|max}"/>
<input class="no-clear dot" name="attr_rating_max" value="5" type="radio" title="@{repeating_calling_$X_rating|max}"/>
</div>
</div>
</div>
<input class="display-control" name="attr_display_state" value="short-knack" hidden="" type="radio" title="@{repeating_calling_$X_display_state}"/>
<div class="display-target short-knack">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_calling_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_calling_$X_collapse}"/>
</label>
<button class="roller" name="roll_clash" data-i18n-alt="roll clash of wills" title="%{repeating_calling_$X_calling}" value="@{clash_action}" type="roll">
</button>
<button name="act_clash-action" hidden="" type="action" title="%{repeating_calling_$X_clash-action}">
</button>
<input name="attr_clash_action" type="hidden" title="@{repeating_calling_$X_clash_action}"/><span name="attr_name" title="@{repeating_calling_$X_name}"></span><span class="parentheses subsystem-display scion-hero" name="attr_level" data-i18n-dynamic="" title="@{repeating_calling_$X_level}"></span>
<input name="attr_active" value="1" type="checkbox" title="@{repeating_calling_$X_active}"/>
<input name="attr_clash_stat_2" value="rating" type="hidden" title="@{repeating_calling_$X_clash_stat_2}"/>
<input class="clash-display-control" name="attr_clash_stat_1" value="select" type="hidden" title="@{repeating_calling_$X_clash_stat_1}"/>
<div class="clash"><span name="attr_clash_stat_1" data-i18n-dynamic="" title="@{repeating_calling_$X_clash_stat_1}"></span><span>+</span><span name="attr_clash_stat_2" value="rating" data-i18n-dynamic="" title="@{repeating_calling_$X_clash_stat_2}"></span>
</div>
</div>
<input class="display-control" name="attr_display_state" value="knack" hidden="" type="radio" title="@{repeating_calling_$X_display_state}"/>
<div class="display-target knack">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_calling_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_calling_$X_collapse}"/>
</label>
<button class="roller" name="roll_clash" data-i18n-alt="roll clash of wills" title="%{repeating_calling_$X_calling}" value="@{clash_action}" type="roll">
</button>
<button name="act_clash-action" hidden="" type="action" title="%{repeating_calling_$X_clash-action}">
</button>
<input name="attr_clash_action" type="hidden" title="@{repeating_calling_$X_clash_action}"/>
<input class="underlined" name="attr_name" type="text" title="@{repeating_calling_$X_name}"/>
<input name="attr_level" value="mortal" type="hidden" title="@{repeating_calling_$X_level}"/>
<select class="parentheses subsystem-display scion-hero" name="attr_level" title="@{repeating_calling_$X_level}">
<option value="mortal" data-i18n="mortal" selected="">
</option>
<option value="immortal" data-i18n="immortal">
</option>
</select>
<input name="attr_active" value="1" type="checkbox" title="@{repeating_calling_$X_active}"/>
<div class="clash">
<h5>
</h5>
<div class="select-container">
<select class="underlined" name="attr_clash_stat_1" title="@{repeating_calling_$X_clash_stat_1}">
<option value="select" data-i18n="select" selected="">
</option>
<option value="query" data-i18n="query">
</option>
<option value="academics" data-i18n="academics">
</option>
<option value="athletics" data-i18n="athletics">
</option>
<option value="close combat" data-i18n="close combat">
</option>
<option value="culture" data-i18n="culture">
</option>
<option value="empathy" data-i18n="empathy">
</option>
<option value="firearms" data-i18n="firearms">
</option>
<option value="integrity" data-i18n="integrity">
</option>
<option value="leadership" data-i18n="leadership">
</option>
<option value="medicine" data-i18n="medicine">
</option>
<option value="occult" data-i18n="occult">
</option>
<option value="persuasion" data-i18n="persuasion">
</option>
<option value="pilot" data-i18n="pilot">
</option>
<option value="science" data-i18n="science">
</option>
<option value="subterfuge" data-i18n="subterfuge">
</option>
<option value="survival" data-i18n="survival">
</option>
<option value="technology" data-i18n="technology">
</option>
</select><span>+</span><span name="attr_clash_stat_2" value="rating" data-i18n-dynamic="" title="@{repeating_calling_$X_clash_stat_2}"></span>
</div>
</div>
<div class="adaptive adaptive--text description"><span class="adaptive--text__span" name="attr_description" title="@{repeating_calling_$X_description}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_description" title="@{repeating_calling_$X_description}"></textarea>
</div>
</div>
<input class="display-control" name="attr_display_state" value="add-detail" hidden="" type="radio" title="@{repeating_calling_$X_display_state}"/>
<div class="display-target add-detail">
<button class="repcontrol-button repcontrol-button--add" name="act_add-knack" data-i18n-title="create a knack" type="action" title="%{repeating_calling_$X_add-knack}">
</button>
</div>
</fieldset>
</section>
<section class="section-purview subsystem-display scion-hero navigable-section navigable-section--all navigable-section--powers" id="purview">
<button class="subsystem-display subsystem-style scion-hero expandable-header purview" name="act_purview" data-i18n="purviews" role="heading" aria-level="2" data-i18n-title="collapse/expand the section" type="action" title="%{purview}">
</button>
<button class="repcontrol-button repcontrol-button--add" name="act_add-purview" data-i18n-title="create a purview" type="action" title="%{add-purview}">
</button>
<button class="repcontrol-button repcontrol-button--edit" name="act_edit-purview" data-i18n-title="edit section" type="action" title="%{edit-purview}">
</button><span class="pseudo-control image-borders" hidden=""></span>
<fieldset class="repeating_purview">
<input class="border-control" name="attr_display_state" type="hidden" title="@{repeating_purview_$X_display_state}"/>
<div class="image-border">
<div class="upper-blur"></div>
<div class="lower-blur"></div>
</div>
<input name="attr_master_id" type="hidden" title="@{repeating_purview_$X_master_id}"/>
<input class="display-control" name="attr_display_state" value="short-master" hidden="" type="radio" title="@{repeating_purview_$X_display_state}"/>
<div class="display-target short-master">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_purview_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_purview_$X_collapse}"/>
</label><span name="attr_name" role="heading" aria-level="4" title="@{repeating_purview_$X_name}"></span>
</div>
<input class="display-control" name="attr_display_state" value="master" hidden="" type="radio" title="@{repeating_purview_$X_display_state}"/>
<div class="display-target master">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_purview_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_purview_$X_collapse}"/>
</label>
<input class="underlined" name="attr_name" role="heading" aria-level="4" data-i18n-placeholder="purview name" type="text" title="@{repeating_purview_$X_name}"/>
<div class="adaptive adaptive--text description"><span class="adaptive--text__span" name="attr_innate_power" title="@{repeating_purview_$X_innate_power}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_innate_power" data-i18n-placeholder="What is the purview's innate power?" title="@{repeating_purview_$X_innate_power}"></textarea>
</div>
<div class="adaptive adaptive--text description"><span class="adaptive--text__span" name="attr_description" title="@{repeating_purview_$X_description}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_description" data-i18n-placeholder="describe the purview" title="@{repeating_purview_$X_description}"></textarea>
</div>
</div>
<input class="display-control" name="attr_display_state" value="short-boon" hidden="" type="radio" title="@{repeating_purview_$X_display_state}"/>
<div class="display-target short-boon">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_purview_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_purview_$X_collapse}"/>
</label><span class="name" name="attr_name" role="heading" aria-level="5" title="@{repeating_purview_$X_name}"></span>
<input class="display-control" name="attr_cost" value="" type="hidden" title="@{repeating_purview_$X_cost}"/>
<label class="input-label cost">
<h5 class="cost" data-i18n="cost">
</h5><span class="cost" name="attr_cost" title="@{repeating_purview_$X_cost}"></span>
</label>
<input class="display-control" name="attr_duration" value="" type="hidden" title="@{repeating_purview_$X_duration}"/>
<label class="input-label duration">
<h5 class="duration" data-i18n="duration">
</h5><span class="duration" name="attr_duration" title="@{repeating_purview_$X_duration}"></span>
</label>
<input class="display-control" name="attr_subject" value="" type="hidden" title="@{repeating_purview_$X_subject}"/>
<label class="input-label subject">
<h5 class="subject" data-i18n="subject">
</h5><span class="subject" name="attr_subject" title="@{repeating_purview_$X_subject}"></span>
</label>
<input class="display-control" name="attr_range" value="" type="hidden" title="@{repeating_purview_$X_range}"/>
<label class="input-label range">
<h5 class="range" data-i18n="range">
</h5><span class="range" name="attr_range" title="@{repeating_purview_$X_range}"></span>
</label>
<input class="display-control" name="attr_action" value="" type="hidden" title="@{repeating_purview_$X_action}"/>
<label class="input-label action">
<h5 class="action" data-i18n="action">
</h5><span class="action" name="attr_action" title="@{repeating_purview_$X_action}"></span>
</label>
<input class="clash-display-control" name="attr_clash_stat_1" value="select" type="hidden" title="@{repeating_purview_$X_clash_stat_1}"/>
<input class="clash-display-control" name="attr_clash_stat_2" value="select" type="hidden" title="@{repeating_purview_$X_clash_stat_2}"/>
<div class="clash">
<button class="roller" name="roll_clash" data-i18n-alt="roll clash of wills" title="%{repeating_purview_$X_purview}" value="@{clash_action}" type="roll">
</button>
<button name="act_clash-action" hidden="" type="action" title="%{repeating_purview_$X_clash-action}">
</button>
<input name="attr_clash_action" type="hidden" title="@{repeating_purview_$X_clash_action}"/><span name="attr_clash_stat_1" data-i18n-dynamic="" title="@{repeating_purview_$X_clash_stat_1}"></span><span>+</span><span name="attr_clash_stat_2" data-i18n-dynamic="" title="@{repeating_purview_$X_clash_stat_2}"></span><span class="vs" data-i18n="vs"></span><span name="attr_clash_defense_1" data-i18n-dynamic="" title="@{repeating_purview_$X_clash_defense_1}"></span><span>+</span><span name="attr_clash_defense_2" data-i18n-dynamic="" title="@{repeating_purview_$X_clash_defense_2}"></span>
</div>
</div>
<input class="display-control" name="attr_display_state" value="boon" hidden="" type="radio" title="@{repeating_purview_$X_display_state}"/>
<div class="display-target boon">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_purview_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_purview_$X_collapse}"/>
</label>
<input class="name underlined" name="attr_name" role="heading" aria-level="5" data-i18n-placeholder="boon name" type="text" title="@{repeating_purview_$X_name}"/>
<label class="input-label cost">
<h5 data-i18n="cost">
</h5>
<input class="underlined" name="attr_cost" type="text" title="@{repeating_purview_$X_cost}"/>
</label>
<label class="input-label duration">
<h5 data-i18n="duration">
</h5>
<input class="underlined" name="attr_duration" type="text" title="@{repeating_purview_$X_duration}"/>
</label>
<label class="input-label subject">
<h5 data-i18n="subject">
</h5>
<input class="underlined" name="attr_subject" type="text" title="@{repeating_purview_$X_subject}"/>
</label>
<label class="input-label range">
<h5 data-i18n="range">
</h5>
<input class="underlined" name="attr_range" type="text" title="@{repeating_purview_$X_range}"/>
</label>
<label class="input-label action">
<h5 data-i18n="action">
</h5>
<input class="underlined" name="attr_action" type="text" title="@{repeating_purview_$X_action}"/>
</label>
<div class="clash">
<button class="roller" name="roll_clash" data-i18n-alt="roll clash of wills" title="%{repeating_purview_$X_purview}" value="@{clash_action}" type="roll">
</button>
<button name="act_clash-action" hidden="" type="action" title="%{repeating_purview_$X_clash-action}">
</button>
<input name="attr_clash_action" type="hidden" title="@{repeating_purview_$X_clash_action}"/>
<h5 data-i18n="clash">
</h5>
<div class="select-container">
<select class="underlined" name="attr_clash_stat_1" title="@{repeating_purview_$X_clash_stat_1}">
<option value="select" data-i18n="select" selected="">
</option>
<option value="query" data-i18n="query">
</option>
<option value="legend" data-i18n="legend">
</option>
<option value="intellect" data-i18n="intellect">
</option>
<option value="cunning" data-i18n="cunning">
</option>
<option value="resolve" data-i18n="resolve">
</option>
<option value="might" data-i18n="might">
</option>
<option value="dexterity" data-i18n="dexterity">
</option>
<option value="stamina" data-i18n="stamina">
</option>
<option value="presence" data-i18n="presence">
</option>
<option value="manipulation" data-i18n="manipulation">
</option>
<option value="composure" data-i18n="composure">
</option>
<option value="academics" data-i18n="academics">
</option>
<option value="athletics" data-i18n="athletics">
</option>
<option value="close combat" data-i18n="close combat">
</option>
<option value="culture" data-i18n="culture">
</option>
<option value="empathy" data-i18n="empathy">
</option>
<option value="firearms" data-i18n="firearms">
</option>
<option value="integrity" data-i18n="integrity">
</option>
<option value="leadership" data-i18n="leadership">
</option>
<option value="medicine" data-i18n="medicine">
</option>
<option value="occult" data-i18n="occult">
</option>
<option value="persuasion" data-i18n="persuasion">
</option>
<option value="pilot" data-i18n="pilot">
</option>
<option value="science" data-i18n="science">
</option>
<option value="subterfuge" data-i18n="subterfuge">
</option>
<option value="survival" data-i18n="survival">
</option>
<option value="technology" data-i18n="technology">
</option>
</select><span>+</span>
<select class="underlined" name="attr_clash_stat_2" title="@{repeating_purview_$X_clash_stat_2}">
<option value="select" data-i18n="select" selected="">
</option>
<option value="query" data-i18n="query">
</option>
<option value="legend" data-i18n="legend">
</option>
<option value="intellect" data-i18n="intellect">
</option>
<option value="cunning" data-i18n="cunning">
</option>
<option value="resolve" data-i18n="resolve">
</option>
<option value="might" data-i18n="might">
</option>
<option value="dexterity" data-i18n="dexterity">
</option>
<option value="stamina" data-i18n="stamina">
</option>
<option value="presence" data-i18n="presence">
</option>
<option value="manipulation" data-i18n="manipulation">
</option>
<option value="composure" data-i18n="composure">
</option>
<option value="academics" data-i18n="academics">
</option>
<option value="athletics" data-i18n="athletics">
</option>
<option value="close combat" data-i18n="close combat">
</option>
<option value="culture" data-i18n="culture">
</option>
<option value="empathy" data-i18n="empathy">
</option>
<option value="firearms" data-i18n="firearms">
</option>
<option value="integrity" data-i18n="integrity">
</option>
<option value="leadership" data-i18n="leadership">
</option>
<option value="medicine" data-i18n="medicine">
</option>
<option value="occult" data-i18n="occult">
</option>
<option value="persuasion" data-i18n="persuasion">
</option>
<option value="pilot" data-i18n="pilot">
</option>
<option value="science" data-i18n="science">
</option>
<option value="subterfuge" data-i18n="subterfuge">
</option>
<option value="survival" data-i18n="survival">
</option>
<option value="technology" data-i18n="technology">
</option>
</select><span class="vs" data-i18n="vs"></span>
<select class="underlined" name="attr_clash_defense_1" title="@{repeating_purview_$X_clash_defense_1}">
<option value="select" data-i18n="select" selected="">
</option>
<option value="legend" data-i18n="legend">
</option>
<option value="intellect" data-i18n="intellect">
</option>
<option value="cunning" data-i18n="cunning">
</option>
<option value="resolve" data-i18n="resolve">
</option>
<option value="might" data-i18n="might">
</option>
<option value="dexterity" data-i18n="dexterity">
</option>
<option value="stamina" data-i18n="stamina">
</option>
<option value="presence" data-i18n="presence">
</option>
<option value="manipulation" data-i18n="manipulation">
</option>
<option value="composure" data-i18n="composure">
</option>
<option value="academics" data-i18n="academics">
</option>
<option value="athletics" data-i18n="athletics">
</option>
<option value="close combat" data-i18n="close combat">
</option>
<option value="culture" data-i18n="culture">
</option>
<option value="empathy" data-i18n="empathy">
</option>
<option value="firearms" data-i18n="firearms">
</option>
<option value="integrity" data-i18n="integrity">
</option>
<option value="leadership" data-i18n="leadership">
</option>
<option value="medicine" data-i18n="medicine">
</option>
<option value="occult" data-i18n="occult">
</option>
<option value="persuasion" data-i18n="persuasion">
</option>
<option value="pilot" data-i18n="pilot">
</option>
<option value="science" data-i18n="science">
</option>
<option value="subterfuge" data-i18n="subterfuge">
</option>
<option value="survival" data-i18n="survival">
</option>
<option value="technology" data-i18n="technology">
</option>
</select><span>+</span>
<select class="underlined" name="attr_clash_defense_2" title="@{repeating_purview_$X_clash_defense_2}">
<option value="select" data-i18n="select" selected="">
</option>
<option value="legend" data-i18n="legend">
</option>
<option value="intellect" data-i18n="intellect">
</option>
<option value="cunning" data-i18n="cunning">
</option>
<option value="resolve" data-i18n="resolve">
</option>
<option value="might" data-i18n="might">
</option>
<option value="dexterity" data-i18n="dexterity">
</option>
<option value="stamina" data-i18n="stamina">
</option>
<option value="presence" data-i18n="presence">
</option>
<option value="manipulation" data-i18n="manipulation">
</option>
<option value="composure" data-i18n="composure">
</option>
<option value="academics" data-i18n="academics">
</option>
<option value="athletics" data-i18n="athletics">
</option>
<option value="close combat" data-i18n="close combat">
</option>
<option value="culture" data-i18n="culture">
</option>
<option value="empathy" data-i18n="empathy">
</option>
<option value="firearms" data-i18n="firearms">
</option>
<option value="integrity" data-i18n="integrity">
</option>
<option value="leadership" data-i18n="leadership">
</option>
<option value="medicine" data-i18n="medicine">
</option>
<option value="occult" data-i18n="occult">
</option>
<option value="persuasion" data-i18n="persuasion">
</option>
<option value="pilot" data-i18n="pilot">
</option>
<option value="science" data-i18n="science">
</option>
<option value="subterfuge" data-i18n="subterfuge">
</option>
<option value="survival" data-i18n="survival">
</option>
<option value="technology" data-i18n="technology">
</option>
</select>
</div>
</div>
<div class="adaptive adaptive--text description"><span class="adaptive--text__span" name="attr_description" title="@{repeating_purview_$X_description}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_description" data-i18n-placeholder="describe the boon" title="@{repeating_purview_$X_description}"></textarea>
</div>
</div>
<input class="display-control" name="attr_display_state" value="add-detail" hidden="" type="radio" title="@{repeating_purview_$X_display_state}"/>
<div class="display-target add-detail">
<button class="repcontrol-button repcontrol-button--add" name="act_add-boon" data-i18n-title="create a boon" type="action" title="%{repeating_purview_$X_add-boon}">
</button>
</div>
</fieldset>
</section>
<section class="section-birthrights subsystem-display scion-hero navigable-section navigable-section--powers navigable-section--all" id="birthrights">
<button class="subsystem-style expandable-header birthrights" name="act_birthrights" data-i18n="birthrights" role="heading" aria-level="2" data-i18n-title="collapse/expand the section" type="action" title="%{birthrights}">
</button>
<button class="repcontrol-button repcontrol-button--edit" name="act_edit-birthright" data-i18n-title="edit section" type="action" title="%{edit-birthright}">
</button>
<label class="input-label"><span class="input-label__text" data-i18n="legendary titles" role="heading" aria-level="5"></span>
<input class="underlined input-label__input" name="attr_legendary_title" type="text" value="" title="@{legendary_title}"/>
</label><span class="pseudo-control bordered-item" hidden=""></span>
<fieldset class="repeating_birthright">
<div class="image-border"></div>
<input class="display-control" name="attr_display_state" value="short-relic" hidden="" type="radio" title="@{repeating_birthright_$X_display_state}"/>
<div class="display-target short-relic">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_birthright_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_birthright_$X_collapse}"/>
</label>
<h5 data-i18n="relic">
</h5><span class="name" name="attr_name" role="heading" aria-level="4" title="@{repeating_birthright_$X_name}"></span>
<select class="dot-number underlined" name="attr_rating" title="@{repeating_birthright_$X_rating}">
<option value="0">0
</option>
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<input class="display-control" name="attr_variety" value="" type="hidden" title="@{repeating_birthright_$X_variety}"/>
<div class="input-label variety">
<h5 data-i18n="variety">
</h5><span name="attr_variety" title="@{repeating_birthright_$X_variety}"></span>
</div>
<input class="display-control" name="attr_tag" value="" type="hidden" title="@{repeating_birthright_$X_tag}"/>
<div class="input-label tag">
<h5 data-i18n="tag">
</h5><span name="attr_tag" title="@{repeating_birthright_$X_tag}"></span>
</div>
<input class="display-control" name="attr_deed" value="" type="hidden" title="@{repeating_birthright_$X_deed}"/>
<div class="input-label deed">
<h5 data-i18n="deed">
</h5><span name="attr_deed" title="@{repeating_birthright_$X_deed}"></span>
</div>
<input class="display-control" name="attr_purview" value="" type="hidden" title="@{repeating_birthright_$X_purview}"/>
<div class="input-label purview">
<h5 data-i18n="purview">
</h5><span name="attr_purview" title="@{repeating_birthright_$X_purview}"></span>
</div>
<input class="display-control" name="attr_motif" value="" type="hidden" title="@{repeating_birthright_$X_motif}"/>
<div class="input-label motif">
<h5 data-i18n="motif">
</h5><span name="attr_motif" title="@{repeating_birthright_$X_motif}"></span>
</div>
<input class="display-control" name="attr_enhancement" value="" type="hidden" title="@{repeating_birthright_$X_enhancement}"/>
<div class="input-label enhancement">
<h5 data-i18n="enhancement">
</h5><span name="attr_enhancement" title="@{repeating_birthright_$X_enhancement}"></span>
</div>
<input class="display-control" name="attr_knack" value="" type="hidden" title="@{repeating_birthright_$X_knack}"/>
<div class="input-label knack">
<h5 data-i18n="knack">
</h5><span name="attr_knack" title="@{repeating_birthright_$X_knack}"></span>
</div>
<input class="display-control" name="attr_flaw" value="" type="hidden" title="@{repeating_birthright_$X_flaw}"/>
<div class="input-label flaw">
<h5 data-i18n="flaw">
</h5><span name="attr_flaw" title="@{repeating_birthright_$X_flaw}"></span>
</div>
</div>
<input class="display-control" name="attr_display_state" value="short-guide" hidden="" type="radio" title="@{repeating_birthright_$X_display_state}"/>
<div class="display-target short-guide">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_birthright_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_birthright_$X_collapse}"/>
</label>
<h5 data-i18n="guide">
</h5><span class="name" name="attr_name" role="heading" aria-level="4" title="@{repeating_birthright_$X_name}"></span>
<select class="dot-number underlined" name="attr_rating" title="@{repeating_birthright_$X_rating}">
<option value="0">0
</option>
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<input class="display-control" name="attr_skills" value="" type="hidden" title="@{repeating_birthright_$X_skills}"/>
<div class="input-label skills">
<h5 data-i18n="skills">
</h5><span name="attr_skills" title="@{repeating_birthright_$X_skills}"></span>
</div>
<input class="display-control" name="attr_benefit" value="" type="hidden" title="@{repeating_birthright_$X_benefit}"/>
<div class="input-label benefit">
<h5 data-i18n="benefit">
</h5><span name="attr_benefit" title="@{repeating_birthright_$X_benefit}"></span>
</div>
<input class="display-control" name="attr_stunt" value="" type="hidden" title="@{repeating_birthright_$X_stunt}"/>
<div class="input-label stunt">
<h5 data-i18n="stunt">
</h5><span name="attr_stunt" title="@{repeating_birthright_$X_stunt}"></span>
</div>
<input class="display-control" name="attr_purview" value="" type="hidden" title="@{repeating_birthright_$X_purview}"/>
<div class="input-label purview">
<h5 data-i18n="purview">
</h5><span name="attr_purview" title="@{repeating_birthright_$X_purview}"></span>
</div>
<input class="display-control" name="attr_calling" value="" type="hidden" title="@{repeating_birthright_$X_calling}"/>
<div class="input-label calling">
<h5 data-i18n="calling">
</h5><span name="attr_calling" title="@{repeating_birthright_$X_calling}"></span>
</div>
<input class="display-control" name="attr_title" value="" type="hidden" title="@{repeating_birthright_$X_title}"/>
<div class="input-label title">
<h5 data-i18n="title">
</h5><span name="attr_title" title="@{repeating_birthright_$X_title}"></span>
</div>
</div>
<input class="display-control" name="attr_display_state" value="short-follower" hidden="" type="radio" title="@{repeating_birthright_$X_display_state}"/>
<div class="display-target short-follower">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_birthright_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_birthright_$X_collapse}"/>
</label>
<h5 data-i18n="follower">
</h5><span class="name" name="attr_name" role="heading" aria-level="4" title="@{repeating_birthright_$X_name}"></span>
<select class="dot-number underlined" name="attr_rating" title="@{repeating_birthright_$X_rating}">
<option value="0">0
</option>
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<input class="display-control" name="attr_archetype" value="" type="hidden" title="@{repeating_birthright_$X_archetype}"/>
<div class="input-label archetype">
<h5 data-i18n="archetype">
</h5><span name="attr_archetype" title="@{repeating_birthright_$X_archetype}"></span>
</div>
<input class="display-control" name="attr_tag" value="" type="hidden" title="@{repeating_birthright_$X_tag}"/>
<div class="input-label tag">
<h5 data-i18n="tag">
</h5><span name="attr_tag" title="@{repeating_birthright_$X_tag}"></span>
</div>
</div>
<input class="display-control" name="attr_display_state" value="short-creature" hidden="" type="radio" title="@{repeating_birthright_$X_display_state}"/>
<div class="display-target short-creature">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_birthright_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_birthright_$X_collapse}"/>
</label>
<h5 data-i18n="creature">
</h5><span class="name" name="attr_name" role="heading" aria-level="4" data-i18n-placeholder="name" title="@{repeating_birthright_$X_name}"></span>
<select class="dot-number underlined" name="attr_rating" title="@{repeating_birthright_$X_rating}">
<option value="0">0
</option>
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
</div>
<input class="expanded-control" name="attr_display_state" value="relic" type="hidden" title="@{repeating_birthright_$X_display_state}"/>
<div class="display-target">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_birthright_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_birthright_$X_collapse}"/>
</label>
<h5 class="relic conditional-show" data-i18n="relic">
</h5>
<h5 class="guide conditional-show" data-i18n="guide">
</h5>
<h5 class="follower conditional-show" data-i18n="follower">
</h5>
<h5 class="creature conditional-show" data-i18n="creature">
</h5>
<input class="name underlined" name="attr_name" role="heading" aria-level="4" data-i18n-placeholder="name" type="text" title="@{repeating_birthright_$X_name}"/>
<div class="dot-row size-number rating">
<select class="dot-number underlined" name="attr_rating" title="@{repeating_birthright_$X_rating}">
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
</select>
<div class="dot-button-container">
<input class="no-clear dot" name="attr_rating" value="1" type="radio" title="@{repeating_birthright_$X_rating}"/>
<input class="no-clear dot" name="attr_rating" value="2" type="radio" title="@{repeating_birthright_$X_rating}"/>
<input class="no-clear dot" name="attr_rating" value="3" type="radio" title="@{repeating_birthright_$X_rating}"/>
<input class="no-clear dot" name="attr_rating" value="4" type="radio" title="@{repeating_birthright_$X_rating}"/>
<input class="no-clear dot" name="attr_rating" value="5" type="radio" title="@{repeating_birthright_$X_rating}"/>
</div>
</div>
<div class="detail-container">
<label class="input-label variety conditional-show relic">
<h5 data-i18n="variety">
</h5>
<input class="underlined" name="attr_variety" type="text" title="@{repeating_birthright_$X_variety}"/>
</label>
<label class="input-label archetype conditional-show follower">
<h5 data-i18n="archetype">
</h5>
<input class="underlined" name="attr_archetype" type="text" title="@{repeating_birthright_$X_archetype}"/>
</label>
<label class="input-label tag conditional-show relic follower">
<h5 data-i18n="tag">
</h5>
<input class="underlined" name="attr_tag" type="text" title="@{repeating_birthright_$X_tag}"/>
</label>
<label class="input-label deed conditional-show relic">
<h5 data-i18n="deed">
</h5>
<input class="underlined" name="attr_deed" type="text" title="@{repeating_birthright_$X_deed}"/>
</label>
<label class="input-label skills conditional-show guide">
<h5 data-i18n="skills">
</h5>
<input class="underlined" name="attr_skills" type="text" title="@{repeating_birthright_$X_skills}"/>
</label>
<label class="input-label benefit conditional-show guide">
<h5 data-i18n="benefit">
</h5>
<input class="underlined" name="attr_benefit" type="text" title="@{repeating_birthright_$X_benefit}"/>
</label>
<label class="input-label stunt conditional-show guide">
<h5 data-i18n="stunt">
</h5>
<input class="underlined" name="attr_stunt" type="text" title="@{repeating_birthright_$X_stunt}"/>
</label>
<label class="input-label purview conditional-show relic guide">
<h5 data-i18n="purview">
</h5>
<input class="underlined" name="attr_purview" type="text" title="@{repeating_birthright_$X_purview}"/>
</label>
<label class="input-label calling conditional-show guide">
<h5 data-i18n="calling">
</h5>
<input class="underlined" name="attr_calling" type="text" title="@{repeating_birthright_$X_calling}"/>
</label>
<label class="input-label motif conditional-show relic">
<h5 data-i18n="motif">
</h5>
<input class="underlined" name="attr_motif" type="text" title="@{repeating_birthright_$X_motif}"/>
</label>
<label class="input-label enhancement conditional-show relic">
<h5 data-i18n="enhancement">
</h5>
<input class="underlined" name="attr_enhancement" type="text" title="@{repeating_birthright_$X_enhancement}"/>
</label>
<label class="input-label knack conditional-show relic">
<h5 data-i18n="knack">
</h5>
<input class="underlined" name="attr_knack" type="text" title="@{repeating_birthright_$X_knack}"/>
</label>
<label class="input-label flaw conditional-show relic">
<h5 data-i18n="flaw">
</h5>
<input class="underlined" name="attr_flaw" type="text" title="@{repeating_birthright_$X_flaw}"/>
</label>
<label class="input-label title conditional-show guide">
<h5 data-i18n="title">
</h5>
<input class="underlined" name="attr_title" type="text" title="@{repeating_birthright_$X_title}"/>
</label>
</div>
</div>
</fieldset>
<div class="add-container bordered-item">
<button class="repcontrol-button repcontrol-button--add" name="act_add-birthright-creature" data-i18n-title="create a birthright-creature" data-i18n="creature" type="action" title="%{add-birthright-creature}">
</button>
<button class="repcontrol-button repcontrol-button--add" name="act_add-birthright-follower" data-i18n-title="create a birthright-follower" data-i18n="follower" type="action" title="%{add-birthright-follower}">
</button>
<button class="repcontrol-button repcontrol-button--add" name="act_add-birthright-guide" data-i18n-title="create a birthright-guide" data-i18n="guide" type="action" title="%{add-birthright-guide}">
</button>
<button class="repcontrol-button repcontrol-button--add" name="act_add-birthright-relic" data-i18n-title="create a birthright-relic" data-i18n="relic" type="action" title="%{add-birthright-relic}">
</button>
</div>
</section>
<section class="section-equipment subsystem-style navigable-section navigable-section--all navigable-section--general" id="equipment">
<button class="subsystem-style expandable-header equipment" name="act_equipment" data-i18n="equipment" role="heading" aria-level="2" data-i18n-title="collapse/expand the section" type="action" title="%{equipment}">
</button>
<button class="repcontrol-button repcontrol-button--add" name="act_add-equipment" data-i18n-title="create a equipment" type="action" title="%{add-equipment}">
</button>
<button class="repcontrol-button repcontrol-button--edit" name="act_edit-equipment" data-i18n-title="edit section" type="action" title="%{edit-equipment}">
</button><span class="pseudo-control bordered-item" hidden=""></span>
<fieldset class="repeating_equipment">
<input class="display-control" name="attr_display_state" type="hidden" title="@{repeating_equipment_$X_display_state}"/>
<div class="image-border"></div>
<input class="display-control" name="attr_display_state" value="short-equipment" hidden="" type="radio" title="@{repeating_equipment_$X_display_state}"/>
<div class="display-target short-equipment">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_equipment_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_equipment_$X_collapse}"/>
</label><span name="attr_name" title="@{repeating_equipment_$X_name}"></span><span name="attr_tag" title="@{repeating_equipment_$X_tag}"></span>
</div>
<input class="display-control" name="attr_display_state" value="equipment" hidden="" type="radio" title="@{repeating_equipment_$X_display_state}"/>
<div class="display-target equipment">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_equipment_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_equipment_$X_collapse}"/>
</label>
<input class="underlined" name="attr_name" data-i18n-placeholder="name" type="text" title="@{repeating_equipment_$X_name}"/>
<input class="underlined" name="attr_tag" data-i18n-placeholder="tags" type="text" title="@{repeating_equipment_$X_tag}"/>
<div class="adaptive adaptive--text description"><span class="adaptive--text__span" name="attr_description" title="@{repeating_equipment_$X_description}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_description" data-i18n-placeholder="describe the item" title="@{repeating_equipment_$X_description}"></textarea>
</div>
</div>
</fieldset>
</section>
<section class="section-notes navigable-section navigable-section--all navigable-section--general" id="notes">
<button class="subsystem-style expandable-header notes" name="act_notes" data-i18n="notes" role="heading" aria-level="2" data-i18n-title="collapse/expand the section" type="action" title="%{notes}">
</button>
<div class="adaptive adaptive--text"><span class="adaptive--text__span" name="attr_notes" title="@{notes}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_notes" title="@{notes}"></textarea>
</div>
</section>
</article>
<article class="navigable-section navigable-section--antagonist subsystem-style system-scion-origin statblock" id="antagonist">
<section class="antagonist" id="antagonist-details">
<div class="statblock__row statblock__row--header">
<input class="image-display-control" name="attr_archetype_symbol" value="" type="hidden" title="@{archetype_symbol}"/><img name="attr_archetype_symbol" src=" " data-i18n-alt="archetype symbol" title="@{archetype_symbol}"/>
<input name="attr_character_name" role="heading" aria-level="1" type="text" title="@{character_name}"/>
</div>
<div class="statblock__row">
<label class="input-label"><span class="input-label__text" data-i18n="archetype" role="heading" aria-level="3"></span>
<input class="underlined input-label__input" name="attr_archetype" type="text" title="@{archetype}"/>
</label>
</div>
<div class="statblock__row">
<label class="input-label"><span class="input-label__text" data-i18n="drive" role="heading" aria-level="3"></span>
<input class="underlined input-label__input" name="attr_drive" type="text" title="@{drive}"/>
</label>
</div>
<div class="statblock__row">
<div class="input-label input-label--button">
<button class="roller input-label__text" name="roll_primary_pool" data-i18n="primary pool" role="heading" aria-level="3" value="@{primary_pool_action}" title="%{primary_pool}" type="roll">
</button>
<input class="input-label__input" name="attr_primary_pool" type="number" value="1" role="heading" aria-level="3" title="@{primary_pool}"/>
</div>
<button name="act_primary-pool-action" hidden="" type="action" title="%{primary-pool-action}">
</button>
<input name="attr_primary_pool_action" type="hidden" title="@{primary_pool_action}"/>
<input class="underlined" name="attr_primary_actions" type="text" title="@{primary_actions}"/>
</div>
<div class="statblock__row">
<div class="input-label input-label--button">
<button class="roller input-label__text" name="roll_secondary_pool" data-i18n="secondary pool" role="heading" aria-level="3" value="@{secondary_pool_action}" title="%{secondary_pool}" type="roll">
</button>
<input class="input-label__input" name="attr_secondary_pool" type="number" value="1" role="heading" aria-level="3" title="@{secondary_pool}"/>
</div>
<button name="act_secondary-pool-action" hidden="" type="action" title="%{secondary-pool-action}">
</button>
<input name="attr_secondary_pool_action" type="hidden" title="@{secondary_pool_action}"/>
<input class="underlined" name="attr_secondary_actions" type="text" title="@{secondary_actions}"/>
</div>
<div class="statblock__row">
<div class="input-label input-label--button">
<button class="roller input-label__text" name="roll_desperation_pool" data-i18n="desperation pool" role="heading" aria-level="3" value="@{desperation_pool_action}" title="%{desperation_pool}" type="roll">
</button>
<input class="input-label__input" name="attr_desperation_pool" type="number" value="1" role="heading" aria-level="3" title="@{desperation_pool}"/>
</div>
<button name="act_desperation-pool-action" hidden="" type="action" title="%{desperation-pool-action}">
</button>
<input name="attr_desperation_pool_action" type="hidden" title="@{desperation_pool_action}"/>
</div>
<div class="statblock__row statblock__row--auto-grid">
<label class="input-label"><span class="input-label__text" data-i18n="health" role="heading" aria-level="3"></span>
<input class="underlined input-label__input" name="attr_health" type="number" title="@{health}"/>
</label>
<label class="input-label"><span class="input-label__text" data-i18n="defense" role="heading" aria-level="3"></span>
<input class="underlined input-label__input" name="attr_defense" type="number" title="@{defense}"/>
</label>
<div class="input-label input-label--button">
<button class="roller input-label__text" name="roll_initiative" data-i18n="initiative" role="heading" aria-level="3" value="@{initiative_action}" title="%{initiative}" type="roll">
</button>
<input class="underlined input-label__input" name="attr_initiative" type="number" title="@{initiative}"/>
</div>
<button name="act_initiative-action" hidden="" type="action" title="%{initiative-action}">
</button>
<input name="attr_initiative_action" type="hidden" title="@{initiative_action}"/>
</div>
<div class="statblock__row statblock__row--inline-container">
<h3 data-i18n="qualities"></h3><span class="inline-fieldset" hidden=""></span>
<fieldset class="repeating_quality">
<input class="display-control" name="attr_display_state" value="short-display" hidden="" type="radio" title="@{repeating_quality_$X_display_state}"/>
<div class="inline-fieldset__summary display-target">
<label class="pointer">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_quality_$X_collapse}"/><span class="inline-fieldset__summary__text" name="attr_name" title="@{repeating_quality_$X_name}"></span>
</label>
</div>
<input class="display-control" name="attr_display_state" value="display" checked="" hidden="" type="radio" title="@{repeating_quality_$X_display_state}"/>
<div class="inline-fieldset__detail display-target">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_quality_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_quality_$X_collapse}"/>
</label>
<input class="underlined" name="attr_name" role="heading" aria-level="3" data-i18n-placeholder="quality name" type="text" title="@{repeating_quality_$X_name}"/>
<div class="statblock__row statblock__row--flex display-target">
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="cost" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_cost" title="@{repeating_quality_$X_cost}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_cost" type="text" title="@{repeating_quality_$X_cost}"/>
</div>
</label>
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="duration" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_duration" title="@{repeating_quality_$X_duration}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_duration" type="text" title="@{repeating_quality_$X_duration}"/>
</div>
</label>
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="subject" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_subject" title="@{repeating_quality_$X_subject}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_subject" type="text" title="@{repeating_quality_$X_subject}"/>
</div>
</label>
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="range" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_range" title="@{repeating_quality_$X_range}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_range" type="text" title="@{repeating_quality_$X_range}"/>
</div>
</label>
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="action" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_action" title="@{repeating_quality_$X_action}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_action" type="text" title="@{repeating_quality_$X_action}"/>
</div>
</label>
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="cooldown" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_cooldown" title="@{repeating_quality_$X_cooldown}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_cooldown" type="text" title="@{repeating_quality_$X_cooldown}"/>
</div>
</label>
</div>
<div class="adaptive adaptive--text"><span class="adaptive--text__span" name="attr_description" title="@{repeating_quality_$X_description}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_description" data-i18n-placeholder="qualities description" title="@{repeating_quality_$X_description}"></textarea>
</div>
</div>
</fieldset>
<button class="repcontrol-button repcontrol-button--add repcontrol-button--inline" name="act_add-quality" type="action" title="%{add-quality}">
</button>
<button class="repcontrol-button repcontrol-button--edit repcontrol-button--inline" name="act_edit-quality" type="action" title="%{edit-quality}">
</button>
</div>
<div class="statblock__row statblock__row--inline-container">
<h3 data-i18n="flairs"></h3><span class="inline-fieldset" hidden=""></span>
<fieldset class="repeating_flair">
<input class="display-control" name="attr_display_state" value="short-display" hidden="" type="radio" title="@{repeating_flair_$X_display_state}"/>
<div class="inline-fieldset__summary display-target">
<label class="pointer">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_flair_$X_collapse}"/><span class="inline-fieldset__summary__text" name="attr_name" title="@{repeating_flair_$X_name}"></span>
</label>
</div>
<input class="display-control" name="attr_display_state" value="display" checked="" hidden="" type="radio" title="@{repeating_flair_$X_display_state}"/>
<div class="inline-fieldset__detail display-target">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_flair_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_flair_$X_collapse}"/>
</label>
<input class="underlined" name="attr_name" role="heading" aria-level="3" data-i18n-placeholder="flair name" type="text" title="@{repeating_flair_$X_name}"/>
<div class="statblock__row statblock__row--flex display-target">
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="cost" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_cost" title="@{repeating_flair_$X_cost}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_cost" type="text" title="@{repeating_flair_$X_cost}"/>
</div>
</label>
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="duration" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_duration" title="@{repeating_flair_$X_duration}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_duration" type="text" title="@{repeating_flair_$X_duration}"/>
</div>
</label>
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="subject" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_subject" title="@{repeating_flair_$X_subject}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_subject" type="text" title="@{repeating_flair_$X_subject}"/>
</div>
</label>
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="range" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_range" title="@{repeating_flair_$X_range}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_range" type="text" title="@{repeating_flair_$X_range}"/>
</div>
</label>
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="action" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_action" title="@{repeating_flair_$X_action}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_action" type="text" title="@{repeating_flair_$X_action}"/>
</div>
</label>
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="cooldown" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_cooldown" title="@{repeating_flair_$X_cooldown}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_cooldown" type="text" title="@{repeating_flair_$X_cooldown}"/>
</div>
</label>
</div>
<div class="adaptive adaptive--text"><span class="adaptive--text__span" name="attr_description" title="@{repeating_flair_$X_description}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_description" data-i18n-placeholder="flairs description" title="@{repeating_flair_$X_description}"></textarea>
</div>
</div>
</fieldset>
<button class="repcontrol-button repcontrol-button--add repcontrol-button--inline" name="act_add-flair" type="action" title="%{add-flair}">
</button>
<button class="repcontrol-button repcontrol-button--edit repcontrol-button--inline" name="act_edit-flair" type="action" title="%{edit-flair}">
</button>
</div>
<div class="statblock__row statblock__row--inline-container">
<h3 data-i18n="extras"></h3><span class="inline-fieldset" hidden=""></span>
<fieldset class="repeating_extra">
<input class="display-control" name="attr_display_state" value="short-display" hidden="" type="radio" title="@{repeating_extra_$X_display_state}"/>
<div class="inline-fieldset__summary display-target">
<label class="pointer">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_extra_$X_collapse}"/><span class="inline-fieldset__summary__text" name="attr_name" title="@{repeating_extra_$X_name}"></span>
</label>
</div>
<input class="display-control" name="attr_display_state" value="display" checked="" hidden="" type="radio" title="@{repeating_extra_$X_display_state}"/>
<div class="inline-fieldset__detail display-target">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_extra_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_extra_$X_collapse}"/>
</label>
<input class="underlined" name="attr_name" role="heading" aria-level="3" data-i18n-placeholder="extra name" type="text" title="@{repeating_extra_$X_name}"/>
<div class="statblock__row statblock__row--flex display-target">
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="cost" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_cost" title="@{repeating_extra_$X_cost}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_cost" type="text" title="@{repeating_extra_$X_cost}"/>
</div>
</label>
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="duration" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_duration" title="@{repeating_extra_$X_duration}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_duration" type="text" title="@{repeating_extra_$X_duration}"/>
</div>
</label>
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="subject" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_subject" title="@{repeating_extra_$X_subject}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_subject" type="text" title="@{repeating_extra_$X_subject}"/>
</div>
</label>
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="range" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_range" title="@{repeating_extra_$X_range}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_range" type="text" title="@{repeating_extra_$X_range}"/>
</div>
</label>
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="action" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_action" title="@{repeating_extra_$X_action}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_action" type="text" title="@{repeating_extra_$X_action}"/>
</div>
</label>
<label class="input-label input-label--adaptive"><span class="input-label__text" data-i18n="cooldown" role="heading" aria-level="4"></span>
<div class="adaptive adaptive--input"><span class="adaptive--input__span" name="attr_cooldown" title="@{repeating_extra_$X_cooldown}"></span>
<input class="underlined input-label__input adaptive--input__input" name="attr_cooldown" type="text" title="@{repeating_extra_$X_cooldown}"/>
</div>
</label>
</div>
<div class="adaptive adaptive--text"><span class="adaptive--text__span" name="attr_description" title="@{repeating_extra_$X_description}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_description" data-i18n-placeholder="extras description" title="@{repeating_extra_$X_description}"></textarea>
</div>
</div>
</fieldset>
<button class="repcontrol-button repcontrol-button--add repcontrol-button--inline" name="act_add-extra" type="action" title="%{add-extra}">
</button>
<button class="repcontrol-button repcontrol-button--edit repcontrol-button--inline" name="act_edit-extra" type="action" title="%{edit-extra}">
</button>
</div>
<div class="statblock__row statblock__row--inline-container">
<h3 data-i18n="callings"></h3><span class="inline-fieldset" hidden=""></span>
<fieldset class="repeating_antagonist-calling">
<input class="display-control" name="attr_display_state" value="short-display" hidden="" type="radio" title="@{repeating_antagonist-calling_$X_display_state}"/>
<div class="inline-fieldset__summary display-target">
<label class="pointer">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_antagonist-calling_$X_collapse}"/><span name="attr_name" title="@{repeating_antagonist-calling_$X_name}"></span> <span class="inline-fieldset__summary__text" name="attr_rating" title="@{repeating_antagonist-calling_$X_rating}"></span>
</label>
</div>
<input class="display-control" name="attr_display_state" value="display" checked="" hidden="" type="radio" title="@{repeating_antagonist-calling_$X_display_state}"/>
<div class="inline-fieldset__detail display-target">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_antagonist-calling_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_antagonist-calling_$X_collapse}"/>
</label>
<div class="statblock__row statblock__row--auto-grid">
<input class="underlined" name="attr_name" role="heading" aria-level="3" data-i18n-placeholder="Calling name" type="text" title="@{repeating_antagonist-calling_$X_name}"/>
<input class="underlined" name="attr_rating" type="number" title="@{repeating_antagonist-calling_$X_rating}"/>
</div>
<div class="adaptive adaptive--text"><span class="adaptive--text__span" name="attr_description" title="@{repeating_antagonist-calling_$X_description}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_description" data-i18n-placeholder="Calling description" title="@{repeating_antagonist-calling_$X_description}"></textarea>
</div>
</div>
</fieldset>
<button class="repcontrol-button repcontrol-button--add repcontrol-button--inline" name="act_add-antagonist-calling" type="action" title="%{add-antagonist-calling}">
</button>
<button class="repcontrol-button repcontrol-button--edit repcontrol-button--inline" name="act_edit-antagonist-calling" type="action" title="%{edit-antagonist-calling}">
</button>
</div>
<div class="statblock__row statblock__row--inline-container">
<h3 data-i18n="purviews"></h3><span class="inline-fieldset" hidden=""></span>
<fieldset class="repeating_antagonist-purview">
<input class="display-control" name="attr_display_state" value="short-display" hidden="" type="radio" title="@{repeating_antagonist-purview_$X_display_state}"/>
<div class="inline-fieldset__summary display-target">
<label class="pointer">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_antagonist-purview_$X_collapse}"/><span class="inline-fieldset__summary__text" name="attr_name" title="@{repeating_antagonist-purview_$X_name}"></span>
</label>
</div>
<input class="display-control" name="attr_display_state" value="display" checked="" hidden="" type="radio" title="@{repeating_antagonist-purview_$X_display_state}"/>
<div class="inline-fieldset__detail display-target">
<input class="collapse-control" name="attr_collapse" value="0" type="hidden" title="@{repeating_antagonist-purview_$X_collapse}"/>
<label class="collapse-interface" data-i18n-title="collapse subsection">
<input name="attr_collapse" value="1" hidden="" type="checkbox" title="@{repeating_antagonist-purview_$X_collapse}"/>
</label>
<input class="underlined" name="attr_name" role="heading" aria-level="3" data-i18n-placeholder="Purview name" type="text" title="@{repeating_antagonist-purview_$X_name}"/>
<div class="adaptive adaptive--text"><span class="adaptive--text__span" name="attr_innate_power" title="@{repeating_antagonist-purview_$X_innate_power}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_innate_power" data-i18n-placeholder="Innate power" title="@{repeating_antagonist-purview_$X_innate_power}"></textarea>
</div>
<div class="adaptive adaptive--text"><span class="adaptive--text__span" name="attr_description" title="@{repeating_antagonist-purview_$X_description}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_description" data-i18n-placeholder="Purview description" title="@{repeating_antagonist-purview_$X_description}"></textarea>
</div>
</div>
</fieldset>
<button class="repcontrol-button repcontrol-button--add repcontrol-button--inline" name="act_add-antagonist-purview" type="action" title="%{add-antagonist-purview}">
</button>
<button class="repcontrol-button repcontrol-button--edit repcontrol-button--inline" name="act_edit-antagonist-purview" type="action" title="%{edit-antagonist-purview}">
</button>
</div>
</section>
</article>
<article class="navigable-section navigable-section--gm-screen gm-screen subsystem-style system-scion-origin statblock" id="gm-screen">
<section class="section-tension subsystem-style" id="tension">
<h2 class="subsystem-style scion-hero" data-i18n="tension">
</h2>
<div class="dot-row twelve-dots momentum-content boxes">
<select class="dot-number underlined" name="attr_tension" title="@{tension}">
<option value="0" selected="">0
</option>
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
<option value="6">6
</option>
<option value="7">7
</option>
<option value="8">8
</option>
<option value="9">9
</option>
<option value="10">10
</option>
<option value="11">11
</option>
<option value="12">12
</option>
</select>
<div class="dot-button-container">
<input class="clearer dot" name="attr_tension" checked="" value="0" type="radio" title="@{tension}"/>
<input class="dot" name="attr_tension" value="1" type="radio" title="@{tension}"/>
<input class="dot" name="attr_tension" value="2" type="radio" title="@{tension}"/>
<input class="dot" name="attr_tension" value="3" type="radio" title="@{tension}"/>
<input class="dot" name="attr_tension" value="4" type="radio" title="@{tension}"/>
<input class="dot" name="attr_tension" value="5" type="radio" title="@{tension}"/>
<input class="dot" name="attr_tension" value="6" type="radio" title="@{tension}"/>
<input class="dot" name="attr_tension" value="7" type="radio" title="@{tension}"/>
<input class="dot" name="attr_tension" value="8" type="radio" title="@{tension}"/>
<input class="dot" name="attr_tension" value="9" type="radio" title="@{tension}"/>
<input class="dot" name="attr_tension" value="10" type="radio" title="@{tension}"/>
<input class="dot" name="attr_tension" value="11" type="radio" title="@{tension}"/>
<input class="dot" name="attr_tension" value="12" type="radio" title="@{tension}"/>
</div>
</div>
</section>
</article>
<article class="navigable-section navigable-section--party-screen party-screen subsystem-style system-scion-origin statblock" id="party-screen">
<section class="section-party-momentum subsystem-style" id="party-momentum">
<h2 class="subsystem-style scion-hero" data-i18n="momentum">
</h2>
<div class="dot-row twelve-dots momentum-content boxes">
<select class="dot-number underlined" name="attr_party_momentum" title="@{party_momentum}">
<option value="0" selected="">0
</option>
<option value="1">1
</option>
<option value="2">2
</option>
<option value="3">3
</option>
<option value="4">4
</option>
<option value="5">5
</option>
<option value="6">6
</option>
<option value="7">7
</option>
<option value="8">8
</option>
<option value="9">9
</option>
<option value="10">10
</option>
<option value="11">11
</option>
<option value="12">12
</option>
</select>
<div class="dot-button-container">
<input class="clearer dot" name="attr_party_momentum" checked="" value="0" type="radio" title="@{party_momentum}"/>
<input class="dot" name="attr_party_momentum" value="1" type="radio" title="@{party_momentum}"/>
<input class="dot" name="attr_party_momentum" value="2" type="radio" title="@{party_momentum}"/>
<input class="dot" name="attr_party_momentum" value="3" type="radio" title="@{party_momentum}"/>
<input class="dot" name="attr_party_momentum" value="4" type="radio" title="@{party_momentum}"/>
<input class="dot" name="attr_party_momentum" value="5" type="radio" title="@{party_momentum}"/>
<input class="dot" name="attr_party_momentum" value="6" type="radio" title="@{party_momentum}"/>
<input class="dot" name="attr_party_momentum" value="7" type="radio" title="@{party_momentum}"/>
<input class="dot" name="attr_party_momentum" value="8" type="radio" title="@{party_momentum}"/>
<input class="dot" name="attr_party_momentum" value="9" type="radio" title="@{party_momentum}"/>
<input class="dot" name="attr_party_momentum" value="10" type="radio" title="@{party_momentum}"/>
<input class="dot" name="attr_party_momentum" value="11" type="radio" title="@{party_momentum}"/>
<input class="dot" name="attr_party_momentum" value="12" type="radio" title="@{party_momentum}"/>
</div>
</div>
</section>
<section class="section-party-notes" id="notes">
<h2 class="subsystem-style scion-hero" data-i18n="notes">
</h2>
<div class="adaptive adaptive--text"><span class="adaptive--text__span" name="attr_notes" title="@{notes}"></span>
<textarea class="underlined adaptive--text__textarea" name="attr_notes" title="@{notes}"></textarea>
</div>
</section>
</article>
</div>
<rolltemplate class="sheet-rolltemplate-storypath">{{#^rollBetween() computed::finished 0 0}}<span class="finished"></span>{{/^rollBetween() computed::finished 0 0}}
<div class="template storypath{{#continuation}} continuation{{/continuation}}{{#first}} first{{/first}} finished">
<div class="upper-blur"></div>
<div class="lower-blur"></div>
<div class="content">
<div class="header">{{#title}}
<h3 class="title">{{title}}</h3>{{/title}}{{#attribute}}
<h4>{{attribute}}</h4>{{/attribute}}{{#skill}}{{#attribute}}
<h4 class="amp">&</h4>{{/attribute}}
<h4>{{skill}}</h4>{{/skill}}{{^continuation}}{{#character_name}}{{#character_id}}
<h4 class="character_name">[{{character_name}}](http://journal.roll20.net/character/{{character_id}})</h4>{{/character_id}}{{^character_id}}
<h4 class="character_name">{{character_name}}</h4>{{/character_id}}{{/character_name}}{{/continuation}}
</div>{{#vs}}
<div class="tempalte-row vs">
<h5 data-i18n="opposed by"></h5><span>{{vs}}</span>
</div>{{/vs}}{{#display_dice}}
<div class="template-row results">{{^continuation}}
<h5 data-i18n="results"></h5>{{/continuation}}<span>{{roll_1}}</span><span>{{roll_2}}</span><span>{{roll_3}}</span><span>{{roll_4}}</span><span>{{roll_5}}</span><span>{{roll_6}}</span><span>{{roll_7}}</span><span>{{roll_8}}</span><span>{{roll_9}}</span><span>{{roll_10}}</span>
</div>{{/display_dice}}{{#^rollTotal() computed::finished 0}}{{#enhancements}}
<div class="template-row">
<h5 data-i18n="enhancements"></h5><span>{{enhancements}}</span>
</div>{{/enhancements}}{{#successes}}
<div class="template-row">
<h5 data-i18n="successes"></h5><span>{{computed::successes}}</span>
</div>{{/successes}}{{#difficulty}}
<div class="template-row">
<h5 data-i18n="difficulty"></h5><span>{{computed::difficulty}}</span>
</div>{{/difficulty}}{{#extra_successes}}
<div class="template-row">
<h5 data-i18n="extra successes"></h5><span>{{computed::extra_successes}}</span>
</div>{{/extra_successes}}{{#description}}
<div class="template-block">
<h5 data-i18n="description"></h5><span class="description">{{description}}</span>
</div>{{/description}}{{/^rollTotal() computed::finished 0}}
</div>
</div>
</rolltemplate>
<script type="text/worker">
const k = (function(){
const kFuncs = {};
const document = false;
const cascades = {"attr_character_name":{"name":"character_name","type":"text","defaultValue":"","affects":[],"triggeredFuncs":["setActionCalls"],"listenerFunc":"accessSheet","listener":"change:character_name"},"attr_template_start":{"name":"template_start","type":"hidden","defaultValue":"@{whisper}&{template:storypath} {{character_name=@{character_name}}} {{character_id=@{character_id}}} {{system=@{system}}}","triggeredFuncs":[],"affects":[]},"attr_sheet_state":{"name":"sheet_state","type":"hidden","defaultValue":"settings","triggeredFuncs":[],"affects":[]},"attr_collapsed":{"name":"collapsed","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_drop_name":{"listenerFunc":"handleCompendiumDrop","name":"drop_name","listener":"change:drop_name","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_drop_data":{"name":"drop_data","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"act_nav-all":{"triggeredFuncs":["navigateSheet"],"name":"nav-all","listener":"clicked:nav-all","listenerFunc":"accessSheet","type":"action"},"act_nav-general":{"triggeredFuncs":["navigateSheet"],"name":"nav-general","listener":"clicked:nav-general","listenerFunc":"accessSheet","type":"action"},"act_nav-powers":{"triggeredFuncs":["navigateSheet"],"name":"nav-powers","listener":"clicked:nav-powers","listenerFunc":"accessSheet","type":"action"},"act_nav-antagonist":{"triggeredFuncs":["navigateSheet"],"name":"nav-antagonist","listener":"clicked:nav-antagonist","listenerFunc":"accessSheet","type":"action"},"act_nav-gm_screen":{"triggeredFuncs":["navigateSheet"],"name":"nav-gm_screen","listener":"clicked:nav-gm_screen","listenerFunc":"accessSheet","type":"action"},"act_nav-party_screen":{"triggeredFuncs":["navigateSheet"],"name":"nav-party_screen","listener":"clicked:nav-party_screen","listenerFunc":"accessSheet","type":"action"},"act_nav-settings":{"triggeredFuncs":["navigateSheet"],"name":"nav-settings","listener":"clicked:nav-settings","listenerFunc":"accessSheet","type":"action"},"attr_system":{"triggeredFuncs":["setupSystem","clashBasis"],"name":"system","listener":"change:system","listenerFunc":"accessSheet","type":"select","defaultValue":"scion-origin","affects":[]},"attr_sheet_type":{"triggeredFuncs":["styleCharacterType"],"name":"sheet_type","listener":"change:sheet_type","listenerFunc":"accessSheet","type":"select","defaultValue":"character","affects":[]},"attr_target_number":{"name":"target_number","type":"number","defaultValue":"8","triggeredFuncs":[],"affects":[]},"attr_again":{"name":"again","type":"number","defaultValue":"10","triggeredFuncs":[],"affects":[]},"attr_difficulty_query":{"name":"difficulty_query","type":"select","defaultValue":"off","triggeredFuncs":[],"affects":[]},"attr_enhancement_query":{"name":"enhancement_query","type":"select","defaultValue":"off","triggeredFuncs":[],"affects":[]},"attr_whisper":{"name":"whisper","type":"select","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_player":{"name":"player","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_chronicle":{"name":"chronicle","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_parent":{"name":"parent","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"act_momentum":{"listenerFunc":"expandHeader","name":"momentum","listener":"clicked:momentum","type":"action"},"attr_momentum":{"name":"momentum","type":"select","defaultValue":0,"triggeredFuncs":[],"affects":[]},"attr_legend":{"name":"legend","type":"select","defaultValue":0,"triggeredFuncs":[],"affects":[]},"attr_legend_max":{"triggeredFuncs":[null],"name":"legend_max","listener":"change:legend_max","listenerFunc":"accessSheet","type":"select","defaultValue":0,"affects":[]},"act_virtue":{"listenerFunc":"expandHeader","name":"virtue","listener":"clicked:virtue","type":"action"},"attr_virtue_1":{"name":"virtue_1","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_virtue":{"name":"virtue","type":"select","defaultValue":-2,"triggeredFuncs":[],"affects":[]},"attr_virtue_2":{"name":"virtue_2","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"act_skills":{"listenerFunc":"expandHeader","name":"skills","listener":"clicked:skills","type":"action"},"attr_repeating_skill_$X_name":{"name":"repeating_skill_$X_name","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_skill_$X_path":{"name":"repeating_skill_$X_path","type":"checkbox","defaultValue":0,"triggeredFuncs":[],"affects":[]},"act_repeating_skill_$X_action":{"listenerFunc":"rollTask","name":"repeating_skill_$X_action","listener":"clicked:repeating_skill:action","type":"action"},"attr_repeating_skill_$X_action":{"name":"repeating_skill_$X_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_skill_$X_specialty":{"name":"repeating_skill_$X_specialty","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_skill_$X_rating":{"affects":["movement_dice"],"name":"repeating_skill_$X_rating","listener":"change:repeating_skill:rating","listenerFunc":"accessSheet","type":"select","defaultValue":0,"triggeredFuncs":[]},"act_attributes":{"listenerFunc":"expandHeader","name":"attributes","listener":"clicked:attributes","type":"action"},"act_intellect-action":{"listenerFunc":"rollTask","name":"intellect-action","listener":"clicked:intellect-action","type":"action"},"attr_intellect_action":{"name":"intellect_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_intellect":{"name":"intellect","type":"select","defaultValue":1,"triggeredFuncs":[],"affects":[]},"act_might-action":{"listenerFunc":"rollTask","name":"might-action","listener":"clicked:might-action","type":"action"},"attr_might_action":{"name":"might_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_might":{"affects":["movement_dice"],"name":"might","listener":"change:might","listenerFunc":"accessSheet","type":"select","defaultValue":1,"triggeredFuncs":[]},"act_presence-action":{"listenerFunc":"rollTask","name":"presence-action","listener":"clicked:presence-action","type":"action"},"attr_presence_action":{"name":"presence_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_presence":{"name":"presence","type":"select","defaultValue":1,"triggeredFuncs":[],"affects":[]},"act_cunning-action":{"listenerFunc":"rollTask","name":"cunning-action","listener":"clicked:cunning-action","type":"action"},"attr_cunning_action":{"name":"cunning_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_cunning":{"name":"cunning","type":"select","defaultValue":1,"triggeredFuncs":[],"affects":[]},"act_dexterity-action":{"listenerFunc":"rollTask","name":"dexterity-action","listener":"clicked:dexterity-action","type":"action"},"attr_dexterity_action":{"name":"dexterity_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_dexterity":{"affects":["movement_dice"],"name":"dexterity","listener":"change:dexterity","listenerFunc":"accessSheet","type":"select","defaultValue":1,"triggeredFuncs":[]},"act_manipulation-action":{"listenerFunc":"rollTask","name":"manipulation-action","listener":"clicked:manipulation-action","type":"action"},"attr_manipulation_action":{"name":"manipulation_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_manipulation":{"name":"manipulation","type":"select","defaultValue":1,"triggeredFuncs":[],"affects":[]},"act_resolve-action":{"listenerFunc":"rollTask","name":"resolve-action","listener":"clicked:resolve-action","type":"action"},"attr_resolve_action":{"name":"resolve_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_resolve":{"affects":["defense"],"name":"resolve","listener":"change:resolve","listenerFunc":"accessSheet","type":"select","defaultValue":1,"triggeredFuncs":[]},"act_stamina-action":{"listenerFunc":"rollTask","name":"stamina-action","listener":"clicked:stamina-action","type":"action"},"attr_stamina_action":{"name":"stamina_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_stamina":{"affects":["defense"],"name":"stamina","listener":"change:stamina","listenerFunc":"accessSheet","type":"select","defaultValue":1,"triggeredFuncs":[]},"act_composure-action":{"listenerFunc":"rollTask","name":"composure-action","listener":"clicked:composure-action","type":"action"},"attr_composure_action":{"name":"composure_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_composure":{"affects":["defense"],"name":"composure","listener":"change:composure","listenerFunc":"accessSheet","type":"select","defaultValue":1,"triggeredFuncs":[]},"act_health":{"listenerFunc":"expandHeader","name":"health","listener":"clicked:health","type":"action"},"act_add-injury":{"listenerFunc":"sectionInteract","name":"add-injury","listener":"clicked:add-injury","type":"action"},"act_edit-injury":{"listenerFunc":"sectionInteract","name":"edit-injury","listener":"clicked:edit-injury","type":"action"},"attr_movement_dice":{"calculation":"movementCalc","name":"movement_dice","type":"number","defaultValue":"1","triggeredFuncs":[],"affects":[]},"act_movement-dice-action":{"listenerFunc":"singleAttributeRoll","name":"movement-dice-action","listener":"clicked:movement-dice-action","type":"action"},"attr_movement_dice_action":{"name":"movement_dice_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_defense":{"calculation":"defenseCalc","name":"defense","type":"number","defaultValue":"1","triggeredFuncs":[],"affects":[]},"act_defense-action":{"listenerFunc":"singleAttributeRoll","name":"defense-action","listener":"clicked:defense-action","type":"action"},"attr_defense_action":{"name":"defense_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_injury_$X_display_state":{"name":"repeating_injury_$X_display_state","type":"hidden","defaultValue":"bruised","triggeredFuncs":[],"affects":[]},"attr_repeating_injury_$X_collapse":{"name":"repeating_injury_$X_collapse","type":"hidden","defaultValue":"0","triggeredFuncs":["collapseSection"],"affects":[],"listener":"change:repeating_injury:collapse","listenerFunc":"accessSheet"},"attr_repeating_injury_$X_affected":{"name":"repeating_injury_$X_affected","type":"checkbox","defaultValue":0,"triggeredFuncs":[],"affects":[]},"attr_repeating_injury_$X_type":{"name":"repeating_injury_$X_type","type":"select","defaultValue":"bruised","triggeredFuncs":[],"affects":[]},"attr_repeating_injury_$X_name":{"name":"repeating_injury_$X_name","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_injury_$X_effect":{"name":"repeating_injury_$X_effect","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"act_deeds":{"listenerFunc":"expandHeader","name":"deeds","listener":"clicked:deeds","type":"action"},"act_add-deed":{"listenerFunc":"sectionInteract","name":"add-deed","listener":"clicked:add-deed","type":"action"},"act_edit-deed":{"listenerFunc":"sectionInteract","name":"edit-deed","listener":"clicked:edit-deed","type":"action"},"attr_experience_used":{"affects":["experience_remaining"],"name":"experience_used","listener":"change:experience_used","listenerFunc":"accessSheet","type":"number","defaultValue":0,"triggeredFuncs":[]},"attr_experience_earned":{"affects":["experience_remaining"],"name":"experience_earned","listener":"change:experience_earned","listenerFunc":"accessSheet","type":"number","defaultValue":0,"triggeredFuncs":[]},"attr_experience_remaining":{"calculation":"calcXP","name":"experience_remaining","type":"number","defaultValue":0,"triggeredFuncs":[],"affects":[]},"fieldset_repeating_deed":{"triggeredFuncs":["deedDisplay"],"name":"repeating_deed","listener":"remove:repeating_deed","listenerFunc":"accessSheet","type":"fieldset"},"attr_repeating_deed_$X_type":{"name":"repeating_deed_$X_type","type":"select","defaultValue":"short","triggeredFuncs":[],"affects":[]},"attr_repeating_deed_$X_name":{"name":"repeating_deed_$X_name","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_deed_$X_completed":{"initialFunc":"orderDeeds","name":"repeating_deed_$X_completed","listener":"change:repeating_deed:completed","listenerFunc":"accessSheet","type":"checkbox","defaultValue":0,"triggeredFuncs":[],"affects":[]},"act_completed-deed":{"listenerFunc":"expandHeader","name":"completed-deed","listener":"clicked:completed-deed","type":"action"},"fieldset_repeating_completed-deed":{"triggeredFuncs":["deedDisplay"],"name":"repeating_completed-deed","listener":"remove:repeating_completed-deed","listenerFunc":"accessSheet","type":"fieldset"},"attr_repeating_completed-deed_$X_type":{"name":"repeating_completed-deed_$X_type","type":"select","defaultValue":"short","triggeredFuncs":[],"affects":[]},"attr_repeating_completed-deed_$X_name":{"name":"repeating_completed-deed_$X_name","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_completed-deed_$X_completed":{"initialFunc":"orderDeeds","name":"repeating_completed-deed_$X_completed","listener":"change:repeating_completed-deed:completed","listenerFunc":"accessSheet","type":"checkbox","defaultValue":0,"triggeredFuncs":[],"affects":[]},"act_paths":{"listenerFunc":"expandHeader","name":"paths","listener":"clicked:paths","type":"action"},"act_add-path":{"listenerFunc":"sectionInteract","name":"add-path","listener":"clicked:add-path","type":"action"},"act_edit-path":{"listenerFunc":"sectionInteract","name":"edit-path","listener":"clicked:edit-path","type":"action"},"fieldset_repeating_path":{"listener":"remove:repeating_path","listenerFunc":"clearChildItems","name":"repeating_path","type":"fieldset"},"attr_repeating_path_$X_display_state":{"name":"repeating_path_$X_display_state","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_path_$X_master_id":{"name":"repeating_path_$X_master_id","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_path_$X_collapse":{"name":"repeating_path_$X_collapse","type":"hidden","defaultValue":"0","triggeredFuncs":["collapseSection"],"affects":[],"listener":"change:repeating_path:collapse","listenerFunc":"accessSheet"},"attr_repeating_path_$X_type":{"name":"repeating_path_$X_type","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_path_$X_name":{"name":"repeating_path_$X_name","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_path_$X_status":{"name":"repeating_path_$X_status","type":"select","defaultValue":"available","triggeredFuncs":[],"affects":[]},"attr_repeating_path_$X_condition":{"name":"repeating_path_$X_condition","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_path_$X_skill":{"name":"repeating_path_$X_skill","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_path_$X_description":{"name":"repeating_path_$X_description","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_path_$X_tags":{"name":"repeating_path_$X_tags","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_path_$X_rating":{"name":"repeating_path_$X_rating","type":"select","defaultValue":0,"triggeredFuncs":[],"affects":[]},"attr_repeating_path_$X_group":{"name":"repeating_path_$X_group","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_path_$X_access":{"name":"repeating_path_$X_access","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_path_$X_obligation":{"name":"repeating_path_$X_obligation","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_path_$X_obligation_status":{"name":"repeating_path_$X_obligation_status","type":"select","defaultValue":"pending","triggeredFuncs":[],"affects":[]},"act_repeating_path_$X_add-contact":{"listenerFunc":"addSubsection","name":"repeating_path_$X_add-contact","listener":"clicked:repeating_path:add-contact","type":"action"},"act_repeating_path_$X_add-group":{"listenerFunc":"addSubsection","name":"repeating_path_$X_add-group","listener":"clicked:repeating_path:add-group","type":"action"},"act_repeating_path_$X_add-access":{"listenerFunc":"addSubsection","name":"repeating_path_$X_add-access","listener":"clicked:repeating_path:add-access","type":"action"},"act_repeating_path_$X_add-obligation":{"listenerFunc":"addSubsection","name":"repeating_path_$X_add-obligation","listener":"clicked:repeating_path:add-obligation","type":"action"},"act_calling":{"listenerFunc":"expandHeader","name":"calling","listener":"clicked:calling","type":"action"},"act_add-calling":{"listenerFunc":"sectionInteract","name":"add-calling","listener":"clicked:add-calling","type":"action"},"act_edit-calling":{"listenerFunc":"sectionInteract","name":"edit-calling","listener":"clicked:edit-calling","type":"action"},"fieldset_repeating_calling":{"listener":"remove:repeating_calling","listenerFunc":"clearChildItems","name":"repeating_calling","type":"fieldset"},"attr_repeating_calling_$X_level":{"name":"repeating_calling_$X_level","type":"hidden","defaultValue":"mortal","triggeredFuncs":[],"affects":[]},"attr_repeating_calling_$X_display_state":{"name":"repeating_calling_$X_display_state","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_calling_$X_master_id":{"name":"repeating_calling_$X_master_id","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_calling_$X_collapse":{"name":"repeating_calling_$X_collapse","type":"hidden","defaultValue":"0","triggeredFuncs":["collapseSection"],"affects":[],"listener":"change:repeating_calling:collapse","listenerFunc":"accessSheet"},"attr_repeating_calling_$X_rating":{"name":"repeating_calling_$X_rating","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_calling_$X_name":{"name":"repeating_calling_$X_name","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_calling_$X_rating_max":{"name":"repeating_calling_$X_rating_max","type":"select","defaultValue":1,"triggeredFuncs":[],"affects":[]},"act_repeating_calling_$X_clash-action":{"listenerFunc":"rollClash","name":"repeating_calling_$X_clash-action","listener":"clicked:repeating_calling:clash-action","type":"action"},"attr_repeating_calling_$X_clash_action":{"name":"repeating_calling_$X_clash_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_calling_$X_active":{"triggeredFuncs":["sumActiveCallings"],"name":"repeating_calling_$X_active","listener":"change:repeating_calling:active","listenerFunc":"accessSheet","type":"checkbox","defaultValue":0,"affects":[]},"attr_repeating_calling_$X_clash_stat_2":{"triggeredFuncs":["sumActiveCallings","clashBasis"],"name":"repeating_calling_$X_clash_stat_2","listener":"change:repeating_calling:clash_stat_2","listenerFunc":"accessSheet","type":"hidden","defaultValue":"rating","affects":[]},"attr_repeating_calling_$X_clash_stat_1":{"name":"repeating_calling_$X_clash_stat_1","type":"hidden","defaultValue":"select","triggeredFuncs":[],"affects":[]},"attr_repeating_calling_$X_description":{"name":"repeating_calling_$X_description","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"act_repeating_calling_$X_add-knack":{"listenerFunc":"addSubsection","name":"repeating_calling_$X_add-knack","listener":"clicked:repeating_calling:add-knack","type":"action"},"act_purview":{"listenerFunc":"expandHeader","name":"purview","listener":"clicked:purview","type":"action"},"act_add-purview":{"listenerFunc":"sectionInteract","name":"add-purview","listener":"clicked:add-purview","type":"action"},"act_edit-purview":{"listenerFunc":"sectionInteract","name":"edit-purview","listener":"clicked:edit-purview","type":"action"},"fieldset_repeating_purview":{"listener":"remove:repeating_purview","listenerFunc":"clearChildItems","name":"repeating_purview","type":"fieldset"},"attr_repeating_purview_$X_display_state":{"name":"repeating_purview_$X_display_state","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_purview_$X_master_id":{"name":"repeating_purview_$X_master_id","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_purview_$X_collapse":{"name":"repeating_purview_$X_collapse","type":"hidden","defaultValue":"0","triggeredFuncs":["collapseSection"],"affects":[],"listener":"change:repeating_purview:collapse","listenerFunc":"accessSheet"},"attr_repeating_purview_$X_name":{"name":"repeating_purview_$X_name","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_purview_$X_innate_power":{"name":"repeating_purview_$X_innate_power","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_purview_$X_description":{"name":"repeating_purview_$X_description","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_purview_$X_cost":{"name":"repeating_purview_$X_cost","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_purview_$X_duration":{"name":"repeating_purview_$X_duration","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_purview_$X_subject":{"name":"repeating_purview_$X_subject","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_purview_$X_range":{"name":"repeating_purview_$X_range","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_purview_$X_action":{"name":"repeating_purview_$X_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_purview_$X_clash_stat_1":{"name":"repeating_purview_$X_clash_stat_1","type":"hidden","defaultValue":"select","triggeredFuncs":[],"affects":[]},"attr_repeating_purview_$X_clash_stat_2":{"name":"repeating_purview_$X_clash_stat_2","type":"hidden","defaultValue":"select","triggeredFuncs":[],"affects":[]},"act_repeating_purview_$X_clash-action":{"listenerFunc":"rollClash","name":"repeating_purview_$X_clash-action","listener":"clicked:repeating_purview:clash-action","type":"action"},"attr_repeating_purview_$X_clash_action":{"name":"repeating_purview_$X_clash_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_purview_$X_clash_defense_1":{"name":"repeating_purview_$X_clash_defense_1","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_purview_$X_clash_defense_2":{"name":"repeating_purview_$X_clash_defense_2","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"act_repeating_purview_$X_add-boon":{"listenerFunc":"addSubsection","name":"repeating_purview_$X_add-boon","listener":"clicked:repeating_purview:add-boon","type":"action"},"act_birthrights":{"listenerFunc":"expandHeader","name":"birthrights","listener":"clicked:birthrights","type":"action"},"act_edit-birthright":{"listenerFunc":"sectionInteract","name":"edit-birthright","listener":"clicked:edit-birthright","type":"action"},"attr_legendary_title":{"name":"legendary_title","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_display_state":{"name":"repeating_birthright_$X_display_state","type":"radio","defaultValue":"short-relic","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_collapse":{"name":"repeating_birthright_$X_collapse","type":"hidden","defaultValue":"0","triggeredFuncs":["collapseSection"],"affects":[],"listener":"change:repeating_birthright:collapse","listenerFunc":"accessSheet"},"attr_repeating_birthright_$X_name":{"name":"repeating_birthright_$X_name","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_rating":{"name":"repeating_birthright_$X_rating","type":"select","defaultValue":0,"triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_variety":{"name":"repeating_birthright_$X_variety","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_tag":{"name":"repeating_birthright_$X_tag","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_deed":{"name":"repeating_birthright_$X_deed","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_purview":{"name":"repeating_birthright_$X_purview","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_motif":{"name":"repeating_birthright_$X_motif","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_enhancement":{"name":"repeating_birthright_$X_enhancement","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_knack":{"name":"repeating_birthright_$X_knack","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_flaw":{"name":"repeating_birthright_$X_flaw","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_skills":{"name":"repeating_birthright_$X_skills","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_benefit":{"name":"repeating_birthright_$X_benefit","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_stunt":{"name":"repeating_birthright_$X_stunt","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_calling":{"name":"repeating_birthright_$X_calling","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_title":{"name":"repeating_birthright_$X_title","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_birthright_$X_archetype":{"name":"repeating_birthright_$X_archetype","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"act_add-birthright-creature":{"listenerFunc":"addSubsection","name":"add-birthright-creature","listener":"clicked:add-birthright-creature","type":"action"},"act_add-birthright-follower":{"listenerFunc":"addSubsection","name":"add-birthright-follower","listener":"clicked:add-birthright-follower","type":"action"},"act_add-birthright-guide":{"listenerFunc":"addSubsection","name":"add-birthright-guide","listener":"clicked:add-birthright-guide","type":"action"},"act_add-birthright-relic":{"listenerFunc":"addSubsection","name":"add-birthright-relic","listener":"clicked:add-birthright-relic","type":"action"},"act_equipment":{"listenerFunc":"expandHeader","name":"equipment","listener":"clicked:equipment","type":"action"},"act_add-equipment":{"listenerFunc":"sectionInteract","name":"add-equipment","listener":"clicked:add-equipment","type":"action"},"act_edit-equipment":{"listenerFunc":"sectionInteract","name":"edit-equipment","listener":"clicked:edit-equipment","type":"action"},"attr_repeating_equipment_$X_display_state":{"name":"repeating_equipment_$X_display_state","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_equipment_$X_collapse":{"name":"repeating_equipment_$X_collapse","type":"hidden","defaultValue":"0","triggeredFuncs":["collapseSection"],"affects":[],"listener":"change:repeating_equipment:collapse","listenerFunc":"accessSheet"},"attr_repeating_equipment_$X_name":{"name":"repeating_equipment_$X_name","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_equipment_$X_tag":{"name":"repeating_equipment_$X_tag","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_equipment_$X_description":{"name":"repeating_equipment_$X_description","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"act_notes":{"listenerFunc":"expandHeader","name":"notes","listener":"clicked:notes","type":"action"},"attr_notes":{"name":"notes","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_archetype_symbol":{"name":"archetype_symbol","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_archetype":{"name":"archetype","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_drive":{"name":"drive","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_primary_pool":{"name":"primary_pool","type":"number","defaultValue":1,"triggeredFuncs":[],"affects":[]},"act_primary-pool-action":{"listenerFunc":"singleAttributeRoll","name":"primary-pool-action","listener":"clicked:primary-pool-action","type":"action"},"attr_primary_pool_action":{"name":"primary_pool_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_primary_actions":{"name":"primary_actions","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_secondary_pool":{"name":"secondary_pool","type":"number","defaultValue":1,"triggeredFuncs":[],"affects":[]},"act_secondary-pool-action":{"listenerFunc":"singleAttributeRoll","name":"secondary-pool-action","listener":"clicked:secondary-pool-action","type":"action"},"attr_secondary_pool_action":{"name":"secondary_pool_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_secondary_actions":{"name":"secondary_actions","type":"text","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_desperation_pool":{"name":"desperation_pool","type":"number","defaultValue":1,"triggeredFuncs":[],"affects":[]},"act_desperation-pool-action":{"listenerFunc":"singleAttributeRoll","name":"desperation-pool-action","listener":"clicked:desperation-pool-action","type":"action"},"attr_desperation_pool_action":{"name":"desperation_pool_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_health":{"name":"health","type":"number","defaultValue":0,"triggeredFuncs":[],"affects":[]},"attr_initiative":{"name":"initiative","type":"number","defaultValue":0,"triggeredFuncs":[],"affects":[]},"act_initiative-action":{"listenerFunc":"singleAttributeRoll","name":"initiative-action","listener":"clicked:initiative-action","type":"action"},"attr_initiative_action":{"name":"initiative_action","type":"hidden","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_quality_$X_display_state":{"name":"repeating_quality_$X_display_state","type":"radio","defaultValue":"short-display","triggeredFuncs":[],"affects":[]},"attr_repeating_quality_$X_collapse":{"triggeredFuncs":["collapseSection"],"name":"repeating_quality_$X_collapse","listener":"change:repeating_quality:collapse","listenerFunc":"accessSheet","type":"checkbox","defaultValue":0,"affects":[]},"attr_repeating_quality_$X_name":{"name":"repeating_quality_$X_name","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_quality_$X_cost":{"name":"repeating_quality_$X_cost","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_quality_$X_duration":{"name":"repeating_quality_$X_duration","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_quality_$X_subject":{"name":"repeating_quality_$X_subject","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_quality_$X_range":{"name":"repeating_quality_$X_range","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_quality_$X_action":{"name":"repeating_quality_$X_action","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_quality_$X_cooldown":{"name":"repeating_quality_$X_cooldown","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_quality_$X_description":{"name":"repeating_quality_$X_description","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"act_add-quality":{"listenerFunc":"sectionInteract","name":"add-quality","listener":"clicked:add-quality","type":"action"},"act_edit-quality":{"listenerFunc":"sectionInteract","name":"edit-quality","listener":"clicked:edit-quality","type":"action"},"attr_repeating_flair_$X_display_state":{"name":"repeating_flair_$X_display_state","type":"radio","defaultValue":"short-display","triggeredFuncs":[],"affects":[]},"attr_repeating_flair_$X_collapse":{"triggeredFuncs":["collapseSection"],"name":"repeating_flair_$X_collapse","listener":"change:repeating_flair:collapse","listenerFunc":"accessSheet","type":"checkbox","defaultValue":0,"affects":[]},"attr_repeating_flair_$X_name":{"name":"repeating_flair_$X_name","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_flair_$X_cost":{"name":"repeating_flair_$X_cost","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_flair_$X_duration":{"name":"repeating_flair_$X_duration","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_flair_$X_subject":{"name":"repeating_flair_$X_subject","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_flair_$X_range":{"name":"repeating_flair_$X_range","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_flair_$X_action":{"name":"repeating_flair_$X_action","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_flair_$X_cooldown":{"name":"repeating_flair_$X_cooldown","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_flair_$X_description":{"name":"repeating_flair_$X_description","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"act_add-flair":{"listenerFunc":"sectionInteract","name":"add-flair","listener":"clicked:add-flair","type":"action"},"act_edit-flair":{"listenerFunc":"sectionInteract","name":"edit-flair","listener":"clicked:edit-flair","type":"action"},"attr_repeating_extra_$X_display_state":{"name":"repeating_extra_$X_display_state","type":"radio","defaultValue":"short-display","triggeredFuncs":[],"affects":[]},"attr_repeating_extra_$X_collapse":{"triggeredFuncs":["collapseSection"],"name":"repeating_extra_$X_collapse","listener":"change:repeating_extra:collapse","listenerFunc":"accessSheet","type":"checkbox","defaultValue":0,"affects":[]},"attr_repeating_extra_$X_name":{"name":"repeating_extra_$X_name","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_extra_$X_cost":{"name":"repeating_extra_$X_cost","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_extra_$X_duration":{"name":"repeating_extra_$X_duration","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_extra_$X_subject":{"name":"repeating_extra_$X_subject","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_extra_$X_range":{"name":"repeating_extra_$X_range","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_extra_$X_action":{"name":"repeating_extra_$X_action","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_extra_$X_cooldown":{"name":"repeating_extra_$X_cooldown","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_extra_$X_description":{"name":"repeating_extra_$X_description","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"act_add-extra":{"listenerFunc":"sectionInteract","name":"add-extra","listener":"clicked:add-extra","type":"action"},"act_edit-extra":{"listenerFunc":"sectionInteract","name":"edit-extra","listener":"clicked:edit-extra","type":"action"},"attr_repeating_antagonist-calling_$X_display_state":{"name":"repeating_antagonist-calling_$X_display_state","type":"radio","defaultValue":"short-display","triggeredFuncs":[],"affects":[]},"attr_repeating_antagonist-calling_$X_collapse":{"triggeredFuncs":["collapseSection"],"name":"repeating_antagonist-calling_$X_collapse","listener":"change:repeating_antagonist-calling:collapse","listenerFunc":"accessSheet","type":"checkbox","defaultValue":0,"affects":[]},"attr_repeating_antagonist-calling_$X_name":{"name":"repeating_antagonist-calling_$X_name","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_antagonist-calling_$X_rating":{"name":"repeating_antagonist-calling_$X_rating","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_antagonist-calling_$X_description":{"name":"repeating_antagonist-calling_$X_description","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"act_add-antagonist-calling":{"listenerFunc":"sectionInteract","name":"add-antagonist-calling","listener":"clicked:add-antagonist-calling","type":"action"},"act_edit-antagonist-calling":{"listenerFunc":"sectionInteract","name":"edit-antagonist-calling","listener":"clicked:edit-antagonist-calling","type":"action"},"attr_repeating_antagonist-purview_$X_display_state":{"name":"repeating_antagonist-purview_$X_display_state","type":"radio","defaultValue":"short-display","triggeredFuncs":[],"affects":[]},"attr_repeating_antagonist-purview_$X_collapse":{"triggeredFuncs":["collapseSection"],"name":"repeating_antagonist-purview_$X_collapse","listener":"change:repeating_antagonist-purview:collapse","listenerFunc":"accessSheet","type":"checkbox","defaultValue":0,"affects":[]},"attr_repeating_antagonist-purview_$X_name":{"name":"repeating_antagonist-purview_$X_name","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_antagonist-purview_$X_innate_power":{"name":"repeating_antagonist-purview_$X_innate_power","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"attr_repeating_antagonist-purview_$X_description":{"name":"repeating_antagonist-purview_$X_description","type":"span","defaultValue":"","triggeredFuncs":[],"affects":[]},"act_add-antagonist-purview":{"listenerFunc":"sectionInteract","name":"add-antagonist-purview","listener":"clicked:add-antagonist-purview","type":"action"},"act_edit-antagonist-purview":{"listenerFunc":"sectionInteract","name":"edit-antagonist-purview","listener":"clicked:edit-antagonist-purview","type":"action"},"attr_tension":{"name":"tension","type":"select","defaultValue":0,"triggeredFuncs":[],"affects":[]},"attr_party_momentum":{"name":"party_momentum","type":"select","defaultValue":0,"triggeredFuncs":[],"affects":[]}};
kFuncs.cascades = cascades;
const repeatingSectionDetails = [{"section":"repeating_skill","fields":["name","path","action","specialty","rating"]},{"section":"repeating_injury","fields":["display_state","collapse","affected","type","name","effect"]},{"section":"repeating_deed","fields":["type","name","completed"]},{"section":"repeating_completed-deed","fields":["type","name","completed"]},{"section":"repeating_path","fields":["display_state","master_id","collapse","type","name","status","condition","skill","description","tags","rating","group","access","obligation","obligation_status"]},{"section":"repeating_calling","fields":["level","display_state","master_id","collapse","rating","name","rating_max","clash_action","active","clash_stat_2","clash_stat_1","description"]},{"section":"repeating_purview","fields":["display_state","master_id","collapse","name","innate_power","description","cost","duration","subject","range","action","clash_stat_1","clash_stat_2","clash_action","clash_defense_1","clash_defense_2"]},{"section":"repeating_birthright","fields":["display_state","collapse","name","rating","variety","tag","deed","purview","motif","enhancement","knack","flaw","skills","benefit","stunt","calling","title","archetype"]},{"section":"repeating_equipment","fields":["display_state","collapse","name","tag","description"]},{"section":"repeating_quality","fields":["display_state","collapse","name","cost","duration","subject","range","action","cooldown","description"]},{"section":"repeating_flair","fields":["display_state","collapse","name","cost","duration","subject","range","action","cooldown","description"]},{"section":"repeating_extra","fields":["display_state","collapse","name","cost","duration","subject","range","action","cooldown","description"]},{"section":"repeating_antagonist-calling","fields":["display_state","collapse","name","rating","description"]},{"section":"repeating_antagonist-purview","fields":["display_state","collapse","name","innate_power","description"]}];
kFuncs.repeatingSectionDetails = repeatingSectionDetails;
const docs = {"js":{},"pug":{"trigger":{"type":"argument","description":"Many of the K-scaffold's mixins utilize the scaffold's trigger system. Triggers can be passed in any mixin that creates an attribute backed element, which is any element that you would give the `name` property to. The trigger is passed as a property of the object that defines the attribute backed element. See the [input mixin](#input) below for a simple example.\nTriggers are how the K-scaffold connects the attributes created in the html of the sheet with the javscript listeners to trigger sheetworker code. When accessed from a sheetworker, a trigger has all of the below properties. When passing a trigger into a mixin, it should only have any or all of the first four properties; `affects`,`initialFunc`, `calculation`, `triggeredFuncs`, and `listenerFunc`. Note that except for `listenerFunc`, the function that is called is passed arguments using the [destructuring assignment pattern](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment). This means that the functions referenced in ,`initialFunc`, `calculation`, and `triggeredFuncs` must be passed in an object associated with a key named as indicated in the arguments below.","arguments":[{"type":"Array","name":"affects","description":"An array of attribute names that this attribute might affect. As an example, the `strength` attribute in a 5e based sheet would have `strength_mod` in its affects array."},{"type":"string","name":"initialFunc","description":"The name of a function that has been registered with the K-scaffold using [k.registerFuncs](https://github.com/Kurohyou/Roll20-Snippets/blob/main/K_Scaffold/readme_docs/k_scaffold_js_documentation.md#registerFuncs). This function will only be called if the change to the attribute is directly caused by the user as opposed to being changed by the sheetworkers.\nThe K-scaffold sends this function the following arguments:\n- `trigger`: The trigger object for the attribute that is being changed\n- `attributes`: the attributes object containing the entire state of the sheet.\n- `sections`: An object containing the row IDs of all the repeating sections, indexed by section name (e.g. repeating_equipment)."},{"type":"string","name":"calculation","description":"The name of a function that has been registered with the K-scaffold using [k.registerFuncs](https://github.com/Kurohyou/Roll20-Snippets/blob/main/K_Scaffold/readme_docs/k_scaffold_js_documentation.md#registerFuncs). This function must return the calculated value of the attribute it is for, and is only called if the attribute is not changed directly by the user. Ideally, this function should be written as a pure function, reacting only to the arguments it is passed, and returning a value without modifying any of the arguments it is passed.\nThe K-scaffold sends this function the following arguments:\n- `trigger`: The trigger object for the attribute that is being changed\n- `attributes`: the attributes object containing the entire state of the sheet.\n- `sections`: An object containing the row IDs of all the repeating sections, indexed by section name (e.g. repeating_equipment)."},{"type":"Array","name":"triggeredFuncs","description":"An array of function names that have been registered with the K-scaffold using [k.registerFuncs](https://github.com/Kurohyou/Roll20-Snippets/blob/main/K_Scaffold/readme_docs/k_scaffold_js_documentation.md#registerFuncs). These functions are called any time an attribute is changed, regardless of the source of the change, do not return any values, and will likely modify the arguments that are passed to them. These functions are used for doing complex logic to determine what should be done in response to a change.\nThe K-scaffold sends these functions the following arguments:\n- `trigger`: The trigger object for the attribute that is being changed\n- `attributes`: the attributes object containing the entire state of the sheet.\n- `sections`: An object containing the row IDs of all the repeating sections, indexed by section name (e.g. repeating_equipment), and in the order that they appear on the sheet."},{"type":"string","name":"listenerFunc","description":"The name of a function that has been registered with the K-scaffold using [k.registerFuncs](https://github.com/Kurohyou/Roll20-Snippets/blob/main/K_Scaffold/readme_docs/k_scaffold_js_documentation.md#registerFuncs). This function will be called directly from the event listener for this attribute instead of the default [accessSheet](https://github.com/Kurohyou/Roll20-Snippets/blob/main/K_Scaffold/readme_docs/k_scaffold_js_documentation.md#accesssheet) listener function. If a `listenerFunc` is specified, the automated handling of the rest of the previous trigger properties will be disabled. You can still use these properties, but will need to code that handling yourself.\nThe K-scaffold sends this function the following argument:\n- `event`: The event information object that is passed to the callback in the [sheet worker event listener](https://wiki.roll20.net/Sheet_Worker_Scripts#Event_listener). This is **NOT** passed using the object destructuring pattern, unlike the previous three function types."},{"type":"string","name":"name","description":"The name of the attribute. When accessed from inside the default function cascade of the K-scaffold, or the callback of [getAllAttrs](https://github.com/Kurohyou/Roll20-Snippets/blob/main/K_Scaffold/readme_docs/k_scaffold_js_documentation.md#getAllAttrs), repeating attributes will include their specific row id for that instance of the attribute."},{"type":"string","name":"type","description":"What type of attribute is this. This is determined by the type of element that first created the trigger. Can be `text`,`number`,`checkbox`,`select`,or `radio`, but will usually be `text` or `number` based on the type of default value that is assigned to the attribute."},{"type":"string|number","name":"defaultValue","description":"What the default value of the attribute is. The k-scaffold uses this to return the default value in the event the value of the attribute becomes corrupted. For checkboxes and radios, this is determined based on the check state of the element. For selects, this is determined by which option has the `selected` property."}]},"input":{"type":"mixin","description":"A generic mixin to create an input. The mixin will replace spaces in the attribute name with underscores and will add a title property if one isn't supplied that will inform the user what the attribute call for the attribute is.","arguments":[{"type":"object","name":"obj","description":"An object containing all of the properties to apply to the element. Must have the properties; `name` and `type`. Can have any property that is valid for an input element. May also have a [trigger](#trigger) property"},{"type":"string","name":"obj.name"}],"example":[["+input({name:'my attribute',type:'text',class:'some-class',trigger:{affects:['other_attribute']}})'","<input name=\"attr_my_attribute\" type=\"text\" class=\"some-class\">'"]]},"text":{"type":"mixin","description":"Alias for [input](#input) that makes a text input.","example":[["+text({name:'my text',class:'some-class',trigger:{affects:['other_attribute']}})","<input type=\"text\" name=\"attr_my_text\" class=\"some-class\">"]]},"checkbox":{"type":"mixin","description":"Alias for [input](#input) that makes a checkbox input.","example":[["+checkbox({name:'my checkbox',class:'some-class',trigger:{affects:['other_attribute']}})","<input type=\"checkbox\" name=\"attr_my_checkbox\" class=\"some-class\">"]]},"collapse":{"type":"mixin","description":"Alias for [checkbox](#checkbox) that creates a checkbox for use in collapsing/expanding a section. Sets the checkbox to unchecked with a checked value of `1` and a class of `collapse`. Additional classes/ids can be applied by applying them inline to the mixin call.","arguments":[{"type":"string","name":"name","description":"The name to assign to the collapse button. Defaults to `collapse`"}]},"radio":{"type":"mixin","description":"Alias for [input](#input) that makes a radio input.","example":[["+radio({name:'my radio',class:'some-class',trigger:{affects:['other_attribute']}})","<input type=\"radio\" name=\"attr_my_radio\" class=\"some-class\">"]]},"number":{"type":"mixin","description":"Alias for [input](#input) that makes a number input.","example":[["+number({name:'my number',class:'some-class',trigger:{affects:['other_attribute']}})","<input type=\"number\" name=\"attr_my_number\" class=\"some-class\">"]]},"range":{"type":"mixin","description":"Alias for [input](#input) that makes a range input.","example":[["+range({name:'my range',class:'some-class',trigger:{affects:['other_attribute']}})","<input type=\"range\" name=\"attr_my_range\" class=\"some-class\">"]]},"hidden":{"type":"mixin","description":"Alias for [input](#input) that makes a hidden input.","example":[["+hidden({name:'my hidden',class:'some-class',trigger:{affects:['other_attribute']}})","<input type=\"hidden\" name=\"attr_my_hidden\" class=\"some-class\">"]]},"fillLeft":{"type":"mixin","description":"A mixin that creates a construction that can be used to recreate sheet mechanics that fill to the left. Will apply BEM style classes in addition to the classes specified. BEM classes that can be applied are\n - `fill-left`: The class for the fill-left container.\n - `fill-left__radio`: The class applied to all the radio buttons in the container\n - `fill-left__radio--clearer`: The class applied to the clear value radio button","arguments":[{"type":"object","name":"radioObj","description":"The object containing the details of the radio input to create. Similar to the [radio mixin](#radio), but the value property passed is used as the default checked value."},{"type":"object","name":"divObj","description":"Optional object containing any details of the div to be applied such as class, id, or other properties. Class and ID can also be supplied by attaching them to the mixin invocation just like with a regular div."},{"type":"array","name":"valueArray","description":"Array containing the values to be used for the fill to left construction. These should be in the order that they should be displayed left to right."},{"name":"noClear","type":"boolean","description":"Optional argument that tells the mixin whether or not to apply the `fill-left__radio--clearer` class to the first radio button value. If falsy (or not passed), the class is applied. If truthy, the class is not applied."}],"example":[["+fillLeft({radioObj:{name:'track',class:'some-class',value:\"0\"},valueArray:[0,1,2]})","<div class=\"fill-left\">\n <input type=\"radio\" name=\"attr_track\" class=\"some-class fill-left__radio fill-left__radio--clearer\" value=\"0\" checked>\n <input type=\"radio\" name=\"attr_track\" class=\"some-class fill-left__radio\" value=\"1\">\n <input type=\"radio\" name=\"attr_track\" class=\"some-class fill-left__radio\" value=\"2\">\n</div>"],["+fillLeft({radioObj:{name:'track',class:'some-class',value:\"0\"},valueArray:[0,1,2],noClear:true})","<div class=\"fill-left\">\n <input type=\"radio\" name=\"attr_track\" class=\"some-class fill-left__radio\" value=\"0\" checked>\n <input type=\"radio\" name=\"attr_track\" class=\"some-class fill-left__radio\" value=\"1\">\n <input type=\"radio\" name=\"attr_track\" class=\"some-class fill-left__radio\" value=\"2\">\n</div>"],["+fillLeft({radioObj:{name:'track',class:'some-class',value:\"0\"},valueArray:[0,1,2],divObj:{'aria-label':'Accessible tracker'}}).custom-tracker-class","<div class=\"fill-left custom-tracker-class\" aria-label:\"Accessible tracker\">\n <input type=\"radio\" name=\"attr_track\" class=\"some-class fill-left__radio fill-left__radio--clearer\" value=\"0\" checked>\n <input type=\"radio\" name=\"attr_track\" class=\"some-class fill-left__radio\" value=\"1\">\n <input type=\"radio\" name=\"attr_track\" class=\"some-class fill-left__radio\" value=\"2\">\n</div>"]]},"textarea":{"type":"mixin","description":"Functions like [input](#input), but creates a textarea instead.","example":[["+textarea({name:'my hidden',class:'some-class',placeholder:'Placeholder text',trigger:{affects:['other_attribute']}})","<textarea type=\"hidden\" name=\"attr_my_hidden\" class=\"some-class\">Placeholder text</textarea>"]]},"option":{"type":"mixin","description":"Creates an option attribute. Also stores the trigger for the select that the option is part of. See [select](#select) for example uses."},"select":{"type":"mixin","description":"Functions like [input](#input), but creates a select instead.","example":[["+select({name:'my select',class:'some-class'})\n +option({value:'option 1','data-i18n':'some-text',trigger:{affects:['some-attribute']}})\n +option({value:'option 2','data-i18n':'other-text'})","<select name=\"attr_my_select\" class=\"some-class\">\n <option value=\"option 1\" data-i18n=\"some-text\"></option>\n <option value=\"option 2\" data-i18n=\"other-text\"></option>\n</select>"]]},"img":{"type":"mixin","description":"Functions like [input](#input), but creates a span instead. The name property is optional.","example":[["+span({name:'my span',class:'some-class'})","<span name=\"attr_my_span\" class=\"some-class\"></span>"]]},"datalist":{"type":"mixin","description":"Functions like [input](#input), but creates a datalist instead. Note that an ID should never be put inside a repeating section, although you can reference one from inside the repeating section.","example":[["+select({name:'my select',list:'my-data'})\n+datalist({id:'my-data'})\n +option({value:'option 1','data-i18n':'some-text',trigger:{affects:['some-attribute']}})\n +option({value:'option 2','data-i18n':'other-text'})","<select name=\"attr_my_select\" class=\"some-class\"></select><datalist id=\"my-data\">\n <option value=\"option 1\" data-i18n=\"some-text\"></option>\n <option value=\"option 2\" data-i18n=\"other-text\"></option>\n</datalist>"]]},"button":{"type":"mixin","description":"Creates a button element. Valid types are `roll` or `action`. If a type is not specified in the object argument, a roll button is created. If an action button is created, spaces in the name are replaced with dashes instead of underscores.","example":[["+button({name:'my button',value:'/r 3d10'})","<button type=\"roll\" name=\"roll_my_button\" value=\"/r 3d10\"></button>"],["+button({name:'my button',type:'action','data-i18n':'action button'})","<button type=\"action\" name=\"act_my-button\" data-i18n=\"action button\"></button>"]]},"action":{"type":"mixin","description":"Alias for [button](#button) that creates a button element with a type of `action`. Spaces in the name are replaced with dashes instead of underscores.","example":[["+action({name:'my button','data-i18n':'action button'})","<button type=\"action\" name=\"act_my-button\" data-i18n=\"action button\"></button>"]]},"navButton":{"type":"mixin","description":"Alias for [button](#button) that creates a combination roll button and action button element to get around the limitation that action buttons cannot be dragged to the macro quickbar. Requires sheetworker infrastructure to work, which should be triggered `on(sheet:opened)` and `on(\"change:character_name\")`.","example":[["+roller({name:'my roll'})","<button type=\"roll\" name=\"roll_my_roll\" value=\"@{my_roll_action}\"></button>\n<button type=\"action\" name=\"act_my-roll-action\" hidden></button>\n<input type=\"hidden\" name=\"attr_my_roll_action\" value=\"\">"]]},"customControlFieldset":{"type":"mixin","description":"Alias for [fieldset](#fieldset) that creates to custom action buttons to add/remove rows to the repeating section. Useful when you need to trigger a sheetworker when a row is added. This also prevents the occassional error of a new row disappearing immediately after the user has clicked the button to create one. Proper use of this will require css to hide the default buttons that fieldsets create automatically. Note that currently this assumes the existence of an addItem and editSection sheetworker function.","arguments":[{"name":"name","type":"string","description":"The name of the repeating section. Will be prefixed with `repeating_` and spaces will be replaced with dashes (`-`)."},{"name":"trigger","type":"object","description":"Trigger that defines how to handle the removal of a row from the fieldset. `Optional`"},{"name":"addClass","type":"string","description":"Any additional classes that should be used for the repeating section. Note that these are not added to the fieldset itself as adding additional classes to the fieldset itself interferes with calling action buttons from chat, but are added to a span that precedes the fieldset. This allows styling of the repcontainer via a css declaration like `.bonus-class + fieldset + .repcontainer`."}],"example":[["+customControlFieldset({name:'equipment'})\n +text({name:'name',class:'underlined'})","<button type=\"action\" name=\"add-equipment\" class=\"repcontrol-button repcontrol-button--add\"></button>\n<button type=\"action\" name=\"edit-equipment\" class=\"repcontrol-button repcontrol-button--edit\"></button>\n<fieldset class=\"repeating_equipment\">\n <input type=\"text\" name=\"attr_name\" title=\"@{repeating_equipment_$x_name}\">\n</fieldset>"]]},"fieldset":{"type":"mixin","description":"A mixin that creates a fieldset for the creation of a repeating section. The mixin prefixes the name with `repeating_` and replaces problem characters (e.g. spaces are replaced with dashes). Additionally, the auto-generated title properties from the K-scaffold's mixins will include the proper repeating section information.","arguments":[{"name":"name","type":"string","description":"The name of the repeating section. Will be prefixed with `repeating_` and spaces will be replaced with dashes (`-`)."},{"name":"trigger","type":"object","description":"Trigger that defines how to handle the removal of a row from the fieldset. `Optional`"},{"name":"addClass","type":"string","description":"Any additional classes that should be used for the repeating section. Note that these are not added to the fieldset itself as adding additional classes to the fieldset itself interferes with calling action buttons from chat, but are added to a span that precedes the fieldset. This allows styling of the repcontainer via a css declaration like `.bonus-class + fieldset + .repcontainer`."}],"example":[["+fieldset({name:'equipment'})\n +text({name:'name',class:'underlined'})","<fieldset class=\"repeating_equipment\"></fieldset><div class=\"repcontainer\" data-groupname=\"repeating_equipment\">\n <input type=\"text\" name=\"attr_name\" title=\"@{repeating_equipment_$x_name}\">\n</div>"],["+fieldset({name:'equipment',trigger:{listenerFunc:'handleDeletedRow'},addClass:'class-1 class-2'})\n +text({name:'name',class:'underlined'})","<span hidden class=\"class-1 class-2\"></span>\n<fieldset class=\"repeating_equipment\"></fieldset><div class=\"repcontainer\" data-groupname=\"repeating_equipment\">\n <input type=\"text\" name=\"attr_name\" title=\"@{repeating_equipment_$x_name}\">\n</div>"]]},"pseudo-button":{"type":"mixin","description":"A mixin for creating pseudo buttons of paired checkboxes/radios and spans such as those that had to be used to create [tabbed sheets](https://wiki.roll20.net/CSS_Wizardry#Show.2FHide_Areas) before action buttons were introduced.","arguments":[{"name":"label","type":"string","description":"The `data-i18n` translation key to use for the displayed text."},{"name":"inputObj","type":"object","description":"An object describing the input to be paired with the span. This is the same object that you would pass to [input](#input)."}],"example":[["+pseudo-button('page 1',{name:'page',type:'radio',value:1,trigger:{triggeredFuncs:['changePage']}})","<input type=\"hidden\" name=\"attr_page\" title=\"@{page} value=\"1\">\n<label class=\"pseudo-button\"><span data-i8n=\"page 1\" class=\"pseudo-button__span\"></span>\n <input type=\"radio\" name=\"attr_page\" value=\"1\"></label>"]]},"button-label":{"type":"mixin","description":"A mixin to create a combined button and input that are within the same container. Similar to [input-label](#input-label), but does not use a label.","arguments":[{"name":"inputObj","type":"object","description":"An object describing the input to be paired with the button. This is the same object that you would pass to [input](#input)."},{"name":"buttonObj","type":"object","description":"An object describing the button to be paired with the input. This is the same object that you would pass to [button](#button)."},{"name":"divObj","type":"object","description":"An object describing the container div. Similar to the first two objects, but will most likely only have a `class` property if it is passed at all."}],"example":[["+button-label({inputObj:{name:'strength',type:'number',class:'underlined',value:10,trigger:{affects:['athletics']}},buttonObj:{name:'strength_roll',type:'roll',value:'/r 1d20+@{strength}'},divObj:{class:'strength'}})","<div class=\"input-label input-label--button strength\">\n <button name=\"roll_strength_roll\" type=\"roll\" value=\"/r 1d20+@strength\">\n <input name=\"attr_strength\" type=\"number\" value=\"10\">\n</div"]]},"roller-label":{"type":"mixin","description":"Similar to the construction created by [button-label](#button-label), except that it creates a [roller](#roller) construction instead of just a straight button.","arguments":[{"name":"inputObj","type":"object","description":"An object describing the input to be paired with the button. This is the same object that you would pass to [input](#input)."},{"name":"buttonObj","type":"object","description":"An object describing the button to be paired with the input. This is the same object that you would pass to [roller](#roller)."},{"name":"divObj","type":"object","description":"An object describing the container div. Similar to the first two objects, but will most likely only have a `class` property if it is passed at all."}]},"action-label":{"type":"mixin","description":"Similar to the construction created by [button-label](#button-label), except that it specifcally creates an [action button](https://wiki.roll20.net/Button#Action_Button) as per [action](#action).","arguments":[{"name":"inputObj","type":"object","description":"An object describing the input to be paired with the button. This is the same object that you would pass to [input](#input)."},{"name":"buttonObj","type":"object","description":"An object describing the button to be paired with the input. This is the same object that you would pass to [action](#action)."},{"name":"divObj","type":"object","description":"An object describing the container div. Similar to the first two objects, but will most likely only have a `class` property if it is passed at all."}]},"select-label":{"type":"mixin","description":"Similar to the construction created by [input-label](#input-label), except that the input is replaced with a select.","arguments":[{"name":"label","type":"string","description":"The `data-i18n` translation key to add to the span in the label."},{"name":"inputObj","type":"object","description":"An object describing the select to be paired with the button. This is the same object that you would pass to [select](#select)."},{"name":"divObj","type":"object","description":"An object describing the container label. Similar to the inputObj, but will most likely only have a `class` property if it is passed at all."},{"name":"spanObj","type":"object","description":"An object describing the span to be paired with the input. This is the same object that you would pass to [span](#span)."},{"name":"block","type":"block","description":"The mixin uses the pug block as the content of the select."}],"example":[["+select-label('Whisper to GM',{name:'whisper'},{class:'div-class'},{class:'span-class'})\n +option({value:'','data-i18n':'never'})\n +option({value:'/w gm ','data-i18n':'always'})","<label class=\"input-label div-class\"><span data-i18n=\"Whisper to GM\" class=\"input-label__text span-class\"></span>\n <select name=\"attr_whisper\" class=\"input-label__input\">\n <option value=\"\" data-i18n=\"never\"></option>\n <option value=\"/w gm \" data-i18n=\"always\"></option>\n </select>\n</label>"]]},"input-label":{"type":"mixin","description":"Creates a construction that nests the input and span in a label so that they are connected. This is beneficial for screen readers as well as making it easier to interact with the input via mouse by clicking on the text associated with it.","arguments":[{"name":"label","type":"string","description":"The `data-i18n` translation key to add to the span in the label."},{"name":"inputObj","type":"object","description":"An object describing the input to be paired with the button. This is the same object that you would pass to [input](#input)."},{"name":"divObj","type":"object","description":"An object describing the container label. Similar to the inputObj, but will most likely only have a `class` property if it is passed at all."},{"name":"spanObj","type":"object","description":"An object describing the span to be paired with the input. This is the same object that you would pass to [span](#span)."},{"name":"block","type":"block","description":"The mixin uses the pug block as the content of the select."}],"example":[["+input-label({label:'strength',inputObj:{name:'strength',type:'number'},divObj:{class:'div-class'},spanObj:{class:'span-class'}})","<label class=\"input-label div-class\"><span data-i18n=\"Whisper to GM\" class=\"input-label__text span-class\"></span>\n <input name=\"attr_strength\" type=\"number\" class=\"input-label__input\">\n</label>"]]},"headedTextarea":{"type":"mixin","description":"Creates a construction for pairing a header with a textarea. Currently is locked to creating an `h3`. This mixin also accepts classes and IDs appended directly to it (see the second example)","arguments":[{"name":"textObj","type":"object","description":"The object describing the textarea as per [textarea](#textarea)"},{"name":"header","type":"string","description":"The `data-i18n` translation key to use for the header"}],"example":[["+headedTextarea({textObj:{name:'character description','data-i18n-placeholder':'The description of your character'},header:'description'})","<div class=\"headed-textarea\">\n <h3 data-i18n=\"description\"></h3>\n <textarea name=\"attr_character_description\" data-i18n-placeholder:\"The description of your character\"></textarea>\n</div>"],["+headedTextarea({textObj:{name:'character description','data-i18n-placeholder':'The description of your character'},header:'description'}).character-description","<div class=\"headed-textarea character-description\">\n <h3 data-i18n=\"description\"></h3>\n <textarea name=\"attr_character_description\" data-i18n-placeholder:\"The description of your character\"></textarea>\n</div>"]]},"script":{"type":"mixin","description":"Creates a generic [Roll20 script block](https://wiki.roll20.net/Building_Character_Sheets#JavaScript_2) for use with the sheetworker system."},"adaptiveTextarea":{"type":"mixin","description":"Creates an html construction for creating a [content-scaled](https://wiki.roll20.net/CSS_Wizardry#Content-scaled_Inputs) textarea.","arguments":[{"name":"textObj","type":"object","description":"The object describing the textarea as per the [textarea](#textarea) mixin. You can apply classes and IDs to the container div by appending them to the mixin call (see the second example)."}],"example":[["+adaptiveTextarea({name:'character description'})","<div class=\"adaptive adaptive--text\"><span name:\"attr_character_description\" class=\"adaptive--text__span\"></span>\n <textarea name=\"attr_character_description\" class=\"adaptive--text__textarea\"></textarea>\n</div>"],["+adaptiveTextarea({name:'character description'}).custom-class","<div class=\"adaptive adaptive--text custom-class\"><span name:\"attr_character_description\" class=\"adaptive--text__span\"></span>\n <textarea name=\"attr_character_description\" class=\"adaptive--text__textarea\"></textarea>\n</div>"]]},"compendiumAttributes":{"type":"mixin","description":"Creates a set of compendium drop target attributes. Defaults to creating target attributes for the `Name` and `data` compendium attributes.","arguments":[{"name":"prefix","type":"string","description":"A prefix to attach to the default attribute names."},{"name":"lookupAttributes","type":"array","description":"An array of the lookup attributes to create targets for. The target attributes are named based on the compendium attribute they are for. lookupAttributes defaults to `[\"Name\",\"data\"]`."},{"name":"triggerAccept","type":"string","description":"The compendium attribute that should trigger the sheetworkers to handle the compendium drop."},{"name":"trigger","type":"object","description":"The trigger object. Defaults to `{listenerFunc:\"handleCompendiumDrop\"}`"}],"example":[["+compendiumAttributes({})","<input name=\"attr_drop_name\" accept=\"Name\" value=\"\" type=\"hidden\" title=\"@{drop_name}\"/>\n<input name=\"attr_drop_data\" accept=\"data\" value=\"\" type=\"hidden\" title=\"@{drop_data}\"/>"],["+compendiumAttributes({prefix:'prefix'})","<input name=\"attr_prefix_drop_name\" accept=\"Name\" value=\"\" type=\"hidden\" title=\"@{prefix_drop_name}\"/>\n<input name=\"attr_prefix_drop_data\" accept=\"data\" value=\"\" type=\"hidden\" title=\"@{prefix_drop_data}\"/>"],["+compendiumAttributes({lookupAttributes:['Name','data','Category'],prefix:'prefix})","<input name=\"attr_prefix_drop_name\" accept=\"Name\" value=\"\" type=\"hidden\" title=\"@{prefix_drop_name}\"/>\n<input name=\"attr_prefix_drop_data\" accept=\"data\" value=\"\" type=\"hidden\" title=\"@{prefix_drop_data}\"/>\n<input name=\"attr_prefix_drop_category\" accept=\"Category\" value=\"\" type=\"hidden\" title=\"@{prefix_drop_category}\"/>"]]},"attrTitle":{"type":"function","description":"Converts an attribute name into an attribute call for that attribute. Converts `_max` attribute names to the proper attribute call syntax for `_max` attributes (see second example). If called from inside the block of a [fieldset](#fieldset) mixin, will also add the appropriate information for calling a repeating attribute.","arguments":[{"name":"attrName","type":"string","description":"The attribute name to create an attribute call for."}],"example":[["- attrTitle('strength') => \"@{strength}\""],["- attrTitle('hp_max') => \"@{hp|max}\""],["+fieldset({name:'equipment'})\n - attrTitle('weight') => \"@{repeating_equipment_$X_weight}\""]],"retValue":{"type":"string"}},"kscript":{"type":"mixin","description":"Similar to [script](#script), but includes the K-scaffold's javascript function library."},"buttonTitle":{"type":"function","description":"Converts an ability name into an ability call for that attribute. If called from inside the block of a [fieldset](#fieldset) mixin, will also add the appropriate information for calling a repeating attribute.","arguments":[{"name":"abilityName","type":"string","description":"The ability name to create an attribute call for."}],"example":[["- buttonTitle('strength') => \"%{strength}\""],["+fieldset({name:'equipment'})\n - buttonTitle('use') => \"%{repeating_equipment_$X_use}\""]],"retValue":{"type":"string"}},"replaceSpaces":{"type":"function","description":"Replaces spaces in a string with underscores (`_`).","arguments":[{"name":"string","type":"string","description":"The string to work on"}],"example":[["- replaceSpaces('attribute name') => \"attribute_name\""]],"retValue":{"type":"string"}},"replaceProblems":{"type":"function","description":"Escapes problem characters in a string for use as a regex.","arguments":[{"name":"string","type":"string","description":"The string to work on"}],"example":[["- replaceProblems(\"Here's a problem => [\") => \"Here's a problem => [\""]],"retValue":{"type":"string"}},"capitalize":{"type":"function","description":"Capitalizes the first let of words in a string.","arguments":[{"name":"string","type":"string","description":"The string to apply capitalization to."}],"retValue":{"type":"string"}}}};
kFuncs.docs = docs;
/**
* This stores the name of your sheet for use in the logging functions {@link log} and {@link debug}
* * @var
* @type {string}
*/
docs.js['k.sheetName'] = {
type:'string',
description:'This stores the name of your sheet for use in the logging functions [k.log](#klog) and [k.debug](#kdebug).'
};
let sheetName = 'kScaffold Powered Sheet';
kFuncs.sheetName = sheetName;
/**
* This stores the version of your sheet for use in the logging functions{@link log} and {@link debug}. It is also stored in the sheet_version attribute on your character sheet.
* @var
* @type {number}
*/
docs.js['k.version'] = {
type:'number',
description:'This stores the version of your sheet for use in the logging functions [k.log](#klog) and [k.debug](#kdebug), and in the K-scaffolds sheet versioning handling. It is also stored in the sheet_version attribute on your character sheet.'
};
let version = 0;
kFuncs.version = version;
/**
* A boolean flag that tells the script whether to enable or disable {@link debug} calls. If the version of the sheet is `0`, or an attribute named `debug_mode` is found on opening this is set to true for your entire session. Otherwise, it remains false.
* @var
* @type {boolean}
*/
docs.js['k.debugMode'] = {
type:'boolean',
description:'A boolean flag that tells the script whether to enable or disable [k.debug](#kdebug) calls. If the version of the sheet is `0`, or an attribute named `debug_mode` is found on opening this is set to true for all sheets you open from that point on. Otherwise, it remains false.'
};
let debugMode = false;
kFuncs.debugMode = debugMode;
const funcs = {};
kFuncs.funcs = funcs;
const updateHandlers = {};
const openHandlers = {};
const initialSetups = {};
const kscaffoldJSVersion = 0.30;
const kscaffoldPUGVersion = 0.30;
/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
docs.js['k.sanitizeForRegex'] = {
type:'function',
invocation:`k.sanitizeForRegex(text)`,
description:'Replaces problem characters to use a string as a regex.',
arguments:[
{type:'string',name:'text',description:'The text to replace characters in.'}
]
};
const sanitizeForRegex = function(text){
return text.replace(/\.|\||\(|\)|\[|\]|\-|\+|\?|\/|\{|\}|\^|\$|\*/g,'\\$&');
};
kFuncs.sanitizeForRegex = sanitizeForRegex;
docs.js['k.value'] = {
type:'function',
invocation:`k.value(val,def)`,
description:'Converts a value to a number, it\'s default value, or `0` if no default value passed.',
arguments:[
{type:'any',name:'val',description:'The value to coerce into a number.'},
{type:'number',name:'def',description:'A default value to use, if not passed, 0 is used instead.'}
]
};
const value = function(val,def){
return (+val||def||0);
};
kFuncs.value = value;
docs.js['k.parseRepeatName'] = {
type:'function',
invocation:`k.parseRepeatName(string)`,
description:'Extracts the section (e.g. `repeating_equipment`), rowID (e.g `-;lkj098J:LKj`), and field name (e.g. `bulk`) from a repeating attribute name.',
arguments:[
{type:'string',name:'string',description:'The attribute name to parse.'}
],
retValue:{
type:'array',
description:'For a repeating attribute named `repeating_equipment_-LKJhpoi98;lj_weight`, the array will be `[\'repeating_equipment\',\'-LKJhpoi98;lj\',\'weight\']`.'
}
};
const parseRepeatName = function(string){
let match = string.match(/(repeating_[^_]+)_([^_]+)(?:_(.+))?/);
match.shift();
return match;
};
kFuncs.parseRepeatName = parseRepeatName;
docs.js['k.parseTriggerName'] = {
type:'function',
invocation:`k.parseTriggerName(string)`,
description:'Parses out the components of a trigger name similar to [parseRepeatName](#parserepeatname). Aliases: parseClickTrigger.\n\nAliases: `k.parseClickTrigger`',
arguments:[
{type:'string',name:'string',description:'The triggerName property of the [event](https://wiki.roll20.net/Sheet_Worker_Scripts#eventInfo_Object).'}
],
retValue:{
type:'array',
description:'For a repeating button named `repeating_equipment_-LKJhpoi98;lj_roll`, the array will be `[\'repeating_equipment\',\'-LKJhpoi98;lj\',\'roll\']`. For a non repeating button named `roll`, the array will be `[undefined,undefined,\'roll\']`'
}
};
const parseTriggerName = function(string){
let match = string.replace(/^clicked:/,'').match(/(?:(repeating_[^_]+)_([^_]+)_)?(.+)/);
match.shift();
return match;
};
kFuncs.parseTriggerName = parseTriggerName;
const parseClickTrigger = parseTriggerName;
kFuncs.parseClickTrigger = parseClickTrigger;
docs.js['k.parseHTMLName'] = {
type:'function',
invocation:`k.parseHTMLName(string)`,
description:'Parses out the attribute name from the htmlattribute name.',
arguments:[
{type:'string',name:'string',description:'The triggerName property of the [event](https://wiki.roll20.net/Sheet_Worker_Scripts#eventInfo_Object).'}
],
retValue:{
type:'array',
description:'For a repeating button named `act_repeating_equipment_-LKJhpoi98;lj_roll`, the array will be `[\'repeating_equipment\',\'-LKJhpoi98;lj\',\'roll\']`. For a non repeating button named `act_roll`, the array will be `[undefined,undefined,\'roll\']`'
}
};
const parseHTMLName = function(string){
let match = string.match(/(?:attr|act|roll)_(.+)/);
match.shift();
return match[0];
};
kFuncs.parseHTMLName = parseHTMLName;
docs.js['k.capitalize'] = {
type:'function',
invocation:`k.capitalize(string)`,
description:'Capitalize each word in a string.',
arguments:[
{type:'string',name:'string',description:'The string to capitalize'},
],
retValue:{
type:'string',
description:'The capitalized string'
}
};
const capitalize = function(string){
return string.replace(/(?:^|\s+|\/)[a-z]/ig,(letter)=>letter.toUpperCase());
};
kFuncs.capitalize = capitalize;
docs.js['k.extractQueryResult'] = {
type:'function',
invocation:`k.extractQueryResult(section,sections,customText)`,
description:'Extracts a roll query result for use in later functions. Must be awaited as per [startRoll documentation](https://wiki.roll20.net/Sheet_Worker_Scripts#Roll_Parsing.28NEW.29). Stolen from [Oosh\'s Adventures with Startroll thread](https://app.roll20.net/forum/post/10346883/adventures-with-startroll).',
arguments:[
{type:'string',name:'query',description:'The query should be just the text as the `?{` and `}` at the start/end of the query are added by the function.'}
],
retValue:{
type:'string',
description:'The selected value from the roll query'
}
};
const extractQueryResult = async function(query){
debug('entering extractQueryResult');
let queryRoll = await startRoll(`!{{query=[[0[response=?{${query}}]]]}}`);
finishRoll(queryRoll.rollId);
return queryRoll.results.query.expression.replace(/^.+?response=|\]$/g,'');
};
kFuncs.extractQueryResult = extractQueryResult;
docs.js['k.pseudoQuery'] = {
type:'function',
invocation:`k.pseudoQuery(section,sections,customText)`,
description:'Simulates a query for ensuring that async/await works correctly in the sheetworker environment when doing conditional startRolls. E.g. if you have an if/else and only one of the conditions results in `startRoll` being called (and thus an `await`), the sheetworker environment would normally crash. Awaiting this in the condition that does not actually need to call `startRoll` will keep the environment in sync.',
arguments:[
{type:'number|string',name:'value',description:'The value to return. Optional.'}
],
retValue:{
type:'string',
description:'The `value` passed to the function is returned after startRoll resolves.'
}
};
const pseudoQuery = async function(value){
debug('entering pseudoQuery');
let queryRoll = await startRoll(`!{{query=[[0[response=${value}]]]}}`);
finishRoll(queryRoll.rollId);
return queryRoll.results.query.expression.replace(/^.+?response=|\]$/g,'');
};
kFuncs.pseudoQuery = pseudoQuery;
docs.js['k.log'] = {
type:'function',
invocation:`k.log(msg)`,
description:'An alias for console.log.',
arguments:[
{type:'string|object|array',name:'msg',description:'The message can be a straight string, an object, or an array. If it is an object or array, the object will be broken down so that each key is used as a label to output followed by the value of that key. If the value of the key is an object or array, it will be output via `console.table`.'}
]
};
const log = function(msg){
if(typeof msg === 'string'){
console.log(`%c${kFuncs.sheetName} log| ${msg}`,"background-color:#159ccf");
}else if(typeof msg === 'object'){
Object.keys(msg).forEach((m)=>{
if(typeof msg[m] === 'string'){
console.log(`%c${kFuncs.sheetName} log| ${m}: ${msg[m]}`,"background-color:#159ccf");
}else{
console.log(`%c${kFuncs.sheetName} log| ${typeof msg[m]} ${m}`,"background-color:#159ccf");
console.table(msg[m]);
}
});
}
};
kFuncs.log = log;
docs.js['k.debug'] = {
type:'function',
invocation:`k.debug(msg,force)`,
description:'Alias for console.log that only triggers when debug mode is enabled or when the sheet\'s version is `0`.',
arguments:[
{type:'string',name:'setObj',description:'See [k.log](#klog)'},
{type:'boolean',name:'force',description:'Pass as a truthy value to force the debug output to be output to the console regardless of debug mode.'}
]
};
const debug = function(msg,force){
if(!kFuncs.debugMode && !force && kFuncs.version > 0) return;
if(typeof msg === 'string'){
console.log(`%c${kFuncs.sheetName} DEBUG| ${msg}`,"background-color:tan;color:red;");
}else if(typeof msg === 'object'){
Object.keys(msg).forEach((m)=>{
if(typeof msg[m] === 'string'){
console.log(`%c${kFuncs.sheetName} DEBUG| ${m}: ${msg[m]}`,"background-color:tan;color:red;");
}else{
console.log(`%c${kFuncs.sheetName} DEBUG| ${typeof msg[m]} ${m}`,"background-color:tan;color:red;font-weight:bold;");
console.table(msg[m]);
}
});
}
};
kFuncs.debug = debug;
docs.js['k.orderSections'] = {
type:'function',
invocation:`k.orderSections(attributes,sections)`,
description:'Orders the section id arrays for all sections in the `sections` object to match the repOrder attribute.',
arguments:[
{type:'object',name:'attributes',description:'The attributes object that must have a value for the reporder for each section.'},
{type:'object',name:'sections',description:'Object containing the IDs for the repeating sections, indexed by repeating section name.'}
]
};
const orderSections = function(attributes,sections){
Object.keys(sections).forEach((section)=>{
attributes.attributes[`_reporder_${section}`] = commaArray(attributes[`_reporder_${section}`]);
orderSection(attributes.attributes[`_reporder_${section}`],sections[section]);
});
};
kFuncs.orderSections = orderSections;
docs.js['k.orderSection'] = {
type:'function',
invocation:`k.orderSection(repOrder,IDs)`,
description:'Orders a single ID array.',
arguments:[
{type:'array',name:'setObj',description:'Array of IDs in the order they are in on the sheet.'},
{type:'array',name:'vocal',description:'Array of IDs to be ordered.'}
]
};
const orderSection = function(repOrder,IDs=[]){
IDs.sort((a,b)=>{
return repOrder.indexOf(a.toLowerCase()) - repOrder.indexOf(b.toLowerCase());
});
};
kFuncs.orderSection = orderSection;
/**
* Splits a comma delimited string into an array
* @param {string} [string='']
* @returns {string[]}
*/
docs.js['k.commaArray'] = {
type:'function',
invocation:`k.commaArray(string)`,
description:'Splits a comma delimited string into an array',
arguments:[
{type:'string',name:'setObj',description:'The string to split.'}
],
retValue:{
type:'array',
description:'The string segments of the comma delimited list.'
}
};
const commaArray = function(string=''){
return string.toLowerCase().split(/\s*,\s*/);
};
kFuncs.commaArray = commaArray;/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
//# Attribute Obj Proxy handler
const createAttrProxy = function(attrs){
//creates a proxy for the attributes object so that values can be worked with more easily.
const getCascObj = function(event,casc){
const eventName = event.sourceAttribute || event.triggerName;
let typePrefix = eventName.startsWith('clicked:') ?
'act_' :
event.removedInfo ?
'fieldset_' :
'attr_';
let cascName = `${typePrefix}${eventName.replace(/clicked:/,'')}`;
let cascObj = casc[cascName];
return cascObj;
};
const triggerFunctions = function(obj,attributes,sections){
if(obj.triggeredFuncs && obj.triggeredFuncs.length){
debug(`triggering functions for ${obj.name}`);
obj.triggeredFuncs && obj.triggeredFuncs.forEach(func=>funcs[func] ?
funcs[func]({trigger:obj,attributes,sections}) :
debug(`!!!Warning!!! no function named ${func} found. Triggered function not called for ${obj.name}`,true));
}
};
const initialFunction = function(obj,attributes,sections){
if(obj.initialFunc){
debug(`initial functions for ${obj.name}`);
funcs[obj.initialFunc] ?
funcs[obj.initialFunc]({trigger:obj,attributes,sections}) :
debug(`!!!Warning!!! no function named ${obj.initialFunc} found. Initial function not called for ${obj.name}`,true);
}
};
const processChange = function({event,trigger,attributes,sections,casc}){
debug({trigger});
if(event && !trigger){
debug('initial change detected. No trigger found');
return;
}
if(!attributes || !sections || !casc){
debug(`!!! Insufficient arguments || attributes > ${!!attributes} | sections > ${!!sections} | casc > ${!!casc} !!!`);
return;
}
//store the queue in attributes.
if(event){
debug('checking for initial functions');
initialFunction(trigger,attributes,sections);//functions that should only be run if the attribute was the thing changed by the user
}
if(trigger){
debug(`processing ${trigger.name}`);
triggerFunctions(trigger,attributes,sections);
if(!event && trigger.calculation && funcs[trigger.calculation]){
attributes[trigger.name] = funcs[trigger.calculation]({trigger,attributes,sections,casc});
}else if(trigger.calculation && !funcs[trigger.calculation]){
debug(`K-Scaffold Error: No function named ${trigger.calculation} found`);
}
if(Array.isArray(trigger.affects)){
attributes.queue.push(...trigger.affects);
}
}
attributes.set({attributes,sections,casc});
};
const attrTarget = {
updates:{},
attributes:{...attrs},
repOrders:{},
queue: [],
casc:{},
processChange,
triggerFunctions,
initialFunction,
getCascObj
};
const attrHandler = {
get:function(obj,prop){//gets the most value of the attribute.
//If it is a repeating order, returns the array, otherwise returns the update value or the original value
if(prop === 'set'){
return function(){
let {attributes,sections,casc,callback,vocal} = arguments[0] ? arguments[0] : {};
if(attributes && attributes.queue.length && sections && casc){
let triggerName = attributes.queue.shift();
let trigger = getCascObj({sourceAttribute:triggerName},casc);
attributes.processChange({trigger,attributes,sections,casc});
}else{
debug({updates:obj.updates});
let trueCallback = Object.keys(obj.repOrders).length ?
function(){
Object.entries(obj.repOrders).forEach(([section,order])=>{
_setSectionOrder(section,order,)
});
callback && callback();
}:
callback;
Object.keys(obj.updates).forEach((key)=>obj.attributes[key] = obj.updates[key]);
const update = obj.updates;
obj.updates = {};
set(update,vocal,trueCallback);
}
}
}else if(Object.keys(obj).some(key=>key===prop)){
return Reflect.get(...arguments)
}else{
let retValue;
switch(true){
case obj.repOrders.hasOwnProperty(prop):
retValue = obj.repOrders[prop];
break;
case obj.updates.hasOwnProperty(prop):
retValue = obj.updates[prop];
break;
default:
retValue = obj.attributes[prop];
break;
}
let cascRef = `attr_${prop.replace(/(repeating_[^_]+_)[^_]+/,'$1\$X')}`;
let numRetVal = +retValue;
if(!Number.isNaN(numRetVal) && retValue !== ''){
retValue = numRetVal;
}else if(cascades[cascRef] && (typeof cascades[cascRef].defaultValue === 'number' || cascades[cascRef].type === 'number')){
retValue = cascades[cascRef].defaultValue;
}
return retValue;
}
},
set:function(obj,prop,value){
//Sets the value. Also verifies that the value is a valid attribute value
//e.g. not undefined, null, or NaN
if(value || value===0 || value===''){
if(/reporder|^repeating_[^_]+$/.test(prop)){
let section = prop.replace(/_reporder_/,'');
obj.repOrders[section] = value;
}else if(`${obj.attributes}` !== `${value}` ||
(obj.updates[prop] && `${obj.updates}` !== `${value}`)
){
obj.updates[prop] = value;
}
}else{
debug(`!!!Warning: Attempted to set ${prop} to an invalid value:${value}; value not stored!!!`);
}
return true;
},
deleteProperty(obj,prop){
//removes the property from the original attributes, updates, and the reporders
Object.keys(obj).forEach((key)=>{
delete obj[key][prop.toLowerCase()];
});
}
};
return new Proxy(attrTarget,attrHandler);
};
/**
* Function that registers a function for being called via the funcs object. Returns true if the function was successfully registered, and false if it could not be registered for any reason.
* @param {object} funcObj - Object with keys that are names to register functions under and values that are functions.
* @param {object} optionsObj - Object that contains options to use for this registration.
* @param {string[]} optionsObj.type - Array that contains the types of specialized functions that apply to the functions being registered. Valid types are `"opener"`, `"updater"`, and `"default"`. `"default"` is always used, and never needs to be passed.
* @returns {boolean} - True if the registration succeeded, false if it failed.
*/
const registerFuncs = function(funcObj,optionsObj = {}){
if(typeof funcObj !== 'object' || typeof optionsObj !== 'object'){
debug(`!!!! K-scaffold error: Improper arguments to register functions !!!!`);
return false;
}
const typeArr = optionsObj.type ? ['default',...optionsObj.type] : ['default'];
const typeSwitch = {
'opener':openHandlers,
'updater':updateHandlers,
'new':initialSetups,
'default':funcs
};
let setState;
Object.entries(funcObj).map(([prop,value])=>{
typeArr.forEach((type)=>{
if(typeSwitch[type][prop]){
debug(`!!! Duplicate function name for ${prop} as ${type}!!!`);
setState = false;
}else if(typeof value === 'function'){
typeSwitch[type][prop] = value;
setState = setState !== false ? true : false;
}else{
debug(`!!! K-scaffold error: Function registration requires a function. Invalid value to register as ${type} !!!`);
setState = false;
}
});
});
return setState;
};
kFuncs.registerFuncs = registerFuncs;
const setActionCalls = function({attributes,sections}){
actionAttributes.forEach((base)=>{
let [section,,field] = k.parseTriggerName(base);
let fieldAction = field.replace(/_/g,'-');
if(section){
sections[section].forEach((id)=>{
attributes[`${section}_${id}_${field}`] = `%{${attributes.character_name}|${section}_${id}_${fieldAction}}`;
});
}else{
attributes[`${field}`] = `%{${attributes.character_name}|${fieldAction}}`;
}
});
};
funcs.setActionCalls = setActionCalls;
/**
* Function to call a function previously registered to the funcs object. May not be used that much. Either returns the function or null if no function exists.
* @param {string} funcName - The name of the function to invoke.
* @param {...any} args - The arguments to call the function with.
* @returns {any}
*/
const callFunc = function(funcName,...args){
if(funcs[funcName]){
debug(`calling ${funcName}`);
return funcs[funcName](...args);
}else{
debug(`Invalid function name: ${funcName}`);
return null;
}
};
kFuncs.callFunc = callFunc;/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
//Sheet Updaters and styling functions
/**
* An object to store your update functions in. Functions should be index by the version they are for (e.g. the update handler for version 1.01 would be indexed to '1.01'). These update functions will be iterated through based on the previous version of the sheet (as stored in the `sheet_version` attribute of the sheet) and the new version of the sheet (as stored in {@link k.version}).
* @type {object}
*/
const updateSheet = function(){
log('updating sheet');
getAllAttrs({props:['debug_mode',...baseGet],callback:(attributes,sections,casc)=>{
kFuncs.debugMode = kFuncs.debugMode || !!attributes.debug_mode;
if(!attributes.sheet_version){
Object.entries(initialSetups).forEach(([funcName,handler])=>{
if(typeof funcs[funcName] === 'function'){
debug(`running ${funcName}`);
funcs[funcName]({attributes,sections,casc});
}else{
debug(`!!!Warning!!! no function named ${funcName} found. Initial sheet setup not performed.`);
}
});
}else{
Object.entries(updateHandlers).forEach(([ver,handler])=>{
if(attributes.version < +ver){
handler({attributes,sections,casc});
}
});
}
Object.entries(openHandlers).forEach(([funcName,func])=>{
if(typeof funcs[funcName] === 'function'){
debug(`running ${funcName}`);
funcs[funcName]({attributes,sections,casc});
}else{
debug(`!!!Warning!!! no function named ${funcName} found. Sheet open handling not performed.`);
}
});
setActionCalls({attributes,sections});
attributes.sheet_version = kFuncs.version;
log(`Sheet Update applied. Current Sheet Version ${kFuncs.version}`);
if(document){
['pug','js'].forEach((type)=>{
log(docGen(type));
});
}
attributes.set();
log('Sheet ready for use');
}});
};
const docGen = function(language){
debug(`generating documentation for ${language}`);
let docHead = [`# K Scaffold ${language.toUpperCase()} documentation`];
Object.keys(docs[language])
.sort((nameA,nameB) => nameA.localeCompare(nameB))
.forEach((funcName)=>{
docHead.push(`- [${funcName}](#${funcName.replace(/\./g,'').replace(/\s/g,'-')})`);
});
return Object.entries(docs[language])
.sort(([nameA,docObjA],[nameB,docObjB]) => nameA.localeCompare(nameB))
.reduce((text,[name,docObj]) => {
let type = docObj.type;
text.push(`## ${docObj.name || name}`,`\`${type}\`\n`);
if(docObj.invocation){
text.push(`\`\`\`js\n${docObj.invocation}\n\`\`\``);
}
if(docObj.description){
text.push(docObj.description);
}
let args = Array.isArray(docObj.arguments) ? docObj.arguments : [];
if(args.length){
text.push('|Argument|type|description|','|---|---|---|')
}
args.forEach((a)=>{
text.push(`|${a.name}|\`${a.type}\`|${a.description || ''}|`)
});
if(args.length){
text.push('\n')
}
let example = Array.isArray(docObj.example) ? docObj.example : [];
if(example.length){
text.push(`### Example${example.length > 1 ? 's' : ''}`);
}
example.forEach((eArr)=>{
text.push(
`**${language.toUpperCase()}**`,
`\`\`\`js`,
eArr[0],
`\`\`\``
);
if(type === 'mixin'){
text.push(
'**HTML**',
`\`\`\`html`,
eArr[1],
`\`\`\``
);
}
});
if(docObj.retValue){
text.push(`returns \`${docObj.retValue.type}\` ${
docObj.retValue.description ?
`- ${docObj.retValue.description}` :
''
}`
);
}
return text;
},docHead).join('\n');
};
const initialSetup = function(attributes,sections){
debug('Initial sheet setup');
};
/**
* This is the default listener function for attributes that the K-Scaffold uses. It utilizes the `triggerFuncs`, `listenerFunc`, `calculation`, and `affects` properties of the K-scaffold trigger object (see the Pug section of the scaffold for more details).
* @param {Roll20Event} event
* @returns {void}
*/
const accessSheet = function(event){
debug({funcs:Object.keys(funcs)});
debug({event});
getAllAttrs({event,callback:(attributes,sections,casc)=>{
let trigger = attributes.getCascObj(event,casc);
attributes.processChange({event,trigger,attributes,sections,casc});
}});
};
funcs.accessSheet = accessSheet;/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
/*
Cascade Expansion functions
*/
//Expands the repeating section templates in cascades to reflect the rows actually available
const expandCascade = function(cascade,sections,attributes){
return _.keys(cascade).reduce((memo,key)=>{//iterate through cascades and replace references to repeating attributes with correct row ids.
if(/^(?:act|attr)_repeating_/.test(key)){//If the attribute is a repeating attribute, do special logic
expandRepeating(memo,key,cascade,sections,attributes);
}else if(key){//for non repeating attributes do this logic
expandNormal(memo,key,cascade,sections);
}
return memo;
},{});
};
const expandRepeating = function(memo,key,cascade,sections,attributes){
key.replace(/((?:attr|act)_)(repeating_[^_]+)_[^_]+?_(.+)/,(match,type,section,field)=>{
(sections[section]||[]).forEach((id)=>{
memo[`${type}${section}_${id}_${field}`]=_.clone(cascade[key]);//clone the details so that each row's attributes have correct ids
memo[`${type}${section}_${id}_${field}`].name = `${section}_${id}_${field}`;
if(key.startsWith('attr_')){
memo[`${type}${section}_${id}_${field}`].affects = memo[`${type}${section}_${id}_${field}`].affects.reduce((m,affected)=>{
if(section === affected){//otherwise if the affected attribute is in the same section, simply set the affected attribute to have the same row id.
m.push(applyID(affected,id));
}else if(/repeating/.test(affected)){//If the affected attribute isn't in the same repeating section but is still a repeating attribute, add all the rows of that section
addAllRows(affected,m,sections);
}else{//otherwise the affected attribute is a non repeating attribute. Simply add it to the computed affected array
m.push(affected);
}
return m;
},[]);
}
});
});
};
const applyID = function(affected,id){
return affected.replace(/(repeating_[^_]+_)[^_]+(.+)/,`$1${id}$2`);
};
const expandNormal = function(memo,key,cascade,sections){
memo[key] = _.clone(cascade[key]);
if(key.startsWith('attr_')){
memo[key].affects = memo[key].affects || [];
memo[key].affects = memo[key].affects.reduce((m,a)=>{
if(/^repeating/.test(a)){
addAllRows(a,m,sections);
}else{
m.push(a);
}
return m;
},[]);
}
};
const addAllRows = function(affected,memo,sections){
affected.replace(/(repeating_[^_]+?)_[^_]+?_(.+)/,(match,section,field)=>{
sections[section].forEach(id=>memo.push(`${section}_${id}_${field}`));
});
};/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
/**
* Alias for [setSectionOrder()](https://wiki.roll20.net/Sheet_Worker_Scripts#setSectionOrder.28.3CRepeating_Section_Name.3E.2C_.3CSection_Array.3E.2C_.3CCallback.3E.29) that allows you to use the section name in either `repeating_section` or `section` formats.
* @name setSectionOrder
* @param {string} section
* @param {string[]} order
* @returns {void}
*/
docs.js['k.setSectionOrder'] = {
type:'function',
description:'Alias for [setSectionOrder()](https://wiki.roll20.net/Sheet_Worker_Scripts#setSectionOrder.28.3CRepeating_Section_Name.3E.2C_.3CSection_Array.3E.2C_.3CCallback.3E.29) that allows you to use the section name in either `repeating_section` or `section` formats. Note that the Roll20 sheetworker [setSectionOrder](https://wiki.roll20.net/Sheet_Worker_Scripts#setSectionOrder.28.3CRepeating_Section_Name.3E.2C_.3CSection_Array.3E.2C_.3CCallback.3E.29) currently causes some display issues on sheets.',
arguments:[
{type:'string',name:'section',description:'The name of the section to change the order in. Accepts the section name with or without the `repeating_` prefix.'},
{type:'[\'string\']',name:'order',description:'Array of the row ids in the order that the rows need to be placed.'}
]
};
const _setSectionOrder = function(section,order){
let trueSection = section.replace(/repeating_/,'');
setSectionOrder(trueSection,order);
};
kFuncs.setSectionOrder = _setSectionOrder;
/**
* Alias for [removeRepeatingRow](https://wiki.roll20.net/Sheet_Worker_Scripts#removeRepeatingRow.28_RowID_.29) that also removes the row from the current object of attribute values and array of section IDs to ensure that erroneous updates are not issued.
* @name removeRepeatingRow
* @param {string} row - The row id to be removed
* @param {attributesProxy} attributes - The attribute values currently in memory
* @param {object} sections - Object that contains arrays of all the IDs in sections on the sheet indexed by repeating name.
* @returns {void}
*/
docs.js['k.removeRepeatingRow'] = {
type:'function',
description:'Alias for [removeRepeatingRow](https://wiki.roll20.net/Sheet_Worker_Scripts#removeRepeatingRow.28_RowID_.29) that also removes the row from the current object of attribute values and array of section IDs to ensure that erroneous updates are not issued.',
arguments:[
{type:'string',name:'row',description:'The row id including the section name, e.g. `repeating_equipment_-oiuLKJ987ulkj`.'},
{type:'object',name:'attributes',description:'The attributes object passed to the callback in [k.getAllAttrs()](#getAllAttrs), [k.getAttrs()](#getAttrs), or [getAttrs()](https://wiki.roll20.net/Sheet_Worker_Scripts#getAttrs.28attributeNameArray.2C_callback.29)'},
{type:'object',name:'sections',description:'Object that contains arrays of all the IDs in sections on the sheet indexed by repeating name.'}
]
};
const _removeRepeatingRow = function(row,attributes,sections){
debug(`removing ${row}`);
Object.keys(attributes.attributes).forEach((key)=>{
if(key.startsWith(row)){
delete attributes[key];
}
});
let [,section,rowID] = row.match(/(repeating_[^_]+)_(.+)/,'');
sections[section] = sections[section].filter((id)=>id!==rowID);
removeRepeatingRow(row);
};
kFuncs.removeRepeatingRow = _removeRepeatingRow;
/**
* Alias for [getAttrs()](https://wiki.roll20.net/Sheet_Worker_Scripts#getAttrs.28attributeNameArray.2C_callback.29) that converts the default object of attribute values into an {@link attributesProxy} and passes that back to the callback function.
* @name getAttrs
* @param {Object} args
* @param {string[]} [args.props=baseGet] - Array of attribute names to get the value of. Defaults to {@link baseGet} if not passed.
* @param {function(attributesProxy)} args.callback - The function to call after the attribute values have been gotten. An {@link attributesProxy} is passed to the callback.
*/
docs.js['k.getAttrs'] = {
type:'function',
invocation:`k.getAttrs({props,callback})`,
description:'Alias for [getAttrs](https://wiki.roll20.net/Sheet_Worker_Scripts#getAttrs.28_RowID_.29) that converts the default object of attribute values into a K-scaffold attributes object and passes that back to the callback function.',
arguments:[
{type:'array',name:'props',description:'Array of attribute names to get the values of as per the [getAttrs() sheetworker](https://wiki.roll20.net/Sheet_Worker_Scripts#getAttrs.28attributeNameArray.2C_callback.29). If not passed, gets all the attributes contained in the cascades object.'},
{type:'function',name:'callback',description:'The function to call after the attribute values have been gotten. Works the same as the callback for the [getAttrs() sheetworker](https://wiki.roll20.net/Sheet_Worker_Scripts#getAttrs.28attributeNameArray.2C_callback.29).'}
]
};
const _getAttrs = function({props=baseGet,callback}){
getAttrs(props,(values)=>{
const attributes = createAttrProxy(values);
callback(attributes);
});
};
kFuncs.getAttrs = _getAttrs;
/**
* Alias for [getAttrs()](https://wiki.roll20.net/Sheet_Worker_Scripts#getAttrs.28attributeNameArray.2C_callback.29) and [getSectionIDs](https://wiki.roll20.net/Sheet_Worker_Scripts#getSectionIDs.28section_name.2Ccallback.29) that combines the actions of both sheetworker functions and converts the default object of attribute values into an {@link attributesProxy}. Also gets the details on how to handle all attributes from the master {@link cascades} object and.
* @param {Object} args
* @param {string[]} [args.props=baseGet] - Array of attribute names to get the value of. Defaults to {@link baseGet} if not passed.
* @param {repeatingSectionDetails} sectionDetails - Array of details about a section to get the IDs for and attributes that need to be gotten.
* @param {function(attributesProxy,sectionObj,expandedCascade):void} args.callback - The function to call after the attribute values have been gotten. An {@link attributesProxy} is passed to the callback along with a {@link sectionObj} and {@link expandedCascade}.
*/
docs.js['k.getAllAttrs'] = {
type:'function',
invocation:`k.getAllAttrs({props,sectionDetails,callback})`,
description:'Alias for [getAttrs()](https://wiki.roll20.net/Sheet_Worker_Scripts#getAttrs.28attributeNameArray.2C_callback.29) and [getSectionIDs()](https://wiki.roll20.net/Sheet_Worker_Scripts#getSectionIDs.28section_name.2Ccallback.29) that combines the actions of both sheetworker functions and converts the default object of attribute values into a K-scaffold attributes object. ',
arguments:[
{type:'array',name:'props',description:'Array of attribute names to get the values of as per the [getAttrs() sheetworker](https://wiki.roll20.net/Sheet_Worker_Scripts#getAttrs.28attributeNameArray.2C_callback.29).'},
{type:'array',name:'sectionDetails',description:'An array of objects that contain the details on how to handle a given repeating section. See [k.getSections](#getSections) for more details.'},
{type:'function',name:'callback(attributes,sections,casc)',description:'The function to call after the attribute values have been gotten. Three arguments are passed to the callback; `attributes`, `sections`, and `casc`. `sections` is an object that holds arrays of row ids, indexed by repeating section name. `casc` is the expanded version of the cascades object with repeating attributes including their row IDs.'}
]
};
const getAllAttrs = function({props=baseGet,sectionDetails=repeatingSectionDetails,callback}){
getSections(sectionDetails,(repeats,sections)=>{
getAttrs([...props,...repeats],(values)=>{
const attributes = createAttrProxy(values);
orderSections(attributes,sections);
const casc = expandCascade(cascades,sections,attributes);
callback(attributes,sections,casc);
})
});
};
kFuncs.getAllAttrs = getAllAttrs;
/**
* Alias for [getSectionIDs()](https://wiki.roll20.net/Sheet_Worker_Scripts#getSectionIDs.28section_name.2Ccallback.29) that allows you to iterate through several functions at once. Also assembles an array of repeating attributes to get.
* @param {object[]} sectionDetails - Array of details about a section to get the IDs for and attributes that need to be gotten.
* @param {string} sectionDetails.section - The full name of the repeating section including the `repeating_` prefix.
* @param {string[]} sectionDetails.fields - Array of field names that need to be gotten from the repeating section
* @param {function(string[],sectionObj)} callback - The function to call once all IDs have been gotten and the array of repating attributes to get has been assembled. The callback is passed the array of repating attributes to get and a {@link sectionObj}.
* @returns {void}
*/
docs.js['k.getSections'] = {
type:'function',
invocation:`k.getSections(sectionDetails,callback)`,
description:'Alias for [getSectionIDs()](https://wiki.roll20.net/Sheet_Worker_Scripts#getSectionIDs.28section_name.2Ccallback.29) that allows you to iterate through several sections at once. Also assembles an array of repeating attributes to get.',
arguments:[
{type:'array',name:'props',description:'Array of attribute names to get the values of as per the [getAttrs() sheetworker](https://wiki.roll20.net/Sheet_Worker_Scripts#getAttrs.28attributeNameArray.2C_callback.29).'},
{type:'array',name:'sectionDetails',description:'An array of objects that contain the details on how to handle a given repeating section. See [k.repeatingSectionDetails](#krepeatingsectiondetails) for more details.'},
{type:'function',name:'callback(repeatAttrs,sections)',description:'The function to call after the attribute values have been gotten. Two arguments are passed to the callback; `repeatAttrs` and `sections`. `repeatAttrs` is an array of repeating attributes ready to be used in a [getAttrs](https://wiki.roll20.net/Sheet_Worker_Scripts#getAttrs.28attributeNameArray.2C_callback.29), or [k.getAttrs](#kgetattrs) call. `sections` is an object that holds arrays of row ids, indexed by repeating section name.'}
]
};
const getSections = function(sectionDetails,callback){
let queueClone = _.clone(sectionDetails);
const worker = (queue,repeatAttrs=[],sections={})=>{
let detail = queue.shift();
getSectionIDs(detail.section,(IDs)=>{
sections[detail.section] = IDs;
IDs.forEach((id)=>{
detail.fields.forEach((f)=>{
repeatAttrs.push(`${detail.section}_${id}_${f}`);
});
});
repeatAttrs.push(`_reporder_${detail.section}`);
if(queue.length){
worker(queue,repeatAttrs,sections);
}else{
callback(repeatAttrs,sections);
}
});
};
if(!queueClone[0]){
callback([],{});
}else{
worker(queueClone);
}
};
kFuncs.getSections = getSections;
// Sets the attributes while always calling with {silent:true}
// Can be awaited to get the values returned from _setAttrs
/**
* Alias for [setAttrs()](https://wiki.roll20.net/Sheet_Worker_Scripts#setAttrs.28values.2Coptions.2Ccallback.29) that sets silently by default.
* @name setAttrs
* @param {object} obj - The object containting attributes to set
* @param {boolean} [vocal=false] - Whether to set silently (default value) or not.
* @param {function()} [callback] - The callback function to invoke after the setting has been completed. No arguments are passed to the callback function.
* @returns {void}
*/
docs.js['k.setAttrs'] = {
type:'function',
invocation:`k.setAttrs(setObj,vocal,callback)`,
description:'Alias for [setAttrs()](https://wiki.roll20.net/Sheet_Worker_Scripts#setAttrs.28values.2Coptions.2Ccallback.29) that sets silently by default.',
arguments:[
{type:'object',name:'setObj',description:'Object with key/value pairs of attributes to set on the sheet. See [the wiki page](https://wiki.roll20.net/Sheet_Worker_Scripts#setAttrs.28values.2Coptions.2Ccallback.29) for more information.'},
{type:'boolean',name:'vocal',description:'Whether to set silently (default value) or not.'},
{type:'function',name:'callback()',description:'The callback function to invoke after the setting has been completed. No arguments are passed to the callback function.'}
]
};
const set = function(obj,vocal=false,callback){
setAttrs(obj,{silent:!vocal},callback);
};
kFuncs.setAttrs = set;
const generateCustomID = function(string){
if(!string.startsWith('-')){
string = `-${string}`;
}
rowID = generateRowID();
let re = new RegExp(`^.{${string.length}}`);
return `${string}${rowID.replace(re,'')}`;
};
/**
* Alias for generateRowID that adds the new id to the {@link sectionObj}. Also allows for creation of custom IDs that conform to the section ID requirements.
* @name generateRowID
* @param {string} section - The section name to create an ID for. The `repeating_` prefix is optional so both `repeating_equipment` and `equipment` are valid.
* @param {sectionObj} sections
* @param {string} [customText] - Custom text to start the ID with. This text should not be longer than the standard repeating section ID format.
* @returns {any}
*/
docs.js['k.generateRowID'] = {
type:'function',
invocation:`k.generateRowID(section,sections,customText)`,
description:'Alias for generateRowID that adds the new id to the sections object. Also allows for creation of custom IDs that conform to the section ID requirements.',
arguments:[
{type:'string',name:'setObj',description:'The section name to create an ID for. The `repeating_` prefix is optional so both `repeating_equipment` and `equipment` are valid.'},
{type:'object',name:'vocal',description:'Object containing the IDs for the repeating sections, indexed by repeating section name.'},
{type:'string',name:'customText',description:'Custom text to start the ID with. This text should not be longer than the standard repeating section ID format.'}
]
};
const _generateRowID = function(section,sections,customText){
let rowID = customText ?
generateCustomID(customText) :
generateRowID();
section = section.match(/^repeating_[^_]+$/) ?
section :
`repeating_${section}`;
sections[section] = sections[section] || [];
sections[section].push(rowID);
return `${section}_${rowID}`;
};
kFuncs.generateRowID = _generateRowID;/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
const listeners = {};
const baseGet = Object.entries(cascades).reduce((memo,[attrName,detailObj])=>{
if(!/repeating/.test(attrName) && detailObj.type !== 'action'){
memo.push(detailObj.name);
}
if(detailObj.listener){
listeners[detailObj.listener] = detailObj.listenerFunc;
}
return memo;
},[]);
kFuncs.baseGet = baseGet;
const registerEventHandlers = function(){
on('sheet:opened',updateSheet);
debug({funcKeys:Object.keys(funcs),funcs});
//Roll20 change and click listeners
Object.entries(listeners).forEach(([event,funcName])=>{
if(funcs[funcName]){
on(event,funcs[funcName]);
}else{
debug(`!!!Warning!!! no function named ${funcName} found. No listener created for ${event}`,true);
}
});
log(`kScaffold Loaded`);
};
setTimeout(registerEventHandlers,0);//Delay the execution of event registration to ensure all event properties are present.
const addItem = function(event){
let [,,section] = parseClickTrigger(event.triggerName);
section = section.replace(/add-/,'');
let rowID = generateRowID();
const setObj = {};
setObj[`repeating_${section}_${rowID}_name`] = '';
k.setAttrs(setObj);
};
registerFuncs({addItem});
const editSection = function(event){
let [,,section] = parseClickTrigger(event.triggerName);
section = section.replace(/edit-/,'');
let target = `fieldset.repeating_${section} + .repcontainer`;
$20(target).toggleClass('editmode');
};
registerFuncs({editSection});return kFuncs;
}());
const actionAttributes = ["repeating_skill_$x_action","intellect_action","might_action","presence_action","cunning_action","dexterity_action","manipulation_action","resolve_action","stamina_action","composure_action","movement_dice_action","defense_action","repeating_calling_$x_clash_action","repeating_purview_$x_clash_action","primary_pool_action","secondary_pool_action","desperation_pool_action","initiative_action"];const inlineFieldsets = ["quality","flair","extra","calling","antagonist purview"];
/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
//Sheet Variables
k.sheetName = 'Storypath';
k.version = 1.02;
const sectionDisplays = {
general:['section-skills','section-attributes','section-equipment','section-notes','section-deeds'],
powers:['section-paths','section-calling','section-purview','section-birthrights']
};
sectionDisplays.all = Object.entries(sectionDisplays).reduce((arr,[prop,sections])=>[...arr,...sections],[]);
const navDisplays = {
antagonist:{show:['antagonist'],hide:['all','general','powers','gm_screen','party_screen']},
character:{show:['all','general','powers'],hide:['antagonist','gm_screen','party_screen']},
gm_screen:{show:['gm_screen'],hide:['all','general','powers','antagonist','party_screen']},
party_screen:{show:['party_screen'],hide:['all','general','powers','antagonist','gm_screen']}
};
const generalSections = ['skills','attributes','equipment','notes','deeds'];
const powerSections = ['paths','calling','purview','birthrights'];
//Object that defines how the attributes affect each other
const complexRepeatingSections = ['repeating_calling','repeating_path','repeating_purview'];
const collapsibleMasters = ['repeating_path','repeating_purview'];
const systemDefaults = {
'scion-origin':{
repeating_skill:{field:'name',additional:false,values:['academics','athletics','close combat','culture','empathy','firearms','integrity','leadership','medicine','occult','persuasion','pilot','science','subterfuge','survival','technology']},
repeating_path:{field:'display_state',values:['master','add-detail'],additional:true},
repeating_calling:{field:'display_state',values:['master','add-detail'],additional:true},
repeating_deed:{field:'type',values:['short','long','band'],additional:true},
'repeating_completed-deed':{field:'type',values:[],additional:true},
repeating_injury:{field:'type',values:['taken out'],additional:true},
repeating_equipment:{number:0,field:'display_state',values:['equipment'],additional:true},
repeating_quality:{number:0,field:'name',values:[''],additional:true},
repeating_flair:{number:0,field:'name',values:[''],additional:true},
repeating_extra:{number:0,field:'name',values:[''],additional:true},
'repeating_antagonist-calling':{number:0,field:'name',values:[''],additional:true},
'repeating_antagonist-purview':{number:0,field:'name',values:[''],additional:true},
attributes:['intellect','cunning','resolve','might','dexterity','stamina','presence','manipulation','composure'],
clashStats:['intellect','cunning','resolve','might','dexterity','stamina','presence','manipulation','composure']
},
'scion-hero':{
repeating_skill:{field:'name',additional:false,values:['academics','athletics','close combat','culture','empathy','firearms','integrity','leadership','medicine','occult','persuasion','pilot','science','subterfuge','survival','technology']},
repeating_path:{field:'display_state',values:['master','add-detail'],additional:true},
repeating_calling:{field:'display_state',values:['master','add-detail'],additional:true},
repeating_deed:{field:'type',values:['short','long','band'],additional:true},
'repeating_completed-deed':{field:'type',values:[],additional:true},
repeating_injury:{field:'type',values:['taken out'],additional:true},
repeating_purview:{field:'display_state',values:['master','add-detail'],additional:true},
repeating_birthright:{number:0,additional:true},
repeating_equipment:{number:0,field:'display_state',values:['equipment'],additional:true},
repeating_quality:{number:0,field:'name',values:[''],additional:true},
repeating_flair:{number:0,field:'name',values:[''],additional:true},
repeating_extra:{number:0,field:'name',values:[''],additional:true},
'repeating_antagonist-calling':{number:0,field:'name',values:[''],additional:true},
'repeating_antagonist-purview':{number:0,field:'name',values:[''],additional:true},
attributes:['intellect','cunning','resolve','might','dexterity','stamina','presence','manipulation','composure'],
clashStats:['legend','intellect','cunning','resolve','might','dexterity','stamina','presence','manipulation','composure']
}
};
const systems = ['scion-origin','scion-hero'];
const repeatMonitor = [];/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
const styleOnOpen = function({attributes,sections}){
navigateSheet({attributes});
setupSystem({attributes,sections});
styleCharacterType({attributes});
retrieveHeaders(attributes);
};
k.registerFuncs({styleOnOpen},{type:['opener']})
const retrieveHeaders = function(attributes){
let collapsed = attributes.collapsed.split(/\s*,\s*/).filter(c=>!/^\s*$/.test(c) && c !== 'completed deeds');
collapsed.forEach((c)=>{
$20(`.${c}.expandable-header`).addClass('collapse');
});
};/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
/*
Sheet Styling
*/
const navigateSheet = function({trigger,attributes}){
k.debug('navigating sheet');
let triggerName = trigger ?
trigger.name :
attributes.sheet_state;
let target = triggerName.replace(/clicked:|nav-/g,'');
k.debug({target});
$20('.navigable-section,.sheet-nav__tab').removeClass('active');
$20(`.sheet-nav__tab.${target},.navigable-section--${target}`).addClass('active');
attributes.sheet_state = target;
};
k.registerFuncs({navigateSheet});
const setupSystem = function({attributes,sections}){
let system = attributes.system;
createSections(system,attributes,sections);
systems.forEach((sys)=>{
let action = sys === system ? 'addClass' : 'removeClass';
$20(`.subsystem-style`)[action](`system-${sys}`);
$20(`.${sys}${sys===system ? '' : `:not(.${system})`}`)[action]('active');
});
setupAttributes(system,attributes);
};
k.registerFuncs({setupSystem});
const setupAttributes = function(system,attributes){
let attrArr = systemDefaults[system].attributes;
attrArr.forEach((attr)=>{
attributes[attr] = attributes[attr] || 1;
});
};
const createSections = function(system,attributes,sections){
let details = systemDefaults[system];
Object.keys(sections).forEach((section)=>{
let sectionDetails = details[section];
if(sectionDetails){
checkSectionContents(sectionDetails,section,sections,attributes);
}else{
sections[section].forEach((id)=>{//clean up unneeded sections
sections[section].forEach((id)=>{
k.removeRepeatingRow(`${section}_${id}`,attributes,sections);
});
});
}
});
};
const checkSectionContents = function(sectionDetails,section,sections,attributes){
const IDs = [...sections[section]];
if(sectionDetails.hasOwnProperty('number')){
let missing = Math.max(sectionDetails.number - sections[section].length,0);
_.range(missing).forEach(()=>{
let row = k.generateRowID(section,sections);
attributes[`${row}_${sectionDetails.field || 'name'}`] = sectionDetails.values[0];
});
}else if(sectionDetails.values){
let missing = [];//Array to store missing values
let unusedIDs = {};//Object to store whether IDs are needed (true) or not (false).
sectionDetails.values.forEach((val)=>{
let found = IDs.some((id)=>{
if(attributes[`${section}_${id}_${sectionDetails.field}`].endsWith(val)){
unusedIDs[id] = true;
return true;
}else{
unusedIDs[id] = unusedIDs[id] || false;
return false;
}
},false);
if(!found){
missing.push(val);
}
return found;
});
if(missing.length){
const parentChild = {
parentID:null,
children:[]
};
missing.forEach((val)=>{
let newRow = k.generateRowID(section,sections,val === 'add-detail' ? 'ADD' : '');
let newID = newRow.replace(/repeating_[^_]+_/,'');
if(complexRepeatingSections.indexOf(section) >= 0){
if(val === 'master'){
parentChild.parentID = newID.toLowerCase();
}else{
parentChild.children.push(newID);
}
}
attributes[`${newRow}_${sectionDetails.field}`] = val;
if(sectionDetails.additionalFields){
sectionDetails.additionalFields
}
attributes[`${newRow}_display_state`] = val;
if(/calling/.test(section)){
attributes[`${newRow}_rating_max`] = 1;
}
});
if(parentChild.parentID){
parentChild.children.forEach((id)=>{
attributes[`${section}_${id}_master_id`] = parentChild.parentID;
});
orderComplex({section,attributes,sections});
}
}
if(!sectionDetails.additional){
Object.keys(unusedIDs).forEach((id)=>{
if(!unusedIDs[id]){
_removeRepeatingRow(`${section}_${id}`,attributes,sections);
}
});
}
}
};/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
//Expands/collapses the sections
const expandHeader = function(event){
let [section,rowID,name] = k.parseClickTrigger(event.triggerName);
const target = `.${name}.expandable-header`;
k.getAllAttrs({props:['collapsed'],callback:(attributes,sections)=>{
let collapsed = attributes.collapsed.split(/\s*,\s*/);
if(section){
name = 'completed deeds';
let hide = 0
if(collapsed.indexOf(name) < 0){
collapsed.push(name);
hide = 1;
}else{
collapsed = collapsed.filter(b => b!==name && !/^\s*$/.test(b) );
}
sections[section].forEach((id)=>{
attributes[`${section}_${id}_hide`] = attributes[`${section}_${id}_completed`] ? hide : 0;
});
}else{
if(collapsed.indexOf(name) < 0){
collapsed.push(name);
}else{
collapsed = collapsed.filter(b => b!==name && !/^\s*$/.test(b) );
}
$20(target).toggleClass('collapse');
}
attributes.collapsed = collapsed.join(',');
attributes.set();
}})
};
k.registerFuncs({expandHeader});
//adds a subsection (e.g. a knack) to the over section (e.g. repeating_calling)
const addSubsection = async function(event){
let [section,rowID,button] = k.parseClickTrigger(event.triggerName);
let type = button.replace(/add-/,'');
let newID = generateRowID();
k.getAllAttrs({props:[],callback:(attributes,sections,casc)=>{
if(/birthright/.test(type)){
addBirthright(attributes,type,newID);
}else{
addChildSection(attributes,sections,section,rowID,type,newID)
}
}})
};
k.registerFuncs({addSubsection});
const addChildSection = function(attributes,sections,section,rowID,type,newID){
attributes[`${section}_${newID}_type`]=type;
attributes[`${section}_${newID}_display_state`]=type;
attributes[`${section}_${newID}_master_id`]=attributes[`${section}_${rowID}_master_id`];
if(/path/.test(section)){
attributes[`${section}_${newID}_rating`] = 1;
}
let triggerPos = sections[section].indexOf(rowID);
sections[section].splice(triggerPos,0,newID);
attributes[section] = sections[section];
attributes.set();
};
const addBirthright = function(attributes,type,newID){
type = type.replace(/birthright-/,'');
attributes[`repeating_birthright_${newID}_type`]=type;
attributes[`repeating_birthright_${newID}_display_state`]=type;
attributes[`repeating_birthright_${newID}_rating`]=1;
attributes.set();
};
const sectionInteract = function(event){
let [action,targetSection] = extractRepcontrolDetails(event.htmlAttributes.name);
const interactSwitch = {
add:addRow,
edit:editSection
};
interactSwitch[action](targetSection);
};
k.registerFuncs({sectionInteract});
const extractRepcontrolDetails = function(name){
let match = name ? name.match(/^act_(.+?)-(.+)/) : [null,null,null];
match.shift();
return match;
};
const addRow = function(section){
k.getAllAttrs({callback:(attributes,sections)=>{
let IDs = sections[`repeating_${section}`];
system = attributes.system;
const defaults = systemDefaults[system][`repeating_${section}`];
if(!defaults) return;
let rowID;
let row;
const childParent = {
parent:'',
children:[]
}
if(!defaults.values){
row = k.generateRowID(section,sections);
attributes[`${row}_${defaults.field}`]='';
}else if(section==='deed'){
addDeed(system,attributes,sections);
}else if(section === 'injury'){
addInjury(system,attributes,sections);
}else{
defaults.values.forEach((value)=>{
row = k.generateRowID(section,sections,value === 'add-detail' ? 'ADD' : '');
rowID = row.replace(/repeating_[^_]+_/,'');
if(value === 'add-detail'){
childParent.children.push(rowID);
}else{
childParent.parent = rowID.toLowerCase();
}
attributes[`${row}_${defaults.field}`] = value;
attributes[`${row}_display_state`] = value;
if(/calling/.test(section)){
attributes[`${row}_rating_max`] = 1;
}
});
childParent.children.forEach((id)=>{
attributes[`repeating_${section}_${id}_master_id`] = childParent.parent;
});
orderComplex({section,attributes,sections});
}
attributes.set();
}});
};
const editSection = function(section){
let target = `fieldset.repeating_${section} + .repcontainer`;
$20(target).toggleClass('editmode');
if(section === 'deed'){
$20(target.replace(/deed/,'completed-deed')).toggleClass('editmode');
}
};
const addInjury = function(system,attributes,sections){
const injuryTracks = {
'scion-origin':attributes.stamina > 0 ? ['bruised','injured','maimed','taken out'] : ['bruised','maimed','taken out']
};
const injuryPositions = {
bruised:(attributes,sections)=>getBruiseIndex(attributes,sections),
injured:(attributes,sections)=>getInjuredIndex(attributes,sections),
maimed:(attributes,sections)=>getMaimedIndex(attributes,sections),
};
injuryTracks['scion-hero'] = injuryTracks['scion-origin'];
let newInjury = injuryTracks[system].find((injury)=>{
return sections.repeating_injury.every((id)=>{
return attributes[`repeating_injury_${id}_type`] !== injury
});
}) || 'bruised';
let newID = generateRowID();
let newRow = `repeating_injury_${newID}`;
attributes[`${newRow}_type`] = newInjury;
attributes[`${newRow}_display_state`] = `short-${newInjury}`;
attributes[`${newRow}_collapse`] = 1;
attributes[`${newRow}_name`] = ' ';
if(newInjury !== 'taken out'){
let index = injuryPositions[newInjury](attributes,sections);
sections.repeating_injury.splice(index,0,newID);
}else{
sections.repeating_injury.push(newID);
}
attributes.repeating_injury = sections.repeating_injury;
};
const getBruiseIndex = function(attributes,sections){
return _.range(sections.repeating_injury.length).find((index)=>{
return attributes[`repeating_injury_${sections.repeating_injury[index]}_type`]==='bruised';
}) || 0;
};
const getInjuredIndex = function(attributes,sections){
return _.range(sections.repeating_injury.length).find((index)=>{
return /injured|maimed|taken out/.test(attributes[`repeating_injury_${sections.repeating_injury[index]}_type`]);
}) || sections.repeating_injury.length - 1;
};
const getMaimedIndex = function(attributes,sections){
return _.range(sections.repeating_injury.length).find((index)=>{
return /maimed|taken out/.test(attributes[`repeating_injury_${sections.repeating_injury[index]}_type`]);
}) || sections.repeating_injury.length - 1;
};
const addDeed = function(system,attributes,sections){
let needed = systemDefaults[system].repeating_deed.values.find((deed)=>{
return sections.repeating_deed.every((id)=>{
return attributes[`repeating_deed_${id}_type`]!==deed || attributes[`repeating_deed_${id}_completed`]
});
}) || systemDefaults[system].repeating_deed.values[0];
let rowID = generateRowID();
let headIndex = sections.repeating_deed.indexOf('-completeheaderstyle');
headIndex = headIndex >= 0 ? headIndex : sections.repeating_deed.length;
sections.repeating_deed.splice(headIndex,0,rowID);
attributes.repeating_deed = sections.repeating_deed;
attributes[`repeating_deed_${rowID}_type`] = needed;
attributes[`repeating_deed_${rowID}_display_state`] = needed;
attributes.repeating_deed = sections.repeating_deed;
};
/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
// Triggered Functions
const collapseSection = function({trigger,attributes,sections}){
const [section,rowID,field] = k.parseTriggerName(trigger.name);
if(attributes[`${section}_${rowID}_type`] === 'add-detail') return;
let collapse = attributes[trigger.name];
let rows;
if(/master/.test(attributes[`${section}_${rowID}_display_state`])){
rows = sections[section].filter((id)=>{
return attributes[`${section}_${id}_master_id`]===rowID && attributes[`${section}_${id}_display_state`] !== 'add-detail';
});
if(collapsibleMasters.indexOf(section)>=0){
rows.push(rowID);
}
}else{
rows = [rowID];
}
rows.forEach((id)=>{
if(collapse){
if(!attributes[`${section}_${id}_display_state`].startsWith('short-')){
attributes[`${section}_${id}_display_state`] = `short-${attributes[`${section}_${id}_display_state`]}`;
attributes[`${section}_${id}_collapse`] = 1;
}
}else{
attributes[`${section}_${id}_display_state`] = attributes[`${section}_${id}_display_state`].replace(/short-/,'');
attributes[`${section}_${id}_collapse`] = 0;
}
});
};
k.registerFuncs({collapseSection});
const sumActiveCallings = function({trigger,attributes,sections}){
const [section,rowID,field] = k.parseTriggerName(trigger.name);
const masterID = attributes[`${section}_${rowID}_master_id`] || rowID;
const knackCosts = {
mortal:1,
immortal:2
}
let knackIDs = sections[section].filter((id)=>attributes[`${section}_${id}_master_id`] === masterID);
let spent = knackIDs.reduce((m,id)=>{
return m+= attributes[`${section}_${id}_active`] * knackCosts[attributes[`${section}_${id}_level`]];
},0);
if(spent > attributes[`${section}_${masterID}_rating_max`]){
if(/active|level/.test(field)){
attributes[`${section}_${rowID}_active`] = 0;
}else{
//Clear all knacks if the calling's level has lowered below the currently used
knackIDs.forEach((id)=>{
attributes[`${section}_${id}_active`] = 0;
attributes[`${section}_${masterID}_rating`] = 0;
});
}
}else{
attributes[`${section}_${masterID}_rating`] = spent;
}
};
k.registerFuncs({sumActiveCallings});
const orderDeeds = function({trigger,attributes,sections}){
const [section,rowID,field] = k.parseTriggerName(trigger.name);
const newSection = /completed/.test(section) ?
'deed' :
'completed-deed';
const newRow = k.generateRowID(newSection,sections);
['type','name','completed'].forEach((attr)=>{
attributes[`${newRow}_${attr}`] = attributes[`${section}_${rowID}_${attr}`];
});
k.removeRepeatingRow(`${section}_${rowID}`,attributes,sections);
deedDisplay({sections});
};
k.registerFuncs({orderDeeds});
const deedDisplay = function({sections}){
k.debug({sections});
const action = sections['repeating_completed-deed'].length ?
'remove' :
'add';
$20('.completed-deed')[`${action}Class`]('disable');
$20('.completed-deed ~ .repcontainer')[`${action}Class`]('disable');
};
k.registerFuncs({deedDisplay},{type:['opener']});
const clashBasis = function({trigger,attributes,sections}){
let [section,rowID] = k.parseTriggerName(trigger.name);
let filterState = section ? (str)=>str===rowID : (str)=>str;
let queue = sections.repeating_calling.filter(id=>filterState(attributes[`repeating_calling_${id}_master_id`]) && /knack/.test(attributes[`repeating_calling_${id}_display_state`]));
queue.forEach((id)=>{
let masterID = attributes[`repeating_calling_${id}_master_id`];
if(attributes.system === 'scion-origin' || attributes[`repeating_calling_${masterID}_rating_max`] >= attributes.legend_max){
attributes[`repeating_calling_${id}_clash_stat_2`] = 'rating';
}else{
attributes[`repeating_calling_${id}_clash_stat_2`] = 'legend';
}
})
};
k.registerFuncs({clashBasis});
const styleCharacterType = function({attributes}){
let type = attributes.sheet_type.replace(/\s+/g,'_');
k.debug({type});
$20('.sheet-nav__tab--possible').addClass('disable');
$20(`.sheet-nav__tab--possible--${type}`).removeClass('disable');
};
k.registerFuncs({styleCharacterType});/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
/*
Calculation Functions
These functions must return a value to be applied to an attribute
*/
const defenseCalc = function({attributes}){
return Math.max(attributes.resolve,attributes.stamina,attributes.composure);
};
k.registerFuncs({defenseCalc});
const calcXP = function({attributes}){
return attributes.experience_earned - attributes.experience_used;
};
k.registerFuncs({calcXP});
const movementCalc = function({attributes,sections}){
const athleticsID = sections.repeating_skill.find((id)=>attributes[`repeating_skill_${id}_name`] === 'athletics');
return attributes[`repeating_skill_${athleticsID}_rating`] +
Math.max(
1,
attributes.might,
attributes.dexterity
);
};
k.registerFuncs({movementCalc});/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
/*
Rolls
*/
const singleAttributeRoll = function(event){
let [,,button] = k.parseClickTrigger(event.triggerName);
let field = button.replace(/-action$/,'').replace(/-/g,'_');
k.getAllAttrs({
props:[...k.baseGet,'difficulty_query','target_number'],sectionDetails:[],
callback:async (attributes)=>{
let [pool,addDice] = await assemblePool(attributes[field],0);
let enhancements = 0;
if(attributes.enhancement_query === 'on'){
enhancements = await k.extractQueryResult(getTranslationByKey('Do you have any enhancements'));
enhancements = k.value(enhancements);
}else{
await pseudoQuery('');
}
let [message,reusableMessage] = await assembleMessage(attributes,pool,field.replace(/_/g,' '),null,null,enhancements);
let confirm;
if(attributes.enhancement_query === 'on' || attributes.difficulty_query === 'on'){
confirm = await confirmRoll(attributes,{skillName:`^{${field.replace(/_/g,' ')}}`,skillDice:attributes[field],enhancements,addDice});
}else{
confirm = await k.pseudoQuery(1);
}
if(k.value(confirm)){
executeRoll(attributes,reusableMessage,message);
}
}
});
};
k.registerFuncs({singleAttributeRoll});
const rollTask = function(event){
k.getAllAttrs({
props:[...k.baseGet,'difficulty_query','target_number'],
callback:async (attributes,sections)=>{
let [pool,skillName,attributeName,enhancements] = await queryPool(event.triggerName,attributes,sections);
if(!pool && !skillName && !attributeName){
return;
}
let [message,reusableMessage] = await assembleMessage(attributes,pool,skillName,attributeName,null,enhancements);
executeRoll(attributes,reusableMessage,message);
}
})
};
k.registerFuncs({rollTask});
const queryPool = async function(clicked,attributes,sections){
let [section,rowID,field] = k.parseClickTrigger(clicked);
field = field.replace(/-action$/,'');
let query;
let queryOptions;
let queryPrompt;
let skillDice;
let attributeDice;
let attributeName;
let skillName;
if(section === 'repeating_skill'){
let systemDetails = systemDefaults[attributes.system];
queryOptions = systemDetails.attributes.reduce((m,attr)=>{
m.push(`${k.capitalize(getTranslationByKey(attr))},${attr}`);
return m;
},[]).join('|');
queryPrompt = getTranslationByKey('attribute query');
skillDice = attributes[`${section}_${rowID}_rating`];
skillName = `^{@{${section}_${rowID}_name}}`;
}else{
let fieldRef = section ? parseSectionRoll(section,rowID,attributes,sections) : field;
section = 'repeating_skill';
queryOptions = sections[section].reduce((m,id)=>{
m.push(`${k.capitalize(getTranslationByKey(attributes[`${section}_${id}_name`]))},${section}_${id}`);
return m;
},[]).join('|')
queryPrompt = getTranslationByKey('skill query');
attributeDice = attributes[fieldRef];
attributeName = `^{${field}}`;
}
query = `${queryPrompt}|${queryOptions}`;
let queryResult = await k.extractQueryResult(query);
if(!attributeDice){
attributeDice = attributes[queryResult];
attributeName = `^{${queryResult}}`;
}else{
skillDice = attributes[`${queryResult}_rating`];
skillName = `^{@{${queryResult}_name}}`;
}
let [pool,addDice] = await assemblePool(skillDice,attributeDice)
let enhancements = 0;
if(attributes.enhancement_query === 'on'){
enhancements = await k.extractQueryResult(getTranslationByKey('Do you have any enhancements'));
enhancements = k.value(enhancements);
}else{
await k.pseudoQuery('');
}
let confirm = await confirmRoll(attributes,{skillName,skillDice,attributeName,attributeDice,enhancements,addDice});
if(k.value(confirm)){
return [pool,skillName,attributeName,enhancements];
}else{
return [];
}
};
const rollClash = async function(event){
k.getAllAttrs({
callback:async (attributes,sections)=>{
let [section,rowID,] = k.parseClickTrigger(event.triggerName);
const masterID = attributes[`${section}_${rowID}_master_id`];
let skillRef;
let attributeRef;
let skillName;
if(attributes[`${section}_${rowID}_clash_stat_2`] === 'select'){
return;
}
switch(attributes[`${section}_${rowID}_clash_stat_1`]){
case 'query':
skillRef = await buildQuery('skill query','repeating_skill',attributes,sections)
break;
case 'select':
skillRef = sections.repeating_skill.find((id)=>attributes[`repeating_skill_${id}_name`] === 'integrity');
skillRef = `repeating_skill_${skillRef}_rating`;
break;
default:
skillRef = sections.repeating_skill.find((id)=>attributes[`repeating_skill_${id}_name`] === attributes[`${section}_${rowID}_clash_stat_1`]);
if(!skillRef){
const attributeNames = systemDefaults[attributes.system].attributes;
k.debug({attributeNames});
skillRef = [...attributeNames,'legend'].find((attr)=>attr === attributes[`${section}_${rowID}_clash_stat_1`]);
skillName = `^{${skillRef}}`;
skillRef = skillRef === 'legend' ?
'legend_max' :
skillRef;
}else{
skillRef = `repeating_skill_${skillRef}_rating`;
}
break;
}
if(!skillRef){
return;
}
switch(attributes[`${section}_${rowID}_clash_stat_2`]){
case 'rating':
attributeRef = `${section}_${masterID}_rating_max`;
k.debug({attributeRef});
break;
case 'query':
attributeRef = await buildQuery('attribute query',systemDefaults[attributes.system].clashStats,attributes,sections);
break;
default:
attributeRef = attributes[`${section}_${rowID}_clash_stat_2`]
break;
}
if(!attributeRef){
return;
}
skillName = skillName || `^{${attributes[skillRef.replace(/rating/,'name')]}}`;
let attributeName = attributeRef.startsWith('repeating') ? '^{rating}' : `^{${attributeRef}}`;
let skillPool = attributes[skillRef];
if(attributes[`${section}_${rowID}_clash_stat_2`] === 'rating' && attributes.legend_max > attributes[attributeRef]){
attributeRef = 'legend';
attributeName = '^{legend}';
}
let attributePool = attributeRef === 'legend' ? attributes[`${attributeRef}_max`] : attributes[attributeRef];
let [pool,addDice] = await assemblePool(skillPool,attributePool);
let enhancements = 0;
if(attributes.enhancement_query === 'on'){
enhancements = await k.extractQueryResult(getTranslationByKey('Do you have any enhancements'));
enhancements = k.value(enhancements);
}else{
await k.pseudoQuery('');
}
let [message,reusableMessage] = await assembleMessage(attributes,pool,skillName,attributeName,attributes[`${section}_${rowID}_name`],enhancements);
if(section === 'repeating_purview'){
const vsRef = `${section}_${rowID}_clash_stat`
let vsMessage = '';
if(attributes[`${vsRef}_1`] !== 'select'){
vsMessage += attributes[`${vsRef}_1`];
}
if(attributes[`${vsRef}_2`] !== 'select'){
vsMessage += ` & ${attributes[`${vsRef}_2`]}`
}
message += `{{vs=${vsMessage}}}`;
}
const confirmObject = {
skillName:/\^\{/.test(skillRef) ?
skillRef.replace(/\^\{|\}/g,'') :
`@{${skillRef}}`,
skillDice:skillPool,
attributeName:`@{${attributeRef}}`,
attributeDice:attributePool,
enhancements,
addDice
};
let confirm = await confirmRoll(attributes,confirmObject);
if(k.value(confirm)){
executeRoll(attributes,reusableMessage,message);
}
}
});
};
k.registerFuncs({rollClash});
const assembleMessage = async function(attributes,pool,skillName,attributeName,rollTitle,enhancements){
let reusableMessage = `{{successes=[[0['computed value']]]}} {{display_dice=true}} {{system=${attributes.system}}} {{finished=[[0]]}} {{enhancements=[[${enhancements}]]}}`;
if(attributes.difficulty_query === 'on'){
let difficulty = await k.extractQueryResult(`${getTranslationByKey('difficulty query')}|0`);
reusableMessage = `{{difficulty=[[0${difficulty}]]}} {{extra_successes=[[0[computed value]]]}} ${reusableMessage}`;
}else{
await k.pseudoQuery('');
}
return [`@{template_start} ${reusableMessage} ${rollTitle ? `{{title=${rollTitle}}}` : ''} {{skill=${skillName || ''}}} {{attribute=${attributeName || ''}}} ${pool} {{first=true}}`,reusableMessage];
};
const buildQuery = async function(prompt,options,attributes,sections){
if(typeof options === 'string'){
options = options.startsWith('repeating') ? sections[options].map(id=>`${k.capitalize(getTranslationByKey(attributes[`${options}_${id}_name`]))},${options}_${id}_rating`) : '';
}
let query = `${getTranslationByKey(prompt)}|${options.join('|')}`;
return await k.extractQueryResult(query);
};
const assemblePool = async function(skillDice,attributeDice){
const baseDice = k.value(skillDice)+k.value(attributeDice);
const additionalDice = await k.extractQueryResult(`${getTranslationByKey('additional dice query')}|${[...Array(Math.max(0,10 - baseDice) + 1).keys()].map(k=>k).join('|')}|`);
return [[...Array(baseDice + (+additionalDice)).keys()].map((n)=>{
return `{{roll_${n+1}=[[1d10cs>@{target_number}cf<1cf>@{again}]]}}`;
}).join(' ').trim() || '{{roll_1=^{no dice available}}}',+additionalDice];
};
const confirmRoll = function(attributes,{skillName,skillDice,attributeName,attributeDice,enhancements,addDice}){
let promptLookup = 'Roll {{skill}} and {{attribute}} with {{enhancement number}} enhancements and {{addDice}} additional dice?';
k.debug({addDice});
if(!skillName && !attributeName){
return k.pseudoQuery(1);
}else if(!skillName){
promptLookup = promptLookup.replace(/\{\{skill\}\} and /,'');
}else if(!attributeName){
promptLookup = promptLookup.replace(/ and \{\{attribute\}\}/,'');
}
if(!enhancements){
promptLookup = promptLookup.replace(/ \{\{enhancement number\}\} enhancements and/,'');
}
if(!addDice){
promptLookup = promptLookup.replace(/\s+(?:and|with) \{\{addDice\}\} additional dice/,'');
}
k.debug({promptLookup});
let prompt = getTranslationByKey(promptLookup);
const rollDetails = {[skillName]:skillDice,[attributeName]:attributeDice,enhancements,addDice};
k.debug({rollDetails});
k.debug({prompt});
Object.entries(rollDetails).forEach(([name,val],index)=>{
k.debug({name,val});
name = /^\^\{/.test(name) ?
(
/@{/.test(name) ?
getTranslationByKey(attributes[name.replace(/[\^@]{|}/g,'')]) :
getTranslationByKey(name.replace(/^\^{|}$/g,''))
) :
name;
let replaceText = name !== 'enhancements' && name !== 'addDice' ?
`${k.capitalize(name)} (${val})` :
val;
let replaceTarget = `\\{\\{${index}\\}\\}`;
prompt = prompt.replace(new RegExp(replaceTarget,'g'),replaceText);
});
k.debug({prompt});
return k.extractQueryResult(`${prompt}|${getTranslationByKey('Yes')},1|${getTranslationByKey('No')},0`);
};
const executeRoll = async function(attributes,reusableMessage,message,accumulator = {successes:0}){
const rollNums = [1,2,3,4,5,6,7,8,9,10];
let roll = await startRoll(message);
const computeObj = {};
const tn = attributes.target_number;
accumulator.successes = Object.keys(roll.results).reduce((total,key)=>{
return total += (/roll_/.test(key) && roll.results[key].result >= tn) ? 1 : 0;
},accumulator.successes);
if(rollNums.some((n)=>roll.results[`roll_${n}`] && roll.results[`roll_${n}`].result >= attributes.again)){
let pool = rollNums.reduce((m,n)=>{
if(roll.results[`roll_${n}`] && roll.results[`roll_${n}`].result >= Math.max(attributes.again,5)){
m+=`{{roll_${n}=[[1d10cs>@{target_number}cf<1cf>@{again}]]}}`;
}
return m;
},'');
let newMessage = `@{template_start} ${reusableMessage} ${pool} {{continuation=true}}`;
executeRoll(attributes,reusableMessage,newMessage,accumulator);
}else{
computeObj.finished = 1;
computeObj.successes = accumulator.successes;
if(accumulator.successes){
computeObj.successes += (roll.results.enhancements.result || 0);
}
if(roll.results.difficulty){
computeObj.extra_successes = Math.max(computeObj.successes - roll.results.difficulty.result,0);
}
}
finishRoll(roll.rollId,computeObj);
};
const parseSectionRoll = function(section,rowID,attributes){
let masterID = section === 'repeating_path' ? rowID : (attributes[`${section}_${rowID}_master_id`] || rowID);
return `${section}_${masterID}_rating`;
};
/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
const clearChildItems = function(event){
const [section,masterID] = k.parseRepeatName(event.sourceAttribute);
k.getAllAttrs({
callback:(attributes,sections,)=>{
if(/master/.test(event.removedInfo[`${section}_${masterID}_display_state`])){
sections[section].forEach((id)=>{
if(attributes[`${section}_${id}_master_id`]===masterID.toLowerCase()){
k.removeRepeatingRow(`${section}_${id}`,attributes,sections);
}
});
}else if(/injury|calling|deed/.test(section)){
//cleanUpSection(attributes,sections,section,masterID);
}
//The below is a temporary fix for display issues associated with setSectionOrder
let clearID = attributes.attributes[`_reporder_${section}`].find(id=>Object.keys(attributes.attributes).some((attr)=>attr.startsWith(`${section}_${id}`)));
if(clearID){
attributes[`${section}_${clearID}_display_state`] = attributes[`${section}_${clearID}_display_state`];
attributes.set();
}
}
});
};
k.registerFuncs({clearChildItems});
const cleanUpSection = function(attributes,sections,section,masterID){
let trigger;
switch(section){
case 'repeating_injury':
//Health handling
break;
case 'repeating_calling':
trigger = {name:`${section}_${masterID}_rating_max`};
sumActiveCallings(trigger,attributes,sections);
break;
case 'repeating_deed':
//remove completed deeds header if no completed deeds
//orderDeeds(trigger,attributes,sections);
break;
}
};/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
const resetOrderStyling = function(attributes,reset=false){//Temporary fix for display issue with reordering section`s via setSectionOrder
const clearObj = {};
let updateKeys = Object.keys(attributes.updates);
let unusedSections = ['repeating_injury','repeating_path','repeating_calling'].filter((sec)=>updateKeys.every((attr)=>!attr.startsWith(sec)));
unusedSections.some((section)=>{
let id = attributes.attributes[`_reporder_${section}`] && attributes.attributes[`_reporder_${section}`].find(i=>Object.keys(attributes.attributes).some((attr)=>attr.startsWith(`${section}_${i}`)));
if(id){
attributes[`${section}_${id}_display_state`] = attributes[`${section}_${id}_display_state`];
clearObj[`${section}_${id}_display_state`] = 'loading';
return true;
}
});
set(clearObj,false,()=>{
let sections = Object.keys(attributes.repOrders);
sections.forEach((section)=>{
k.setSectionOrder(section,attributes.repOrders[section]);
});
if(reset){
set(attributes.attributes);
}
});
};
const orderComplex = function({section,attributes,sections}){
section = section.startsWith('repeating_') ? section : `repeating_${section}`;
const masterIDs = sections[section].filter((id)=>!attributes[`${section}_${id}_master_id`]);
sections[section] = sections[section].reduce((memo,id)=>{
if(attributes[`${section}_${id}_master_id`]){
const isDetail = attributes[`${section}_${id}_display_state`] === 'add-detail';
const lastChildIndex = getChildIndex(memo,section,id,attributes,isDetail);
if(lastChildIndex < 0){
k.removeRepeatingRow(`${section}_${id}`,attributes,sections)
}else{
memo.splice(lastChildIndex,0,id);
}
}
return memo;
},masterIDs);
attributes[section] = sections[section];
};
const getChildIndex = function(memo,section,id,attributes,detailAdd){
const lastChild = [...memo].reverse().find((fid)=>{
if(attributes[`${section}_${fid}_master_id`] === attributes[`${section}_${id}_master_id`]){
return detailAdd ?
true :
attributes[`${section}_${fid}_display_state`] !== 'add-detail';
}else{
return fid.toLowerCase() === attributes[`${section}_${id}_master_id`];
}
});
let lastIndex = memo.indexOf(lastChild);
return lastIndex >= 0 ? lastIndex + 1 : 0;
};/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
//Initiate a compendium lookup
const specialCategories = {
'antagonist-calling':'Callings',
'antagonist-purview':'Purviews'
};
//These categories are the part after the data- in a bestiary entry. E.g. a monster has a data-Armors JSON, but the actual compendium category is "Armor". These are converted to the proper compendium category via the categoryLookup Proxy
const itemCategories = ['Callings','Equipment','Knacks','Paths','Qualities','Flairs','Extras','antagonist-calling','antagonist-purview'];
//Start of the actual compendium lookup functions
//Function to initiate the lookup. Parses the statblock to figure out what needs to be looked up in the compendium, and what attribute should be filtered for based on the category.
//ARGUMENTS
//statblock (object): base object dropped from the compendium
//callback (function): A function that will use the parsed compendium lookup data to finish the drag and drop of the item
//The callback function receives the parsed statblock as an argument
const compendiumLookup = function({queue, callback, origBlock, attributes, sections, casc, pass = 0}) {
pass++;
origBlock = origBlock || queue[0];
queue = queue || [origBlock];
let searchArray = [];
queue.forEach((statblock)=>{
searchArray = itemCategories.reduce((m, type) => {//Construct an array of items to search for.
let searchType = specialCategories[type] || type;
if (statblock[`data-${type}`]){
let searchNames = statblock[`data-${type}`].map((obj) => obj.name || obj.display_name || '')
.join('|')
.replace(/\|{2,}/g,'')
.replace(/\|$/,'');
if(searchNames.length > 0){
let searchString = `Category:${searchType} display_name:${searchNames}`;
m.push(searchString);
}
}
return m;
}, searchArray);
k.debug({searchArray});
if(searchArray.length){
lookupBurndown(statblock, searchArray, callback, origBlock, attributes, sections, casc,pass);
}else{
callback(origBlock);
}
});
};
//Actually queries the compendium to get details on the items in each category using the searchArray assembled in compendiumLookup
//ARGUMENTS
//statblock (object): the original object dropped from the compendium
//callback (function): A function that will use the parsed compendium lookup data to finish the drag and drop of the item
//The callback function receives the parsed statblock as an argument
const lookupBurndown = function(statblock, searchArray, callback, origBlock, attributes, sections, casc,pass) {
getCompendiumQuery(searchArray, (dataArr) => {
k.debug({dataArr});
const expansionIDs = dataArr
.reduce( (arr,obj)=>{
arr.push(k.value(obj.data.Expansion));
return arr;
},[])
.sort((a,b) => b - a);
itemCategories.forEach((category) => {
if (statblock[`data-${category}`]) {
origBlock[`data-${category}`] = statblock[`data-${category}`].map((obj) => {
const fullItem = getItemDetails(obj, dataArr, expansionIDs);
fullItem['data-cs-name'] = fullItem['data-cs-name'] || fullItem.name;
return fullItem;
});
}
});
const queue = additionalLookups(statblock,origBlock);
if(queue.length /*&& pass < 2*/){
compendiumLookup({queue,callback,origBlock, attributes, sections, casc,pass});
}else{
callback(origBlock);
}
});
};
const additionalLookups = function(statblock,origBlock){
return Object.entries(statblock).reduce((memo,[prop,arr])=>{
if(prop.startsWith('data-') && Array.isArray(arr)){
let nestedData = arr.reduce((m,obj)=>{
Object.entries(obj).forEach(([nProp,nVal])=>{
/*commented code shouldn't be needed
if(
nProp.startsWith('data-') &&
typeof nVal === 'string' &&
nVal.startsWith('[{')
){
try{
let jArr = JSON.parse(nVal);
if(Array.isArray(jArr)){
jArr = jArr.map((o)=>{
o.datasource = obj['cs-name'] || obj.Category;
if(!o.datasource){
delete o.datasource;
}
return o;
});
origBlock[nProp] = origBlock[nProp] ?
[...origBlock[nProp],...jArr] :
[...jArr];
m.data[nProp] = jArr;
m.nested = true;
}
}catch(err){
//if the parse failed, do nothing
}
}else */
if(nProp === 'data-features'){
try{
if(typeof nVal === 'string'){
k.debug('string data-feature detected');
nVal = JSON.parse(nVal);
}
nVal.forEach((feature)=>{
if(!origBlock[`data-${feature.category}`] || origBlock[`data-${feature.category}`].every((o)=>o.display_name.toLowerCase() !== feature.name.toLowerCase())){
m.nested = true;
m.data[`data-${feature.category}`] = m.data[`data-${feature.category}`] || [];
m.data[`data-${feature.category}`].push({display_name:feature.name});
}
});
}catch(err){
k.debug({[`Invalid data-feature on ${obj.display_name}`]:err,'data-feature':nVal},true);
}
}
});
return m;
},{data:{},nested:false});
if(nestedData && nestedData.nested){
memo.push(nestedData.data);
}
}
return memo;
},[]);
};
//Finds the compendium item that most precisely matches the needs of the compendium item based on expansion ID and name property.
//If nothing matches based on expansion ID, simply returns the first item with appropriate name property.
//ARGUMENTS
//itemObj (object): the data on the Item to return that is included in the base statblock
//dataArr (array): The compendium items that were returned from getCompendiumQuery
const getItemDetails = function(itemObj, dataArr, expansionIDs) {
let objName = itemObj.display_name || itemObj.name;
let compendiumObj;
expansionIDs.find((id) => {
compendiumObj = dataArr.find((dataObj) => k.value(dataObj.data.Expansion) === id &&
dataObj.data.display_name === objName);
if (compendiumObj) {
return true;
} else {
return false;
}
});
if (!compendiumObj) { //If we didn't find an object matching the expansion pathways and the object name, just find the first item with a matching name
compendiumObj = dataArr.find((dataObj) =>
dataObj.data.display_name === objName);
if (!compendiumObj) { //If there still isn't a matching compendium object, return the original Item
return itemObj;
}
}
Object.keys(compendiumObj.data).forEach((key) => {
itemObj[key] = itemObj[key] || compendiumObj.data[key];
});
return itemObj;
};/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
const handleCompendiumDrop = function(event){
k.debug({event});
k.getAllAttrs({
callback:(attributes,sections,casc)=>{
let data = parseDropData(attributes.drop_data);
if(!data) return;
k.debug({data});
if(data.Category === 'Antagonists'){
clearSheet(attributes,sections,casc);
attributes.sheet_state = 'antagonist';
attributes.queue.push('sheet_type');
attributes.queue.push('character_name');
navigateSheet({attributes});
}
clearDropAttributes();
compendiumLookup({
origBlock:data,
attributes,sections,casc,
callback:async (lookupObj)=>{
if(lookupObj.Category === 'Antagonists'){
['Calling','Purview'].forEach((sectionType)=>{
lookupObj[`data-antagonist-${sectionType.toLowerCase()}`] = lookupObj[`data-${sectionType}s`];
delete lookupObj[`data-${sectionType}s`];
});
}
k.debug({'antagonist data':data});
await processDropData({data:lookupObj,attributes,sections,casc});
k.debug('Drop processing complete');
attributes.set({attributes,sections,casc});
}
});
}
});
};
k.registerFuncs({handleCompendiumDrop});
const parseDropData = function(drop_data){
k.debug('parsing drop data');
k.debug({drop_data:`"${drop_data}"`});
try{
let data = JSON.parse(drop_data);
data = Object.entries(data)
.reduce((memo,[key,val])=>{
if(val){
if(typeof val === 'string' && val.startsWith('[{')){
val = JSON.parse(val);
}
memo[key] = val;
}
return memo;
},{});
if(data.Category !== 'Antagonists'){
let category = data.Category.replace(/\s.+/,'');
data = {[`data-${category}`]:[data]};
if(data[`data-${category}`]['data-features']){
data[category]['data-features'].forEach((feature)=>{
let cat = k.capitalize(feature.category);
data[`data-${cat}`] = data[`data-${cat}`] || [];
data[`data-${cat}`].push({name:feature.name});
});
}
}
return data;
}catch(err){
k.debug({'Invalid Drop Data! Drop aborted. Error:':err,drop_data},true);
return false;
}
};
const clearSheet = function(attributes,sections,casc){
Object.entries(sections).forEach(([section,idArray])=>{
idArray.forEach((id)=>{
k.removeRepeatingRow(`${section}_${id}`,attributes,sections);
});
});
Object.keys(attributes.attributes).forEach((attr)=>{
if(casc[`attr_${attr}`]){
attributes[attr] = casc[`attr_${attr}`].hasOwnProperty('defaultValue') ?
casc[`attr_${attr}`].defaultValue :
'';
}
})
};
const clearDropAttributes = function(){
k.setAttrs({drop_name:'',drop_data:''});
};
const processDropData = function({data, attributes, sections, casc,section=''}){
const repeatProcessors = {
Paths:dropGenericSection,
Callings:dropGenericSection,
Knacks:dropChildItem,
Purviews:dropGenericSection,
Boons:dropChildItem,
Equipment:dropEquipment,
Flairs:dropGenericSection,
Qualities:dropGenericSection,
'antagonist-calling':dropGenericSection,
'antagonist-purview':dropGenericSection,
Extras:dropGenericSection
}
section = section ? `${section}_` : '';
if(data.Category === 'Antagonists'){
const tokenObj = {
width:70,
height:70,
};
setDefaultToken(tokenObj);
attributes.sheet_type = 'antagonist';
}
const worker = async (queue) => {
let [key,val] = queue.shift();
try{
let setKey = key.replace(/^(?:data-)?cs(?:list)?-/,'');
if(typeof val === 'string' && val.startsWith('[{')){
val = JSON.parse(val);
}
if(!Array.isArray(val) && (key.startsWith('cs-') || key.startsWith('data-cs-'))){
await k.pseudoQuery();
attributes[`${section}${setKey}`] = val;
}else if(Array.isArray(val) && key.startsWith('data-')){
let lookupKey = key.replace(/data-(?:cs(?:list)?-)?/,'');
if(repeatProcessors[lookupKey]){
k.debug(`processing ${lookupKey}`);
await repeatProcessors[lookupKey](lookupKey,val,attributes,sections,casc);
}else if(key.startsWith('data-cslist-')){
await k.pseudoQuery();
attributes[`${section}${setKey}`] = val.map((o)=>o.name).join(', ');
}else if(key === 'data-content'){
await k.pseudoQuery();
attributes[`${section}description`] = val.reduce((textArr,content)=>{
if(content.heading){
textArr.push(content.heading);
}
if(content.content){
let text = /list/.test(content.type) ? `• ${content.content}` : content.content;
textArr.push(text);
}
return textArr;
},[]).join('\n')
.replace(/\n{2,}/,'\n')
.replace(/\n+$/,'');
}
}
}catch(err){
k.debug({[`Invalid JSON entered for ${key} on ${data.display_name}`]:err,JSON:val});
}
if(queue.length){
return worker(queue);
}else{
return true;
}
};
return worker(Object.entries(data));
};
const singular = {
Paths:'Path',
Callings:'Calling',
Knacks:'Knack',
Purviews:'Purview',
Boons:'Boon',
Equipment:'Equipment',
Flairs:'Flair',
Qualities:'Quality',
Extras:'extra'
};
const sectionDisplayNames = {
path:'short-master',
calling:'master',
purview:'short-master',
knack:'short-knack',
contact:'short-contact',
group:'short-group',
access:'short-access',
obligation:'short-obligation',
boon:'short-boon',
creature:'short-creature',
follower:'short-follower',
guide:'short-guide',
relic:'short-relic',
flair:'short-display',
quality:'short-display',
extra:'short-display',
'antagonist-calling':'short-display',
'antagonist-purview':'short-display'
};
const dropGenericSection = async function(lookupKey,arr,attributes,sections,casc){
await k.pseudoQuery();
k.debug(`dropping generic section for ${lookupKey}`);
if(!Array.isArray(arr)){
k.debug({'Invalid section details passed. Exiting. Object passed was:':arr},true);
return;
}
let type = (singular[lookupKey] || lookupKey).toLowerCase();
k.debug({arr});
const worker = async (queue)=>{
let itemObj = queue.shift();
let section = k.generateRowID(type,sections);
itemObj[`cs-display_state`] = sectionDisplayNames[type];
if(itemObj[`cs-display_state`]){
if(itemObj[`cs-display_state`].startsWith('short-')){
itemObj['cs-collapse'] = 1;
}
if(/master/.test(itemObj[`cs-display_state`])){
let controlSection = k.generateRowID(type,sections,'ADD');
attributes[`${controlSection}_master_id`] = section.toLowerCase().replace(/repeating_[^_]+_/,'');
attributes[`${controlSection}_display_state`] = 'add-detail';
}
itemObj[`cs-rating_max`] = 1;
orderComplex({section:type,sections,attributes});
}
if(itemObj['data-cs-condition']){
itemObj['data-cs-condition'] = ['data-cs-condition','data-cs-condition_effect','data-cs-condition_momentum']
.map((attr)=>{
let c = itemObj[attr];
delete itemObj[attr];
return c;
})
.filter( c => c)
.join('\n');
}
await processDropData({data:itemObj,attributes,sections,casc,section});
if(queue.length){
return worker(queue);
}else{
return true;
}
};
return worker([...arr]);
};
const dropChildItem = async function(lookupKey,arr,attributes,sections,casc){
k.debug(`dropping childItem for ${lookupKey}`);
await k.pseudoQuery();
if(!Array.isArray(arr)){
k.debug({'Invalid section details passed. Exiting. Object passed was:':arr},true);
return;
}
const parentSections = {
Knacks:'calling',
Boons:'purview'
};
let type = singular[lookupKey].toLowerCase();
let section = `repeating_${parentSections[lookupKey]}`;
let queryText = `${getTranslationByKey(`${lookupKey} drop query`)}|`;
let queryOptions = sections[section]
.filter((id)=>attributes[`${section}_${id}_display_state`].endsWith('master'))
.map((id)=>`${attributes[`${section}_${id}_name`]
|| getTranslationByKey('unnamed')},${id}`);
let target = queryOptions.length > 1 ? undefined : queryOptions[0].replace(/^.+,([^_]+)$/,'$1');
let query = target ? undefined : `${queryText}|${queryOptions.join('|')}`;
const worker = async (queue,t) =>{
let itemObj = queue.shift();
target = await (target ? k.pseudoQuery(target) : k.extractQueryResult(query));
let row = k.generateRowID(parentSections[lookupKey],sections);
itemObj['cs-master_id'] = target;
itemObj['cs-collapse'] = 1;
itemObj[`cs-display_state`] = `short-${type}`;
await processDropData({data:itemObj,attributes,sections,casc,section:row});
orderComplex({section,sections,attributes});
if(queue.length){
return worker(queue);
}else{
return true;
}
};
await worker([...arr],target);
};
const dropEquipment = async function(lookupKey,arr,attributes,sections,casc){
k.debug(`dropping equipment for ${lookupKey}`);
await pseudoQuery();
if(!Array.isArray(arr)){
k.debug({'Invalid section details passed. Exiting. Object passed was:':arr},true);
return;
}
const worker = async (queue) =>{
let itemObj = queue.shift();
let type = /weapon|armor/i.test(itemObj['data-cs-type']) ?
'equipment' :
'birthright';
itemObj['cs-collapse'] = 1;
itemObj[`cs-display_state`] = `short-${type}`;
let section = `repeating_${type}_${generateRowID()}`;
await processDropData({data:itemObj,attributes,sections,casc,section});
if(queue.length){
return worker(queue);
}else{
return true;
}
};
return await worker([...arr]);
};/*jshint esversion: 11, laxcomma:true, eqeqeq:true*/
/*jshint -W014,-W084,-W030,-W033*/
//Update functions. These functions should be added to the updateHandlers object for iteration through by the updateSheet function.
const update1x01 = function({attributes,sections}){
attributes.defense = defenseCalc({attributes,sections});
attributes.movement_dice = movementCalc({attributes,sections});
};
k.registerFuncs({'1.01':update1x01},{type:['updater']});
</script>