"use strict"; //// progress.js// examples//// Created by David Rowe on 29 Jan 2015.// Copyright 2015 High Fidelity, Inc.//// This script displays a progress download indicator when downloads are in progress.//// Distributed under the Apache License, Version 2.0.// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html// (function () { // BEGIN LOCAL_SCOPE function debug() { //print.apply(null, arguments); } Script.include("/~/system/libraries/globals.js"); var rawProgress = 100, // % raw value. displayProgress = 100, // % smoothed value to display. alpha = 0.0, alphaDelta = 0.0, // > 0 if fading in; < 0 if fading out. ALPHA_DELTA_IN = 0.15, ALPHA_DELTA_OUT = -0.02, fadeTimer = null, FADE_INTERVAL = 30, // ms between changes in alpha. fadeWaitTimer = null, FADE_OUT_WAIT = 1000, // Wait before starting to fade out after progress 100%. visible = false, BAR_DESKTOP_2K_WIDTH = 2240, // Width of SVG image in pixels. Sized for 1920 x 1080 display with 6 visible repeats. BAR_DESKTOP_2K_REPEAT = 320, // Length of repeat in bar = 2240 / 7. BAR_DESKTOP_2K_HEIGHT = 3, // Display height of SVG BAR_DESKTOP_2K_URL = Script.resolvePath("assets/images/progress-bar-2k.svg"), BAR_DESKTOP_4K_WIDTH = 4480, // Width of SVG image in pixels. Sized for 4096 x 1920 display with 6 visible repeats. BAR_DESKTOP_4K_REPEAT = 640, // Length of repeat in bar = 2240 / 7. BAR_DESKTOP_4K_HEIGHT = 6, // Display height of SVG BAR_DESKTOP_4K_URL = Script.resolvePath("assets/images/progress-bar-4k.svg"), BAR_HMD_WIDTH = 2240, // Desktop image works with HMD well. BAR_HMD_REPEAT = 320, BAR_HMD_HEIGHT = 3, BAR_HMD_URL = Script.resolvePath("assets/images/progress-bar-2k.svg"), BAR_Y_OFFSET_DESKTOP = 0, // Offset of progress bar while in desktop mode BAR_Y_OFFSET_HMD = -100, // Offset of progress bar while in HMD ANIMATION_SECONDS_PER_REPEAT = 4, // Speed of bar animation TEXT_HEIGHT = 32, TEXT_WIDTH = 256, TEXT_URL = Script.resolvePath("assets/images/progress-bar-text.svg"), windowWidth = 0, windowHeight = 0, barDesktop = {}, barHMD = {}, textDesktop = {}, // Separate desktop and HMD overlays because can't change text size after overlay created. textHMD = {}, SCALE_TEXT_DESKTOP = 0.6, SCALE_TEXT_HMD = 1.0, isHMD = false, // Max seen since downloads started. This is reset when all downloads have completed. maxSeen = 0, // Progress is defined as: (pending_downloads + active_downloads) / max_seen // We keep track of both the current progress (rawProgress) and the // best progress we've seen (bestRawProgress). As you are downloading, you may // encounter new assets that require downloads, increasing the number of // pending downloads and thus decreasing your overall progress. bestRawProgress = 0, // True if we have known active downloads isDownloading = false, // Entities are streamed to users, so you don't receive them all at once; instead, you // receive them over a period of time. In many cases we end up in a situation where // // The initial delay cooldown keeps us from tracking progress before the allotted time // has passed. INITIAL_DELAY_COOLDOWN_TIME = 1000, initialDelayCooldown = 0, isInInterstitialMode = false; function fade() { alpha = alpha + alphaDelta; if (alpha < 0) { alpha = 0; } else if (alpha > 1) { alpha = 1; } if (alpha === 0 || alpha === 1) { // Finished fading in or out alphaDelta = 0; Script.clearInterval(fadeTimer); } if (alpha === 0) { // Finished fading out visible = false; } Overlays.editOverlay(barDesktop.overlay, { alpha: alpha, visible: visible && !isHMD }); Overlays.editOverlay(barHMD.overlay, { alpha: alpha, visible: visible && isHMD }); Overlays.editOverlay(textDesktop.overlay, { alpha: alpha, visible: visible && !isHMD }); Overlays.editOverlay(textHMD.overlay, { alpha: alpha, visible: visible && isHMD }); } Window.domainChanged.connect(function () { isDownloading = false; bestRawProgress = 100; rawProgress = 100; displayProgress = 100; }); function onDownloadInfoChanged(info) { debug("PROGRESS: Download info changed ", info.downloading.length, info.pending, maxSeen); // Update raw progress value if (info.downloading.length + info.pending === 0) { isDownloading = false; rawProgress = 100; bestRawProgress = 100; initialDelayCooldown = INITIAL_DELAY_COOLDOWN_TIME; } else { var count = info.downloading.length + info.pending; if (!isDownloading) { isDownloading = true; bestRawProgress = 0; rawProgress = 0; initialDelayCooldown = INITIAL_DELAY_COOLDOWN_TIME; displayProgress = 0; maxSeen = count; } if (count > maxSeen) { maxSeen = count; } if (initialDelayCooldown <= 0) { rawProgress = ((maxSeen - count) / maxSeen) * 100; if (rawProgress > bestRawProgress) { bestRawProgress = rawProgress; } } } debug("PROGRESS:", rawProgress, bestRawProgress, maxSeen); } function createOverlays() { barDesktop.overlay = Overlays.addOverlay("image", { imageURL: barDesktop.url, subImage: { x: 0, y: 0, width: barDesktop.width - barDesktop.repeat, height: barDesktop.height }, width: barDesktop.width, height: barDesktop.height, visible: false, alpha: 0.0 }); barHMD.overlay = Overlays.addOverlay("image", { imageURL: BAR_HMD_URL, subImage: { x: 0, y: 0, width: BAR_HMD_WIDTH - BAR_HMD_REPEAT, height: BAR_HMD_HEIGHT }, width: barHMD.width, height: barHMD.height, visible: false, alpha: 0.0 }); textDesktop.overlay = Overlays.addOverlay("image", { imageURL: TEXT_URL, width: textDesktop.width, height: textDesktop.height, visible: false, alpha: 0.0 }); textHMD.overlay = Overlays.addOverlay("image", { imageURL: TEXT_URL, width: textHMD.width, height: textHMD.height, visible: false, alpha: 0.0 }); } function deleteOverlays() { Overlays.deleteOverlay(barDesktop.overlay); Overlays.deleteOverlay(barHMD.overlay); Overlays.deleteOverlay(textDesktop.overlay); Overlays.deleteOverlay(textHMD.overlay); } function updateProgressBarLocation() { var viewport = Controller.getViewportDimensions(); windowWidth = viewport.x; windowHeight = viewport.y; isHMD = HMD.active; if (isHMD) { Overlays.editOverlay(barHMD.overlay, { x: windowWidth / 2 - barHMD.width / 2, y: windowHeight - 2 * barHMD.height + BAR_Y_OFFSET_HMD }); Overlays.editOverlay(textHMD.overlay, { x: windowWidth / 2 - textHMD.width / 2, y: windowHeight - 2 * barHMD.height - textHMD.height + BAR_Y_OFFSET_HMD }); } else { Overlays.editOverlay(barDesktop.overlay, { x: windowWidth / 2 - barDesktop.width / 2, y: windowHeight - 2 * barDesktop.height + BAR_Y_OFFSET_DESKTOP, width: barDesktop.width }); Overlays.editOverlay(textDesktop.overlay, { x: windowWidth / 2 - textDesktop.width / 2, y: windowHeight - 2 * barDesktop.height - textDesktop.height + BAR_Y_OFFSET_DESKTOP }); } } function update() { var viewport, diff, x, gpuTextures; initialDelayCooldown -= 30; if (displayProgress < rawProgress) { diff = rawProgress - displayProgress; if (diff < 0.5) { displayProgress = rawProgress; } else { displayProgress += diff * 0.05; } } gpuTextures = Render.getConfig("Stats").texturePendingGPUTransferCount; // Update state if (!visible) { // Not visible because no recent downloads if ((displayProgress < 100 || gpuTextures > 0) && !isInInterstitialMode && !isInterstitialOverlaysVisible) { // Have started downloading so fade in visible = true; alphaDelta = ALPHA_DELTA_IN; fadeTimer = Script.setInterval(fade, FADE_INTERVAL); } } else if (alphaDelta !== 0.0) { // Fading in or out if (alphaDelta > 0) { if (rawProgress === 100 && gpuTextures === 0) { // Was downloading but now have finished so fade out alphaDelta = ALPHA_DELTA_OUT; } } else { if (displayProgress < 100 || gpuTextures > 0) { // Was finished downloading but have resumed so fade in alphaDelta = ALPHA_DELTA_IN; } } } else { // Fully visible because downloading or recently so if (fadeWaitTimer === null) { if (rawProgress === 100 && gpuTextures === 0) { // Was downloading but have finished so fade out soon fadeWaitTimer = Script.setTimeout(function () { alphaDelta = ALPHA_DELTA_OUT; fadeTimer = Script.setInterval(fade, FADE_INTERVAL); fadeWaitTimer = null; }, FADE_OUT_WAIT); } } else { if (displayProgress < 100 || gpuTextures > 0) { // Was finished and waiting to fade out but have resumed so // don't fade out Script.clearInterval(fadeWaitTimer); fadeWaitTimer = null; } } } if (visible) { x = ((Date.now() / 1000) % ANIMATION_SECONDS_PER_REPEAT) / ANIMATION_SECONDS_PER_REPEAT; if (!isHMD) { x = x * barDesktop.repeat; } else { x = x * BAR_HMD_REPEAT; } if (isInInterstitialMode || isInterstitialOverlaysVisible) { visible = false; } // Update progress bar Overlays.editOverlay(barDesktop.overlay, { visible: !isHMD && visible, bounds: { x: barDesktop.repeat - x, y: windowHeight - barDesktop.height, width: barDesktop.width - barDesktop.repeat, height: barDesktop.height } }); Overlays.editOverlay(barHMD.overlay, { visible: isHMD && visible, bounds: { x: BAR_HMD_REPEAT - x, y: windowHeight - BAR_HMD_HEIGHT, width: BAR_HMD_WIDTH - BAR_HMD_REPEAT, height: BAR_HMD_HEIGHT } }); Overlays.editOverlay(textDesktop.overlay, { visible: !isHMD && visible }); Overlays.editOverlay(textHMD.overlay, { visible: isHMD && visible }); // Update 2D overlays to maintain positions at bottom middle of window viewport = Controller.getViewportDimensions(); if (viewport.x !== windowWidth || viewport.y !== windowHeight || isHMD !== HMD.active) { updateProgressBarLocation(); } } } function interstitialModeChanged(inMode) { isInInterstitialMode = inMode; } function setUp() { var is4k = Window.innerWidth > 3000; isHMD = HMD.active; barDesktop.width = is4k ? BAR_DESKTOP_4K_WIDTH - BAR_DESKTOP_4K_REPEAT : BAR_DESKTOP_2K_WIDTH - BAR_DESKTOP_2K_REPEAT; barDesktop.height = is4k ? BAR_DESKTOP_4K_HEIGHT : BAR_DESKTOP_2K_HEIGHT; barDesktop.repeat = is4k ? BAR_DESKTOP_4K_REPEAT : BAR_DESKTOP_2K_REPEAT; barDesktop.url = is4k ? BAR_DESKTOP_4K_URL : BAR_DESKTOP_2K_URL; barHMD.width = BAR_HMD_WIDTH - BAR_HMD_REPEAT; barHMD.height = BAR_HMD_HEIGHT; textDesktop.width = SCALE_TEXT_DESKTOP * TEXT_WIDTH; textDesktop.height = SCALE_TEXT_DESKTOP * TEXT_HEIGHT; textHMD.width = SCALE_TEXT_HMD * TEXT_WIDTH; textHMD.height = SCALE_TEXT_HMD * TEXT_HEIGHT; createOverlays(); } function tearDown() { deleteOverlays(); } setUp(); Window.interstitialModeChanged.connect(interstitialModeChanged); GlobalServices.downloadInfoChanged.connect(onDownloadInfoChanged); GlobalServices.updateDownloadInfo(); Script.setInterval(update, 1000 / 60); Script.scriptEnding.connect(tearDown); }()); // END LOCAL_SCOPE
"use strict";
//
// progress.js
// examples
//
// Created by David Rowe on 29 Jan 2015.
// Copyright 2015 High Fidelity, Inc.
//
// This script displays a progress download indicator when downloads are in progress.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
(function () { // BEGIN LOCAL_SCOPE
function debug() {
//print.apply(null, arguments);
}
Script.include("/~/system/libraries/globals.js");
var rawProgress = 100, // % raw value.
displayProgress = 100, // % smoothed value to display.
alpha = 0.0,
alphaDelta = 0.0, // > 0 if fading in; < 0 if fading out.
ALPHA_DELTA_IN = 0.15,
ALPHA_DELTA_OUT = -0.02,
fadeTimer = null,
FADE_INTERVAL = 30, // ms between changes in alpha.
fadeWaitTimer = null,
FADE_OUT_WAIT = 1000, // Wait before starting to fade out after progress 100%.
visible = false,
BAR_DESKTOP_2K_WIDTH = 2240, // Width of SVG image in pixels. Sized for 1920 x 1080 display with 6 visible repeats.
BAR_DESKTOP_2K_REPEAT = 320, // Length of repeat in bar = 2240 / 7.
BAR_DESKTOP_2K_HEIGHT = 3, // Display height of SVG
BAR_DESKTOP_2K_URL = Script.resolvePath("assets/images/progress-bar-2k.svg"),
BAR_DESKTOP_4K_WIDTH = 4480, // Width of SVG image in pixels. Sized for 4096 x 1920 display with 6 visible repeats.
BAR_DESKTOP_4K_REPEAT = 640, // Length of repeat in bar = 2240 / 7.
BAR_DESKTOP_4K_HEIGHT = 6, // Display height of SVG
BAR_DESKTOP_4K_URL = Script.resolvePath("assets/images/progress-bar-4k.svg"),
BAR_HMD_WIDTH = 2240, // Desktop image works with HMD well.
BAR_HMD_REPEAT = 320,
BAR_HMD_HEIGHT = 3,
BAR_HMD_URL = Script.resolvePath("assets/images/progress-bar-2k.svg"),
BAR_Y_OFFSET_DESKTOP = 0, // Offset of progress bar while in desktop mode
BAR_Y_OFFSET_HMD = -100, // Offset of progress bar while in HMD
ANIMATION_SECONDS_PER_REPEAT = 4, // Speed of bar animation
TEXT_HEIGHT = 32,
TEXT_WIDTH = 256,
TEXT_URL = Script.resolvePath("assets/images/progress-bar-text.svg"),
windowWidth = 0,
windowHeight = 0,
barDesktop = {},
barHMD = {},
textDesktop = {}, // Separate desktop and HMD overlays because can't change text size after overlay created.
textHMD = {},
SCALE_TEXT_DESKTOP = 0.6,
SCALE_TEXT_HMD = 1.0,
isHMD = false,
// Max seen since downloads started. This is reset when all downloads have completed.
maxSeen = 0,
// Progress is defined as: (pending_downloads + active_downloads) / max_seen
// We keep track of both the current progress (rawProgress) and the
// best progress we've seen (bestRawProgress). As you are downloading, you may
// encounter new assets that require downloads, increasing the number of
// pending downloads and thus decreasing your overall progress.
bestRawProgress = 0,
// True if we have known active downloads
isDownloading = false,
// Entities are streamed to users, so you don't receive them all at once; instead, you
// receive them over a period of time. In many cases we end up in a situation where
//
// The initial delay cooldown keeps us from tracking progress before the allotted time
// has passed.
INITIAL_DELAY_COOLDOWN_TIME = 1000,
initialDelayCooldown = 0,
isInInterstitialMode = false;
function fade() {
alpha = alpha + alphaDelta;
if (alpha < 0) {
alpha = 0;
} else if (alpha > 1) {
alpha = 1;
}
if (alpha === 0 || alpha === 1) { // Finished fading in or out
alphaDelta = 0;
Script.clearInterval(fadeTimer);
}
if (alpha === 0) { // Finished fading out
visible = false;
}
Overlays.editOverlay(barDesktop.overlay, {
alpha: alpha,
visible: visible && !isHMD
});
Overlays.editOverlay(barHMD.overlay, {
alpha: alpha,
visible: visible && isHMD
});
Overlays.editOverlay(textDesktop.overlay, {
alpha: alpha,
visible: visible && !isHMD
});
Overlays.editOverlay(textHMD.overlay, {
alpha: alpha,
visible: visible && isHMD
});
}
Window.domainChanged.connect(function () {
isDownloading = false;
bestRawProgress = 100;
rawProgress = 100;
displayProgress = 100;
});
function onDownloadInfoChanged(info) {
debug("PROGRESS: Download info changed ", info.downloading.length, info.pending, maxSeen);
// Update raw progress value
if (info.downloading.length + info.pending === 0) {
isDownloading = false;
rawProgress = 100;
bestRawProgress = 100;
initialDelayCooldown = INITIAL_DELAY_COOLDOWN_TIME;
} else {
var count = info.downloading.length + info.pending;
if (!isDownloading) {
isDownloading = true;
bestRawProgress = 0;
rawProgress = 0;
initialDelayCooldown = INITIAL_DELAY_COOLDOWN_TIME;
displayProgress = 0;
maxSeen = count;
}
if (count > maxSeen) {
maxSeen = count;
}
if (initialDelayCooldown <= 0) {
rawProgress = ((maxSeen - count) / maxSeen) * 100;
if (rawProgress > bestRawProgress) {
bestRawProgress = rawProgress;
}
}
}
debug("PROGRESS:", rawProgress, bestRawProgress, maxSeen);
}
function createOverlays() {
barDesktop.overlay = Overlays.addOverlay("image", {
imageURL: barDesktop.url,
subImage: {
x: 0,
y: 0,
width: barDesktop.width - barDesktop.repeat,
height: barDesktop.height
},
width: barDesktop.width,
height: barDesktop.height,
visible: false,
alpha: 0.0
});
barHMD.overlay = Overlays.addOverlay("image", {
imageURL: BAR_HMD_URL,
subImage: {
x: 0,
y: 0,
width: BAR_HMD_WIDTH - BAR_HMD_REPEAT,
height: BAR_HMD_HEIGHT
},
width: barHMD.width,
height: barHMD.height,
visible: false,
alpha: 0.0
});
textDesktop.overlay = Overlays.addOverlay("image", {
imageURL: TEXT_URL,
width: textDesktop.width,
height: textDesktop.height,
visible: false,
alpha: 0.0
});
textHMD.overlay = Overlays.addOverlay("image", {
imageURL: TEXT_URL,
width: textHMD.width,
height: textHMD.height,
visible: false,
alpha: 0.0
});
}
function deleteOverlays() {
Overlays.deleteOverlay(barDesktop.overlay);
Overlays.deleteOverlay(barHMD.overlay);
Overlays.deleteOverlay(textDesktop.overlay);
Overlays.deleteOverlay(textHMD.overlay);
}
function updateProgressBarLocation() {
var viewport = Controller.getViewportDimensions();
windowWidth = viewport.x;
windowHeight = viewport.y;
isHMD = HMD.active;
if (isHMD) {
Overlays.editOverlay(barHMD.overlay, {
x: windowWidth / 2 - barHMD.width / 2,
y: windowHeight - 2 * barHMD.height + BAR_Y_OFFSET_HMD
});
Overlays.editOverlay(textHMD.overlay, {
x: windowWidth / 2 - textHMD.width / 2,
y: windowHeight - 2 * barHMD.height - textHMD.height + BAR_Y_OFFSET_HMD
});
} else {
Overlays.editOverlay(barDesktop.overlay, {
x: windowWidth / 2 - barDesktop.width / 2,
y: windowHeight - 2 * barDesktop.height + BAR_Y_OFFSET_DESKTOP,
width: barDesktop.width
});
Overlays.editOverlay(textDesktop.overlay, {
x: windowWidth / 2 - textDesktop.width / 2,
y: windowHeight - 2 * barDesktop.height - textDesktop.height + BAR_Y_OFFSET_DESKTOP
});
}
}
function update() {
var viewport, diff, x, gpuTextures;
initialDelayCooldown -= 30;
if (displayProgress < rawProgress) {
diff = rawProgress - displayProgress;
if (diff < 0.5) {
displayProgress = rawProgress;
} else {
displayProgress += diff * 0.05;
}
}
gpuTextures = Render.getConfig("Stats").texturePendingGPUTransferCount;
// Update state
if (!visible) { // Not visible because no recent downloads
if ((displayProgress < 100 || gpuTextures > 0) && !isInInterstitialMode && !isInterstitialOverlaysVisible) { // Have started downloading so fade in
visible = true;
alphaDelta = ALPHA_DELTA_IN;
fadeTimer = Script.setInterval(fade, FADE_INTERVAL);
}
} else if (alphaDelta !== 0.0) { // Fading in or out
if (alphaDelta > 0) {
if (rawProgress === 100 && gpuTextures === 0) { // Was downloading but now have finished so fade out
alphaDelta = ALPHA_DELTA_OUT;
}
} else {
if (displayProgress < 100 || gpuTextures > 0) { // Was finished downloading but have resumed so fade in
alphaDelta = ALPHA_DELTA_IN;
}
}
} else { // Fully visible because downloading or recently so
if (fadeWaitTimer === null) {
if (rawProgress === 100 && gpuTextures === 0) { // Was downloading but have finished so fade out soon
fadeWaitTimer = Script.setTimeout(function () {
alphaDelta = ALPHA_DELTA_OUT;
fadeTimer = Script.setInterval(fade, FADE_INTERVAL);
fadeWaitTimer = null;
}, FADE_OUT_WAIT);
}
} else {
if (displayProgress < 100 || gpuTextures > 0) { // Was finished and waiting to fade out but have resumed so
// don't fade out
Script.clearInterval(fadeWaitTimer);
fadeWaitTimer = null;
}
}
}
if (visible) {
x = ((Date.now() / 1000) % ANIMATION_SECONDS_PER_REPEAT) / ANIMATION_SECONDS_PER_REPEAT;
if (!isHMD) {
x = x * barDesktop.repeat;
} else {
x = x * BAR_HMD_REPEAT;
}
if (isInInterstitialMode || isInterstitialOverlaysVisible) {
visible = false;
}
// Update progress bar
Overlays.editOverlay(barDesktop.overlay, {
visible: !isHMD && visible,
bounds: {
x: barDesktop.repeat - x,
y: windowHeight - barDesktop.height,
width: barDesktop.width - barDesktop.repeat,
height: barDesktop.height
}
});
Overlays.editOverlay(barHMD.overlay, {
visible: isHMD && visible,
bounds: {
x: BAR_HMD_REPEAT - x,
y: windowHeight - BAR_HMD_HEIGHT,
width: BAR_HMD_WIDTH - BAR_HMD_REPEAT,
height: BAR_HMD_HEIGHT
}
});
Overlays.editOverlay(textDesktop.overlay, {
visible: !isHMD && visible
});
Overlays.editOverlay(textHMD.overlay, {
visible: isHMD && visible
});
// Update 2D overlays to maintain positions at bottom middle of window
viewport = Controller.getViewportDimensions();
if (viewport.x !== windowWidth || viewport.y !== windowHeight || isHMD !== HMD.active) {
updateProgressBarLocation();
}
}
}
function interstitialModeChanged(inMode) {
isInInterstitialMode = inMode;
}
function setUp() {
var is4k = Window.innerWidth > 3000;
isHMD = HMD.active;
barDesktop.width = is4k ? BAR_DESKTOP_4K_WIDTH - BAR_DESKTOP_4K_REPEAT : BAR_DESKTOP_2K_WIDTH - BAR_DESKTOP_2K_REPEAT;
barDesktop.height = is4k ? BAR_DESKTOP_4K_HEIGHT : BAR_DESKTOP_2K_HEIGHT;
barDesktop.repeat = is4k ? BAR_DESKTOP_4K_REPEAT : BAR_DESKTOP_2K_REPEAT;
barDesktop.url = is4k ? BAR_DESKTOP_4K_URL : BAR_DESKTOP_2K_URL;
barHMD.width = BAR_HMD_WIDTH - BAR_HMD_REPEAT;
barHMD.height = BAR_HMD_HEIGHT;
textDesktop.width = SCALE_TEXT_DESKTOP * TEXT_WIDTH;
textDesktop.height = SCALE_TEXT_DESKTOP * TEXT_HEIGHT;
textHMD.width = SCALE_TEXT_HMD * TEXT_WIDTH;
textHMD.height = SCALE_TEXT_HMD * TEXT_HEIGHT;
createOverlays();
}
function tearDown() {
deleteOverlays();
}
setUp();
Window.interstitialModeChanged.connect(interstitialModeChanged);
GlobalServices.downloadInfoChanged.connect(onDownloadInfoChanged);
GlobalServices.updateDownloadInfo();
Script.setInterval(update, 1000 / 60);
Script.scriptEnding.connect(tearDown);
}()); // END LOCAL_SCOPE