interface ExampleDefinitions { [ pageUrl ] : string ; } /**
 * Example browser HTML / DOM app.
 */ function exampleBrowser ( exampleDefinitions ) { const navPanel = document . getElementById ( "navPanel" ) as HTMLDivElement ; const exampleFrameElement = document . getElementById ( "exampleFrame" ) as HTMLIFrameElement ; const viewSourceButton = document . getElementById ( "viewSource" ) as HTMLButtonElement ; const exampleListElement = document . getElementById ( "exampleList" ) as HTMLDivElement ; let currentlySelectedSource ; const categories = { } ; const orderedCategories = [ "Getting started" , "Datasource" , "Rendering" , "Styling" , "Threejs" , "Miscellaneous" ] ; const elements = [ ] ; const titleElements = [ ] ; /**
     * Query params parsed out of hash.
     *
     * Used by xyz example to reload with params while keeping internal state.
     */ let queryParams = "" ; installHamburgerHandler ( ) ; populateExamplesMenu ( ) ; installFilter ( document . getElementById ( "filterInput" ) as HTMLInputElement ) ; function installHamburgerHandler ( ) { const expandButton = document . getElementById ( "hamburgerMenu" ) as HTMLAnchorElement ; const closeButton = document . getElementById ( "closeButton" ) as HTMLButtonElement ; expandButton . addEventListener ( "click" , event => { navPanel . classList . toggle ( "collapsed" ) ; event . preventDefault ( ) ; } ) ; closeButton . addEventListener ( "click" , event => { navPanel . classList . toggle ( "collapsed" ) ; event . preventDefault ( ) ; } ) ; } function populateExamplesMenu ( ) { Object . keys ( exampleDefinitions ) . sort ( ) . forEach ( pageUrl => { const linkName = getName ( pageUrl ) . replace ( new RegExp ( "-" , "g" ) , " " ) ; const linkElements = linkName . split ( " / " ) ; let linkSubMenu = linkElements . length > 1 ? linkElements [ 0 ] : "miscellaneous" ; linkSubMenu = linkSubMenu . charAt ( 0 ) . toUpperCase ( ) + linkSubMenu . slice ( 1 ) ; if ( categories [ linkSubMenu ] === undefined ) { categories [ linkSubMenu ] = [ ] ; } const visibleText = linkElements . length === 1 ? linkName : linkElements . slice ( 1 ) . join ( " / " ) ; const linkElement = createDomElement < HTMLAnchorElement > ( "a" , { innerText : visibleText , href : "#" + pageUrl , className : "link" } ) ; ( linkElement as any ) . nameWithCategory = linkName ; ( linkElement as any ) . nameWithoutCategory = visibleText ; categories [ linkSubMenu ] . push ( linkElement ) ; elements . push ( linkElement ) ; } ) ; Object . keys ( categories ) . sort ( ) . forEach ( category => { if ( ! orderedCategories . includes ( category ) ) { orderedCategories . push ( category ) ; } } ) ; orderedCategories . forEach ( menuElement => { const menu = document . createElement ( "div" ) ; const title = document . createElement ( "h2" ) ; title . innerHTML = menuElement ; titleElements . push ( title ) ; menu . appendChild ( title ) ; const category = categories [ menuElement ] ; if ( category === undefined ) { return ; } category . forEach ( anchor => { menu . appendChild ( anchor ) ; } ) ; exampleListElement . appendChild ( menu ) ; } ) ; } let isSearching = false ; function goInSearchMode ( ) { titleElements . forEach ( title => { title . style . cssText = "display:none;" ; } ) ; document . getElementById ( "magnifier-placeholder" ) ! . style . cssText = "display:none;" ; document . getElementById ( "clearFilterButton" ) ! . style . cssText = "" ; elements . forEach ( anchor => { anchor . innerText = ( anchor as any ) . nameWithCategory ; } ) ; isSearching = true ; } function leaveSearchMode ( ) { titleElements . forEach ( title => { title . style . cssText = "" ; } ) ; document . getElementById ( "magnifier-placeholder" ) ! . style . cssText = "" ; document . getElementById ( "clearFilterButton" ) ! . style . cssText = "display:none;" ; elements . forEach ( anchor => { anchor . classList . remove ( "filtered" ) ; anchor . innerText = ( anchor as any ) . nameWithoutCategory ; } ) ; ( document . getElementById ( "filterInput" ) as HTMLInputElement ) . value = "" ; isSearching = false ; } function installFilter ( filterInput ) { filterInput . addEventListener ( "input" , e => { const filterValue = ( filterInput . value || "" ) . trim ( ) ; if ( filterValue . length > 0 && ! isSearching ) { goInSearchMode ( ) ; } if ( filterValue . length === 0 && isSearching ) { leaveSearchMode ( ) ; } for ( const element of elements ) { const text = element . textContent ; if ( text === null ) { continue ; } const matches = filterValue === "" || text . includes ( filterValue . toLowerCase ( ) ) ; if ( matches ) { element . classList . remove ( "filtered" ) ; } else { element . classList . add ( "filtered" ) ; } } } ) ; document . getElementById ( "clearFilterButton" ) ! . addEventListener ( "click" , leaveSearchMode ) ; } param pageUrl function showExample ( pageUrl ) { const expandButton = document . getElementById ( "hamburgerMenu" ) as HTMLAnchorElement ; expandButton . classList . toggle ( "expanded" , ! navPanel . classList . contains ( "collapsed" ) ) ; if ( ! ( pageUrl in exampleDefinitions ) ) { viewSourceButton . style . display = "none" ; exampleListElement . style . bottom = "365px" ; exampleFrameElement . contentWindow ! . document . body . innerHTML = `<p style="color:#888;font-size:20px;font-family:sans-serif;text-align:center;` + `top: 50%; margin-top: -100px; position: absolute; width: 100% ">` + `<strong style="font-size:80px; ">404</strong><br/>Example not found</p>` ; return ; } window . location . hash = "#" + pageUrl ; if ( queryParams ) { window . location . search = queryParams ; } exampleFrameElement . src = pageUrl + queryParams ; elements . forEach ( element => { const elementTargetPage = element . hash . substr ( 1 ) ; if ( elementTargetPage === pageUrl ) { element . classList . add ( "selected" ) ; } else { element . classList . remove ( "selected" ) ; } } ) ; currentlySelectedSource = exampleDefinitions [ pageUrl ] ; viewSourceButton . style . display = "block" ; exampleListElement . style . bottom = "65px" ; navPanel . classList . toggle ( "collapsed" ) ; } /**
     * Install view source button handler
     */ viewSourceButton ! . addEventListener ( "click" , ( ) => { if ( ! currentlySelectedSource ) { return ; } window . open ( "codebrowser.html?src=" + encodeURIComponent ( currentlySelectedSource ) ) ; } ) ; /**
     * Show example based on `location.hash` if it's not empty.
     */ function showExampleFromHash ( ) { const hash = window . location . hash ; if ( hash ) { let pageUrl ; queryParams = "" ; const match = window . location . hash . match ( /([^\?]*)\?(.*)/ ) ; if ( match !== null && match . length > 2 ) { pageUrl = match [ 1 ] . substring ( 1 ) ; queryParams = "?" + match [ 2 ] ; } else { pageUrl = window . location . hash . substring ( 1 ) ; } if ( window . location . search ) { queryParams = queryParams ? window . location . search + "&" + queryParams . substr ( 1 ) : window . location . search ; } showExample ( pageUrl ) ; } } window . addEventListener ( "hashchange" , showExampleFromHash ) ; showExampleFromHash ( ) ; interface DomElementProps { [ property ] : string ; } function createDomElement < T = HTMLElement > ( name , options ? ) { const element = ( document . createElement ( name ) as any ) as T ; if ( options !== undefined ) { Object . assign ( element , options ) ; } return element ; } returns function getName ( pageUrl ) { const name = basename ( pageUrl ) . replace ( /\.[a-z]+$/ , "" ) . split ( "_" ) ; return name . join ( " / " ) ; } /**
     * Get base name of file, so all parent folders and trailing '/' are removed.
     */ function basename ( path ) { const i = path . lastIndexOf ( "/" ) ; if ( i === - 1 ) { return path ; } else { return path . substr ( i + 1 ) ; } } } /**
 * Maps pageUrl to srcUrl.
 *
 * Loaded using <script> tag `example-definitions.js`, which is generated by `webpack.config.js`.
 */ declare const examples ; exampleBrowser ( examples ) ;