1import{T as t}from"../scripts-CvZq4oMA.min.js";import"./player-B0WZnxGH.js";/*! lifestories v1.0.23 | | (c) 2026 Huncwot.com | All Rights Reserved */const e=`{# 2 Template: t_interview-back-btn 3 Exit button displayed in the top-left corner of the interview lightbox. 4 @param {string} url_back - URL for the back/exit navigation 5#} 6<a href="{{ url_back }}" class="interview__back js-interview-close" data-history="false" data-gtm='{"event":"interview_exit_btn_click"}'> 7 <i class="icon-close"></i> 8 <span class="sr-only">Exit</span> 9</a> 10`,n=`{# 11 Template: t_interview-sidebar--details 12 Details panel with rich-text interview description. 13 @param {string} [info] - HTML string with interview description 14#} 15{%- if info -%} 16 <div class="interview-panel interview-details interview-text js-interview-details" id="details" role="tabpanel" aria-labelledby="tab-details"> 17 <div class="interview-panel__content interview-panel__content--details"> 18 <div class="interview-panel__head"> 19 <h2 class="interview-panel__title">Details</h2> 20 <button class="interview-panel__close button button--ghost button--dark button--small button--helvetica js-nav-close" data-gtm='{"event":"interview_details_close_btn_click"}'>Close</button> 21 </div> 22 <div class="interview-details__text"> 23 {% if info %} 24 {{info|raw}} 25 {% endif %} 26 </div> 27 </div> 28 </div> 29{%- endif %} 30`,i=`{% if lessons -%} 31<div class="interview-bottombar interview-bottombar--education" id="bottom-education" role="tabpanel" aria-labelledby="bottom-tab-education" data-hidden="true"> 32 <div class="interview-bottombar__head"> 33 <span class="interview-bottombar__title">Education</span> 34 <button class="button button--ghost button--dark js-nav-close" type="button" data-gtm='{"event":"interview_education_close_btn_click"}'>Close</button> 35 </div> 36 <div class="interview-bottombar__content"> 37 <ul class="interview-tiles"> 38 {% for item in lessons %} 39 {% set item_image = (item.image.desktop is defined or item.image.src is defined) ? item.image : (item.image ? {src: item.image} : null) %} 40 <li class="interview-tile interview-tile--horizontal js-item"> 41 <a href="{{item.url}}" class="interview-tile__link" data-gtm='{"event":"interview_education_tile_click"}'> 42 <figure class="interview-tile__image"> 43 {{- picture({ image: item_image, alt: '', lazy: true }) -}} 44 </figure> 45 <div class="interview-tile__main"> 46 <div class="interview-tile__title">{{item.type}}</div> 47 <div class="interview-tile__descr">{{item.title}}</div> 48 </div> 49 </a> 50 </li> 51 {% endfor %} 52 </ul> 53 </div> 54</div> 55{%- endif %} 56`,a=`{# 57 Template: t_interview-emotions 58 59 @param {string} api.emotions - Emotions endpoint; query string carries object_type/object_id for GET, POST goes to the bare path 60 @param {string} id - Interview ID sent as a POST param 61 @param {object} [emotions] - Emotion counts keyed by emotion name (e.g. emotions['like']) 62#} 63{% if api.emotions %} 64 {% set emotions_url = api.emotions|split('?')|first %} 65 <div class="interview-emotions"> 66 67 <button type="button" class="interview-emotions__item js-emotions-item" aria-label="Like" 68 data-api='{ "url": "{{ emotions_url }}", "action": "POST", "turnstile": true, "callback": "onEmotion", "params": {"object_id": "{{ id }}", "object_type": "{{ type }}", "emotion": "like"}}' 69 data-gtm='{"event":"interview_emotions_btn_click", "id": "{{ id }}", "emotion": "like"}'> 70 <span class="interview-emotions__icon"><svg class="svg-30-emotions-like" viewBox="0 0 30 30"><path d="M9.75 12.81H6.93a.47.47 0 0 0-.47.47v7.51c0 .26.21.47.47.47h2.82c.26 0 .47-.21.47-.47v-7.51a.47.47 0 0 0-.47-.47M23.32 13.7c0-.76-.52-1.54-1.53-1.54h-4.55c.65-1.16.84-2.8.39-3.99-.33-.88-.97-1.39-1.79-1.44h-.01c-.53-.03-1 .37-1.04.9-.12 1.19-.64 3.28-1.38 4.03-.63.63-1.16.89-2.05 1.32q-.195.09-.42.21v7.529999999999999c.11.04.21.07.32.11 1.47.51 2.74.94 4.68.94h3.67c1 0 1.53-.77 1.53-1.54 0-.23-.05-.45-.14-.66.33-.06.63-.22.84-.47.25-.28.38-.65.38-1.05 0-.23-.05-.45-.14-.66.81-.14 1.22-.83 1.22-1.51 0-.4-.14-.8-.42-1.09.27-.29.42-.69.42-1.
7009Z"/></svg></span> 71 <span class="interview-emotions__count js-count">{{ emotions['like'] ?? 0 }}</span> 72 <span class="interview-emotions__tooltip">Like</span> 73 </button> 74 75 <button type="button" class="interview-emotions__item js-emotions-item" aria-label="This Moved Me" 76 data-api='{ "url": "{{ emotions_url }}", "action": "POST", "turnstile": true, "callback": "onEmotion", "params": {"object_id": "{{ id }}", "object_type": "{{ type }}", "emotion": "moved-me"}}' 77 data-gtm='{"event":"interview_emotions_btn_click", "id": "{{ id }}", "emotion": "moved-me"}'> 78 <span class="interview-emotions__icon"><svg class="svg-30-emotions-moved-me" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 30 30"><path d="M14.924 10.205a4.38 4.38 0 0 0-3.847-2.262c-2.404 0-4.36 1.917-4.36 4.271 0 5.214 8.207 9.798 8.207 9.798s8.207-4.584 8.207-9.798c0-2.354-1.956-4.27-4.36-4.27a4.38 4.38 0 0 0-3.847 2.261" clip-rule="evenodd"/></svg></span> 79 <span class="interview-emotions__count js-count">{{ emotions['moved-me'] ?? 0 }}</span> 80 <span class="interview-emotions__tooltip">This Moved Me</span> 81 </button> 82 83 <button type="button" class="interview-emotions__item js-emotions-item" aria-label="I Needed This Today" 84 data-api='{ "url": "{{ emotions_url }}", "action": "POST", "turnstile": true, "callback": "onEmotion", "params": {"object_id": "{{ id }}", "object_type": "{{ type }}", "emotion": "hope"}}' 85 data-gtm='{"event":"interview_emotions_btn_click", "id": "{{ id }}", "emotion": "hope"}'> 86 <span class="interview-emotions__icon"><svg class="svg-30-emotions-hope" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 30 30"><path d="M20.027 6.686a3.23 3.23 0 0 0-2.259-.936c-.814 0-1.628.306-2.259.936l-.509.53-.529-.53a3.23 3.23 0 0 0-2.259-.936c-.834 0-1.689.326-2.3.977-1.2 1.262-1.119 3.277.102 4.498l4.6 4.6a.54.54 0 0 0 .753 0l4.66-4.661c1.241-1.201 1.241-3.236 0-4.478M12.843 18.104c-.326-.55-.896-1.221-1.466-1.873-.488-.57-1.017-1.14-1.384-1.689-.264-.387-.732-.387-1.058-.183-.407.244-.712.794-.264 1.648.223.448.773 1.038 1.343 1.67.04.04.06.08.102.121.142.143.101.387-.061.489-.143.081-.306.04-.428-.061l-.102-.102c-.427-.489-.834-.936-1.14-1.343a3 3 0 0 1-.305-.489c-.346-.651-.346-1.241-.162-1.689-.306-.651-.57-1.282-.692-1.689-.367-1.16-1.954-.875-1.893.366.061 1.282.509 5.454 1.73 6.879.55.651 1.547 1.526 2.605 2.259a.64.64 0 0 1 .264.509v.855a.46.46 0 0 0 .468.468h2.972a.46.46 0 0 0 .468-.468c-.02-.51-.04-1.364-.082-2.097-.101-1.546-.57-2.97-.915-3.581M22.774 12.934c-.122.407-.386 1.018-.692 1.69.183.447.163 1.037-.162 1.688-.082.163-.184.306-.306.489a18 18 0 0 1-1.14 1.343c-.02.04-.06.061-.101.102a.316.316 0 0 1-.428.06c-.162-.1-.203-.345-.06-.488.04-.04.06-.08.101-.122.57-.63 1.12-1.22 1.343-1.668.428-.835.143-1.405-.264-1.649-.346-.203-.814-.203-1.059.183-.366.55-.875 1.14-1.383 1.69-.57.65-1.14 1.322-1.466 1.872-.366.61-.814 2.035-.915 3.54-.041.733-.062 1.588-.082 2.097a.46.46 0 0 0 .468.468H19.6a.46.46 0 0 0 .469-.468v-.855c0-.203.101-.386.264-.508 1.058-.733 2.056-1.608 2.605-2.26 1.221-1.424 1.649-5.596 1.73-6.838.061-1.24-1.526-1.526-1.893-.366"/></svg></span> 87 <span class="interview-emotions__count js-count">{{ emotions['hope'] ?? 0 }}</span> 88 <span class="interview-emotions__tooltip">I Needed This Today</span> 89 </button> 90 91 <button type="button" class="interview-emotions__item js-emotions-item" aria-label="I Learned Something" 92 data-api='{ "url": "{{ emotions_url }}", "action": "POST", "turnstile": true, "callback": "onEmotion", "params": {"object_id": "{{ id }}", "object_type": "{{ type }}", "emotion": "learned"}}' 93 data-gtm='{"event":"interview_emotions_btn_click", "id": "{{ id }}", "emotion": "learned"}'> 94 <span class="interview-emotions__icon"><svg class="svg-30-emotions-learned" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 30 30"><path d="M16.51 22.96c-.12.898-1.034 1.596-2.144 1.597s-2.023-.699-2.143-1.596zm.528-1.843a.519.519 0 0 1 0 1.037h-5.49a.519.519 0 0 1 0-1.037zm-2.71-17.194q.506 0 1.019.074c1.944.28 3.676 1.419 4.752 3.123a6.76 6.76 0 0 1 .744 5.701c-.236.76-.649 1.523-1.228 2.267-.382.491-.79 1.051-1.211 1.666-.604.881-.923 1.115-.923 2.188v.602a.64.64 0 0 1-.637.638h-5.063a.64.64 0 0 1-.636-.638v-.615c0-1.08-.32-1.315-.924-2.19a35 35 0 0 0-1.29-1.752c-1.209-1.541-1.693-3.47-1.362-5.43a6.56 6.56 0 0 1 1.277-2.92c1.349-1.74 3.346-2.714 5.482-2.714m-2.154 8.132a.5.5 0 1 0 0 1h1.49v5.468a.5.5 0 0 0 1 0v-5.468h1.5a.5.5 0 0 0 0-1z" clip-rule="evenodd"/></svg></span>
95 <span class="interview-emotions__count js-count">{{ emotions['learned'] ?? 0 }}</span> 96 <span class="interview-emotions__tooltip">I Learned Something</span> 97 </button> 98 99 {# <button type="button" class="interview-emotions__item js-emotions-item" aria-label="Rare Find" 100 data-api='{"beforeCall": "login", "theme": "dark", "url": "{{ emotions_url }}", "action": "POST", "turnstile": true, "callback": "onEmotion", "params": {"object_id": "{{ id }}", "object_type": "{{ type }}", "emotion": "rare"}}'> 101 <span class="interview-emotions__icon"><svg class="svg-30-emotions-rare" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><path d="m19.13 13.21-3.97 10.38h-.34l-3.97-10.38h8.27Zm-15.44 0 9.48 10.38h.46L9.66 13.21zm15.24-1.12L15 7.01l-3.93 5.08h7.85Zm7.49 0L22.71 7l-1.95 5.09h5.65ZM16.37 23.6h.46l9.48-10.38h-5.97zm5.35-17.15h-5.73l3.83 4.96zm-7.71 0H8.28l1.9 4.96zm-6.73.54-3.7 5.1h5.65z"/></svg></span> 102 <span class="interview-emotions__count js-count">{{ emotions['rare'] ?? 0 }}</span> 103 <span class="interview-emotions__tooltip">Rare</span> 104 </button>#} 105 106 <button type="button" class="interview-emotions__item js-emotions-item" aria-label="Speaks to Me" 107 data-api='{ "url": "{{ emotions_url }}", "action": "POST", "turnstile": true, "callback": "onEmotion", "params": {"object_id": "{{ id }}", "object_type": "{{ type }}", "emotion": "speaks-to-me"}}' 108 data-gtm='{"event":"interview_emotions_btn_click", "id": "{{ id }}", "emotion": "speaks-to-me"}'> 109 <span class="interview-emotions__icon"><svg class="svg-30-emotions-speaks-to-me" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 30 30"><path d="M21.115 6.34c-.301.023-.651.22-.95.699-1.094 1.504-5.568 3.417-9.295 3.417H7.453a2.734 2.734 0 0 0-2.734 2.734v.683a2.734 2.734 0 0 0 2.734 2.734L6.7 21.621l-.099.62c-.127.424.48.924.851.85h2.337c.17 0 .314-.137.403-.284.088-.148.166-.347.166-.49l.856-5.71c2.624-.164 7.174 1.367 9.224 4.101.547.683 1.367.43 1.367 0V6.902c0-.327-.303-.59-.69-.561m1.759 4.283v5.812h.001a2.97 2.97 0 0 0 2.377-2.901 2.97 2.97 0 0 0-2.377-2.91z"/></svg></span> 110 <span class="interview-emotions__count js-count">{{ emotions['speaks-to-me'] ?? 0 }}</span> 111 <span class="interview-emotions__tooltip">Speaks to Me</span> 112 </button> 113 114 </div> 115{% endif %} 116`,s=`<div class="interview-foot js-footnotes"> 117 {% if footnotes %} 118 <div class="interview-foot__footnotes"> 119 <button class="interview-foot__close js-footnotes-close" aria-label="Close footnotes" data-gtm='{"event":"interview_footnotes_close_btn_click"}'><i class="icon-x"></i></button> 120 <ol> 121 {% for footnote in footnotes %} 122 <li class="js-footnote" data-id="{{loop.index}}">{{footnote}}</li> 123 {% endfor %} 124 </ol> 125 </div> 126 {% endif %} 127</div> 128`,o=`{# 129 Template: t_interview-head 130 @param {string} id - Interview ID 131 @param {object} head - Head info: title (string|array), description, source: { label, url } 132 @param {string} [description] - Interview description (shown in playlist mode) 133 @param {object} [playlist] - Playlist data; presence triggers playlist modifier 134 @param {string} [url_full] - Full interview URL (shown in playlist mode, desktop) 135 @param {string} [api.favorite] - Favorites toggle API URL 136 @param {array} [tags] - Array of tag objects: name, url 137#} 138{% if head or tags %} 139 <div class="interview-panel interview-head js-interview-head"> 140 141 <div class="interview-panel__content interview-panel__content--head"> 142 143 {% set headTitle = head.title is iterable ? head.title : [head.title] %} 144 {% if head.url -%} 145 <a href="{{head.url}}" class="interview-head__title" data-close-search data-gtm='{"event":"interview_head_title_click"}'> 146 <span>{{headTitle|join('</span> 147 <span>')}}</span> 148 </a> 149 {%- else -%} 150 <div class="interview-head__title"> 151 <span>{{headTitle|join('</span> <span>')}}</span> 152 </div> 153 {%- endif %} 154 155 {% if head.description -%} 156 <div class="interview-head__description"> 157 <span>{{head.description}}</span> 158 </div> 159 {%- endif %} 160 161 {% if tags %} 162 <div class="interview-head__tags interview-tags js-interview-tags"> 163 {% for tag in tags %} 164 {% if tag.name and tag.url %} 165 <a href="{{tag.url}}" class="interview-tag{% if loop.index > 5 %} interview-tag--hidden{% endif %}" data-close-search data-gtm='{"event":"interview_tag_click", "tag":"{{tag.name}}"}'>{{tag.name}}</a> 166 {% endif %} 167 {% endfor %} 168 {% if tags|length > 5 %} 169 <button type="button" class="interview-tag interview-tag--more js-interview-tags-more" data-gtm='{"event":"interview_head_tags_more_click"}'>...</button> 170 {% endif %} 171 </div> 172 {% endif %} 173
174 {% if head.source.label or head.dates or head.interviewers -%} 175 <div class="interview-head__details"> 176 {% if head.interviewers %} 177 <div>Interviewer 178 {%- if head.interviewers|length > 1 -%}s 179 {%- endif -%}: 180 {% for i in head.interviewers %} 181 <a style="text-decoration:none" href="{{i.url}}" data-close-search data-gtm='{"event":"interview_head_interviewer_link_click"}'>{{i.label}}</a>{% if not loop.last %}, {% endif %} 182 {% endfor %} 183 </div> 184 {% endif %} 185 {% if head.dates %} 186 <div>Date 187 {%- if head.dates|length > 1 -%}s 188 {%- endif -%}: 189 {{head.dates|join(', ')}}</div> 190 {% endif %} 191 {% if head.source.label or head.source.copyright %} 192 <div>Source: 193 {% if head.source.url %}<a style="text-decoration:none" href="{{head.source.url}}" data-close-search data-gtm='{"event":"interview_head_source_link_click"}'>{{head.source.label}}</a>{% else %}{{head.source.label}}{% endif %} 194 {% if head.source.copyright %} 195 © {{head.source.copyright}} 196 {% endif %} 197 </div> 198 {% endif %} 199 </div> 200 {%- endif %} 201 202 <div class="interview-head__time player__time desktop-only"><span class="js-interview-time"></span> / <span class="js-interview-duration"></span></div> 203 204 </div> 205 206 </div> 207{% endif %} 208`,r=`{# 209 Template: t_interview-index 210 Content list (chapter index) for the interview. 211 @param {array} sessions - Array of sessions; each has index[] entries 212 @param {object} [media] - Media metadata: duration (seconds), used for session time offsets 213#} 214{% import 'interview-macros' as macros %} 215 216{% if not playlist and (sessions|first).index is defined %} 217<div class="interview-panel interview-index{% if sessions|length <= 1 %} interview-index--single{% endif %} js-interview-index" id="index" role="tabpanel" aria-labelledby="tab-index"> 218 219 <div class="interview-panel__content interview-panel__content--index"> 220 221 <div class="interview-panel__head"> 222 <h2 class="interview-panel__title">Content List</h2> 223 <button class="interview-panel__close button button--ghost button--dark button--small button--helvetica js-nav-close" data-gtm='{"event":"interview_index_close_btn_click"}'>Close</button> 224 </div> 225 226 227 <div class="interview-index__main"> 228 {% set sessionOffset = 0 %} 229 {% for session in sessions %} 230 231 {% if sessions|length > 1 %} 232 <div class="interview-index__session"> 233 <div class="interview-index__session-label interview-index__session-label--top"> 234 Session <span>{{loop.index}}</span> 235 </div> 236 {% endif %}{# end if more sessions #} 237 238 {% for paragraph in session.index %} 239 {% set time = paragraph[0] + sessionOffset %} 240 <div class="interview-index__item{% if paragraph[2] %} interview-index__item--{{paragraph[2]}}{% endif %} js-index-part"> 241 242 <button data-time="{{time}}" data-gtm='{"event":"transcript_time_btn_click"}'> 243 <span class="interview-index__time">{{ macros.secondsToMinutes(time) }}</span> 244 <span class="interview-index__title">{{paragraph[1]}}</span> 245 </button> 246 247 </div> 248 {% endfor %} 249 250 {% set sessionOffset = sessionOffset + (session.video.duration ?? session.audio.duration ?? 0) %} 251 252 {% if sessions|length > 1 %}{# end if more sessions #} 253 </div>{# close div if more sessions #} 254 {% endif %} 255 256 {% endfor %}{# end for sessions #} 257 </div>{# close main #} 258 </div>{# close content #} 259</div>{# close panel #} 260{% endif %} 261`,l=`{# 262 Template: t_interview-sidebar--macros 263 Shared Twig macros for sidebar sub-templates. 264#} 265{% macro secondsToMinutes(seconds) %} 266 267{% set hours = seconds / 3600 %} 268{% set hours = hours|round(0, 'floor') %} 269{% set hours = hours|number_format %} 270 271{% set minutes = (seconds / 60)|round(0, 'floor') % 60 %} 272{% set minutes = minutes|number_format %} 273{% set minutes = ('00' ~ minutes)|slice(-2) %} 274 275{% set seconds = seconds|round(0, 'floor') % 60 %} 276{% set seconds = seconds|number_format %} 277{% set seconds = ('00' ~ seconds)|slice(-2) %} 278 279{{ hours }}:{{ minutes}}:{{ seconds }} 280 281{% endmacro %} 282 283 284{% macro duration(seconds) %} 285 286{% set mins = (seconds / 60)|round(0, 'floor') %} 287{% set secs = seconds|round(0, 'floor') % 60 %} 288{% set secs = ('00' ~ secs)|slice(-2) %} 289 290{% if seconds >= 3600 %} 291 {% set hrs = (seconds / 3600)|round(0, 'floor') %} 292 {% set mins = ('00' ~ mins % 60)|slice(-2) %} 293 {{- hrs }}:{{ mins }}:{{ secs -}} 294{% else %} 295 {{- mins }}:{{ secs -}} 296{% endif %} 297 298{% endmacro %} 299`,d=`{# 300 Template: t_interview-modal-comment 301 @param {string} id - Interview ID (used in API params) 302 @param {object} [api] - API URL overrides (inherited from t_interview) 303 @param {string}
303 [api.comments] - POST: submit comment (default: /api/comments) 304#} 305{% set url_comment = api.comments ?: '/api/comments' %} 306<dialog class="interview-modal" id="comment-imodal" data-component="InterviewModal"> 307 <div class="interview-modal__panel"> 308 <div class="interview-modal__header"> 309 <span class="interview-modal__title">Add a comment</span> 310 </div> 311 <button class="interview-modal__close js-imodal-close" type="button" data-gtm='{"event":"modal_close_btn_click", "id": "{{ id }}"}'> 312 <i class="icon-close"></i> 313 <span class="sr-only">Close</span> 314 </button> 315 <form class="interview-modal__body" action="{{ url_comment }}" method="post" data-api='{"beforeCall": "login", "theme": "dark", "callback": "onComment", "params": {"object_type": "{{type}}", "object_id": "{{id}}"}}' novalidate> 316 <div class="interview-modal__field"> 317 <textarea class="interview-modal__textarea" name="comment" placeholder="Share your thoughtsâ¦" required></textarea> 318 </div> 319 <label class="interview-modal__checkbox checkbox checkbox--dark"> 320 <input type="checkbox" name="anonymous" value="1"> 321 <span></span> 322 Share this comment anonymously 323 </label> 324 <div class="interview-modal__footer"> 325 <button class="interview-modal__submit button button--secondary button--dark" type="submit" data-gtm='{"event":"interview_comment_submit_click", "id": "{{ id }}"}'>Send <svg class="sprite-30-arrow-right"><use xlink:href="#sprite-30-arrow-right"/></svg></button> 326 </div> 327 </form> 328 </div> 329</dialog> 330`,c=`{# 331 Template: t_interview-modal-highlight 332 @param {string} id - Interview ID (used in API params) 333 @param {string} type - Object type (used in API params) 334 @param {object} [api] - API URL overrides (inherited from t_interview) 335 @param {string} [api.highlights] - POST: save highlight (default: /api/highlights) 336#} 337{% set url_highlights = api.highlights ?: '/api/highlights' %} 338<dialog class="interview-modal interview-modal--highlight" id="highlight-imodal" data-component="InterviewModal"> 339 <div class="interview-modal__panel"> 340 <div class="interview-modal__header"> 341 <span class="interview-modal__title">Select what to add to Highlights</span> 342 </div> 343 <button class="interview-modal__close js-imodal-close" type="button" data-gtm='{"event":"modal_close_btn_click", "id": "{{ id }}"}'> 344 <i class="icon-close"></i> 345 <span class="sr-only">Close</span> 346 </button> 347 <form class="interview-modal__body" action="{{ url_highlights }}" method="post" data-api='{"beforeCall": "login", "theme": "dark", "callback": "onHighlight", "params": {"object_type": "{{type}}", "object_id": "{{id}}"}}' novalidate> 348 <div class="interview-modal__field"> 349 <div class="interview-modal__quote js-highlight-quote"></div> 350 </div> 351 <input type="hidden" name="text" value=""> 352 <input type="hidden" name="seconds" value=""> 353 <div class="interview-modal__footer"> 354 <button class="interview-modal__submit button button--secondary" type="submit" data-gtm='{"event":"interview_highlight_submit_click", "id": "{{ id }}"}'>Save <svg class="sprite-30-arrow-right"><use xlink:href="#sprite-30-arrow-right"/></svg></button> 355 </div> 356 </form> 357 </div> 358</dialog> 359`,v=`{# 360 Template: t_interview-modal-playlist 361 @param {string} id - Interview ID (used in API params) 362 @param {string} type - Object type (used in API params) 363 @param {object} [api] - API URL overrides (inherited from t_interview) 364 @param {string} [api.playlists] - GET: load playlists list 365 @param {string} [api.playlist_create] - POST: create new playlist 366 @param {string} [api.playlist_add] - POST: add interview to playlist; playlist_id appended as URL path segment 367#} 368{%- if api.playlists -%} 369<dialog class="interview-modal" id="playlist-imodal" data-component="InterviewModal" data-playlist-url="{{ api.playlist_add ?: api.playlists }}" data-object-id="{{ id }}" data-object-type="{{ type }}"> 370 <div class="interview-modal__panel"> 371 <div class="interview-modal__header">
372 <span class="interview-modal__title">Add to playlist</span> 373 </div> 374 <button class="interview-modal__close js-imodal-close" type="button" data-gtm='{"event":"modal_close_btn_click", "id": "{{ id }}"}'> 375 <i class="icon-close"></i> 376 <span class="sr-only">Close</span> 377 </button> 378 <div class="interview-modal__body"> 379 <form action="{{ api.playlists }}" method="post" data-api='{"beforeCall": "login", "theme": "dark", "callback": "onPlaylistAdded"}' class="interview-modal__new-playlist"> 380 <input class="interview-modal__input" type="text" name="label" placeholder="New playlist title"> 381 <button class="interview-modal__add-btn" type="submit" data-gtm='{"event":"playlist_create_submit_click"}'> 382 <i class="icon-plus"></i> 383 </button> 384 </form> 385 <form class="interview-modal__playlist-list js-imodal-playlist-list" data-api-load='{"auth": true, "action": "GET", "url": "{{ api.playlists }}", "template": "playlists", "callback": "onInterviewPlaylistsLoaded"}' id="playlists-list"> 386 </form> 387 <div class="interview-modal__footer"> 388 <button class="interview-modal__submit button button--secondary button--dark js-imodal-close" type="button" data-gtm='{"event":"playlist_modal_done_click", "id": "{{ id }}"}'> 389 Done <svg class="sprite-30-arrow-right"><use xlink:href="#sprite-30-arrow-right"/></svg> 390 </button> 391 </div> 392 </div> 393 </div> 394</dialog> 395{%- endif -%} 396`,p=`{# 397 Template: t_interview-nav 398 Sidebar navigation tabs. Active state managed entirely by JS via is-active / aria-selected. 399 @param {object} [info] - Details panel data; button shown only when info.text is present 400 @param {array} [sessions] - Sessions array; index/transcript buttons shown only when transcript exists 401 @param {object} [playlist] - Playlist data; when present, index/transcript buttons are hidden 402 @param {array} [related] - Related items; button shown only when present 403 @param {array} [lessons] - Education items; button shown only when present 404 @param {string} [url_full] - Full interview URL; renders the "Go to full interview" button 405#} 406{%- if info or (sessions|first).index is defined or (sessions|first).transcript is defined or related or lessons or url_full -%} 407 <div class="interview-nav js-interview-nav" role="tablist"> 408 409 {%- if info is defined -%} 410 <a class="button button--ghost button--dark" id="tab-details" role="tab" href="#details" aria-controls="details" aria-selected="false" data-gtm='{"event":"transcript_tab_click", "tab":"details"}'>Details</a> 411 {%- endif -%} 412 413 {%- if not playlist and (sessions|first).index is defined -%} 414 <a class="button button--ghost button--dark" id="tab-index" role="tab" href="#index" aria-controls="index" aria-selected="false" data-gtm='{"event":"transcript_tab_click", "tab":"index"}'>Content List</a> 415 {%- endif -%} 416 417 {%- if (sessions|first).transcript is defined -%} 418 <a class="button button--ghost button--dark" id="tab-transcript" role="tab" href="#transcript" aria-controls="transcript" aria-selected="false" data-gtm='{"event":"transcript_tab_click", "tab":"transcript"}'>Transcript</a> 419 {%- endif -%} 420 421 {%- if related -%} 422 <a class="button button--ghost button--dark" id="bottom-tab-related" role="tab" href="#bottom-related" aria-controls="bottom-related" aria-selected="false" data-gtm='{"event":"transcript_tab_click", "tab":"related"}'>Related</a> 423 {%- endif -%} 424 425 {%- if lessons -%} 426 <a class="button button--ghost button--dark" id="bottom-tab-education" role="tab" href="#bottom-education" aria-controls="bottom-education" aria-selected="false" data-gtm='{"event":"transcript_tab_click", "tab":"education"}'>Education</a> 427 {%- endif -%} 428 429 {%- if url_full %} 430 <a class="button button--ghost button--dark" data-interview='{"id":{{id}}}' href="{{url_full}}" data-gtm='{"event":"interview_full_link_click"}'>Go to full interview <svg class="sprite-30-arrow-right"><use xlink:href="#sprite-30-arrow-right"/></svg></a> 431 {%- endif %} 432 </div> 433{%- endif %} 434`,m=`{% if playlist and playlist.items|length > 1 %} 435<div class="interview-playlist__head desktop-only"> 436 {% if playlist.title %} 437 <div class="interview-playlist__title">{{ playlist.title }}</div> 438 <div class="interview-playlist__amount amount amount--dark amount--extra-small">{{ playlist.items|length }}</div> 439 {% endif %} 440 {% if playlist.description %} 441 <div class="interview-playlist__description">{{ playlist.description }}</div> 442 {% endif %} 443 {% if playlist.date %} 444 <div class="interview-playlist__date"><time>{{ playlist.date }}</time></div> 445 {% endif %} 446</div> 447<ul class="interview-playlist__list"> 448 {% for item in playlist.items %} 449 <li class="interview-playlist__tile interview-tile interview-tile--vert
449ical js-item"> 450 {% include 'tile' with {mode: 'playlist', url: item.url, id: item.id, image: item.image, name: item.name, description: item.description, duration: item.duration, gtm_event: 'playlist_item_click'} %} 451 </li> 452 {% endfor %} 453</ul> 454{% endif %} 455`,_=`{% if related -%} 456<div class="interview-bottombar interview-bottombar--related" id="bottom-related" role="tabpanel" aria-labelledby="bottom-tab-related" data-hidden="true"> 457 <div class="interview-bottombar__head"> 458 <span class="interview-bottombar__title">Related</span> 459 <button class="interview-bottombar__close button button--ghost button--dark button--small js-nav-close" type="button" data-gtm='{"event":"interview_related_close_btn_click"}'>Close</button> 460 </div> 461 <div class="interview-bottombar__content"> 462 <ul class="interview-tiles"> 463 {% for item in related %} 464 {# backend ships some related entries without a slug (url = bare "/interviews") â fall back to the id route, which the api resolves too #} 465 {% set item_url = null %} 466 {% if (item.url|split('/')|length) > 2 %} 467 {% set item_url = item.url %} 468 {% elseif item.id and item.type == 'clip' %} 469 {% set item_url = '/stories/' ~ item.id %} 470 {% elseif item.id and item.type == 'interview' %} 471 {% set item_url = '/interviews/' ~ item.id %} 472 {% endif %} 473 {% if item_url %} 474 <li class="interview-tile interview-tile--horizontal interview-tile--{{item.type}} js-item"> 475 {% include 'tile' with { 476 url: item_url, 477 image: item.image, 478 name: item.narrator ?: item.title, 479 description: item.profession ?: item.description, 480 duration: item.duration, 481 author: item.narrator, 482 gtm_event: 'interview_related_tile_click' 483 } %} 484 </li> 485 {% endif %} 486 {% endfor %} 487 </ul> 488 </div> 489</div> 490{%- endif %} 491`,u=`{# 492 Template: t_interview-survey 493 End-of-video overlay: emotions survey, comment prompt and community quote steps + "Next to watch" strip. 494 @param {string} id - Interview ID (used in API params) 495 @param {object} [api] - API URLs (emotions, comments â steps render only when set) 496 @param {object} [emotions] - Emotion counts keyed by emotion name (step 1 gate, as in t_interview-emotions) 497 @param {string} [community_quote] - Community quote text (step 3, skipped when empty) 498 @param {array} [related] - Related items; first 3 render as "Next to watch" 499#} 500{% if api.emotions or api.comments or community_quote %} 501<div class="interview-survey js-interview-survey"> 502 503 {% if api.emotions %} 504 <div class="interview-survey__step js-survey-step"> 505 <h2 class="interview-survey__title">How did this story resonate with you?</h2> 506 {% include 'interview-emotions' %} 507 </div> 508 {% endif %} 509 510 {% if api.comments %} 511 <div class="interview-survey__step js-survey-step"> 512 <h2 class="interview-survey__title">Leave a comment</h2> 513 <button class="interview-survey__comment" type="button" data-imodal="comment-imodal" data-gtm='{"event":"interview_survey_comment_click", "id": "{{id}}"}' aria-label="Leave a comment"><svg class="svg-30-comment" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 30 30"><path d="M10.42 24.096v-4.58h1.386a6.806 6.806 0 1 1 0-13.611h6.39a6.805 6.805 0 0 1 0 13.61H15zm.868-9.694a1.242 1.242 0 1 0 0 2.485 1.242 1.242 0 0 0 0-2.485m3.712 0a1.243 1.243 0 1 0 .001 2.486A1.243 1.243 0 0 0 15 14.402m3.712 0a1.243 1.243 0 1 0 0 2.485 1.243 1.243 0 0 0 0-2.485"/></svg></button> 514 </div> 515 {% endif %} 516 517 {% if community_quote %} 518 <div class="interview-survey__step interview-survey__step--quote js-survey-step"> 519 <span class="interview-survey__label">Community quote</span> 520 <blockquote class="interview-survey__quote">“{{ community_quote }}”</blockquote> 521 </div> 522 {% endif %} 523 524 {% if related %} 525 <div class="interview-survey__related js-survey-related">
526 <span class="interview-survey__related-title">Watch Next</span> 527 <ul class="interview-survey__tiles js-survey-tiles"> 528 {% for item in related %} 529 {# backend ships some related entries without a slug (url = bare "/interviews") â fall back to the id route, which the api resolves too #} 530 {% set item_url = null %} 531 {% if (item.url|split('/')|length) > 2 %} 532 {% set item_url = item.url %} 533 {% elseif item.id and item.type == 'clip' %} 534 {% set item_url = '/stories/' ~ item.id %} 535 {% elseif item.id and item.type == 'interview' %} 536 {% set item_url = '/interviews/' ~ item.id %} 537 {% endif %} 538 {% if item_url %} 539 <li class="interview-tile interview-tile--horizontal interview-survey__tile js-item" style="--i: {{ loop.index0 }}"> 540 {% include 'tile' with { 541 url: item_url, 542 image: item.image, 543 name: item.narrator ?: item.title, 544 description: item.profession ?: item.description, 545 duration: item.duration, 546 author: item.narrator, 547 gtm_event: 'interview_survey_tile_click' 548 } %} 549 </li> 550 {% endif %} 551 {% endfor %} 552 </ul> 553 </div> 554 {% endif %} 555 556</div> 557{% endif %} 558`,w=`{# 559 Template: t_interview-tools 560 @param {object} api - API URLs; each key renders its tool button 561 @param {string} [api.favorite] - Favorites toggle URL 562 @param {string} [api.playlists] - Playlists list URL 563 @param {string} [api.comments] - Comments URL 564 @param {string} [type] - Object type (GTM) 565 @param {string} [id] - Object id (GTM) 566 567 On mobile only the plus toggle is shown; it expands the list below (see \`.js-tools-toggle\`, 568 handled in Interview.ts). \`data-no-expand\` keeps the generic Expand widget off the button â 569 it binds every [aria-controls] element and would fight the class-based toggle. 570#} 571{% if api.favorite or api.playlists or api.comments %} 572 <div class="interview-tools js-interview-tools"> 573 <button type="button" data-no-expand aria-expanded="false" aria-controls="interview-tools-list" aria-label="Show tools" class="interview-tool interview-tool--toggle button button--ghost button--dark js-tools-toggle" data-gtm='{"event":"interview_head_tools_toggle_click"}'> 574 <i class="icon-plus-small"></i> 575 </button> 576 577 <div class="interview-tools__list" id="interview-tools-list"> 578 {% if api.favorite %} 579 <a href="{{api.favorite}}" data-api='{"beforeCall": "login", "theme": "dark", "callback": "onFavoriteToggle"}' data-gtm='{"event":"interview_head_favorite_click", "object_type": "{{type}}", "object_id": "{{id}}"}' class="interview-tool interview-tool--fav button button--ghost button--dark button--icon-left js-favorite-btn"> 580 <span>Remove from favorites</span> 581 <span>Add to favorites</span> 582 <i class="icon-plus-small"></i> 583 </a> 584 {% endif %} 585 586 {% if api.playlists %} 587 <a href="#" data-imodal="playlist-imodal" data-gtm='{"event":"interview_head_playlist_btn_click", "id": "{{id}}"}' class="interview-tool interview-tool--playlist button button--ghost button--dark button--icon-left js-playlist-btn"> 588 Add to playlist<i class="icon-plus-small"></i> 589 </a> 590 {% endif %} 591 592 {% if api.comments %} 593 <a href="#" data-imodal="comment-imodal" data-gtm='{"event":"interview_head_comment_btn_click", "id": "{{id}}"}' class="interview-tool interview-tool--comment button button--ghost button--dark button--icon-left"> 594 Add a comment<i class="icon-plus-small"></i> 595 </a> 596 {% endif %} 597 </div> 598 </div> 599{% endif %} 600`,g=`{# 601 Template: t_interview-transcript 602 Transcript panel with per-session paragraphs and time-jump buttons. 603 @param {array} sessions - Array of sessions; each has transcript[] entries 604 @param {object} [media] - Media metadata: duration (seconds), used for session time offsets 605#} 606{% import 'interview-macros' as macros %} 607 608{% if (sessions|first.transcript ?? null) %} 609<div class="interview-panel interview-transcript{% if sessions|length <= 1 %} interview-transcript--single{% endif %} js-interview-transcript" id="transcript" role="tabpanel" aria-labelledby="tab-transcript"> 610 611 <div class="interview-panel__content interview-panel__content--transcript"> 612 613 <div class="interview-panel__head"> 614 <h2 class="interview-panel__title">Transcript</h2> 615 <button class="interview-panel__close button button--ghost button--dark button--small button--helvetica js-nav-close" data-gtm='{"event":"interview_transcript_close_btn_click"}'>Close</button> 616 </div> 617 618 <div class="interview-transcript__main js-transcript-content"> 619 620 {% set sessionOffset = 0 %} 621 {% for session in sessions %} 622 623 {% set sessionId = loop.index %} 624 625 {% if sessions|length > 1 %} 626 <div class="interview-transcript__session"> 627 <div class="interview-transcript__session-label"> 628 Session <span>{{loop.index}}</span> 629 </div> 630 {% endif %}{# end if more sessions #} 631 632 633 {# paragraphs #} 634 {% for paragraph in session.transcript %} 635 636 {% set time = paragraph[0] + sessionOffset %} 637 638 <div 639 class="interview-transcript__part{% if paragraph[2] %} interview-transcript__part--{{paragraph[2]}}{% endif %} js-transcript-part"> 640 <button class="interview-transcript__time" data-time="{{time}}" data-gtm='{"event":"transcript_time_btn_click"}'>{{ macros.secondsToMinutes(time) }}</button> 641 <button class="interview-transcript__highlight js-highlight-open" type="button" data-imodal="highlight-imodal" data-gtm='{"event":"transcript_highlight_btn_click"}'>+ Add to Highlights</button> 642 <div class="interview-transcript__paragraph js-transcript-paragraph"> 643 {#{% if paragraph[2] and paragraph[2]!='question' and paragraph[2]!='answer' %}<span class="interview-transcript__speaker">{{paragraph[2]}}:</span> {% endif %}#} 644 {{paragraph[1]}}</div> 645 </div> 646 647 {% endfor %}{# end for transcript paragraphs #} 648 649 {# increase session time offset #} 650 {% set sessionOffset = sessionOffset + (session.video.duration ?? session.audio.duration ?? 0) %} 651 {% if sessions|length > 1 %} 652 </div>{# close div if more sessions #} 653 {% endif %} 654 655 {% endfor %}{# end for sessions #} 656 </div>{# close main #} 657 658 659 {# SEARCH #} 660 <div class="interview-search"> 661 <form class="interview-search__form js-transcript-search" novalidate autocomplete="off"> 662 <div class="interview-search__input">
663 <span class="interview-search__icon"><svg class="svg-30-search" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><circle cx="13.8" cy="13.73" r="4.5" fill="none" stroke="#000"/><path fill="none" stroke="#000" d="m17.16 17.38 3.54 3.53"/></svg></span> 664 <input type="search" name="transcript" id="transcript-search" maxlength="52" placeholder=" "> 665 <label for="transcript-search">Search</label> 666 </div> 667 <div class="interview-search__nav js-transcript-navigation"> 668 <span class="interview-search__numbers js-transcript-numbers"><strong>0</strong> / 0</span> 669 <button class="interview-search__btn js-transcript-prev" type="button" aria-label="Previous result" data-gtm='{"event":"transcript_search_prev_click"}'><svg class="svg-nexus-chevron" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> 670 <path d="M6 3 L11 8 L6 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> 671</svg> 672</button> 673 <button class="interview-search__btn js-transcript-next" type="button" aria-label="Next result" data-gtm='{"event":"transcript_search_next_click"}'><svg class="svg-nexus-chevron" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> 674 <path d="M6 3 L11 8 L6 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> 675</svg> 676</button> 677 <button class="interview-search__close js-transcript-close" type="button" aria-label="Clear search" data-gtm='{"event":"transcript_search_clear_click"}'><i class="icon-close"></i></button> 678 </div> 679 </form> 680 </div> 681 </div>{# close content #} 682</div>{# close panel #} 683{% endif %} 684`,b=`{# 685 Template: t_interview-video 686 @param {array} sessions - Array of sessions; if all are 'text' type, video is hidden. 687 Each session may define \`chapterCaptions\`: [time, text, duration?][] 688 â chapter-title cards shown over the video at \`time\` for \`duration\` seconds (default 4). 689 @param {boolean} [result] - API result flag; when false, message is shown instead of player 690 @param {string} [message] - Error message from API (e.g. HTTP 451 region block) 691 @param {string} [action] - 'login' when the video needs a signed-in user (HTTP 401) â renders the login prompt instead of message 692 @param {string} [shareUrl] - Current page URL; the login link's href, so sign-in returns to this video 693#} 694{% if message %} 695<div class="interview-video js-interview-video" id="interview-video"> 696 <div class="interview-video__wrap"> 697 {% if action == 'login' %} 698 <div class="interview-video__error interview-video__error--login"> 699 <p class="interview-video__error-heading">This video is free to watch but you need to be logged in.</p>
700 <svg class="interview-video__error-arrow" viewBox="0 0 9 24" aria-hidden="true"><path d="M4.5 0v18" stroke="currentColor"/><path d="M1 17h7l-3.5 7z" fill="currentColor"/></svg> 701 <p class="interview-video__error-text">Please <a href="{{ shareUrl }}" data-login="dark" data-gtm='{"event":"stream_login_link_click"}'>login</a> or <a href="/register" data-gtm='{"event":"stream_register_link_click"}'>create</a> free account if you don't have one.</p> 702 </div> 703 {% else %} 704 <div class="interview-video__error">{{ message }}</div> 705 {% endif %} 706 </div> 707</div> 708{% else %} 709{% set noMedia = true %} 710{% for session in sessions %} 711 {% if session.media != 'text' %}{% set noMedia = false %}{% endif %} 712{% endfor %} 713{% if not noMedia %} 714<div class="interview-video js-interview-video" id="interview-video"> 715 <div class="interview-video__wrap"> 716 {% include 'player' %} 717 {% include 'interview-survey' %} 718 719 <div class="interview-video__chapter-captions js-video-chapter-captions"> 720 {% set sessionOffset = 0 %} 721 {% for session in sessions %} 722 {% for caption in session.chapterCaptions %} 723 <div class="interview-video__chapter-caption js-video-chapter-caption" data-time="{{ caption[0] + sessionOffset }}" data-duration="{{ caption[2] ?? 4 }}"> 724 {{ caption[1] }} 725 </div> 726 {% endfor %} 727 {% set sessionOffset = sessionOffset + (session.video.duration ?? session.audio.duration ?? 0) %} 728 {% endfor %} 729 </div> 730 </div> 731</div> 732{% endif %} 733{% endif %} 734`,h=`{# 735 Template: t_interview-warning 736 @param {string}
736 [warning] - Content warning label (e.g. "Sexual Content"); omit to skip rendering 737 @param {string} [url_back] - URL to navigate to when the user closes without consenting 738#} 739{% if warning %} 740<dialog class="interview-warning" data-component="InterviewWarning" data-options="{{ { warning: warning.id, urlBack: url_back|default('')|url_encode }|json_encode|e('html_attr') }}"> 741 <div class="interview-warning__panel"> 742 <button class="interview-warning__close js-iwarning-close" type="button" data-gtm='{"event":"interview_warning_dismiss_btn_click"}'> 743 <i class="icon-close"></i> 744 <span class="sr-only">Close</span> 745 </button> 746 <p class="interview-warning__label">Content Warning</p> 747 <h2 class="interview-warning__title">{{ warning.text }}</h2> 748 <label class="interview-warning__remember checkbox checkbox--dark"> 749 <input class="js-iwarning-remember" type="checkbox" value="1"> 750 <span></span> 751 Remember my consent 752 </label> 753 </div> 754 <div class="interview-warning__panel"> 755 <div class="interview-warning__actions"> 756 <button class="js-iwarning-close button button--dark button--ghost button--large" type="button" data-gtm='{"event":"interview_warning_close_btn_click"}'>Close</button> 757 <button class="js-iwarning-continue button button--secondary button--large button--dark" type="button" data-gtm='{"event":"interview_warning_continue_btn_click"}'>Continue viewing <svg class="sprite-30-arrow-right"><use xlink:href="#sprite-30-arrow-right"/></svg></button> 758 </div> 759 </div> 760</dialog> 761{% endif %} 762`,f=`{# 763 Template: t_interview 764 @param {string} url_back - URL for the exit/back button 765 @param {string} id - Interview ID 766 @param {object} head - Head: title (string|array), description, source: { label, url } 767 @param {string} [description] - Description (shown in playlist mode) 768 @param {object} [playlist] - Playlist data; triggers playlist layout 769 @param {string} [url_full] - Full interview URL (playlist mode only) 770 @param {string} [shareUrl] - Absolute URL for the share widget (set client-side from window.location.href) 771 @param {array} sessions - Sessions with transcript[], index[], media.duration 772 @param {object} [media] - Media metadata (duration etc.) 773 @param {array} [tags] - Tag objects: name, url 774 @param {object} [info] - Details: text (HTML string) 775 @param {array}
775 [related] - Related tiles 776 @param {array} [lessons] - Education tiles 777 @param {boolean} [result] - API result flag; when false, message is shown instead of video 778 @param {string} [message] - Error message from API (e.g. HTTP 451) 779 @param {object} [api] - API URL overrides 780 @param {string} [api.favorite] - Favorites toggle URL 781 @param {string} [api.comment] - POST: submit comment (default: /api/comment) 782 @param {string} [api.playlists] - GET: load playlists list (default: /api/playlists) 783 @param {string} [api.playlist_create] - POST: create new playlist (default: /api/playlist/create) 784 @param {string} [api.playlist_add] - POST: add interview to playlist (default: /api/playlist) 785#} 786 787{% include 'interview-back-btn' %} 788{% include 'interview-head' %} 789 790{% if related or lessons or api.emotions %} 791{% include 'share' with { 792 classes: ['interview__share', 'js-interview-share'], 793 modifiers: ['left'], 794 buttonDark: true, 795 shareUrl: shareUrl 796} %} 797{% endif %} 798 799{% include 'interview-tools' %} 800{% include 'interview-video' %} 801{% include 'interview-nav' %} 802 803<div class="interview__bottom js-bottombar"> 804 {% include 'interview-emotions' %} 805 {% include 'interview-related' %} 806 {% include 'interview-education' %} 807</div> 808 809{% include 'interview-details' with { info: info } %} 810{% include 'interview-index' with { sessions: sessions, media: media } %} 811{% include 'interview-transcript' with { sessions: sessions, media: media } %} 812 813<div class="interview-modals"> 814 {% include 'interview-modal-comment' %} 815 {% include 'interview-modal-playlist' %} 816 {% include 'interview-modal-highlight' %} 817</div> 818 819{% include 'interview-warning' %} 820`;t.register(Object.assign({"/application/views/templates/t_interview-back-btn.twig":e,"/application/views/templates/t_interview-details.twig":n,"/application/views/templates/t_interview-education.twig":i,"/application/views/templates/t_interview-emotions.twig":a,"/application/views/templates/t_interview-foot.twig":s,"/application/views/templates/t_interview-head.twig":o,"/application/views/templates/t_interview-index.twig":r,"/application/views/templates/t_interview-macros.twig":l,"/application/views/templates/t_interview-modal-comment.twig":d,"/application/views/templates/t_interview-modal-highlight.twig":c,"/application/views/templates/t_interview-modal-playlist.twig":v,"/application/views/templates/t_interview-nav.twig":p,"/application/views/templates/t_interview-playlist.twig":m,"/application/views/templates/t_interview-related.twig":_,"/application/views/templates/t_interview-survey.twig":u,"/application/views/templates/t_interview-tools.twig":w,"/application/views/templates/t_interview-transcript.twig":g,"/application/views/templates/t_interview-video.twig":b,"/application/views/templates/t_interview-warning.twig":h,"/application/views/templates/t_interview.twig":f}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.