Vrchnostenské Česko aneb Ke kořenům zaostávání e-governmentu na příkladu půjček pro mladé

21. 8. 2018
Doba čtení: 10 minut

Sdílet

Autor: Depositphotos
Když už dnes stát legálně shromažďuje takové množství údajů o svých občanech, ať je to alespoň k nějakému užitku.

Nedávno spuštěné přijímání žádostí v rámci SFRB Programu pro mladé je ukázkovým příkladem toho, jak Česko zaostává v oblasti zefektivnění státní správy elektronizací. Pojďme se podívat, co by v tomto konkrétním případě mohlo být zlepšeno. Zároveň se pokusím upozornit na jeden aspekt veřejné správy Česka, který vnímám jako jednu z kořenových příčin toho, proč to pořád nejde lépe.

Je středa 15. srpna 2018, svítá a ve dvou ulicích v Praze a v Olomouci vycházející slunce odhaluje zástup lidí, kteří postávají a posedávají na chodníku. Obě řady končí u vchodu do budovy, která je označen jako pobočka Státního fondu rozvoje bydlení (SFRB). Od osmé hodiny totiž úředníci začínají přijímat žádosti o státem podporované půjčky na bydlení pro mladé.

Pominu pro tento článek rozpravu o způsobu podpory bydlení pro mladé rodiny. Co bych ale rád prozkoumal zevrubně, jsou podmínky pro přijetí žádosti. V době, kdy si prakticky odkudkoli, kde je rozumné připojení k internetu, můžete během pár minut nakoupit letenky na cestu kolem světa, musíte osobně a v danou dobu dorazit na úřad a k nohám úředníka složit poníženou supliku ve formě svazku dokladů z velké části získaných od jiných státních úřadů.

Vrchnostenské Česko

Možná označíte poslední větu za silná slova, ale budu na nich trvat, a než se ponořím do této konkrétní kauzy věcně, dovolím si krátkou úvahu na toto téma. Zájemci o čistý eGov, nechť přistoupí k další kapitole. A protože mě popisovaný přístup státu opravdu rozčiluje, omluvte prosím místy záměrné citově zabarvené formulace.

Existuje nezanedbatelné množství indicií dokladujících, že úřednický systém českého státu zdaleka (čest výjimkám existujících na nejnižších stupních) nepřekročil stín rakousko-uherského mocnářství a jeho feudální správy. Stát reprezentovaný svým byrokratickým aparátem a silovými složkami by podle mého názoru měl být v běžném jednání s občany partnerem, který poskytuje svým občanům službu, a to včetně okamžiku, kdy je úřadu přisouzena pravomoc posoudit soulad s předpisy v rámci různých povolovacích řízení, např. stavebního řízení. Opět pomineme složitou otázku rozumné míry regulace a použijeme pouze závěr: fungující stát se bez jisté míry regulace, a tedy povolovacích procesů, neobejde.

Naladění zástupců byrokracie ilustruje termín „vrchnostenské postavení“. Když jsem se s ním poprvé setkal, nevěřil jsem vlastním očím. Do mého pojetí demokratické republiky jako dobrovolného sdružení svobodných občanů tohle slovo nepatří. Právníci možná nebudou souhlasit, budou ho prosazovat jako právní termín, ale já s nimi budu do posledních sil nesouhlasit. Pídil jsem se po významu tohoto termínu právě s cílem najít jeho roli v právním systému a narazil jsem na následující shrnutí:

Patrimoniální nebo také vrchnostenská správa bývala veřejná správa, kterou pozemková vrchnost vykonávala na svých panstvích. Zahrnovala jak správu majetku, tak správní a soudní oprávnění vůči poddaným. V českých zemích se vedle městské a církevní správy uplatňovala od 13. století až do roku 1848.

Nahlédnutím do návrhů některých zákonů a jejich důvodových zpráv se ukáže, že mysl tvůrců zákonů, úředníků centrálního byrokratického aparátu, se od doby před rokem 1848 neposunula a nevšimla si zrušení poddanství, ke kterému toho roku po revolučních bouřích došlo. Ne, na území Česka žádní poddaní nežijí. Proto termín vrchnostenské postavení do jakéhokoli dokumentu, který je spojen s tvorbou legislativy v souvislosti se správou tohoto státu, nepatří. Je nezbytné změnit nastavení myslí stavu úřednického a přepnout vnímání úředníků do režimu rovnocenných partnerů a poskytovatelů služby. Jeden příklad z důvodové zprávy zákona č. 297/2016:

K § 6 – Ustanovení § 6 dopadá na situace, kdy se právně jedná vůči veřejnoprávním podepisujícím a dalším subjektům uvedeným v § 5 jako vrchnostenským (výsostným) entitám, tj. odesílatel dokumentu není při právním jednání vůči těmto subjektům v rovném postavení. …

Rozdělení na vrchnost a poddané je v myslích úředníků hluboko zakořeněné. Ve spojení s obecným lidským sklonem svěřenou pravomoc zaměňovat s osobní mocí jde ruku v ruce podvědomé či vědomé zneužívání domnělé osobní moci k posílení vlastní důležitosti formou drobné či větší šikany oddaných poddaných. Takové naladění pak v úředníkově mysli vyvolává otázky: Proč by to vlastně měli mít poddaní snadné? Proč neuplatnit moc a trochu jim to znesnadnit? Ostatně tak alespoň nebude tolik práce.

Pro nastolení rovnoprávného vztahu mezi státem a občanem je nezbytné v první řadě vymýtit z úřednických myslí vnímání úřadu jako vrchnosti. Na tomto základě pak bude snazší stavět služby pro partnerskou spolupráci mezi úřady a občany.

Rozbor náležitostí žádosti

Už samotný proces přijímání žádostí, nastavená pravidla a termíny uvrhují žadatele do pozice prosebníka o almužnu. Pokud je nabídka atraktivní a je očekáván velký zájem, proč místo potupného postávání ve frontách v přesně stanovenou dobu a skládání žádostí k nohám úředníků není možné přijmout všechny žádosti podané v době jednoho měsíce, a pokud bude převis poptávky, pak použít losování z žádostí, které splňují požadavky? Když to jde u veřejných zakázek, proč ne zde?

Pro úplnost je třeba uvést, že žádost bylo možné podat v elektronické formě s tím, že některé přílohy žádosti je nutno dodávat ve formě výstupu autorizované konverze.

Samostatnou kategorií je samotný požadovaný obsah žádosti. Vycházím z předpokladu, že SFRB je agentura reprezentující stát. Projdu všechny požadované údaje a posoudím, jaké vlastně údaje stát požaduje a které z nich už má. Jednotlivé požadované údaje jsem rozdělil do tří kategorií:

  • [NE] – údaj není nutno předkládat, protože jej již některá složka státu má k dispozici
  • [ČÁST] – nedokážu zcela posoudit, zda údaje stát má, nebo zda jde o novou informaci; nejistý může být také účel získání dat a konkrétní obsah
  • [OK] – informace, které jsou podstatou žádosti a jsou oprávněně požadovány po žadateli, protože stát jimi nedisponuje

Co je tedy požadováno v případě Úvěru na pořízení:

  1. [NE] Osobní a kontaktní údaje žadatele(ky) – kompletní osobní a kontaktní údaje – přesně stejné, které již v současné době poskytuje Národní bod pro identifikaci a autentizaci (NIA) skrze portál eidentita.cz, takže by mohly být získány automaticky.
  2. [NE] Osobní údaje spolužadatele(ky) – vzhledem k tomu, že níže je požadována i aktivita spolužadatele (čestné prohlášení apod.), nejsnazší cestou by bylo „nasdílet“ (např. odesláním odkazu) rozpracovanou žádost spolužadateli, aby doplnil svou část.
  3. [ČÁST] Zdroj příjmů – uvádí se jak pro žadatele, tak pro spolužadatele, duplicitně pak bude uveden v potvrzeních o příjmech – tato položka je nadbytečná
  4. [NE] Děti – tento údaj má stát v různých registrech k dispozici (registr obyvatel u vlastních dětí, rozhodnutí soudů o svěření do péče apod.)
  5. [OK] Použití úvěru, cena pořizované nemovitosti a zdroje financování – nutno vyplnit, nová informace pro stát
  6. [ČÁST] Měsíční příjmy – jak žadatele, tak spolužadatele může stát dohledat v daňovém přiznání, které má za minulý rok k dispozici
  7. [OK] Měsíční výdaje – pro stát nový údaj, nutno zadat
  8. [OK] Zajištění úvěru – pro stát nový udaj, nutno zadat
  9. [OK] Použití nemovitosti k podnikání – pro stát nový údaj, nutno zadat
  10. [NE] Čestné prohlášení o bezdlužnosti u státu žadatele a spolužadatele – nadbytečné, jedná se o dluhy evidované státem, což si může stát zjistit ve svých systémech, ale zde se nic nezadává
  11. [OK] Zpracování osobních údajů – nic se nezadává

Celkem je ve formuláři žádosti požadováno vyplnění 59 údajů. Z toho 24 položek by bylo možné eliminovat přihlášením žadatele a spolužadatele pomocí elektronické identifikace (např. eOP), 6 získat z existujících registrů (děti), 4 položky o příjmech získat od FÚ z daňového přiznání, 8 položek (zaměstnavatel) získat také od FÚ. Zůstává tedy 21 položek, které jsou podstatou žádosti a které musí žadatel vyplnit. Což je redukce na cca 30 %.  

Přílohy požadované jako doklady k žádosti:

  1. [NE] Oddací list/ doklad o reg. partnerství – stát má k dispozici, nadbytečné
  2. [NE] Kopie občanského průkazu – naprosto nadbytečné v případě použití elektronické identifikace a na hraně zákona, který zakazuje vytvářet kopie bez souhlasu držitele. Zde je souhlas s kopírováním vynucen.
  3. [NE] Povolení k pobytu – nadbytečné, mohlo by být řešeno elektronickou identifikací – cizinci v současné době nemají eOP, a proto je prozatím elektronická identifikace problematická
  4. [NE] Výpis z centrální evidence exekucí – jedná se o veřejný rejstřík vedený komorou exekutorů, takže by stát mohl získat údaje sám. Oblast exekucí je jeden velký tunel exekutorské lobby a podmínky provozu tohoto rejstříku jsou toho zářným příkladem. Za jeden každý dotaz zaplatíte 60 Kč. Pokud zadáte dotaz a spustíte hledání, strhne se vám 60 Kč z kreditu, a to i v případě, kdy zadáte do formuláře evidentně nesprávný údaj. Ověřeno za vás zadáním rodného čísla, které nesplňuje kontrolu modulo 11 a utracením 60 Kč za vyhledání 0 záznamů. A to všechno přesně v souladu s vyhláškou, kterou vydalo ministerstvo spravedlnosti. To samo o sobě považuji za velkou hanbu úředníků.
  5. [NE] Potvrzení o výši příjmu – platí pro zaměstnance, zřejmě vydané zaměstnavatelem, stát by mohl získat údaje z FÚ z dosud podaných daňových přiznání.
  6. [NE] Daňové přiznání – netřeba dokládat, stát má všechna daňová přiznání k dispozici
  7. [NE] Doklady o jiných pravidelných příjmech – zde jsou uváděny sociální dávky či výživné – vše by měl mít stát k dispozici ve formě rozhodnutí o výplatě dávek, rozhodnutí soudu o výživném apod.
  8. [OK] Doklady k závazkům – nutno dodat, pro stát nová informace
  9. Doklady k pořízení obydlí – Výstavba
    • [NE] Povolení stavby dle stavebního zákona – stát má, stačilo by uvést číslo jednací
    • [OK] Smlouva o provedení výstavby v případě dodavatelské stavby – nutno dodat, nová informace pro stát
    • [ČÁST] Projektová dokumentace – stát již má, je součástí spisu nutného pro vydání stavebního povolení
    • [OK] Položkový rozpočet stavby vytvořený oprávněnou osobou – při stavbě svépomocí, nutno dodat, nová informace pro stát
    • [NE] Vyjádření vodoprávního úřadu – jedná se o státní úřad, stát informaci má
    • [ČÁST] Sdělení oprávněné osoby o velikosti podlahové plochy – je součástí dokumentace ke stavebnímu povolení, v některých případech může být požadováno
  10. Doklady k pořízení obydlí – Nákup
    • [OK] Kupní smlouva a doklad o zjištěné ceně – nová informace, nutno dodat
    • [NE] Výpis z katastru nemovitostí – stát si může zjistit sám, stačí dodat identifikaci nemovitosti
    • [NE] Vyjádření vodoprávního úřadu – státní instituce, stát si může zajistit sám
    • [ČÁST] Sdělení oprávněné osoby o velikosti podlahové plochy – zpravidla bývá uvedeno v RUIAN, u starších nemovitostí nemusí být uvedeno, pak je nutno doložit
    • [NE] Potvrzení o příjmu ručitele – možno získat na FÚ na základě minulých daňových přiznání
    • [NE] Daňové přiznání ručitele – možno získat na FÚ na základě minulých daňových přiznání
    • [NE] Doklad o bezdlužnosti ručitele od správce daně – možno získat přímo u správce daně
    • [NE] Výpis z centrální evidence exekucí – viz výše – může získat stát z veřejného rejstříku
    • [NE] Rodný list dítěte – stát má údaje k dispozici v evidenci obyvatel
    • [NE] Rozhodnutí soudu o svěření do péče – stát má rozhodnutí k dispozici

Pokud se tedy podíváme na celkový rozsah požadovaných informací a dokladů, vychází následující rozdělení:

  • Celkem posuzováno 41 položek, které stát požaduje doložit
  • [NE] –  23× (56 %) stát požaduje doložit údaj, který má sám v držení, mnohdy ve formě potvrzení vydaná jedním úřadem, které tak bude přes občana doručeno na úřad druhý
  • [ČÁST] – 7× (17 %) je možné, že stát požaduje informace, které sám má
  • [OK] – 11× (27 %) oprávněně požaduje informace, které nemá

Celkem tedy zhruba tři čtvrtiny údajů je po žadatelích požadováno zbytečně, resp. žadatelé zde vystupují v roli kurýrů, kteří přenášejí úřední dokumenty z jednoho úřadu do druhého.

Pokud si představím ideální případ, jak by podání takovéto žádosti mohlo vypadat, bylo by následující:

  1. Žadatel se přihlásí na portál úřadu pomocí své elektronické identity
  2. Založí žádost, kam vyplní potřebné údaje, které ještě stát nemá k dispozici
  3. Udělí úřadu oprávnění další potřebné údaje získat přímo ze zdrojových systémů, kde jsou uloženy
  4. Pokud má spolužadatele a/nebo ručitele, zadá jejich kontaktní údaje (e-mail, mobil), na které systém úřadu odešle výzvu k doplnění žádosti.
  5. Další osoby, které se účastní podání žádosti na základě doručené výzvy, vstoupí do systému s využitím elektronické identifikace a doplní potřebné
  6. O celém průběh tvorby žádosti dostává žadatel a další účastníci notifikace, aby věděli, zda vše stihnou v termínu

Úřad tak může průběžně získávat informace o zájmu na základě rozpracovaných žádostí a odpovídajícím způsobem může komunikovat stav programu.

WT100_25_SE

ICT Unie připravuje ve spolupráci s poslanci návrh zákona, kterému někteří zúčastnění říkají „digitální ústava“ a jehož pracovní název zní „Zákon o právu na digitální služby“, který mimo jiné zakotví právo občana vzepřít se požadavku na poskytnutí údajů, které již stát má v držení. Pokud zákon vejde v platnost, bylo by možné ve dvou třetinách případů do žádosti uvést odpověď „Požadované informace již má veřejná správa k dispozici“ a takováto odpověď by nesměla být důvodem k odmítnutí žádosti.

Stát v dnešní době shromažďuje enormní množství údajů. To samo o sobě by mělo být předmětem veřejné diskuse. Ale když už dnes stát takové množství údajů legálně shromažďuje, nechť je to alespoň k nějakému užitku. Za předpokladu, že osoba, jíž se data týkají, vyjádří souhlas, měly by si státní úřady pro daný konkrétní případ být schopny potřebné údaje předávat.  

Autor článku

Autor je open [mind|source|data] positive IT Architekt idealista snažící se přežít v korporaci s touhou i po 20 letech v oboru tvořit systémy, které pomáhají nebo aspoň neprudí.

'; document.getElementById('preroll-iframe').onload = function () { setupIframe(); } prerollContainer = document.getElementsByClassName('preroll-container-iframe')[0]; } function setupIframe() { prerollDocument = document.getElementById('preroll-iframe').contentWindow.document; let el = prerollDocument.createElement('style'); prerollDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:20px;right:25px}"; videoContent = prerollDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('PREROLL sound allowed'); // setUpIMA(true); videoContent.volume = 1; videoContent.muted = false; setUpIMA(); }).catch(function () { console.log('PREROLL sound forbidden'); videoContent.volume = 0; videoContent.muted = true; setUpIMA(); }); } } function setupDimensions() { prerollWidth = Math.min(iinfoPrerollPosition.offsetWidth, 480); prerollHeight = Math.min(iinfoPrerollPosition.offsetHeight, 320); } function setUpIMA() { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Preroll advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = prerollWidth; // adsRequest.linearAdSlotHeight = prerollHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. prerollDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( prerollDocument.getElementById('adContainer'), videoContent); } function unmutePrerollAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } } function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(prerollWidth, prerollHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } function onAdEvent(adEvent) { const ad = adEvent.getAd(); console.log('Preroll event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: if (!ad.isLinear()) { videoContent.play(); } prerollDocument.getElementById('adContainer').style.width = '100%'; prerollDocument.getElementById('adContainer').style.maxWidth = '640px'; prerollDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); if (ad.isLinear()) { intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } prerollDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (prerollLastError === 303) { playYtVideo(); } break; case google.ima.AdEvent.Type.COMPLETE: if (ad.isLinear()) { clearInterval(intervalTimer); } playYtVideo(); break; } } function onAdError(adErrorEvent) { console.log(adErrorEvent.getError()); prerollLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { playYtVideo(); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoPrerollPosition.remove(); playPrerollAd(); } else { return false; } adVolume = 1; return true; } function onContentPauseRequested() { videoContent.pause(); } function onContentResumeRequested() { videoContent.play(); } function onActiveView() { if (prerollContainer) { const containerOffset = prerollContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (prerollPaused) { adsManager.resume(); prerollPaused = false; } return true; } else { if (!prerollPaused) { adsManager.pause(); prerollPaused = true; } } } return false; } function playYtVideo() { iinfoPrerollPosition.remove(); youtubeIframe.style.display = 'block'; youtubeIframe.src += '&autoplay=1&mute=1'; } }
Upozorníme vás na články, které by vám neměly uniknout (maximálně 2x týdně).
'; document.getElementById('outstream-iframe').onload = function () { setupIframe(); } replayScreen = document.getElementById('iinfoOutstreamReplay'); iinfoOutstreamPosition = document.getElementById('iinfoOutstreamPosition'); outstreamContainer = document.getElementsByClassName('outstream-container')[0]; setupReplayScreen(); } function setupIframe() { outstreamDocument = document.getElementById('outstream-iframe').contentWindow.document; let el = outstreamDocument.createElement('style'); outstreamDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:-5px;right:25px}"; videoContent = outstreamDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; if ( location.href.indexOf('rejstriky.finance.cz') !== -1 || location.href.indexOf('finance-rejstrik') !== -1 || location.href.indexOf('firmy.euro.cz') !== -1 || location.href.indexOf('euro-rejstrik') !== -1 || location.href.indexOf('/rejstrik/') !== -1 || location.href.indexOf('/rejstrik-firem/') !== -1) { outstreamDirectPlayed = true; soundAllowed = true; iinfoVastUrlIndex = 0; } if (!outstreamDirectPlayed) { console.log('OUTSTREAM direct'); setUpIMA(true); } else { if (soundAllowed) { const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('OUTSTREAM sound allowed'); setUpIMA(false); }).catch(function () { console.log('OUTSTREAM sound forbidden'); renderBanner(); }); } } else { renderBanner(); } } } function getWrapper() { let articleWrapper = document.querySelector('.rs-outstream-placeholder'); // Outstream Placeholder from RedSys manipulation if (articleWrapper && articleWrapper.style.display !== 'block') { articleWrapper.innerHTML = ""; articleWrapper.style.display = 'block'; } // Don't render OutStream on homepages if (articleWrapper === null) { if (document.querySelector('body.p-index')) { return null; } } if (articleWrapper === null) { articleWrapper = document.getElementById('iinfo-outstream'); } if (articleWrapper === null) { articleWrapper = document.querySelector('.layout-main__content .detail__article p:nth-of-type(6)'); } if (articleWrapper === null) { // Euro, Autobible, Zdravi articleWrapper = document.querySelector('.o-article .o-article__text p:nth-of-type(6)'); } if (articleWrapper === null) { articleWrapper = document.getElementById('sidebar'); } if (!articleWrapper) { console.error("Outstream wrapper of article was not found."); } return articleWrapper; } function setupDimensions() { outstreamWidth = Math.min(iinfoOutstreamPosition.offsetWidth, 480); outstreamHeight = Math.min(iinfoOutstreamPosition.offsetHeight, 320); } /** * Sets up IMA ad display container, ads loader, and makes an ad request. */ function setUpIMA(direct) { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); if (direct) { adsRequest.adTagUrl = directVast; console.log('Outstream DIRECT CAMPAING advert: ' + directVast); videoContent.muted = true; videoContent.volume = 0; outstreamDirectPlayed = true; } else { adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Outstream advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; } // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = outstreamWidth; // adsRequest.linearAdSlotHeight = outstreamHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function setupReplayScreen() { replayScreen.addEventListener('click', function () { iinfoOutstreamPosition.remove(); iinfoVastUrlIndex = 0; outstreamInit(); }); } /** * Sets the 'adContainer' div as the IMA ad display container. */ function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. outstreamDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( outstreamDocument.getElementById('adContainer'), videoContent); } function unmuteAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } } /** * Loads the video content and initializes IMA ad playback. */ function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(outstreamWidth, outstreamHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } /** * Handles the ad manager loading and sets ad event listeners. * @param { !google.ima.AdsManagerLoadedEvent } adsManagerLoadedEvent */ function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } /** * Handles actions taken in response to ad events. * @param { !google.ima.AdEvent } adEvent */ function onAdEvent(adEvent) { // Retrieve the ad from the event. Some events (for example, // ALL_ADS_COMPLETED) don't have ad object associated. const ad = adEvent.getAd(); console.log('Outstream event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: // This is the first event sent for an ad - it is possible to // determine whether the ad is a video ad or an overlay. if (!ad.isLinear()) { // Position AdDisplayContainer correctly for overlay. // Use ad.width and ad.height. videoContent.play(); } outstreamDocument.getElementById('adContainer').style.width = '100%'; outstreamDocument.getElementById('adContainer').style.maxWidth = '640px'; outstreamDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); // This event indicates the ad has started - the video player // can adjust the UI, for example display a pause button and // remaining time. if (ad.isLinear()) { // For a linear ad, a timer can be started to poll for // the remaining time. intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } outstreamDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (outstreamLastError === 303) { if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } } break; case google.ima.AdEvent.Type.COMPLETE: // This event indicates the ad has finished - the video player // can perform appropriate UI actions, such as removing the timer for // remaining time detection. if (ad.isLinear()) { clearInterval(intervalTimer); } if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } break; } } /** * Handles ad errors. * @param { !google.ima.AdErrorEvent } adErrorEvent */ function onAdError(adErrorEvent) { // Handle the error logging. console.log(adErrorEvent.getError()); outstreamLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { renderBanner(); } } function renderBanner() { if (isBanner) { console.log('Outstream: Render Banner'); iinfoOutstreamPosition.innerHTML = ""; iinfoOutstreamPosition.style.height = "330px"; iinfoOutstreamPosition.appendChild(bannerDiv); } else { console.log('Outstream: Banner is not set'); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoOutstreamPosition.remove(); outstreamInit(); } else { return false; } adVolume = 1; return true; } /** * Pauses video content and sets up ad UI. */ function onContentPauseRequested() { videoContent.pause(); // This function is where you should setup UI for showing ads (for example, // display ad timer countdown, disable seeking and more.) // setupUIForAds(); } /** * Resumes video content and removes ad UI. */ function onContentResumeRequested() { videoContent.play(); // This function is where you should ensure that your UI is ready // to play content. It is the responsibility of the Publisher to // implement this function when necessary. // setupUIForContent(); } function onActiveView() { if (outstreamContainer) { const containerOffset = outstreamContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (outstreamPaused) { adsManager.resume(); outstreamPaused = false; } return true; } else { if (!outstreamPaused) { adsManager.pause(); outstreamPaused = true; } } } return false; } let outstreamInitInterval; if (typeof cpexPackage !== "undefined") { outstreamInitInterval = setInterval(tryToInitializeOutstream, 100); } else { const wrapper = getWrapper(); if (wrapper) { let outstreamInitialized = false; window.addEventListener('scroll', () => { if (!outstreamInitialized) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { outstreamInit(); outstreamInitialized = true; } } }); } } function tryToInitializeOutstream() { const wrapper = getWrapper(); if (wrapper) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { if (cpexPackage.adserver.displayed) { clearInterval(outstreamInitInterval); outstreamInit(); } } } else { clearInterval(outstreamInitInterval); } } }
OSZAR »