PageSourceSearch

https://www.astellas.com/etc.clientlibs/dam/components/scene7/dyna…dia.min.352810a1959b7f94172c6e57b74c69ae.js

js astellas.com collected 2026-10-02 02:27:50 UTC 32,190 bytes, 733 lines download raw bytes

1/*
2 * ADOBE CONFIDENTIAL
3 *
4 * Copyright 2016 Adobe Systems Incorporated
5 * All Rights Reserved.
6 *
7 * NOTICE:  All information contained herein is, and remains
8 * the property of Adobe Systems Incorporated and its suppliers,
9 * if any.  The intellectual and technical concepts contained
10 * herein are proprietary to Adobe Systems Incorporated and its
11 * suppliers and may be covered by U.S. and Foreign Patents,
12 * patents in process, and are protected by trade secret or copyright law.
13 * Dissemination of this information or reproduction of this material
14 * is strictly forbidden unless prior written permission is obtained
15 * from Adobe Systems Incorporated.
16 */
17
18(function() {
19    'use strict';
20
21
22    var COMP_SELECTOR = '.s7dm-dynamic-media';
23    var VIEWER_JS = {
24        'BasicZoomViewer': 'html5/js/BasicZoomViewer.js',
25        'FlyoutViewer': 'html5/js/FlyoutViewer.js',
26        'MixedMediaViewer': 'html5/js/MixedMediaViewer.js',
27        'SpinViewer': 'html5/js/SpinViewer.js',
28        'VideoViewer': 'html5/js/VideoViewer.js',
29        'ZoomViewer': 'html5/js/ZoomViewer.js',
30        'ZoomVerticalViewer': 'html5/js/ZoomVerticalViewer.js',
31        'Responsive': 'libs/responsive_image.js'
32    };
33    var responsiveViewerCSS = 's7responsiveViewer'; //defined in responsive.css
34
35    $(document).ready(function(){
36        //do nothing if there is no component due to no asset yet or DM disabled
37        if ($(COMP_SELECTOR).length > 0) {
38            var viewers = new S7dmUtils.Viewer();
39            var viewerRootPath = $(COMP_SELECTOR).data('viewer-path');
40            var pageLocale = $(COMP_SELECTOR).data('page-locale');
41            var s7i18nPath = '/libs/dam/components/scene7/common/clientlibs/i18n.js';
42            if (typeof Granite != 'undefined' && typeof Granite.I18n != 'undefined') {
43                Granite.I18n.setLocale(pageLocale);
44                s7i18nPath = Granite.HTTP.externalize(s7i18nPath);
45            }
46            $('head').append('<script type="text/javascript" src="' + s7i18nPath + '"></script>');
47            viewers.load(VIEWER_JS, viewerRootPath)
48                .ready({
49                    success: initViewers,
50                    fail: failViewerLoader
51                });
52        }
53    });
54
55    /**
56     * Viewer intialization for interactive media component
57     */
58    function initViewers(){
59        var components = $(COMP_SELECTOR);
60        components.each(function(){
61            setupViewer($(this));
62        });
63    }
64
65    function videoChapterInit(data, viewerCustom) {
66        const compId = viewerCustom.containerId;
67        const videoPlayer = viewerCustom.getComponent("videoPlayer");
68        const compElement = document.getElementById(compId);
69        const navigation = videoPlayer.getNavigation();
70        if(navigation && compElement.querySelectorAll('.s7chapterbutton').length < 1) {
71            if($('#chapter-scroll-height').length < 1){
72                $('body').append(`<input type="hidden" id="chapter-scroll-height" style="margin-top:calc(var(--space-xl) * 8);" />`);
73            }
74            const controlBar = viewerCustom.getComponent("controls");
75            controlBar.attachView(videoPlayer, false);
76            let htmlStr = '';
77            navigation && navigation['items'].forEach(function(nav, key) {
78                htmlStr += `<div class="chapter" data-start="${nav.start}" data-end="${nav.end}" data-index="${key}" data-id="${nav.id}" tabindex='0'><span>${nav.data}</span></div>`;
79            });
80            let chapterTitle = 'Chapters';
81            let separatorStyle = '';
82            const dmVideo = $('#'+compId).closest('.dm-custom-parameter');
83            if(dmVideo.length){
84                if(dmVideo.data('chapterTitle') && dmVideo.data('chapterTitle').length){
85                    chapterTitle = dmVideo.data('chapterTitle');
86                }
87                if(dmVideo.data('chapterSeparatorStyle') && dmVideo.data('chapterSeparatorStyle').length){
88                    separatorStyle = dmVideo.data('chapterSeparatorStyle');
89                }
90            }
91            const separator = `<div class="separator ${separatorStyle}"><div class="cmp-separator"><hr></div></div>`;
92            const chapterListHeader = `<div class="chapter-title">
93                <div class="chapter-title--label">${chapterTitle}</div>
94                <div class="global-link cmp-global-link-icon-secondary">
95                    <ul>
96                        <li>
97                            <a href="javascript:void(0)">
98                                <span>close</span>
99                                <span class="material-symbols-rounded close-icon">close</span>
100                            </a>
101                        </li>
102                    </ul>
103                </div>
104            </div>`;
105            const chapterList = `<div class="chapter-list hide" data-description="Scene7ComponentHolder" data-component="chapter list section">
106                ${chapterListHeader}
107                ${separator}
108                <div class="chapter-list-wrapper">
109                    ${htmlStr}
110                </div>
111            </div>`;
112    
113            // Create a new button element
114            const chapterNav = document.createElement('div');
115            chapterNav.setAttribute('data-namespace', 's7classic');
116            chapterNav.setAttribute('data-description', 'Scene7ComponentHolder');
117            chapterNav.setAttribute('data-component', 'ChapterButton');
118            chapterNav.setAttribute('class','chapternav s7button s7chapterbutton');
119            chapterNav.id = compId+'_chapterNavButton'
120            chapterNav.innerHTML = `<div class="chapters" 
121                                        data-description='Scene7ComponentHolder' 
122                                        data-component='ChapterButton'
123                                        role='button'
124                                        lang='en'
125                                        title='chapter list'
126                                        aria-label='chapter list'
127                                        tabindex='0'></div>${chapterList}`;
128    
129            controlBar.component.innerContainer.append(chapterNav);
130    
131            // Define functionality for the new button
132            chapterNav.onclick = function (e) {
133                chapterListHideShow(e,chapterNav, compId);
134            };
135
136            chapterNav.onkeydown = function(event) {
137                // If the user presses the "Enter" key on the keyboard
138                if (event.key === "Enter") {
139                  // Cancel the default action, if needed
140                  event.preventDefault();
141                  // Trigger the button element with a click
142                  chapterListHideShow(event,chapterNav, compId);
143                }
144            };
145
146            chapterNav.onmousedown = function() {
147                chapterNav.setAttribute("state", "down");
148            }
149
150            chapterNav.onmouseup = function() {
151                chapterNav.setAttribute("state", "up");
152            }
153
154            chapterNav.ontouchstart = function() {
155                chapterNav.setAttribute("state", "down");
156            }
157
158            chapterNav.ontouchend = function() {
159                chapterNav.setAttribute("state", "up");
160            }
161            
162            const hoverTooltip = new s7sdk.SimpleToolTip(chapterNav.querySelector('.chapters'),"chapter list");
163
164            chapterNav.querySelectorAll('.chapter').forEach(function(chapter) {
165                chapter.onclick = function () {
166                    videoPlayer.seek(chapter.dataset.start);
167                    videoPlayer.play();
168                };
169                chapter.onkeydown = function(event) {
170                    // If the user presses the "Enter" key on the keyboard
171                    if (event.key === "Enter") {
172                        videoPlayer.seek(chapter.dataset.start);
173                        videoPlayer.play();
174                        $(event.currentTarget).closest('.s7innercontrolbarcontainer').find('.s7playpausebutton').focus();
175                    }
176                }
177            });
178
179            $('#'+compId).on('mouseenter touchstart', function(){
180                $(this).closest('.cmp-extended-modal__container').addClass('cmp-overflow-visible');
181                $(this).closest('.cmp-extended-modal__container__body').addClass('cmp-overflow-visible');
182            });
183
184            $('#'+compId).on('mouseleave', function(){
185                $(this).closest('.cmp-extended-modal__container').removeClass('cmp-overflow-visible');
186                $(this).closest('.cmp-extended-modal__container__body').removeClass('cmp-overflow-visible');
187            });
188
189            if($(window).width() <= 1024 && $('#'+compId+'>.s7container').attr('mode') !== 'fullscreen'){
190                $('#'+compId).find('.chapter-list').width($('#'+compId).width());
191            }
192
193            $(window).on('resize', () => {
194                $('#'+compId).closest('.cmp-extended-modal__container').removeClass('cmp-overflow-visible');
195                $('#'+compId).closest('.cmp-extended-modal__container__body').removeClass('cmp-overflow-visible');
196                if($(window).width() <= 1024 && $('#'+compId+'>.s7container').attr('mode') !== 'fullscreen'){
197                    $('#'+compId).find('.chapter-list').width($('#'+compId).width());
198                } else{
199                    $('#'+compId).find('.chapter-list').attr('style', '');
200                }
201            });
202
203            $('.chapter-list').find('.chapter:last').on('keydown',function(e) {
204                // If the user presses the "Enter" key on the keyboard
205                if (e.key === "Tab") {
206                    $(this).closest('.s7chapterbutton').find('.chapters').focus();
207                }
208            });
209
210            if(window.DMvideoLoadIcons){
211                window.DMvideoLoadIcons();
212            }
213        }
214    }
215
216    function chapterListHideShow(e,chapterNav,compId){
217        if(e.target.className !== 'chapter-title--label') {
218            chapterNav.querySelector('.chapter-list').classList.toggle('hide');
219        
220            if(chapterNav.getAttribute("selected") && chapterNav.getAttribute("selected") == "true"){
221                chapterNav.setAttribute("selected", "false");
222            }else{
223                chapterNav.setAttribute("selected", "true");
224            }
225
226            if($(chapterNav.querySelector('.chapter-list')).hasClass('hide')) {
227                $(chapterNav).find('.chapters').focus();
228            }
229
230            if($(window).width() <= 1024 && $('#'+compId+'>.s7container').attr('mode') !== 'fullscreen'){
231                $('#'+compId).find('.chapter-list').width($('#'+compId).width());
232            } else{
233                $('#'+compId).find('.chapter-list').attr('style', '');
234            }
235
236            if($('#'+compId).find('.chapter-list').height() >= parseFloat($("#chapter-scroll-height").css("margin-top").replace("px", ""))){
237                $('#'+compId).find('.chapter-list-wrapper').addClass('is-scrollable');
238            }else{
239                $('#'+compId).find('.chapter-list-wrapper').removeClass('is-scrollable');
240            }
241        }
242    }
243	
244	function fmt(ms){
245	  const d=new Date(ms), h=d.getUTCHours(),
246			m=String(d.getUTCMinutes()).padStart(2,'0'),
247			s=String(d.getUTCSeconds()).padStart(2,'0');
248	  return h>0 ? `${h}:${m}:${s}` : `${m}:${s}`;
249	}
250	
251    // Define an event handler function to update the videotime for VideoPlayer changes
252    function onNotifyVideoTime(viewerCustom){
253        const videoPlayer = viewerCustom.getComponent("videoPlayer");
254        const controlBar = viewerCustom.getComponent("controls");
255        controlBar.attachView(videoPlayer, false);
256        let customTime;
257        if(viewerCustom.videoTime.getPlayedTime()){
258            customTime = new Date(viewerCustom.videoTime.getPlayedTime());
259        }else{
260            customTime = new Date(viewerCustom.videoTime.getDuration());
261        }
262        const minute = (customTime.getUTCMinutes() < 10 ? '0' : '') + customTime.getUTCMinutes();
263        const second = (customTime.getUTCSeconds() < 10 ? '0' : '') + customTime.getUTCSeconds();
264		const hour = String(customTime.getUTCHours());
265        if($("#"+controlBar.compId).find(".s7customTimer").length){
266            $("#"+controlBar.compId).find(".s7customTimer").html(fmt(customTime.getTime()));
267        }else{
268            $("#"+controlBar.compId).find(".s7videotime").append(`<div class="s7customTimer">${fmt(customTime.getTime())}</div>`);
269        }
270        if($("#"+controlBar.compId).find(".chapter-list-wrapper").length){
271            const $chapterList = $("#"+controlBar.compId).find(".chapter-list-wrapper");
272            const $chapter = $chapterList.find('.chapter');
273            $chapter.each(function() { 
274                const start = parseFloat($(this).data('start'));
275                const end = parseFloat($(this).data('end'));
276                if (start <= viewerCustom.videoTime.getPlayedTime() && end >= viewerCustom.videoTime.getPlayedTime()) {
277                    $(this).addClass('active');
278                } else {
279                    $(this).removeClass('active');
280                }
281            });
282        }
283          
284    }
285
286    function updatePlayTime(viewerCustom){
287        const compId = viewerCustom.containerId;
288        const videoPlayer = viewerCustom.getComponent("videoPlayer");
289        const duration = fmt(viewerCustom.videoTime.getDuration());
290        const $component = $("#" + compId);
291        if ($component.parents(".panelcontainer.cmp-panelcontainer-featureblock-video.cmp-video-no-timer").length || $component.parents(".cmp-video-no-timer").length) {
292            return;
293        }
294        const $timer = $("#" + videoPlayer.compId).find(".current_play_time");
295        if ($timer.length) {
296            $timer.text(duration);
297        } else {
298            $("#" + videoPlayer.compId).append(`<div class="current_play_time">${duration}</div>`);
299        }
300    }
301
302    function setupCustomTabOrder(viewer) {
303        const $container = $("#" + viewer.containerId);
304        const controls = [$container.find(".s7playpausebutton")  , $container.find(".s7mutebutton") , $container.find(".s7verticalvolume .s7knob") , $container.find(".s7videoscrubber .s7knob") , $container.find(".s7closedcaptionbutton") , $container.find(".s7fullscreenbutton")];
305        controls.forEach(($control, index) => {
306            if (!$control.length) {
307                return;
308            }
309            $control.on("keydown.customtab", function(e) {
310                if (e.key !== "Tab") {
311                    return;
312                }
313                if (e.shiftKey) {
314                    if (index === 0) {
315                        return;
316                    }
317                    e.preventDefault();
318                    controls[index - 1].focus();
319                } else {
320                    if (index === controls.length - 1) {
321                        return;
322                    }
323                    e.preventDefault();
324                    controls[index + 1].focus();
325                }
326            });
327        });
328    }
329
330
331    /**
332     * Setup viewer based on component
333     * @param component a div component contains viewer config
334     */
335    function setupViewer(component){
336        var compId = component.attr('id');
337        var viewer = S7dmUtils[compId],
338            assetType = component.data('asset-type'),
339            mode = component.data('mode'),
340            stageSize = component.data('stagesize');
341
342        if (typeof viewer != 'undefined' && viewer != null) {
343            viewer.dispose();
344            S7dmUtils[compId] = null;
345            component.removeClass(responsiveViewerCSS);
346        }
347        component.html('');
348        var viewerType = component.data('viewer-type');
349
350        if (viewerType) {
351
352            var viewerParams = buildViewerParams(component);
353            var viewerSettings = { 
354                'containerId' : component.attr('id'),
355                'params': viewerParams,
356                "handlers":{
357                    "initComplete":function() {
358                        if($('body').hasClass('elements-dynamic-video')){
359                         const videoPlayer = viewer.getComponent("videoPlayer");
360                         var dcTitle = "Closed Caption Button";
361                         if(!viewer.isCaption){
362                            const closedCaptionButton = viewer.getComponent("closedCaptionButton");
363                            $("#"+closedCaptionButton.compId).addClass("s7closedCaptionDisabled");
364                            closedCaptionButton.component.toolTipSelected = "Closed Caption not Available";
365                            closedCaptionButton.component.toolTipUnselected = "Closed Caption not Available";
366                            dcTitle = "Closed Caption Button Disable"
367                         }
368                         const container = document.getElementById(viewer.containerId);
369          				 if (container) {
370                         const ccBtnElem = container.querySelector('[data-component="ClosedCaptionButton"].s7closedcaptionbutton');
371                            if (ccBtnElem) {
372                            ccBtnElem.addEventListener('click', function() {
373                                if (document.body.getAttribute('data-cmp-data-layer-enabled') !== undefined) {
374                                window.adobeDataLayer.push({
375                                    event: "cmp:click",
376                                    attributes: {
377                                    "@type": "global/components/globalcomponents/navigation/global-link/v1/global-link/link",
378                                    "dc:title": dcTitle,
379                                    "parentId": "internal",
380                                    "xdm:linkTarget": "_self",
381                                    "xdm:linkType": "internal",
382                                    "xdm:linkURL": "#"
383                                    }
384                                });
385                               }
386                            });
387                           }
388                        }
389                        
390                        // Add an event listener for the VideoPlayer navigation/chapters change event
391                        videoPlayer.addEventListener(s7sdk.event.VideoEvent.NOTF_NAVIGATION, function(event){
392                            videoChapterInit(event.s7event.data, viewer);
393                            const videoScrubber = viewer.getComponent('videoScrubber');
394                            videoScrubber.setNavigation(event.s7event.data); // Forcing to load again while we have resize.
395                        }, false);
396
397                        // Add an event listener for the VideoPlayer volume change event
398                        videoPlayer.addEventListener(s7sdk.event.VideoEvent.NOTF_VOLUME, function(event){
399                            // This event is used to update model issue with volume & timer.
400                            const controlBar = viewer.getComponent("controls");
401                            if(!$("#"+controlBar.compId).find(".s7customTimer").length){
402                                if(window.DMvideoLoadIcons){
403                                    window.DMvideoLoadIcons();
404                                }
405                                onNotifyVideoTime(viewer);
406                            }
407                            
408                        }, false);
409
410                        // Add an event listener for the VideoPlayer notify ready event
411                        videoPlayer.addEventListener(s7sdk.event.StatusEvent.NOTF_VIEW_READY, function(event){
412                            if(window.DMvideoLoadIcons){
413                                window.DMvideoLoadIcons();
414                            }
415                            if(window.exitModalVideoUpdate && this.closest(".cmp-extended-modal")){
416                                window.exitModalVideoUpdate();
417                            }
418                            updatePlayTime(viewer);
419                            onNotifyVideoTime(viewer);
420                            setupCustomTabOrder(viewer);
421                        }, false);
422
423                        // Add an event listener for the VideoPlayer duration change event
424                        videoPlayer.addEventListener(s7sdk.event.VideoEvent.NOTF_DURATION, function(event){
425                            if(window.DMvideoLoadIcons){
426                                window.DMvideoLoadIcons();
427                            }
428                            if(window.exitModalVideoUpdate && this.closest(".cmp-extended-modal")){
429                                window.exitModalVideoUpdate();
430                            }
431                            updatePlayTime(viewer);
432                            onNotifyVideoTime(viewer);
433                        }, false);
434                        
435                        // Add an event listener for the VideoPlayer current time change event
436                        videoPlayer.addEventListener(s7sdk.event.VideoEvent.NOTF_CURRENT_TIME, function(event){
437                            onNotifyVideoTime(viewer);
438                        }, false);
439
440                        /* In future if any resize issue comes we could test & use this by removing modal exitModalVideoUpdate funtion
441                        // Create ParameterManager instance to handles modifiers		
442                        const params = new s7sdk.ParameterManager();
443                        // Create the Container component object
444                        const container = viewer.getComponent('container');
445                        // Add an event listener for Container resize events
446                        container.addEventListener(s7sdk.event.ResizeEvent.COMPONENT_RESIZE, function(event){
447                            videoPlayer.resize(event.s7event.w, event.s7event.h);
448                        }, false);*/
449                        }
450                    }
451                },
452            };
453            if (!(viewerType == 'FlyoutViewer' && stageSize)) {
454                component.addClass(responsiveViewerCSS);
455            }
456            viewer = new s7viewers[viewerType](viewerSettings);
457            if (typeof Granite != 'undefined' && typeof Granite.I18n != 'undefined') {
458                viewer.setLocalizedTexts(getLocalizedText()); //passing localized text to the viewer
459            }
460            S7dmUtils[compId] = viewer;
461            viewer.init();
462        }
463        else if(assetType === 'image') {
464            if (component.data('breakpoints') || mode == 'smartcrop') {
465                component[0].removeAttribute('data-stagesize');
466                buildResponsiveImage(component);
467            }
468            else {
469                component[0].removeAttribute('data-enablehd');
470                buildImage(component);
471            }
472        }
473
474    }
475
476    /**
477     * Build Image and anchor when there is no viewer constructor defined for IMAGE ONLY
478     * @param component a div component contains viewer config
479     */
480    function buildImage(component) {
481        var stageSize = component.data('stagesize'),
482            linkURL = component.data('linkurl'),
483            linkTarget = component.data('linktarget'),
484            title = component.data('title'),
485            altText = component.data('alt'),
486            imagePreset = component.data('imagepreset'),
487            imageServer = component.data('imageserver'),
488            modifiers = component.data('urlmodifiers');
489
490        var imgSetup = {
491            'src': imageServer + component.data('asset-path')
492        }
493        if (imagePreset) {
494            imgSetup['src'] += '?$' + imagePreset + '$';
495        }
496        if (modifiers) {
497            imgSetup['src'] += (imagePreset ? '&' : '?') + modifiers
498        }
499
500        if (stageSize) {
501            var stageSizeParts = stageSize.split(',');
502            imgSetup['width'] = stageSizeParts[0];
503            if (stageSizeParts.length > 1) {
504                imgSetup['height'] = stageSizeParts[1];
505            }
506        }
507
508        var imgComp = $('<img>', imgSetup);
509        //if there is link, wrap it around image
510        if (linkURL) {
511            var anchorSetup = {
512                'href': linkURL,
513                'target': linkTarget
514            };
515            if (altText) {
516                anchorSetup['alt'] = altText;
517                anchorSetup['title'] = altText;  // default to alt text
518                imgComp.attr('alt', altText);
519            }
520            if (title) {
521                anchorSetup['title'] = title;
522            }
523            var anchor = $('<a>', anchorSetup);
524            anchor.append(imgComp);
525            component.append(anchor);
526        }
527        else {
528            //Add alt text if it's set
529            if (altText) {
530                imgComp.attr('alt', altText);
531            }
532            component.append(imgComp);
533        }
534
535    }
536
537    /**
538     * Build responsive image
539     * @param component container
540     */
541    function buildResponsiveImage(component) {
542        var imagePreset = component.data('imagepreset'),
543            imageServer = component.data('imageserver'),
544            linkURL = component.data('linkurl'),
545            linkTarget = component.data('linktarget'),
546            title = component.data('title'),
547            altText = component.data('alt');
548        var modifiers = component.data('urlmodifiers');
549        var respCon = $('<div>', { 'class': 's7responsiveContainer' });
550        var respImgId = component.attr('id') + '_resp';
551        var respImgSetup = {
552            'id': respImgId,
553            'src': "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",
554            'data-src': imageServer + component.data('asset-path'),
555            'class': 'fluidimage',
556            'data-mode': component.data('mode'),
557            'data-breakpoints': component.data('breakpoints'),
558            'data-enablehd': component.data('enablehd') == "never" ? "never" : "always"
559        }
560        if (imagePreset) {
561            respImgSetup['data-src'] += '?$' + imagePreset + '$';
562        }
563        if (modifiers) {
564            respImgSetup['data-src'] += (imagePreset ? '&' : '?') + modifiers
565        }
566        var respImg = $('<img>', respImgSetup);
567        //if there is link, wrap it around image
568        if (linkURL) {
569            var anchorSetup = {
570                'href': linkURL,
571                'target': linkTarget
572            };
573            if (altText) {
574                anchorSetup['alt'] = altText;
575                anchorSetup['title'] = altText;  // default to alt text
576                respImg.attr('alt', altText);
577            }
578            if (title) {
579                anchorSetup['title'] = title;
580            }
581            var anchor = $('<a>', anchorSetup);
582            anchor.append(respImg);
583            respCon.append(anchor);
584        } else {
585            if (altText) {
586                respImg.attr('alt', altText);
587            }
588            respCon.append(respImg);
589        }
590        component.append(respCon);
591        s7responsiveImage(document.getElementById(respImgId));
592    }
593
594    /**
595     * @param component a div element with viewer setup
596     * @return viewer parameters in JSON
597     */
598    function buildViewerParams(component) {
599        var assetPath = component.data('asset-path'),
600            assetType = component.data('asset-type'),
601            viewerType = component.data('viewer-type'),
602            imageserver = component.data('imageserver'),
603            videoserver = component.data('videoserver'),
604            contentserver = component.data('contenturl'),
605            config = component.data('config'),
606            wcmdisabled = component.data('wcmdisabled'),
607            stageSize = component.data('stagesize'),
608            viewerModifiers = component.data('viewermodifiers'),
609            isdms7 = component.data('dms7');
610
611        var viewerParams = {
612            'asset': assetPath,
613            'serverurl': imageserver,
614            'contenturl': contentserver,
615        };
616        //Add extra viewer modifiers if any
617        if (viewerModifiers) {
618            $.extend(viewerParams, getViewerModifiers(viewerModifiers));
619        }
620
621        var isAuthor = !wcmdisabled && wcmdisabled != '';
622
623        //Add cache=off when WCM is not disabled (author side)
624        if (isAuthor) {
625            viewerParams['asset'] += '?cache=off';
626        }
627        if (stageSize) {
628            viewerParams['stagesize'] = stageSize;
629        }
630        if (viewerType == 'FlyoutViewer') {
631            viewerParams['imagereload'] = '1,breakpoint,100;320;480';
632        }
633        if (assetPath.indexOf('/') != 0) {
634            viewerParams['aemmode'] = '0';
635        }
636
637        //For video, we add videoserverurl
638        if (viewerType.indexOf('Video') >= 0 || viewerType.indexOf('Mixed') >= 0) {
639            viewerParams['videoserverurl'] = videoserver;
640            // force native if
641            // Asset is non-AVS video (apply to both DMS7 and DM Hybrid for playing progressively) OR
642            // (Asset is DMS7 video regardless of AVS or non-AVS AND the page is on author side)
643            if (assetType == 'video' || ((typeof isdms7 != 'undefined') && isAuthor)) {
644                viewerParams['playback'] = 'native';
645                viewerParams['progressivebitrate'] = '20000';
646            }
647        }
648        //check for viewer preset setup
649        if (typeof config != 'undefined' && config.length > 0) {
650            viewerParams['config'] = getViewerPresetPath(config);
651        }
652        //  viewerParams['navigation'] = 'Scene7SharedAssets/adobe_qbc_final_nc';
653        return viewerParams;
654    }
655
656    /**
657     * Parse viewer preset path for viewer-usable format
658     * @param config viewer preset path stored in the component node
659     * @return viewer-usable format viewer preset path
660     */
661    function getViewerPresetPath(config) {
662        var configParts = config.split('|');
663        return configParts[0];
664    }
665
666    /**
667     * Parse viewer preset path for isCustom Preset flag
668     * @param config viewer preset string
669     * @return flag for custom preset
670     */
671    function isCustomPreset(config) {
672        var configParts = config.split('|');
673        return configParts[2];
674    }
675
676    /**
677     * Fail viewer loader handler
678     */
679    function failViewerLoader(){
680        console.log('S7Viewer is missing');
681    }
682
683    /**
684     * Parse free-form viewer modifiers
685     * @param viewerModifiers string for free-form viewer modifiers
686     * @return JSON representing viewer modifiers
687     */
688    function getViewerModifiers(viewerModifiers) {
689        var modifiers = {};
690        if (viewerModifiers) {
691            var items = viewerModifiers.split('&');
692            for (var i = 0; i < items.length; i++) {
693                //only when there is key=val pair
694                if (items[i].indexOf('=') > 0) {
695                    var key = items[i].substring(0, items[i].indexOf('='));
696                    var val = items[i].substring(items[i].indexOf('=') + 1);
697                    modifiers[key] = val;
698                }
699            }
700        }
701        return modifiers;
702    }
703
704    /**
705     * Get localized text for viewer from s7sdk_i18n.localizedText
706     * @return JSON for localized text
707     */
708    function getLocalizedText() {
709        var localizedText = {};
710        localizedText[Granite.I18n.getLocale()] = formatLocalizedText(s7sdk_i18n.localizedText);
711        localizedText['defaultLocale'] = Granite.I18n.getLocale();
712        return localizedText;
713    }
714
715    /**
716     * Format localized text into a correct viewer format
717     * @param localizedText localized text parsed from s7sdk
718     * @return formatted localized text with correct key for viewer
719     */
720    function formatLocalizedText(localizedText) {
721        var formatTexts = {};
722        for (var compKey in localizedText) {
723            var compObj = localizedText[compKey];
724            for (var symbolKey in compObj) {
725                var modKey = compKey + '.' + symbolKey;
726                var symbolVal = compObj[symbolKey];
727                formatTexts[modKey] = symbolVal;
728            }
729        }
730        return formatTexts;
731    }
732
733}).call(this);

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.