OHO privacy policy DE

From OHO - search engine for sustainable open hardware projects
Revision as of 11:08, 7 June 2021 by Thehunter (talk | contribs) (Created page with "<!DOCTYPE html> <html lang="en"> <head> <!-- v2.0.0 --> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <meta charset="utf-8" /> <meta name="viewport" content="width=d...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title></title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css"> <link rel="stylesheet" type="text/css" href="assets/idrviewer.css"> <script src="assets/idrviewer.js" type="text/javascript"></script> <script src="assets/idrviewer.querystring-navigation.js"></script> <script src="assets/idrviewer.fullscreen.js"></script> <script src="assets/idrviewer.search.js"></script> <script src="assets/idrviewer.annotations.js"></script> <script type="text/javascript"> (function () {

   "use strict";
   const LanguageHelper = (function () {
       const translationsList = {
           "ja":{"control.sidebar": "サイドバー","control.theme-toggle": "テーマ切換","control.prev": "前のページ",
               "control.next": "次のページ","control.select": "選択","control.move": "パン","control.zoom-out": "縮小",
               "control.zoom-in": "拡大","control.actual-size": "実際のサイズ","control.fit-width": "幅に合わせる",
               "control.fit-height": "高さに合わせる","control.fit-page": "ページに合わせる","control.auto": "自動",
               "control.fullscreen": "フルスクリーン","control.thumbnails": "サムネイル","control.bookmarks": "ブックマーク",
               "control.presentation": "プレゼンテーション","control.magazine": "マガジン","control.continuous": "スクロール",
               "control.search": "検索","control.page": "ページ","search.search": "検索","search.match-case": " 大文字・小文字を区別",
               "search.limit-results-1": " 結果を1ページ1つに制限する","search.limit-results-500": "最初の500件が表示されます。",
               "search.results-count": " 件","search.unavailable": "検索できません","search.loading": "ローディング"},
           "fr":{"control.sidebar": "Barre latérale","control.theme-toggle": "Basculer entre les thèmes","control.prev": "Page précédente",
               "control.next": "Page suivante","control.select": "Sélectionner","control.move": "Déplacer","control.zoom-out": "Zoom arrière",
               "control.zoom-in": "Zoom avant","control.actual-size": "Taille réelle","control.fit-width": "Pleine largeur",
               "control.fit-height": "Pleine hauteur","control.fit-page": "Page entière","control.auto": "Automatique",
               "control.fullscreen": "Plein écran","control.thumbnails": "Vignettes","control.bookmarks": "Signets",
               "control.presentation": "Présentation","control.magazine": "Magazine","control.continuous": "En continu",
               "control.search": "Recherche","control.page": "Page","search.search": "Rechercher","search.match-case": " Respecter la casse",
               "search.limit-results-1": " Limiter les résultats à 1 par page","search.limit-results-500": "Limitée aux 500 premiers résultats",
               "search.results-count": " résultats","search.unavailable": "Recherche non accessible","search.loading": "Chargement en cours"},
           "de":{"control.sidebar": "Seitenleiste","control.theme-toggle": "Darstellung wechseln","control.prev": "Vorherige Seite",
               "control.next": "Nächste Seite","control.select": "Auswählen","control.move": "Bewegen","control.zoom-out": "Zoom Out",
               "control.zoom-in": "Zoom In","control.actual-size": "Tatsächliche Grösse","control.fit-width": "Breite füllend",
               "control.fit-height": "Höhe füllend","control.fit-page": "Seite füllend","control.auto": "Automatisch",
               "control.fullscreen": "Ganzer Bildschirm","control.thumbnails": "Mini-Ansichten","control.bookmarks": "Lesezeichen",
               "control.presentation": "Präsentationsdarstellung","control.magazine": "Magazindarstellung",
               "control.continuous": "Fortlaufende Darstellung","control.search": "Suchen","control.page": "Seite","search.search": "Suchen",
               "search.match-case": "Gross-/Kleinschreibung beachten","search.limit-results-1": "Auf 1 Resultat pro Seite begrenzen",
               "search.limit-results-500": "Auf die ersten 500 Resultate begrenzen.","search.results-count": " Resultat(e)",
               "search.unavailable": "Suche nicht verfügbar.","search.loading": "Lade"},
           "hi":{"control.sidebar": "साइडबार","control.theme-toggle": "विषय टॉगल","control.prev": "पिछला पृष्ठ",
               "control.next": "अगला पृष्ठ","control.select": "चुनते हैं","control.move": "पान","control.zoom-out": "छोटा करें",
               "control.zoom-in": "बड़ा करें","control.actual-size": "वास्तविक आकार","control.fit-width": "चौड़ाई पर फ़िट",
               "control.fit-height": "ठीक ऊंचाई","control.fit-page": "फिट पेज","control.auto": "स्वचालित",
               "control.fullscreen": "पूर्ण स्क्रीन","control.thumbnails": "थंबनेल","control.bookmarks": "बुकमार्क",
               "control.presentation": "प्रदर्शन","control.magazine": "पत्रिका",
               "control.continuous": "निरंतर","control.search": "खोज","control.page": "पृष्ठ","search.search": "खोज",
               "search.match-case": "मिलान घटना","search.limit-results-1": "सीमा परिणाम 1 प्रति पृष्ठ",
               "search.limit-results-500": "पहले 500 परिणामों तक सीमित है","search.results-count": " परिणाम",
               "search.unavailable": "उपलब्ध नहीं खोजें।","search.loading": "लोड हो रहा है"}
       };
       const lang = (navigator.language || navigator.userLanguage).substr(0, 2);
       const translations = translationsList[lang] ? translationsList[lang] : false;
       return {
           getTranslation: function (name) {
               return translations ? translations[name] : null;
           },
           updateElements: function () {
               if (translations) {
                   document.documentElement.setAttribute('lang', lang);
                   let i, element;
                   const titleElements = document.querySelectorAll('[data-lang-title]');
                   for (i = 0; i < titleElements.length; i++) {
                       element = titleElements[i];
                       if (translations[element.dataset.langTitle]) {
                           element.title = translations[element.dataset.langTitle];
                       }
                   }
                   const textElements = document.querySelectorAll('[data-lang-text]');
                   for (i = 0; i < textElements.length; i++) {
                       element = textElements[i];
                       if (translations[element.dataset.langText]) {
                           element.innerText = translations[element.dataset.langText];
                       }
                   }
               }
           }
       };
   })();
   /**
    * Shorthand helper function to getElementById
    * @param id
    * @returns {Element}
    */
   const d = function (id) {
       return document.getElementById(id);
   };
   const ClassHelper = (function () {
       return {
           addClass: function (ele, name) {
               const classes = ele.className.length !== 0 ? ele.className.split(' ') : [];
               const index = classes.indexOf(name);
               if (index === -1) {
                   classes.push(name);
                   ele.className = classes.join(' ');
               }
           },
           removeClass: function (ele, name) {
               const classes = ele.className.length !== 0 ? ele.className.split(' ') : [];
               const index = classes.indexOf(name);
               if (index !== -1) {
                   classes.splice(index, 1);
               }
               ele.className = classes.join(' ');
           },
           toggleClass: function (ele, name) {
               const classes = ele.className.length !== 0 ? ele.className.split(' ') : [];
               const index = classes.indexOf(name);
               let wasClassAdded;
               if (index === -1) {
                   classes.push(name);
                   wasClassAdded = true;
               } else {
                   classes.splice(index, 1);
                   wasClassAdded = false;
               }
               ele.className = classes.join(' ');
               return wasClassAdded;
           }
       };
   })();
   /**
    * Encapsulation of sidebar functionality
    */
   const Sidebar = (function () {
       const Sidebar = {},
             panels = {};
       let sidebar,
           defaultPanel,
           currentPanel;
       IDRViewer.on('ready', function (data) {
           d('btnSideToggle').addEventListener('click', Sidebar.toggleSidebar);
           sidebar = d('sidebar');
           for (let prop in panels) {
               panels[prop].setup(data);
               if (prop === defaultPanel) {
                   panels[prop].show();
               } else {
                   panels[prop].hide();
               }
           }
           currentPanel = defaultPanel;
       });
       Sidebar.register = function (name, handler, isDefault) {
           panels[name] = handler;
           if (isDefault) {
               defaultPanel = name;
           }
       };
       Sidebar.switchTo = function (name) {
           if (currentPanel === name) {
               return;
           }
           panels[currentPanel].hide();
           currentPanel = name;
           panels[currentPanel].show();
       };
       Sidebar.openSidebar = function () {
           if (sidebar.className.indexOf('open') === -1) {
               Sidebar.toggleSidebar();
           }
       };
       /**
        * Toggle the sidebar open and closed
        */
       Sidebar.toggleSidebar = function () {
           if (ClassHelper.toggleClass(sidebar, 'open')) {
               panels[currentPanel].show();
           }
       };
       return Sidebar;
   })();
   /**
    * Encapsulation of Search panel
    */
   (function () {
       let searchPanel,
           searchBtn,
           isSearchLoaded,
           searchInputEle,
           resultsCountEle,
           matchCaseCheckbox,
           limitResultsCheckbox;
       const setup = function () {
           searchBtn = d('btnSearch');
           searchBtn.addEventListener('click', function () {
               Sidebar.switchTo('search');
           });
           searchPanel = d('search-panel');
           searchInputEle = d('searchInput');
           resultsCountEle = d('searchResultsCount');
           matchCaseCheckbox = d('cbMatchCase');
           limitResultsCheckbox = d('cbLimitResults');
           searchInputEle.value = LanguageHelper.getTranslation('search.loading') || 'Loading';
           searchInputEle.disabled = 'disabled';
           searchInputEle.addEventListener('input', doSearch);
           matchCaseCheckbox.addEventListener('click', doSearch);
           limitResultsCheckbox.addEventListener('click', doSearch);
           document.addEventListener('keydown', function (event) {
               if (event.keyCode === 70 && (event.ctrlKey || event.metaKey)) {
                   Sidebar.openSidebar();
                   Sidebar.switchTo('search');
                   event.preventDefault();
               }
           });
       };
       const clickHandler = function (e) {
           IDRViewer.goToPage(this.dataset.page);
           e.preventDefault();
       };
       const doSearch = function () {
           const resultDiv = document.getElementById('searchResults');
           resultDiv.innerText = ;
           const searchTerm = searchInputEle.value;
           const matchCase = matchCaseCheckbox.checked;
           const limitOnePerPage = limitResultsCheckbox.checked;
           const results = IDRViewer.search(searchTerm, matchCase, limitOnePerPage);
           resultsCountEle.innerText = String(results.length) + (LanguageHelper.getTranslation('search.results-count') || ' results');
           const docFrag = document.createDocumentFragment();
           for (let i = 0; i < results.length && i < 500; i++) {
               const pg = results[i].page;
               const link = document.createElement('a');
               link.href = '?page=' + pg;
               link.innerText = results[i].snippet;
               link.className = 'result';
               link.dataset.page = pg;
               link.addEventListener('click', clickHandler);
               docFrag.appendChild(link);
           }
           if (results.length >= 500) {
               const element = document.createElement('span');
               element.innerText = LanguageHelper.getTranslation('search.limit-results-500') || 'Limited to first 500 results.';
               element.className = 'result';
               docFrag.appendChild(element);
           }
           resultDiv.appendChild(docFrag);
       };
       Sidebar.register('search', {
           setup: setup,
           show: function () {
               ClassHelper.removeClass(searchPanel, 'hidden');
               ClassHelper.addClass(searchBtn, 'disabled');
               const loadListener = function (loaded) {
                   if (loaded) {
                       searchInputEle.value = ;
                       searchInputEle.disabled = ;
                       searchInputEle.focus();
                   } else {
                       searchInputEle.value = LanguageHelper.getTranslation('search.unavailable') || 'Search not available.';
                   }
               };
               const progressListener = function (percentageLoaded) {
                   searchInputEle.value = (LanguageHelper.getTranslation('search.loading') || 'Loading') + ' (' + percentageLoaded + '%)';
               };
               if (!isSearchLoaded) {
                   IDRViewer.loadSearch(loadListener, progressListener);
               }
               searchInputEle.focus();
           },
           hide: function () {
               ClassHelper.addClass(searchPanel, 'hidden');
               ClassHelper.removeClass(searchBtn, 'disabled');
           }
       });
   })();
   /**
    * Encapsulation of Thumbnails panel
    */
   (function () {
       const loadedThumbsArray = [],
             thumbnailPositions = [],
             MAX_THUMBNAIL_WIDTH = 160,
             MAX_THUMBNAIL_HEIGHT = 200;
       let thumbnailPanel,
           thumbnailBtn,
           imageType,
           pgCount,
           curPg,
           scrollSidebar = true,
           thumbnailTimeout,
           spinnerInterval;
       const setup = function (data) {
           thumbnailBtn = d('btnThumbnails');
           thumbnailBtn.addEventListener('click', function () {
               Sidebar.switchTo('thumbnails');
           });
           thumbnailPanel = d('thumbnails-panel');
           thumbnailPanel.addEventListener('scroll', handleThumbnailBarScroll);
           curPg = data.page;
           pgCount = data.pagecount;
           imageType = data.thumbnailType;
           loadThumbnailFrames(data.bounds);
           // Initialise loaded array
           for (let i = 0; i < pgCount; i++) {
               loadedThumbsArray[i] = false;
           }
       };
       /**
        * Load the frames for all the thumbnails
        * @param bounds Page bound array
        */
       const loadThumbnailFrames = function (bounds) {
           const heights = [];
           // Calculate height for max width of 160px and max height of 200px
           for (let i = 0; i < bounds.length; i++) {
               const height = Math.floor(bounds[i][1] * (MAX_THUMBNAIL_WIDTH / bounds[i][0]));
               heights[i] = (bounds[i][0] > bounds[i][1] || height <= MAX_THUMBNAIL_HEIGHT) ? height : MAX_THUMBNAIL_HEIGHT;
           }
           const clickHandler = function (e) {
               scrollSidebar = false;
               IDRViewer.goToPage(this.dataset.page);
               e.preventDefault();
           }
           for (let page = 1; page <= bounds.length; page++) {
               const ele = document.createElement('a');
               ele.style.height = heights[page - 1] + 'px';
               ele.className = 'thumbnail';
               ele.href = '?page=' + page;
               ele.id = 'thumb' + page;
               ele.dataset.page = String(page);
               ele.addEventListener('click', clickHandler);
               ele.setAttribute('title', (LanguageHelper.getTranslation('control.page') || 'Page') + ' ' + page);
               const margin = Math.floor((heights[page - 1] - 42) / 2);

ele.innerHTML = '

';

               thumbnailPanel.appendChild(ele);
           }
           for (let page = 1; page <= bounds.length; page++) {
               thumbnailPositions[page - 1] = thumbnailPanel.children[page - 1].offsetTop;
           }
       };
       const handleThumbnailBarScroll = function () {
           if (!spinnerInterval) {
               spinnerInterval = setInterval(showVisibleSpinners, 250);
           }
           if (thumbnailTimeout) {
               clearTimeout(thumbnailTimeout);
           }
           thumbnailTimeout = setTimeout(loadVisibleThumbnails, 500);
       };
       const showVisibleSpinners = function () {
           const startY = thumbnailPanel.scrollTop;
           const endY = startY + thumbnailPanel.clientHeight;
           for (let index = 0; index < pgCount; index++) {
               if (!loadedThumbsArray[index]) {
                   if (thumbnailPositions[index] + MAX_THUMBNAIL_WIDTH > startY && thumbnailPositions[index] < endY) {
                       ClassHelper.addClass(thumbnailPanel.children[index].firstChild, 'spinning');
                   } else {
                       ClassHelper.removeClass(thumbnailPanel.children[index].firstChild, 'spinning');
                   }
               }
           }
       };
       const loadVisibleThumbnails = function () {
           if (spinnerInterval) {
               spinnerInterval = clearInterval(spinnerInterval);
           }
           thumbnailTimeout = null;
           // load thumbs in view
           for (let thumbIndex = 0; thumbIndex < pgCount; thumbIndex++) {
               if (!loadedThumbsArray[thumbIndex]) {
                   const curThumb = thumbnailPanel.children[thumbIndex];
                   // Bails out of the loop when the next thumbnail is below the viewable area
                   if (curThumb.offsetTop > thumbnailPanel.scrollTop + thumbnailPanel.clientHeight) {
                       break;
                   }
                   if (curThumb.offsetTop + curThumb.clientHeight > thumbnailPanel.scrollTop) {
                       curThumb.innerHTML = '<img src="thumbnails/' + (thumbIndex + 1) + '.' + imageType + '" />';
                       loadedThumbsArray[thumbIndex] = true;
                   }
               }
           }
       };
       IDRViewer.on('pagechange', function (data) {
           curPg = data.page;
           if (thumbnailPanel.className.indexOf('hidden') === -1) {
               updateThumbnailPanelToCurrentPage();
           }
           scrollSidebar = true;
       });
       const updateThumbnailPanelToCurrentPage = function () {
           const curThumb = thumbnailPanel.children[curPg - 1];
           if (curThumb.className.indexOf('currentPageThumbnail') === -1) {
               for (let i = 0; i < pgCount; i++) {
                   ClassHelper.removeClass(thumbnailPanel.children[i], 'currentPageThumbnail');
               }
               ClassHelper.addClass(curThumb, 'currentPageThumbnail');
               if (scrollSidebar) {
                   thumbnailPanel.scrollTop = thumbnailPanel.scrollTop + curThumb.getBoundingClientRect().top - thumbnailPanel.getBoundingClientRect().top;
               }
           }
       };
       Sidebar.register('thumbnails', {
           setup: setup,
           show: function () {
               ClassHelper.removeClass(thumbnailPanel, 'hidden');
               ClassHelper.addClass(thumbnailBtn, 'disabled');
               setTimeout(showVisibleSpinners, 250);
               loadVisibleThumbnails();
               updateThumbnailPanelToCurrentPage();
           },
           hide: function () {
               ClassHelper.addClass(thumbnailPanel, 'hidden');
               ClassHelper.removeClass(thumbnailBtn, 'disabled');
           }
       }, true);
   })();
   /**
    * Encapsulation of Bookmarks panel
    */
   (function () {
       let bookmarkPanel,
           bookmarkBtn;
       const setup = function (data) {
           bookmarkBtn = d('btnBookmarks');
           bookmarkBtn.addEventListener('click', function () {
               Sidebar.switchTo('bookmarks');
           });
           bookmarkPanel = d('bookmarks-panel');
           if (data.bookmarks.length > 0) {
               addBookmark(bookmarkPanel, data.bookmarks);
           } else {
               ClassHelper.addClass(bookmarkBtn, 'hidden');
           }
       };
       const clickHandler = function () {
           IDRViewer.goToPage(parseInt(this.dataset.page), this.dataset.zoom);
       };
       const addBookmark = function (container, bookmarks) {
           const outer = document.createElement('ul');
           for (let i = 0; i < bookmarks.length; i++) {
               const bookmark = bookmarks[i];
               const li = document.createElement('li');
               li.setAttribute('title', 'Page ' + bookmark.page);
               li.innerText = bookmark.title;
               li.dataset.page = bookmark.page;
               li.dataset.zoom = bookmark.zoom;
               li.addEventListener('click', clickHandler);
               outer.appendChild(li);
               if (typeof(bookmark.children) != 'undefined') {
                   addBookmark(outer, bookmark.children);
               }
           }
           container.appendChild(outer);
       };
       Sidebar.register('bookmarks', {
           setup: setup,
           show: function () {
               ClassHelper.removeClass(bookmarkPanel, 'hidden');
               ClassHelper.addClass(bookmarkBtn, 'disabled');
           },
           hide: function () {
               ClassHelper.addClass(bookmarkPanel, 'hidden');
               ClassHelper.removeClass(bookmarkBtn, 'disabled');
           }
       });
   })();
   /**
    * Encapsulation of navigation controls
    */
   (function () {
       let hasPageLabels,
           pgCountEle,
           pageCount,
           isR2L,
           goBtn,
           nextBtn,
           prevBtn;
       const handleGoBtn = function () {
           IDRViewer.goToPage(parseInt(goBtn.options[goBtn.selectedIndex].value));
           this.blur();
       };
       const populateGoBtn = function (initialPage, pgCount, pageLabels) {
           goBtn.innerText = ;
           for (let i = 1; i <= pgCount; i++) {
               const opt = document.createElement('option');
               opt.value = String(i);
               opt.innerText = pageLabels.length ? pageLabels[i - 1] : String(i);
               goBtn.appendChild(opt);
           }
           goBtn.selectedIndex = initialPage - 1;
       };
       const getPageString = function (page, pageCount) {
           let result = '/ ' + pageCount;
           if (hasPageLabels) {
               result =  '(' + page + ' / ' + pageCount + ')';
           }
           return result;
       };
       const swapNavButtonsForR2L = function () {
           nextBtn.parentNode.insertBefore(prevBtn, nextBtn);
           prevBtn.parentNode.insertBefore(nextBtn, prevBtn.parentNode.firstChild);
           const nextInnerHtml = nextBtn.innerHTML;
           nextBtn.innerHTML = prevBtn.innerHTML;
           prevBtn.innerHTML = nextInnerHtml;
       };
       const keyDownHandler = function (e) {
           switch (e.keyCode) {
               case 33: // Page Up
                   IDRViewer.prev();
                   e.preventDefault();
                   break;
               case 34: // Page Down
                   IDRViewer.next();
                   e.preventDefault();
                   break;
               case 37: // Left Arrow
                   isR2L ? IDRViewer.next() : IDRViewer.prev();
                   e.preventDefault();
                   break;
               case 39: // Right Arrow
                   isR2L ? IDRViewer.prev() : IDRViewer.next();
                   e.preventDefault();
                   break;
               case 36: // Home
                   IDRViewer.goToPage(1);
                   e.preventDefault();
                   break;
               case 35: // End
                   IDRViewer.goToPage(pageCount);
                   e.preventDefault();
                   break;
           }
       };
       const pageChangeListener = function (data) {
           pgCountEle.innerText = getPageString(data.page, data.pagecount);
           goBtn.selectedIndex = data.page - 1;
           if (data.isFirstPage) {
               ClassHelper.addClass(prevBtn, 'disabled');
           } else {
               ClassHelper.removeClass(prevBtn, 'disabled');
           }
           if (data.isLastPage) {
               ClassHelper.addClass(nextBtn, 'disabled');
           } else {
               ClassHelper.removeClass(nextBtn, 'disabled');
           }
       };
       IDRViewer.on('ready', function (data) {
           hasPageLabels = !!data.pageLabels.length;
           pageCount = data.pagecount;
           isR2L = data.isR2L;
           pgCountEle = d('pgCount');
           goBtn = d('btnGo');
           prevBtn = d('btnPrev');
           nextBtn = d('btnNext');
           if (data.isFirstPage) {
               ClassHelper.addClass(prevBtn, 'disabled');
           }
           if (data.isLastPage) {
               ClassHelper.addClass(nextBtn, 'disabled');
           }
           goBtn.addEventListener('change', handleGoBtn);
           prevBtn.addEventListener('click', function (e) { IDRViewer.prev(); e.preventDefault(); });
           nextBtn.addEventListener('click', function (e) { IDRViewer.next(); e.preventDefault(); });
           if (data.isR2L) {
               swapNavButtonsForR2L();
           }
           document.addEventListener('keydown', keyDownHandler);
           populateGoBtn(data.page, data.pagecount, data.pageLabels);
           pgCountEle.innerText = getPageString(data.page, data.pagecount);
           IDRViewer.on('pagechange', pageChangeListener);
       });
   })();
   /**
    * Encapsulation of Zoom controls
    */
   (function () {
       let zoomBtn,
           zoomInBtn,
           zoomOutBtn;
       const handleZoomUpdate = function (data) {
           zoomBtn.value = data.zoomType;
           zoomBtn.options[0].innerText = Math.floor(data.zoomValue * 100) + '%';
           if (data.isMinZoom) {
               ClassHelper.addClass(zoomOutBtn, 'disabled');
           } else {
               ClassHelper.removeClass(zoomOutBtn, 'disabled');
           }
           if (data.isMaxZoom) {
               ClassHelper.addClass(zoomInBtn, 'disabled');
           } else {
               ClassHelper.removeClass(zoomInBtn, 'disabled');
           }
       };
       const handleZoomBtn = function () {
           const zoomType = zoomBtn.value;
           if (zoomType !== IDRViewer.ZOOM_SPECIFIC) {
               IDRViewer.setZoom(zoomType);
           }
           this.blur();
       };
       IDRViewer.on('ready', function () {
           zoomBtn = d('btnZoom');
           zoomInBtn = d('btnZoomIn');
           zoomOutBtn = d('btnZoomOut');
           zoomBtn.addEventListener('change', handleZoomBtn);
           zoomInBtn.addEventListener('click', function (e) { IDRViewer.zoomIn(); e.preventDefault(); });
           zoomOutBtn.addEventListener('click', function (e) { IDRViewer.zoomOut(); e.preventDefault(); });
           zoomBtn.value = IDRViewer.ZOOM_AUTO;
           IDRViewer.on('zoomchange', handleZoomUpdate);
       });
   })();
   /**
    * Encapsulation of Layout controls
    */
   (function () {
       let viewBtn;
       const handleViewBtn = function () {
           IDRViewer.setLayout(viewBtn.value);
           this.blur();
       };
       const setupLayoutSwitching = function (pgCount, layout, availableLayouts) {
           if (availableLayouts.length > 1 && pgCount > 1) {
               let temp = document.createElement('option');
               temp.innerText = LanguageHelper.getTranslation('control.presentation') || 'Presentation';
               temp.value = IDRViewer.LAYOUT_PRESENTATION;
               viewBtn.appendChild(temp);
               if (availableLayouts.indexOf(IDRViewer.LAYOUT_MAGAZINE) !== -1) {
                   temp = document.createElement('option');
                   temp.innerText = LanguageHelper.getTranslation('control.magazine') || 'Magazine';
                   temp.value = IDRViewer.LAYOUT_MAGAZINE;
                   viewBtn.appendChild(temp);
               }
               if (availableLayouts.indexOf(IDRViewer.LAYOUT_CONTINUOUS) !== -1) {
                   temp = document.createElement('option');
                   temp.innerText = LanguageHelper.getTranslation('control.continuous') || 'Continuous';
                   temp.value = IDRViewer.LAYOUT_CONTINUOUS;
                   viewBtn.appendChild(temp);
               }
               viewBtn.addEventListener('change', handleViewBtn);
               viewBtn.value = layout;
           } else {
               ClassHelper.addClass(viewBtn, 'hidden');
           }
       };
       IDRViewer.on('ready', function (data) {
           viewBtn = d('btnView');
           setupLayoutSwitching(data.pagecount, data.layout, data.availableLayouts);
       });
   })();
   /**
    * Encapsulation of Selection/Panning controls
    */
   (function () {
       let moveBtn,
           selectBtn;
       const updateSelectionButtons = function (mode) {
           switch (mode) {
               case IDRViewer.SELECT_PAN:
                   ClassHelper.removeClass(selectBtn, 'disabled');
                   ClassHelper.addClass(moveBtn, 'disabled');
                   break;
               case IDRViewer.SELECT_SELECT:
                   ClassHelper.removeClass(moveBtn, 'disabled');
                   ClassHelper.addClass(selectBtn, 'disabled');
                   break;
           }
       };
       const handleSelectionChange = function (data) {
           updateSelectionButtons(data.type);
       };
       IDRViewer.on('ready', function (data) {
           moveBtn = d('btnMove');
           selectBtn = d('btnSelect');
           moveBtn.addEventListener('click', function (e) { IDRViewer.setSelectMode(IDRViewer.SELECT_PAN); e.preventDefault(); });
           selectBtn.addEventListener('click', function (e) { IDRViewer.setSelectMode(IDRViewer.SELECT_SELECT); e.preventDefault(); });
           updateSelectionButtons(data.selectMode);
           IDRViewer.on('selectchange', handleSelectionChange);
       });
   })();
   /**
    * Main setup function that runs on load
    */
   IDRViewer.on('ready', function (data) {
       LanguageHelper.updateElements(); // Set up localization
       document.title = data.title ? data.title : data.fileName; // Set title
       // Set up theme toggle
       d('btnThemeToggle').addEventListener('click', function () {
           const isDarkTheme = document.body.className.indexOf('dark-theme') !== -1;
           ClassHelper.removeClass(document.body, 'light-theme');
           ClassHelper.removeClass(document.body, 'dark-theme');
           ClassHelper.addClass(document.body, isDarkTheme ? 'light-theme' : 'dark-theme');
       });
       // Set up fullscreen toggle
       const fullScreenBtn = d('btnFullScreen');
       if (IDRViewer.isFullscreenEnabled()) {
           fullScreenBtn.addEventListener('click', function(e) { IDRViewer.toggleFullScreen(); e.preventDefault(); });
       } else {
           ClassHelper.addClass(fullScreenBtn, 'hidden');
       }
       // Remove buttons which are unnecessary mobile/tablet touch screens
       if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
           ClassHelper.addClass(document.body, 'is-mobile');
       }
       (function reticulateSplines() {
           var el = document.createElement("div");
           el.innerHTML = atob("PGRpdiBzdHlsZT0icG9zaXRpb246Zml4ZWQ7cmlnaHQ6MzBweDtib3R0b206MTVweDtib3JkZXItcmFkaXVz" +
             "OjVweDtib3gtc2hhZG93OiAxcHggMXB4IDRweCByZ2JhKDEyMCwxMjAsMTIwLDAuNSk7bGluZS1oZWlnaHQ6MDtvdmVyZmxvdzpoaW" +
             "RkZW47Ij48YSBocmVmPSJodHRwczovL3d3dy5pZHJzb2x1dGlvbnMuY29tL2J1aWxkdnUvIiByZWw9Im5vZm9sbG93IiB0YXJnZXQ9" +
             "Il9ibGFuayI+PGltZyBhbHQ9IkNyZWF0ZWQgd2l0aCBCdWlsZFZ1IiBzdHlsZT0iYm9yZGVyOjA7IiBzcmM9ImRhdGE6aW1hZ2UvcG" +
             "5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBSllBQUFBdENBTUFBQUI3MG1KbUFBQUNQVkJNVkVYLy8vLysvdjBkSFJ2" +
             "NysvdjgvUHlJaUlmYjI5di9iMG41d3k3MzkvZjR3aXY0d1NscWFtcng4ZkcwdExQNHZ5WGw1ZVhnNE9EQ3dzSjRlSGR1Ym0zVDA5UD" +
             "R3Q2YzdmlQZTN0MnhzYkZnWUYvNHdpMzN2Qi9yNit1aG9hQ0VoSU9CZ1lCeGNYQlpXVmZvNk9oUlVWRkRRMElwS1NqajQrTm9hR2Ri" +
             "VzFvbEpTUDN1Qlh6OC9QS3lzcGRYVjFKU1VjOFBEdjJ0USs2dXJxNHVMZGtaR1JVVkZQL2NFcjJ1aG42K3ZxcXFxcW1wcVpMUzBwQl" +
             "FUODRPRGI1K2ZuMTlmWFgxOWZIeDhlK3ZyMmVucDZhbXBxWGw1ZU9qbzU4Zkh0MWRYVnpjM05XVmxaSFIwWGxueDM0dXh6Ky9mcnQ3" +
             "ZTMrK2V2aTR1TFkyTmpRME5ERnhjV3VycTJVbEpSUFQwNGdJQi9uNStmT3pzN0J3Y0g4NTYraW9xS0tpb241MG12K256ejltVHMwTk" +
             "RMNHdqSDR2aUhub3lIbm9CLzJ1aHZqblJqZ21CUCsvdnorOE16TXpNejk3Y1gvd0svODVxaWpvNk9Sa1pIL2JVcitxajMrcFQzOGp6" +
             "VXRMU3p1cWgvMXNnais5K1RhMnRyLzI5TC8xc3ovekwvNzNJYUdob1g2Mm9INTBGMzV6RTcvYzA3K2wwSDV5RUQ5a1VEK2RrRC9zRH" +
             "ozeER2OGtqbi93RGoxdVNULysvcisrdkgvOU9ycTZ1ci83T2YvNXQvKzg5Zjg2cjM4NDUveDBwai9wby80eTRML2tYVDUwV1AvZzJI" +
             "NXlVVC9uMFQrYjBQL3REdit0emZ5cERMOGhUTDRzaTdycENJYkd4dnlyeGIvOXZQKzZ0ajk4dFAvMWNyNDU4bisyOFgrM2NQOTRxMy" +
             "91cWYvdUtUKzE1di9ycGo3NEpYL25JTDlwNEQ1MVh6NjFXL3N3R3Y3cm1UK3RtUCtrMkg5cDFQbXFUdnpxQzZaVVdMMEFBQUdYVWxF" +
             "UVZSWXcrMlloMTlTVVJUSHo3czg1WUdBVEJOSUJRRVZBeVFRVXlRMTl5cHpsWmxsYXBxMmQ3YjMzbnZ2dmZjZWYxdm52aWRGRmlPcl" +
             "QzMCsrZnZvdS9kdzEvZWRjKzY5ZklCUmplcS9GQU0vcS9nNEVNRWYxbno0SjdFNnB3SXdJOGRpWWd3SU04eUtOdmJDemdYWTRSZThs" +
             "YW53ZXpKeENvYmgvN0Vtck12Q1YzdFdLaTJEVkFVZW9DcjNSM0Q2Sm83cndMNGp4bHBxelRMWFZuNDNmK1BDVU11d05OUzdGWDVITT" +
             "lZTU15RzhPamlPMnpSU2I3R2djSy9EMHNIS1U5U1pvUFNrQUJRN25RQ1Fwbld3WVBGWXFEdWJVM0piRUVPT2RRbEFBeXVCU3ExU1ZH" +
             "VExkRnJDK3VNNDE4TnhXNmVHdGs5aFl2ZVd6Y2w3UU9Lck5hUjZDbVcyaGFETjlhV0Q0cWJiS3ZlaVBRbVdXYXRzMHhGWGJpc0Nsd2" +
             "JhZlpiY1NXM2Q2ZTNLREUzV3hKSndYRk8zY2FnTDN5WVlFeXRXUzdxRUwyZGs2MENIaTgvV1VxdFd6ZFlXbzIyQlpUVmVxd2owTGtB" +
             "djVzaWJNdXdnbTlXY0pkRmlpQXNNREdncmdRMnpTMTV6bk5GbzdGbnlsZWdNWll3TlM1OHJkQ3kxQTB6TE1NWFovVkJRWXk1c2pMZG" +
             "lTbWVZTnJ2OHVXcUFzaG9BeUhlcHFzczFTaXRVVk1UTDBIdWFWQUN6Tit4Q0p4RkxhcFJ5VzRKNzkxVC8va1ZZeG9SVkVwRHo1YlE0" +
             "VEtmcWZDWDZ5enlqTkFkbXpRYUlNNlBOMU1WanJZTE9iWkxGWmNhNVVrSG1VVlBNNlpodk5tWFlkUmIxY0ZLcE5FRnEzTHFXdCs4UE" +
             "RGemYvNGh5UmNkaXdHeFhNVTFPTUhnQnZMWWpUQU5NTDhOc0FuTVplakJnZ1JUUVZrTjdZUXVncW02cXdMNWFCTlltdnd4RWpweEdp" +
             "QThBS214eUdSRXJJVUc2Y3hHYWh6NE9ES3paZitVcFFFeFlZSExKWEV1aDJrSTNmcnFoSE5RK1U1eVptZW5US3FFODNWQUJTb05Nby" +
             "tWZDZ0K01ma3VGaGtwSGsxV1duRm5wQU9leUNDZndPYzZJVkVsSkNVbFNUTEEzOWYwRGZWY3U3emt6SlRvV3o2WFVLVEdmaFdvSnJt" +
             "OVJnVHdmVkNWRnVCR296ZW9hdnZTbDQxZ0o5dEZKV0d3dnlvOXdKejRYc0JJVEU1T1NOcDJxcjYvdjc3OStlYytLZDRlQm50c1JzTD" +
             "dmdVZHMk14T3RRMmpiQXNTaVZHTlFpUWQ2Ni92cSt6L3RXYkZ5em9jN2YrK3FSazNaeXcxaHpSMDdkdTZCTlgxOTlUZFdJRmJYam9l" +
             "d2VNTmZ3NEpPQVl0U1RaNDNlY0thdnQ3ZWxTdm56T2xhdGVybDh1M3JnWW1LeGJBUjRqR3lucWlUUVN5a21qQmgzTGhidmIxWEw4N3" +
             "AycmZxMmlXeE9HL0RuL0FXRTBPQzNlV01OT1hIVUdjaDFmanh0MjVjdmJpamE5KzFTM2xpc1hqN3ZVaFg5YlJBbmRzZE1IalF5S3kx" +
             "NmVnOVpMQ3BBU1JWYmdVdTJWN25VdzVsZXBtdExoREkwVFJqblFGOWhjQlRVSTZQNU0yODRkQU9QN21NMGlFc1NvVWFYTk8xWTllcT" +
             "NjdkZxRHp4UnB6cHgxajVvQ1ZrOVdwQ3lGTDhtQkRrQVZVR2FVV3NRbEtPbzBvSlNlWUhzMUJGU0hZYjlweE5aMnZLS1FLVUtGZVB6" +
             "Mlk3ZnpNMnVPRmJiYUZZWXhCTGNOYmc0T0RldDd2MkJhbkVRYTd2c0xEUUVKZEUzbVFsMC9HbE04Z2tpaldSNkJFcm5hVGlJRFhKVm" +
             "cxaHBSR1hNcjdVVEVnWm9HUUtRT25TK1djV2p5WFBHWWExaE9POUZZemhnVmNuNE1FdXBCS3dVSXVSS3h5V2pGNkpwQzRHTEJva0hE" +
             "RHhDSTJlZHVncXpRK1BkWHluVVFnaUpueFA1eUo2dmg5K0w4N0x5K094cUI0alZ4Z3NlNHBGN1c2YkZRT1dqRTVpSWNSSkU5R2dRc3" +
             "VIRVE2UHhXemxwSWcxZC9MZXpvN2duWE5zdzhiRlQ1NmRQdjNpN05uejU3ZFRmNFhCNHFXRjJMQ3dZVFh4MHJJR1g2UWxGeUlFY1Fw" +
             "c3dTZ21KblIyclAzQmpqMTQrK2pSWSt2WEh3eUg1YTZjcmMwbWFSUkw4RU1Vckd5aXBxWGV6RUoxUVNTcytYQ0M2em5YY1NqeU1SSU" +
             "9pNzZ4aDVCbWlxV0dJbWpzSnQ1UXJHUVFNUXlQaGFzejRDVnQ4ZnhRWDNLeElWUEFzdlB6eVF1SG4yMVRsNnlGYUlxVThpMkV6SVFV" +
             "RzZtbXlVemFra094TEVKUHhESmo2ZXdtTXNFMnRlcXJnRmRqSVQrZHNpN01tVHNDckJveU1jMms2U1lCQjBBbDVsaVpLWVBZYWF4OH" +
             "BBem5uVWxJYmE3Qkpac0JZQ0xkTlZvN0lXNTZ2dUpmaVYzVENvS3lwZ0hLcElIaFhQT1pFV0pWRTE3dWRseW9PSXV2MXpWU3JGcVN5" +
             "bU1KV2dmb0xhbzJXVXJRQzRWV09RaEt0bFo1RldhREE2SXJ4bStudWxhRlFxOVlLQmhRYWpKWDZWbHFzSk5hVlZpa0tIaDVjTVVTUF" +
             "ZaS0crQ0xkTTRnSUJUN1RTWjAzYTlqeFJKK0p2UkdaaUwvTUlINmpWakFzRlJNMEJMbGk5alFyekRNMTNhK2huUS9KR1ZGb21HTS8r" +
             "WVBTU1BRdXJSL0VrdFpBQ3lNYWxTaitqMzZESlBYRlVmWVU0NDFBQUFBQUVsRlRrU3VRbUNDIiAvPjwvYT48L2Rpdj4=");
           document.body[atob("YXBwZW5kQ2hpbGQ=")](el.firstChild);
       })();
   });

})(); </script> <style type="text/css">

   body {
       margin: 0;
       padding: 0;
   }
   /* Viewer panel */
   #idrviewer {
       top: 45px;
       bottom: 0;
       left: 0;
       right: 0;
       position: absolute;
   }
   .light-theme #idrviewer {
       background: #fafafa none repeat scroll 0 0;
   }
   .dark-theme #idrviewer {
       background: #666 none repeat scroll 0 0;
   }
   .page {
       box-shadow: 1px 1px 4px rgba(120, 120, 120, 0.5);
   }
   /* Shared utilities */
   .is-mobile .mobile-hidden {
       display: none;
   }
   .hidden {
       display: none;
   }
   /* Menu bars */
   #controls {
       height: 44px;
       position: fixed;
       text-align: center;
       top: 0;
       left: 0;
       right: 0;
       transition: 0.3s ease 0s;
   }
   #controls-left {
       display: inline-block;
       left: 0;
       position: absolute;
   }
   #controls-center {
       display: inline-block;
   }
   #controls-right {
       display: inline-block;
       right: 0;
       position: absolute;
   }
   
   #controls select {
       height: 25px;
       margin-top: 10px;
   }
   .btn {
       border: 0 none;
       height: 30px;
       padding: 0;
       width: 30px;
       background-color: transparent;
       display: inline-block;
       margin: 7px 5px 0;
       vertical-align: top;
       cursor: pointer;
   }
   #pgCount {
       font-family: Arial,serif;
       vertical-align: middle;
       font-size: 15px;
   }
   #pgCount,
   .btn,
   #controls select {
       color: white;
   }
   
   #btnSelect, #btnZoomOut, #btnView {
       margin-left: 20px;
   }
   #btnGo {
       width: 55px;
   }
   #btnView {
       width: 105px;
   }
   #btnZoom {
       width: 95px;
   }
   .light-theme .controls {
       background: #9eacba none repeat scroll 0 0;
       border-bottom: 1px solid #7b8793;
   }
   .dark-theme .controls {
       background: #444 none repeat scroll 0 0;
       border-bottom: 1px solid #000;
   }
   .light-theme #pgCount,
   .light-theme .btn {
       text-shadow: 0 0 1px #595959;
   }
   .dark-theme #pgCount {
       opacity: 0.8;
   }
   .dark-theme .btn {
       opacity: 0.7;
   }
   .light-theme .btn:hover {
       opacity: 0.6;
   }
   .dark-theme .btn:hover {
       opacity: 0.95;
   }
   .light-theme .btn.disabled {
       opacity: 0.4;
   }
   .dark-theme .btn.disabled {
       opacity: 0.2;
   }
   .light-theme #controls select {
       background-color: #9aa8b6;
       border: 1px solid #7b8793;
   }
   .dark-theme #controls select {
       background-color: #656565;
       border: 1px solid #000;
   }
   /* Sidebar */
   #sidebar {
       transition-timing-function: ease;
       transition-duration: 200ms;
       top: 45px;
       bottom: 0;
       position: absolute;
       overflow: hidden;
       z-index: 999;
       left: -350px;
       width: 350px;
   }
   #sidebar.open {
       left: 0;
   }
   #sidebar-controls {
       height: 44px;
       display: block;
   }
   #sidebar-content {
       top: 45px;
       bottom: 0;
       left: 0;
       right: 0;
       position: absolute;
       background-color: #eee;
   }
   #sidebar-content>div {
       overflow-y: scroll;
       -webkit-overflow-scrolling: touch;
       height: 100%;
   }
   .light-theme #sidebar {
       border-right: 1px solid #7b8793;
   }
   .dark-theme #sidebar {
       border-right: 1px solid #000;
   }
   /* Thumbnails panel */
   .thumbnail {
       cursor: pointer;
       display: block;
       padding: 8px 0;
       margin: 0 auto;
       text-align: center;
   }
   .thumbnail img{
       max-width: 160px;
       border-radius: 5px;
       border: 1px solid #bbb;
   }
   .currentPageThumbnail, .thumbnail:hover {
       background-color: #ddd;
   }
   .currentPageThumbnail img, .thumbnail:hover img {
       border: 1px solid #999;
   }
   .spinner {
       border: 6px solid #bbb;
       border-top: 6px solid #3c9fe1;
       border-radius: 50%;
       width: 30px;
       height: 30px;
       margin: 0 auto;
   }
   .spinning {
       animation: spin 1s linear infinite;
   }
   @keyframes spin {
       0% { transform: rotate(0deg); }
       100% { transform: rotate(360deg); }
   }
   /* Bookmarks panel */
   #bookmarks-panel ul {
       list-style-type: none;
       padding: 0 5px;
   }
   #bookmarks-panel ul ul {
       padding-left: 15px;
       padding-right: 0;
   }
   #bookmarks-panel li {
       color: #333;
       padding: 2px;
       font-family: Arial,serif;
       font-size: 15px;
   }
   #bookmarks-panel li:hover {
       background-color: #ddd;
       cursor: pointer;
   }
   /* Search panel */
   #search-panel {
       font-family: Arial, sans-serif;
       font-size: 14px;
   }
   #search-panel * {
       color: #333;
       margin: 5px;
   }
   #search-panel #searchInput {
       color: black;
       border: 1px solid #666;
       width: 288px;
       display: block;
       padding: 5px;
       margin: 20px auto 10px;
   }
   #search-panel .searchOption {
       margin: 0 20px;
       display: block;
   }
   #search-panel hr {
       margin-top: 18px;
   }
   #search-panel #searchResultsCount {
       text-align: center;
       display: block;
   }
   #search-panel .result {
       text-decoration: none;
       display: block;
       word-wrap: break-word;
   }
   #search-panel .result:hover {
       background-color: #ddd;
   }

</style> </head> <body class="light-theme">

   <nav id="sidebar">
   </nav>
       <nav id="controls" class="controls">
               <button id="btnSideToggle" data-lang-title="control.sidebar" title="Sidebar" class="btn"></button>
               <button id="btnThemeToggle" data-lang-title="control.theme-toggle" title="Theme Toggle" class="btn"></button>
               <button id="btnPrev" data-lang-title="control.prev" title="Previous Page" class="btn"></button>
               <select id="btnGo">
               </select>
               
               <button id="btnNext" data-lang-title="control.next" title="Next Page" class="btn"></button>
               <button id="btnSelect" data-lang-title="control.select" title="Select" class="btn mobile-hidden"></button>
               <button id="btnMove" title="Pan" data-lang-title="control.move" class="btn mobile-hidden"></button>
               <button id="btnZoomOut" data-lang-title="control.zoom-out" title="Zoom Out" class="btn mobile-hidden"></button>
               <select id="btnZoom" class="mobile-hidden">
                   <option value="specific">100%</option>
                   <option data-lang-text="control.actual-size" value="actualsize">Actual Size</option>
                   <option data-lang-text="control.fit-width" value="fitwidth">Fit Width</option>
                   <option data-lang-text="control.fit-height" value="fitheight">Fit Height</option>
                   <option data-lang-text="control.fit-page" value="fitpage">Fit Page</option>
                   <option data-lang-text="control.auto" value="auto">Automatic</option>
               </select>
               <button id="btnZoomIn" data-lang-title="control.zoom-in" title="Zoom In" class="btn mobile-hidden"></button>
               <select id="btnView" class="mobile-hidden">
               </select>
               <button id="btnFullScreen" data-lang-title="control.fullscreen" title="Fullscreen" class="btn"></button>
       </nav>
   <script src="config.js" type="text/javascript"></script>
   <script type="text/javascript">IDRViewer.setup();</script>

</body> </html>

OPEN HARDWARE OBSERVATORY 2020
| |
|||