mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-04 16:42:27 +00:00
* feat(catalog): play the real composition on catalog pages Catalog previews were uploaded MP4s, published by hand to the CDN. Each page now embeds the composition itself, running in <hyperframes-player>, so a preview is the block rather than a recording of it. The composition is delivered as JSON under docs/public/catalog, and the player is mounted inside an iframe. Both are forced: the docs host publishes only JSON and images out of docs/public, and its MDX renderer strips unknown custom elements, so a player written into the page never reaches the DOM and an .html payload 404s in production. Assets are inlined as data URIs, which sidesteps the file-type restriction for fonts, scripts and models alike. 164 of 168 items build a payload; the rest keep their MP4 and say so. * chore: rebuild docs preview * chore: route isolation probe * chore: drop the route isolation probe page * chore: probe which asset types the docs host publishes * refactor(catalog): host preview assets instead of inlining them Fonts were being base64'd into every payload that used them, so a handful of files cost tens of megabytes in the repository to say the same thing over and over. Assets are now written once, content-addressed, under docs/public/catalog/assets and linked. Which types can be hosted was settled by fetching one file of each from a deployed preview: woff2, wav, mp4, svg and the image formats are published, glb is not. Types the host drops still travel inside the payload, because a link that 404s is worse than a larger payload. Also fixes the four type errors the scripts typecheck caught, all of them unchecked index access on a split() result. * refactor(catalog): share preview assets instead of repeating them * style: format the asset module
1 line
70 KiB
JSON
1 line
70 KiB
JSON
{"html":"<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=1920, height=1080\" />\n <title>Liquid Glass Media Controls</title>\n <script src=\"https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js\"></script>\n <script src=\"https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js\"></script>\n <script src=\"data:text/javascript;base64,dmFyIExpcXVpZEdsYXNzID0gKCgpID0+IHsKICB2YXIgRSA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTsKICB2YXIgRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7CiAgdmFyIHogPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lczsKICB2YXIgTiA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7CiAgdmFyIE8gPSAobSwgZSkgPT4gewogICAgICBmb3IgKHZhciB0IGluIGUpIEUobSwgdCwgeyBnZXQ6IGVbdF0sIGVudW1lcmFibGU6ICEwIH0pOwogICAgfSwKICAgIEggPSAobSwgZSwgdCwgcikgPT4gewogICAgICBpZiAoKGUgJiYgdHlwZW9mIGUgPT0gIm9iamVjdCIpIHx8IHR5cGVvZiBlID09ICJmdW5jdGlvbiIpCiAgICAgICAgZm9yIChsZXQgbiBvZiB6KGUpKQogICAgICAgICAgIU4uY2FsbChtLCBuKSAmJgogICAgICAgICAgICBuICE9PSB0ICYmCiAgICAgICAgICAgIEUobSwgbiwgeyBnZXQ6ICgpID0+IGVbbl0sIGVudW1lcmFibGU6ICEociA9IEQoZSwgbikpIHx8IHIuZW51bWVyYWJsZSB9KTsKICAgICAgcmV0dXJuIG07CiAgICB9OwogIHZhciBJID0gKG0pID0+IEgoRSh7fSwgIl9fZXNNb2R1bGUiLCB7IHZhbHVlOiAhMCB9KSwgbSk7CiAgdmFyIFkgPSB7fTsKICBPKFksIHsKICAgIENTU19QUk9QRVJUWV9NQVA6ICgpID0+IF8sCiAgICBERUZBVUxUUzogKCkgPT4gdywKICAgIEdsYXNzUmVuZGVyZXJHUFU6ICgpID0+IHksCiAgICBMaXF1aWRHbGFzc0NhbnZhczogKCkgPT4gUiwKICB9KTsKICB2YXIgdyA9IHsKICAgICAgYmx1ckFtb3VudDogMCwKICAgICAgcmVmcmFjdGlvbjogMC42OSwKICAgICAgY2hyb21BYmVycmF0aW9uOiAwLjA1LAogICAgICBlZGdlSGlnaGxpZ2h0OiAwLjA1LAogICAgICBzcGVjdWxhcjogMCwKICAgICAgZnJlc25lbDogMSwKICAgICAgZGlzdG9ydGlvbjogMCwKICAgICAgY29ybmVyUmFkaXVzOiA2NSwKICAgICAgelJhZGl1czogNDAsCiAgICAgIG9wYWNpdHk6IDEsCiAgICAgIHNhdHVyYXRpb246IDAsCiAgICAgIHRpbnRTdHJlbmd0aDogMCwKICAgICAgYnJpZ2h0bmVzczogMCwKICAgICAgc2hhZG93T3BhY2l0eTogMC4zLAogICAgICBzaGFkb3dTcHJlYWQ6IDEwLAogICAgICBzaGFkb3dPZmZzZXRZOiAxLAogICAgICBiZXZlbE1vZGU6IDAsCiAgICB9LAogICAgXyA9IHsKICAgICAgIi0tbGctYmx1ciI6ICJibHVyQW1vdW50IiwKICAgICAgIi0tbGctcmVmcmFjdGlvbiI6ICJyZWZyYWN0aW9uIiwKICAgICAgIi0tbGctY2hyb20tYWJlcnJhdGlvbiI6ICJjaHJvbUFiZXJyYXRpb24iLAogICAgICAiLS1sZy1lZGdlLWhpZ2hsaWdodCI6ICJlZGdlSGlnaGxpZ2h0IiwKICAgICAgIi0tbGctc3BlY3VsYXIiOiAic3BlY3VsYXIiLAogICAgICAiLS1sZy1mcmVzbmVsIjogImZyZXNuZWwiLAogICAgICAiLS1sZy1kaXN0b3J0aW9uIjogImRpc3RvcnRpb24iLAogICAgICAiLS1sZy1jb3JuZXItcmFkaXVzIjogImNvcm5lclJhZGl1cyIsCiAgICAgICItLWxnLXotcmFkaXVzIjogInpSYWRpdXMiLAogICAgICAiLS1sZy1vcGFjaXR5IjogIm9wYWNpdHkiLAogICAgICAiLS1sZy1zYXR1cmF0aW9uIjogInNhdHVyYXRpb24iLAogICAgICAiLS1sZy10aW50IjogInRpbnRTdHJlbmd0aCIsCiAgICAgICItLWxnLWJyaWdodG5lc3MiOiAiYnJpZ2h0bmVzcyIsCiAgICAgICItLWxnLXNoYWRvdy1vcGFjaXR5IjogInNoYWRvd09wYWNpdHkiLAogICAgICAiLS1sZy1zaGFkb3ctc3ByZWFkIjogInNoYWRvd1NwcmVhZCIsCiAgICAgICItLWxnLXNoYWRvdy1vZmZzZXQteSI6ICJzaGFkb3dPZmZzZXRZIiwKICAgICAgIi0tbGctYmV2ZWwtbW9kZSI6ICJiZXZlbE1vZGUiLAogICAgfSwKICAgIEwgPSA2LAogICAgVCA9IDIwOwogIHZhciBxID0gYC8vIEJsaXQgc2hhZGVyIC0gY29weSB0ZXh0dXJlIHdpdGggVVYgdHJhbnNmb3JtCgpzdHJ1Y3QgQmxpdFVuaWZvcm1zIHsKICBzY2FsZTogdmVjMmYsCiAgb2Zmc2V0OiB2ZWMyZiwKfQoKQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1OiBCbGl0VW5pZm9ybXM7CkBncm91cCgwKSBAYmluZGluZygxKSB2YXIgdGV4U2FtcGxlcjogc2FtcGxlcjsKQGdyb3VwKDApIEBiaW5kaW5nKDIpIHZhciB0ZXg6IHRleHR1cmVfMmQ8ZjMyPjsKCnN0cnVjdCBWZXJ0ZXhPdXRwdXQgewogIEBidWlsdGluKHBvc2l0aW9uKSBwb3NpdGlvbjogdmVjNGYsCiAgQGxvY2F0aW9uKDApIHV2OiB2ZWMyZiwKfQoKQHZlcnRleApmbiB2ZXJ0ZXhNYWluKEBsb2NhdGlvbigwKSBwb3M6IHZlYzJmKSAtPiBWZXJ0ZXhPdXRwdXQgewogIHZhciBvdXQ6IFZlcnRleE91dHB1dDsKICBvdXQudXYgPSBwb3MgKiAwLjUgKyAwLjU7CiAgb3V0LnBvc2l0aW9uID0gdmVjNGYocG9zLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG91dDsKfQoKQGZyYWdtZW50CmZuIGZyYWdtZW50TWFpbihpbjogVmVydGV4T3V0cHV0KSAtPiBAbG9jYXRpb24oMCkgdmVjNGYgewogIHJldHVybiB0ZXh0dXJlU2FtcGxlKHRleCwgdGV4U2FtcGxlciwgaW4udXYgKiB1LnNjYWxlICsgdS5vZmZzZXQpOwp9CmAsCiAgICBrID0gYC8vIEJsdXIgc2hhZGVyIC0gOS10YXAgR2F1c3NpYW4gYmx1ciAoc2luZ2xlIGRpcmVjdGlvbikKCnN0cnVjdCBCbHVyVW5pZm9ybXMgewogIGRpcjogdmVjMmYsCiAgX3BhZDogdmVjMmYsCn0KCkBncm91cCgwKSBAYmluZGluZygwKSB2YXI8dW5pZm9ybT4gdTogQmx1clVuaWZvcm1zOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyIHRleFNhbXBsZXI6IHNhbXBsZXI7CkBncm91cCgwKSBAYmluZGluZygyKSB2YXIgdGV4OiB0ZXh0dXJlXzJkPGYzMj47CgpzdHJ1Y3QgVmVydGV4T3V0cHV0IHsKICBAYnVpbHRpbihwb3NpdGlvbikgcG9zaXRpb246IHZlYzRmLAogIEBsb2NhdGlvbigwKSB1djogdmVjMmYsCn0KCkB2ZXJ0ZXgKZm4gdmVydGV4TWFpbihAbG9jYXRpb24oMCkgcG9zOiB2ZWMyZikgLT4gVmVydGV4T3V0cHV0IHsKICB2YXIgb3V0OiBWZXJ0ZXhPdXRwdXQ7CiAgb3V0LnV2ID0gcG9zICogMC41ICsgMC41OwogIG91dC5wb3NpdGlvbiA9IHZlYzRmKHBvcywgMC4wLCAxLjApOwogIHJldHVybiBvdXQ7Cn0KCkBmcmFnbWVudApmbiBmcmFnbWVudE1haW4oaW46IFZlcnRleE91dHB1dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICB2YXIgcyA9IHRleHR1cmVTYW1wbGUodGV4LCB0ZXhTYW1wbGVyLCBpbi51dikgKiAwLjIyNzAyNzsKICBzICs9IHRleHR1cmVTYW1wbGUodGV4LCB0ZXhTYW1wbGVyLCBpbi51diArIHUuZGlyICogMS4wKSAqIDAuMTk0NTk0OwogIHMgKz0gdGV4dHVyZVNhbXBsZSh0ZXgsIHRleFNhbXBsZXIsIGluLnV2IC0gdS5kaXIgKiAxLjApICogMC4xOTQ1OTQ7CiAgcyArPSB0ZXh0dXJlU2FtcGxlKHRleCwgdGV4U2FtcGxlciwgaW4udXYgKyB1LmRpciAqIDIuMCkgKiAwLjEyMTYyMjsKICBzICs9IHRleHR1cmVTYW1wbGUodGV4LCB0ZXhTYW1wbGVyLCBpbi51diAtIHUuZGlyICogMi4wKSAqIDAuMTIxNjIyOwogIHMgKz0gdGV4dHVyZVNhbXBsZSh0ZXgsIHRleFNhbXBsZXIsIGluLnV2ICsgdS5kaXIgKiAzLjApICogMC4wNTQwNTQ7CiAgcyArPSB0ZXh0dXJlU2FtcGxlKHRleCwgdGV4U2FtcGxlciwgaW4udXYgLSB1LmRpciAqIDMuMCkgKiAwLjA1NDA1NDsKICBzICs9IHRleHR1cmVTYW1wbGUodGV4LCB0ZXhTYW1wbGVyLCBpbi51diArIHUuZGlyICogNC4wKSAqIDAuMDE2MjE2OwogIHMgKz0gdGV4dHVyZVNhbXBsZSh0ZXgsIHRleFNhbXBsZXIsIGluLnV2IC0gdS5kaXIgKiA0LjApICogMC4wMTYyMTY7CiAgcmV0dXJuIHM7Cn0KYCwKICAgIFcgPSBgLy8gR2xhc3Mgc2hhZGVyIC0gdGhlIGNvcmUgbGlxdWlkIGdsYXNzIGVmZmVjdAoKc3RydWN0IEdsYXNzVW5pZm9ybXMgewogIGNlbnRlcjogdmVjMmYsCiAgc2l6ZTogdmVjMmYsCiAgcmVzOiB2ZWMyZiwKICByYWRpdXM6IGYzMiwKICBwYWQ6IGYzMiwKICByZWZyYWN0OiBmMzIsCiAgY2hyb21hOiBmMzIsCiAgZWRnZUhMOiBmMzIsCiAgc3BlYzogZjMyLAogIGZyZXNuZWw6IGYzMiwKICBkaXN0b3J0OiBmMzIsCiAgYWxwaGE6IGYzMiwKICBzYXQ6IGYzMiwKICB0aW50OiBmMzIsCiAgelJhZGl1czogZjMyLAogIGJyaWdodG5lc3M6IGYzMiwKICBzaGFkb3dBbHBoYTogZjMyLAogIHNoYWRvd1NwcmVhZDogZjMyLAogIHNoYWRvd09mZlk6IGYzMiwKICBiZXZlbE1vZGU6IGYzMiwKICBfcGFkOiB2ZWMyZiwKfQoKQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1OiBHbGFzc1VuaWZvcm1zOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyIHRleFNhbXBsZXI6IHNhbXBsZXI7CkBncm91cCgwKSBAYmluZGluZygyKSB2YXIgYmdUZXg6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDMpIHZhciBibHVyVGV4OiB0ZXh0dXJlXzJkPGYzMj47CgpzdHJ1Y3QgVmVydGV4T3V0cHV0IHsKICBAYnVpbHRpbihwb3NpdGlvbikgcG9zaXRpb246IHZlYzRmLAogIEBsb2NhdGlvbigwKSBsb2NhbFB4OiB2ZWMyZiwKICBAbG9jYXRpb24oMSkgc2NyZWVuVVY6IHZlYzJmLAp9CgpAdmVydGV4CmZuIHZlcnRleE1haW4oQGxvY2F0aW9uKDApIHBvczogdmVjMmYpIC0+IFZlcnRleE91dHB1dCB7CiAgdmFyIG91dDogVmVydGV4T3V0cHV0OwogIGxldCB0b3RhbCA9IHUuc2l6ZSArIHZlYzJmKHUucGFkICogMi4wKTsKICBvdXQubG9jYWxQeCA9IHBvcyAqIHRvdGFsOwogIGxldCBweCA9IHUuY2VudGVyICsgcG9zICogdG90YWw7CiAgb3V0LnNjcmVlblVWID0gdmVjMmYocHgueCAvIHUucmVzLngsIDEuMCAtIHB4LnkgLyB1LnJlcy55KTsKICB2YXIgbmRjID0gKHB4IC8gdS5yZXMpICogMi4wIC0gMS4wOwogIG5kYy55ID0gLW5kYy55OwogIG91dC5wb3NpdGlvbiA9IHZlYzRmKG5kYywgMC4wLCAxLjApOwogIHJldHVybiBvdXQ7Cn0KCi8vIFJvdW5kZWQtcmVjdCBzaWduZWQgZGlzdGFuY2UKZm4gcnJTREYocDogdmVjMmYsIGI6IHZlYzJmLCByOiBmMzIpIC0+IGYzMiB7CiAgbGV0IHEgPSBhYnMocCkgLSBiICsgdmVjMmYocik7CiAgcmV0dXJuIG1pbihtYXgocS54LCBxLnkpLCAwLjApICsgbGVuZ3RoKG1heChxLCB2ZWMyZigwLjApKSkgLSByOwp9CgovLyBCZXZlbCBoZWlnaHQgZmllbGQKZm4gYmV2ZWxIZWlnaHQoZDogZjMyLCB6UjogZjMyKSAtPiBmMzIgewogIGlmIChkIDw9IDAuMCkgeyByZXR1cm4gMC4wOyB9CiAgaWYgKGQgPj0gelIpIHsgcmV0dXJuIHpSOyB9CiAgcmV0dXJuIHNxcnQoZCAqICgyLjAgKiB6UiAtIGQpKTsKfQoKZm4gaGFzaChwOiB2ZWMyZikgLT4gZjMyIHsKICByZXR1cm4gZnJhY3Qoc2luKGRvdChwLCB2ZWMyZigxMjcuMSwgMzExLjcpKSkgKiA0Mzc1OC41NDUzKTsKfQoKQGZyYWdtZW50CmZuIGZyYWdtZW50TWFpbihpbjogVmVydGV4T3V0cHV0KSAtPiBAbG9jYXRpb24oMCkgdmVjNGYgewogIGxldCBoYWxmXyA9IHUuc2l6ZSAqIDAuNTsKICBsZXQgciA9IG1pbih1LnJhZGl1cywgbWluKGhhbGZfLngsIGhhbGZfLnkpKTsKICBsZXQgc2RmID0gcnJTREYoaW4ubG9jYWxQeCwgaGFsZl8sIHIpOwoKICAvLyBBbnRpLWFsaWFzZWQgbWFzawogIGxldCBtYXNrID0gMS4wIC0gc21vb3Roc3RlcCgtMS41LCAwLjUsIHNkZik7CgogIGxldCBtYXhEID0gbWluKGhhbGZfLngsIGhhbGZfLnkpOwogIGxldCBpbnNpZGUgPSAtc2RmOwogIGxldCBlZGdlID0gc21vb3Roc3RlcChtYXhEICogMC4zNSwgMC4wLCBpbnNpZGUpOwoKICAvLyBTdXJmYWNlIG5vcm1hbCB2aWEgYmV2ZWwgaGVpZ2h0IGZpZWxkCiAgbGV0IHpSID0gdS56UmFkaXVzOwogIGxldCBlID0gMi4wOwogIGxldCBkQyA9IGluc2lkZTsKICBsZXQgZFIgPSAtcnJTREYoaW4ubG9jYWxQeCArIHZlYzJmKGUsIDAuMCksIGhhbGZfLCByKTsKICBsZXQgZEwgPSAtcnJTREYoaW4ubG9jYWxQeCAtIHZlYzJmKGUsIDAuMCksIGhhbGZfLCByKTsKICBsZXQgZFUgPSAtcnJTREYoaW4ubG9jYWxQeCArIHZlYzJmKDAuMCwgZSksIGhhbGZfLCByKTsKICBsZXQgZEQgPSAtcnJTREYoaW4ubG9jYWxQeCAtIHZlYzJmKDAuMCwgZSksIGhhbGZfLCByKTsKICBsZXQgaEMgPSBiZXZlbEhlaWdodChkQywgelIpOwogIGxldCBoUiA9IGJldmVsSGVpZ2h0KGRSLCB6Uik7CiAgbGV0IGhMID0gYmV2ZWxIZWlnaHQoZEwsIHpSKTsKICBsZXQgaFUgPSBiZXZlbEhlaWdodChkVSwgelIpOwogIGxldCBoRCA9IGJldmVsSGVpZ2h0KGRELCB6Uik7CiAgbGV0IGhHcmFkID0gdmVjMmYoaFIgLSBoTCwgaFUgLSBoRCkgLyAoMi4wICogZSk7CiAgbGV0IE4gPSBub3JtYWxpemUodmVjM2YoLWhHcmFkLCAxLjApKTsKCiAgbGV0IGRlcHRoID0gc21vb3Roc3RlcCgwLjAsIHpSLCBpbnNpZGUpOwoKICAvLyBSZWZyYWN0aW9uIC0gY29tcHV0ZSBib3RoIG1vZGVzIGFuZCBzZWxlY3QKICBsZXQgcHhUb1VWID0gdmVjMmYoMS4wLCAtMS4wKSAvIHUucmVzOwogIGxldCBpb3IgPSAxLjU7CiAgbGV0IHJlZnJQb3cgPSAxLjAgLSAxLjAgLyBpb3I7CiAgbGV0IHRoaWNrbmVzcyA9IGhDICogMi4wOwogIGxldCB0aGlja05vcm0gPSB0aGlja25lc3MgLyBtYXgoelIgKiAyLjAsIDEuMCk7CgogIC8vIEJpY29udmV4IG1vZGUKICBsZXQgZXhpdFJlZnIgPSBoR3JhZCAqIHJlZnJQb3c7CiAgbGV0IGVudHJ5UmVmciA9IGhHcmFkICogcmVmclBvdzsKICBsZXQgdGhyb3VnaFJlZnIgPSBlbnRyeVJlZnIgKiB0aGlja05vcm0gKiAwLjU7CiAgdmFyIHJlZnJQeEJpY29udmV4ID0gKGV4aXRSZWZyICsgZW50cnlSZWZyICsgdGhyb3VnaFJlZnIpICogdS5yZWZyYWN0ICogMzAuMDsKICBsZXQgY2VudGVyRGlyID0gLWluLmxvY2FsUHggLyBtYXgoaGFsZl8sIHZlYzJmKDEuMCkpOwogIHJlZnJQeEJpY29udmV4ICs9IGNlbnRlckRpciAqIHUucmVmcmFjdCAqIDQuMCAqIGRlcHRoOwoKICAvLyBEb21lIG1vZGUKICBsZXQgcmVmclB4RG9tZSA9IC1pbi5sb2NhbFB4ICogdS5yZWZyYWN0ICogZGVwdGggKiAwLjM1OwoKICAvLyBTZWxlY3QgYmFzZWQgb24gYmV2ZWwgbW9kZQogIGxldCByZWZyUHggPSBzZWxlY3QocmVmclB4Qmljb252ZXgsIHJlZnJQeERvbWUsIHUuYmV2ZWxNb2RlID49IDAuNSk7CiAgbGV0IHJlZnIgPSByZWZyUHggKiBweFRvVVY7CgogIC8vIE1pY3JvLWRpc3RvcnRpb24gbm9pc2UKICBsZXQgbnMgPSBpbi5sb2NhbFB4ICogMC4wODsKICBsZXQgYWJzUHhUb1VWID0gdmVjMmYoMS4wKSAvIHUucmVzOwogIGxldCBtaWNybyA9ICh2ZWMyZihoYXNoKG5zKSwgaGFzaChucyArIHZlYzJmKDM3LjApKSkgLSAwLjUpICogdS5kaXN0b3J0ICogNC4wICogYWJzUHhUb1VWOwoKICAvLyBDaHJvbWF0aWMgYWJlcnJhdGlvbgogIGxldCBjYVMgPSB1LmNocm9tYSAqIDE4LjAgKiAoZWRnZSAqIDAuNyArIDAuMykgKiAyLjA7CiAgbGV0IGNhRCA9IE4ueHkgKiBjYVMgKiBweFRvVVY7CiAgbGV0IGJhc2UgPSBpbi5zY3JlZW5VViArIHJlZnIgKyBtaWNybzsKCiAgLy8gU2FtcGxlIHRleHR1cmVzIChtdXN0IGJlIGluIHVuaWZvcm0gY29udHJvbCBmbG93KQogIGxldCBzaGFycFIgPSB0ZXh0dXJlU2FtcGxlKGJnVGV4LCB0ZXhTYW1wbGVyLCBiYXNlICsgY2FEKS5yOwogIGxldCBzaGFycEcgPSB0ZXh0dXJlU2FtcGxlKGJnVGV4LCB0ZXhTYW1wbGVyLCBiYXNlKS5nOwogIGxldCBzaGFycEIgPSB0ZXh0dXJlU2FtcGxlKGJnVGV4LCB0ZXhTYW1wbGVyLCBiYXNlIC0gY2FEKS5iOwogIGxldCBzaGFycCA9IHZlYzNmKHNoYXJwUiwgc2hhcnBHLCBzaGFycEIpOwoKICBsZXQgYmx1clIgPSB0ZXh0dXJlU2FtcGxlKGJsdXJUZXgsIHRleFNhbXBsZXIsIGJhc2UgKyBjYUQpLnI7CiAgbGV0IGJsdXJHID0gdGV4dHVyZVNhbXBsZShibHVyVGV4LCB0ZXhTYW1wbGVyLCBiYXNlKS5nOwogIGxldCBibHVyQiA9IHRleHR1cmVTYW1wbGUoYmx1clRleCwgdGV4U2FtcGxlciwgYmFzZSAtIGNhRCkuYjsKICBsZXQgYmx1ciA9IHZlYzNmKGJsdXJSLCBibHVyRywgYmx1ckIpOwoKICAvLyBFZGdlLXdlaWdodGVkIGJsdXIgbWl4CiAgbGV0IGVkZ2VNaXggPSAxLjAgLSBlZGdlICogMC4xNTsKICB2YXIgY29sID0gbWl4KHNoYXJwLCBibHVyLCBlZGdlTWl4KTsKCiAgLy8gQnJpZ2h0bmVzcwogIGNvbCAqPSAxLjAgKyB1LmJyaWdodG5lc3M7CgogIC8vIFNhdHVyYXRpb24KICBsZXQgbHVtID0gZG90KGNvbCwgdmVjM2YoMC4yOTksIDAuNTg3LCAwLjExNCkpOwogIGNvbCA9IG1peCh2ZWMzZihsdW0pLCBjb2wsIDEuMCArIHUuc2F0KTsKCiAgLy8gQ29vbCBnbGFzcyB0aW50CiAgY29sID0gbWl4KGNvbCwgY29sICogdmVjM2YoMC45MiwgMC45NSwgMS4wNSksIHUudGludCk7CiAgY29sICo9IDEuMCArIDAuMDYgKiBkZXB0aDsKCiAgLy8gRnJlc25lbAogIGxldCBmcmVzID0gcG93KDEuMCAtIGFicyhOLnopLCA0LjApICogdS5mcmVzbmVsOwoKICAvLyBTcGVjdWxhciBoaWdobGlnaHRzIChtdWx0aS1saWdodCBCbGlubi1QaG9uZykKICBsZXQgViA9IHZlYzNmKDAuMCwgMC4wLCAxLjApOwogIGxldCBMMSA9IG5vcm1hbGl6ZSh2ZWMzZigwLjQsIDAuNywgMS4wKSk7CiAgbGV0IEgxID0gbm9ybWFsaXplKEwxICsgVik7CiAgbGV0IHNwMSA9IHBvdyhtYXgoZG90KE4sIEgxKSwgMC4wKSwgOTAuMCk7CiAgbGV0IEwyID0gbm9ybWFsaXplKHZlYzNmKC0wLjMsIC0wLjUsIDEuMCkpOwogIGxldCBIMiA9IG5vcm1hbGl6ZShMMiArIFYpOwogIGxldCBzcDIgPSBwb3cobWF4KGRvdChOLCBIMiksIDAuMCksIDUwLjApICogMC4zOwogIGxldCBMMyA9IG5vcm1hbGl6ZSh2ZWMzZigwLjEsIDAuMywgMS4wKSk7CiAgbGV0IHNwQiA9IHBvdyhtYXgoZG90KE4sIEwzKSwgMC4wKSwgNi4wKSAqIDAuMTsKICBsZXQgTDQgPSBub3JtYWxpemUodmVjM2YoMC4wLCAwLjksIDAuNCkpOwogIGxldCBINCA9IG5vcm1hbGl6ZShMNCArIFYpOwogIGxldCBzcDQgPSBwb3cobWF4KGRvdChOLCBINCksIDAuMCksIDEyMC4wKSAqIDAuNjsKICBsZXQgdG90YWxTcGVjID0gKHNwMSArIHNwMiArIHNwQiArIHNwNCkgKiB1LnNwZWM7CgogIC8vIElubmVyIGJvcmRlciAvIHN0cm9rZSBoaWdobGlnaHQKICBsZXQgYm9yZGVyV2lkdGggPSAxLjU7CiAgbGV0IGlubmVyU3Ryb2tlID0gc21vb3Roc3RlcCgtYm9yZGVyV2lkdGggLSAxLjAsIC1ib3JkZXJXaWR0aCwgc2RmKQogICAgICAgICAgICAgICAgICAqICgxLjAgLSBzbW9vdGhzdGVwKC0xLjAsIDAuMCwgc2RmKSk7CiAgbGV0IHRvcEJpYXMgPSAwLjUgKyAwLjUgKiAoLWluLmxvY2FsUHgueSAvIGhhbGZfLnkpOwogIGxldCBpbm5lclN0cm9rZUZpbmFsID0gaW5uZXJTdHJva2UgKiAoMC40ICsgMC42ICogdG9wQmlhcyk7CgogIC8vIEVkZ2UgaGlnaGxpZ2h0ICYgaW5uZXIgZ2xvdwogIGxldCByaW0gPSBlZGdlICogdS5lZGdlSEwgKiAwLjIyOwogIGxldCBpbm5lckdsb3cgPSBzbW9vdGhzdGVwKDUuMCwgMC4wLCAtc2RmKSAqIHUuZWRnZUhMICogMC4xNTsKCiAgLy8gRW52aXJvbm1lbnQtbGlrZSByZWZsZWN0aW9uIChmYWtlKQogIGxldCBlbnZSZWZsID0gKE4ueSAqIDAuNSArIDAuNSkgKiBmcmVzICogMC4wODsKCiAgLy8gQ29tcG9zaXRlIGdsYXNzIGVmZmVjdAogIHZhciBmaW4gPSBjb2w7CiAgZmluICs9IHZlYzNmKHRvdGFsU3BlYyk7CiAgZmluICs9IHZlYzNmKHJpbSArIGlubmVyR2xvdyk7CiAgZmluICs9IHZlYzNmKGlubmVyU3Ryb2tlRmluYWwgKiB1LmVkZ2VITCAqIDAuNTUpOwogIGZpbiArPSB2ZWMzZihlbnZSZWZsKTsKICBmaW4gPSBtaXgoZmluLCB2ZWMzZigxLjApLCBmcmVzICogMC4yKTsKCiAgLy8gU2hhZG93IGNhbGN1bGF0aW9uIChvdXRzaWRlIHBhbmVsKQogIGxldCBzZGZTaGFkb3cgPSByclNERihpbi5sb2NhbFB4IC0gdmVjMmYoMC4wLCB1LnNoYWRvd09mZlkpLCBoYWxmXywgcik7CiAgbGV0IHNoYWRvd0QgPSBtYXgoc2RmU2hhZG93IC0gMS4wLCAwLjApOwogIGxldCBzcHJlYWQgPSBtYXgodS5zaGFkb3dTcHJlYWQsIDEuMCk7CiAgbGV0IGZhbGxvZmYgPSAxLjAgLyAoc3ByZWFkICogc3ByZWFkKTsKICBsZXQgb3V0ZXJTaGFkb3cgPSBleHAoLXNoYWRvd0QgKiBzaGFkb3dEICogZmFsbG9mZikgKiAwLjY1OwogIGxldCBjb250YWN0U2hhZG93ID0gZXhwKC1zaGFkb3dEICogMC4wOCAvIG1heChzcHJlYWQgKiAwLjA0LCAwLjAxKSkgKiAwLjM1OwogIGxldCBzaGFkb3cgPSAob3V0ZXJTaGFkb3cgKyBjb250YWN0U2hhZG93KSAqIHUuc2hhZG93QWxwaGE7CgogIC8vIFNlbGVjdCBiZXR3ZWVuIHNoYWRvdyAob3V0c2lkZSkgYW5kIGdsYXNzIChpbnNpZGUpCiAgbGV0IGlzT3V0c2lkZSA9IHNkZiA+IDAuMDsKICBsZXQgZmluYWxDb2xvciA9IHNlbGVjdChmaW4sIHZlYzNmKDAuMCksIGlzT3V0c2lkZSk7CiAgbGV0IGZpbmFsQWxwaGEgPSBzZWxlY3QobWFzayAqIHUuYWxwaGEsIHNoYWRvdywgaXNPdXRzaWRlKTsKCiAgcmV0dXJuIHZlYzRmKGZpbmFsQ29sb3IsIGZpbmFsQWxwaGEpOwp9CmAsCiAgICB5ID0gY2xhc3MgewogICAgICBjYW52YXM7CiAgICAgIGRldmljZSA9IG51bGw7CiAgICAgIGNvbnRleHQgPSBudWxsOwogICAgICBmb3JtYXQgPSAiYmdyYTh1bm9ybSI7CiAgICAgIGJsaXRQaXBlbGluZSA9IG51bGw7CiAgICAgIGJsdXJQaXBlbGluZSA9IG51bGw7CiAgICAgIGdsYXNzUGlwZWxpbmUgPSBudWxsOwogICAgICBxdWFkQnVmZmVyID0gbnVsbDsKICAgICAgcGFuZWxCdWZmZXIgPSBudWxsOwogICAgICBibGl0VW5pZm9ybUJ1ZmZlciA9IG51bGw7CiAgICAgIGJsdXJVbmlmb3JtQnVmZmVyID0gbnVsbDsKICAgICAgZ2xhc3NVbmlmb3JtQnVmZmVyID0gbnVsbDsKICAgICAgc2FtcGxlciA9IG51bGw7CiAgICAgIHRhcmdldENhY2hlID0gbmV3IE1hcCgpOwogICAgICBhY3RpdmVUYXJnZXRzID0gbnVsbDsKICAgICAgYmdUZXh0dXJlID0gbnVsbDsKICAgICAgYmdUZXh0dXJlVmlldyA9IG51bGw7CiAgICAgIHdpZHRoID0gMDsKICAgICAgaGVpZ2h0ID0gMDsKICAgICAgX2luaXRQcm9taXNlID0gbnVsbDsKICAgICAgX2luaXRpYWxpemVkID0gITE7CiAgICAgIGNvbnN0cnVjdG9yKCkgewogICAgICAgICgodGhpcy5jYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJjYW52YXMiKSksCiAgICAgICAgICAodGhpcy5jYW52YXMuc3R5bGUuZGlzcGxheSA9ICJub25lIiksCiAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMuY2FudmFzKSk7CiAgICAgIH0KICAgICAgYXN5bmMgaW5pdCgpIHsKICAgICAgICByZXR1cm4gdGhpcy5faW5pdFByb21pc2UKICAgICAgICAgID8gdGhpcy5faW5pdFByb21pc2UKICAgICAgICAgIDogKCh0aGlzLl9pbml0UHJvbWlzZSA9IHRoaXMuX2RvSW5pdCgpKSwgdGhpcy5faW5pdFByb21pc2UpOwogICAgICB9CiAgICAgIGFzeW5jIF9kb0luaXQoKSB7CiAgICAgICAgaWYgKCFuYXZpZ2F0b3IuZ3B1KSByZXR1cm4gKGNvbnNvbGUud2FybigiV2ViR1BVIG5vdCBzdXBwb3J0ZWQiKSwgITEpOwogICAgICAgIGxldCBlID0gYXdhaXQgbmF2aWdhdG9yLmdwdS5yZXF1ZXN0QWRhcHRlcigpOwogICAgICAgIHJldHVybiBlCiAgICAgICAgICA/ICgodGhpcy5kZXZpY2UgPSBhd2FpdCBlLnJlcXVlc3REZXZpY2UoKSksCiAgICAgICAgICAgIHRoaXMuZGV2aWNlCiAgICAgICAgICAgICAgPyAoKHRoaXMuY29udGV4dCA9IHRoaXMuY2FudmFzLmdldENvbnRleHQoIndlYmdwdSIpKSwKICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dAogICAgICAgICAgICAgICAgICA/ICgodGhpcy5mb3JtYXQgPSBuYXZpZ2F0b3IuZ3B1LmdldFByZWZlcnJlZENhbnZhc0Zvcm1hdCgpKSwKICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQuY29uZmlndXJlKHsKICAgICAgICAgICAgICAgICAgICAgIGRldmljZTogdGhpcy5kZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQ6IHRoaXMuZm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgYWxwaGFNb2RlOiAicHJlbXVsdGlwbGllZCIsCiAgICAgICAgICAgICAgICAgICAgfSksCiAgICAgICAgICAgICAgICAgICAgdGhpcy5faW5pdFBpcGVsaW5lcygpLAogICAgICAgICAgICAgICAgICAgIHRoaXMuX2luaXRCdWZmZXJzKCksCiAgICAgICAgICAgICAgICAgICAgKHRoaXMuX2luaXRpYWxpemVkID0gITApLAogICAgICAgICAgICAgICAgICAgICEwKQogICAgICAgICAgICAgICAgICA6IChjb25zb2xlLndhcm4oIkZhaWxlZCB0byBnZXQgV2ViR1BVIGNvbnRleHQiKSwgITEpKQogICAgICAgICAgICAgIDogKGNvbnNvbGUud2FybigiRmFpbGVkIHRvIGdldCBXZWJHUFUgZGV2aWNlIiksICExKSkKICAgICAgICAgIDogKGNvbnNvbGUud2FybigiTm8gV2ViR1BVIGFkYXB0ZXIgZm91bmQiKSwgITEpOwogICAgICB9CiAgICAgIGdldCBpbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdGhpcy5faW5pdGlhbGl6ZWQ7CiAgICAgIH0KICAgICAgX2luaXRQaXBlbGluZXMoKSB7CiAgICAgICAgbGV0IGUgPSB0aGlzLmRldmljZTsKICAgICAgICB0aGlzLnNhbXBsZXIgPSBlLmNyZWF0ZVNhbXBsZXIoewogICAgICAgICAgbWFnRmlsdGVyOiAibGluZWFyIiwKICAgICAgICAgIG1pbkZpbHRlcjogImxpbmVhciIsCiAgICAgICAgICBhZGRyZXNzTW9kZVU6ICJjbGFtcC10by1lZGdlIiwKICAgICAgICAgIGFkZHJlc3NNb2RlVjogImNsYW1wLXRvLWVkZ2UiLAogICAgICAgIH0pOwogICAgICAgIGxldCB0ID0gZS5jcmVhdGVTaGFkZXJNb2R1bGUoeyBjb2RlOiBxIH0pLAogICAgICAgICAgciA9IGUuY3JlYXRlQmluZEdyb3VwTGF5b3V0KHsKICAgICAgICAgICAgZW50cmllczogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGJpbmRpbmc6IDAsCiAgICAgICAgICAgICAgICB2aXNpYmlsaXR5OiBHUFVTaGFkZXJTdGFnZS5WRVJURVggfCBHUFVTaGFkZXJTdGFnZS5GUkFHTUVOVCwKICAgICAgICAgICAgICAgIGJ1ZmZlcjogeyB0eXBlOiAidW5pZm9ybSIgfSwKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsgYmluZGluZzogMSwgdmlzaWJpbGl0eTogR1BVU2hhZGVyU3RhZ2UuRlJBR01FTlQsIHNhbXBsZXI6IHsgdHlwZTogImZpbHRlcmluZyIgfSB9LAogICAgICAgICAgICAgIHsgYmluZGluZzogMiwgdmlzaWJpbGl0eTogR1BVU2hhZGVyU3RhZ2UuRlJBR01FTlQsIHRleHR1cmU6IHsgc2FtcGxlVHlwZTogImZsb2F0IiB9IH0sCiAgICAgICAgICAgIF0sCiAgICAgICAgICB9KTsKICAgICAgICB0aGlzLmJsaXRQaXBlbGluZSA9IGUuY3JlYXRlUmVuZGVyUGlwZWxpbmUoewogICAgICAgICAgbGF5b3V0OiBlLmNyZWF0ZVBpcGVsaW5lTGF5b3V0KHsgYmluZEdyb3VwTGF5b3V0czogW3JdIH0pLAogICAgICAgICAgdmVydGV4OiB7CiAgICAgICAgICAgIG1vZHVsZTogdCwKICAgICAgICAgICAgZW50cnlQb2ludDogInZlcnRleE1haW4iLAogICAgICAgICAgICBidWZmZXJzOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYXJyYXlTdHJpZGU6IDgsCiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiBbeyBzaGFkZXJMb2NhdGlvbjogMCwgb2Zmc2V0OiAwLCBmb3JtYXQ6ICJmbG9hdDMyeDIiIH1dLAogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF0sCiAgICAgICAgICB9LAogICAgICAgICAgZnJhZ21lbnQ6IHsgbW9kdWxlOiB0LCBlbnRyeVBvaW50OiAiZnJhZ21lbnRNYWluIiwgdGFyZ2V0czogW3sgZm9ybWF0OiAicmdiYTh1bm9ybSIgfV0gfSwKICAgICAgICAgIHByaW1pdGl2ZTogeyB0b3BvbG9neTogInRyaWFuZ2xlLXN0cmlwIiB9LAogICAgICAgIH0pOwogICAgICAgIGxldCBuID0gZS5jcmVhdGVTaGFkZXJNb2R1bGUoeyBjb2RlOiBrIH0pLAogICAgICAgICAgaSA9IGUuY3JlYXRlQmluZEdyb3VwTGF5b3V0KHsKICAgICAgICAgICAgZW50cmllczogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGJpbmRpbmc6IDAsCiAgICAgICAgICAgICAgICB2aXNpYmlsaXR5OiBHUFVTaGFkZXJTdGFnZS5WRVJURVggfCBHUFVTaGFkZXJTdGFnZS5GUkFHTUVOVCwKICAgICAgICAgICAgICAgIGJ1ZmZlcjogeyB0eXBlOiAidW5pZm9ybSIgfSwKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsgYmluZGluZzogMSwgdmlzaWJpbGl0eTogR1BVU2hhZGVyU3RhZ2UuRlJBR01FTlQsIHNhbXBsZXI6IHsgdHlwZTogImZpbHRlcmluZyIgfSB9LAogICAgICAgICAgICAgIHsgYmluZGluZzogMiwgdmlzaWJpbGl0eTogR1BVU2hhZGVyU3RhZ2UuRlJBR01FTlQsIHRleHR1cmU6IHsgc2FtcGxlVHlwZTogImZsb2F0IiB9IH0sCiAgICAgICAgICAgIF0sCiAgICAgICAgICB9KTsKICAgICAgICB0aGlzLmJsdXJQaXBlbGluZSA9IGUuY3JlYXRlUmVuZGVyUGlwZWxpbmUoewogICAgICAgICAgbGF5b3V0OiBlLmNyZWF0ZVBpcGVsaW5lTGF5b3V0KHsgYmluZEdyb3VwTGF5b3V0czogW2ldIH0pLAogICAgICAgICAgdmVydGV4OiB7CiAgICAgICAgICAgIG1vZHVsZTogbiwKICAgICAgICAgICAgZW50cnlQb2ludDogInZlcnRleE1haW4iLAogICAgICAgICAgICBidWZmZXJzOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYXJyYXlTdHJpZGU6IDgsCiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiBbeyBzaGFkZXJMb2NhdGlvbjogMCwgb2Zmc2V0OiAwLCBmb3JtYXQ6ICJmbG9hdDMyeDIiIH1dLAogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF0sCiAgICAgICAgICB9LAogICAgICAgICAgZnJhZ21lbnQ6IHsgbW9kdWxlOiBuLCBlbnRyeVBvaW50OiAiZnJhZ21lbnRNYWluIiwgdGFyZ2V0czogW3sgZm9ybWF0OiAicmdiYTh1bm9ybSIgfV0gfSwKICAgICAgICAgIHByaW1pdGl2ZTogeyB0b3BvbG9neTogInRyaWFuZ2xlLXN0cmlwIiB9LAogICAgICAgIH0pOwogICAgICAgIGxldCBzID0gZS5jcmVhdGVTaGFkZXJNb2R1bGUoeyBjb2RlOiBXIH0pLAogICAgICAgICAgbCA9IGUuY3JlYXRlQmluZEdyb3VwTGF5b3V0KHsKICAgICAgICAgICAgZW50cmllczogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGJpbmRpbmc6IDAsCiAgICAgICAgICAgICAgICB2aXNpYmlsaXR5OiBHUFVTaGFkZXJTdGFnZS5WRVJURVggfCBHUFVTaGFkZXJTdGFnZS5GUkFHTUVOVCwKICAgICAgICAgICAgICAgIGJ1ZmZlcjogeyB0eXBlOiAidW5pZm9ybSIgfSwKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsgYmluZGluZzogMSwgdmlzaWJpbGl0eTogR1BVU2hhZGVyU3RhZ2UuRlJBR01FTlQsIHNhbXBsZXI6IHsgdHlwZTogImZpbHRlcmluZyIgfSB9LAogICAgICAgICAgICAgIHsgYmluZGluZzogMiwgdmlzaWJpbGl0eTogR1BVU2hhZGVyU3RhZ2UuRlJBR01FTlQsIHRleHR1cmU6IHsgc2FtcGxlVHlwZTogImZsb2F0IiB9IH0sCiAgICAgICAgICAgICAgeyBiaW5kaW5nOiAzLCB2aXNpYmlsaXR5OiBHUFVTaGFkZXJTdGFnZS5GUkFHTUVOVCwgdGV4dHVyZTogeyBzYW1wbGVUeXBlOiAiZmxvYXQiIH0gfSwKICAgICAgICAgICAgXSwKICAgICAgICAgIH0pOwogICAgICAgIHRoaXMuZ2xhc3NQaXBlbGluZSA9IGUuY3JlYXRlUmVuZGVyUGlwZWxpbmUoewogICAgICAgICAgbGF5b3V0OiBlLmNyZWF0ZVBpcGVsaW5lTGF5b3V0KHsgYmluZEdyb3VwTGF5b3V0czogW2xdIH0pLAogICAgICAgICAgdmVydGV4OiB7CiAgICAgICAgICAgIG1vZHVsZTogcywKICAgICAgICAgICAgZW50cnlQb2ludDogInZlcnRleE1haW4iLAogICAgICAgICAgICBidWZmZXJzOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYXJyYXlTdHJpZGU6IDgsCiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiBbeyBzaGFkZXJMb2NhdGlvbjogMCwgb2Zmc2V0OiAwLCBmb3JtYXQ6ICJmbG9hdDMyeDIiIH1dLAogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF0sCiAgICAgICAgICB9LAogICAgICAgICAgZnJhZ21lbnQ6IHsKICAgICAgICAgICAgbW9kdWxlOiBzLAogICAgICAgICAgICBlbnRyeVBvaW50OiAiZnJhZ21lbnRNYWluIiwKICAgICAgICAgICAgdGFyZ2V0czogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvcm1hdDogdGhpcy5mb3JtYXQsCiAgICAgICAgICAgICAgICBibGVuZDogewogICAgICAgICAgICAgICAgICBjb2xvcjogewogICAgICAgICAgICAgICAgICAgIHNyY0ZhY3RvcjogInNyYy1hbHBoYSIsCiAgICAgICAgICAgICAgICAgICAgZHN0RmFjdG9yOiAib25lLW1pbnVzLXNyYy1hbHBoYSIsCiAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uOiAiYWRkIiwKICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgYWxwaGE6IHsgc3JjRmFjdG9yOiAib25lIiwgZHN0RmFjdG9yOiAib25lLW1pbnVzLXNyYy1hbHBoYSIsIG9wZXJhdGlvbjogImFkZCIgfSwKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgXSwKICAgICAgICAgIH0sCiAgICAgICAgICBwcmltaXRpdmU6IHsgdG9wb2xvZ3k6ICJ0cmlhbmdsZS1zdHJpcCIgfSwKICAgICAgICB9KTsKICAgICAgfQogICAgICBfaW5pdEJ1ZmZlcnMoKSB7CiAgICAgICAgbGV0IGUgPSB0aGlzLmRldmljZTsKICAgICAgICAoKHRoaXMucXVhZEJ1ZmZlciA9IGUuY3JlYXRlQnVmZmVyKHsKICAgICAgICAgIHNpemU6IDMyLAogICAgICAgICAgdXNhZ2U6IEdQVUJ1ZmZlclVzYWdlLlZFUlRFWCwKICAgICAgICAgIG1hcHBlZEF0Q3JlYXRpb246ICEwLAogICAgICAgIH0pKSwKICAgICAgICAgIG5ldyBGbG9hdDMyQXJyYXkodGhpcy5xdWFkQnVmZmVyLmdldE1hcHBlZFJhbmdlKCkpLnNldChbLTEsIC0xLCAxLCAtMSwgLTEsIDEsIDEsIDFdKSwKICAgICAgICAgIHRoaXMucXVhZEJ1ZmZlci51bm1hcCgpLAogICAgICAgICAgKHRoaXMucGFuZWxCdWZmZXIgPSBlLmNyZWF0ZUJ1ZmZlcih7CiAgICAgICAgICAgIHNpemU6IDMyLAogICAgICAgICAgICB1c2FnZTogR1BVQnVmZmVyVXNhZ2UuVkVSVEVYLAogICAgICAgICAgICBtYXBwZWRBdENyZWF0aW9uOiAhMCwKICAgICAgICAgIH0pKSwKICAgICAgICAgIG5ldyBGbG9hdDMyQXJyYXkodGhpcy5wYW5lbEJ1ZmZlci5nZXRNYXBwZWRSYW5nZSgpKS5zZXQoWwogICAgICAgICAgICAtMC41LCAtMC41LCAwLjUsIC0wLjUsIC0wLjUsIDAuNSwgMC41LCAwLjUsCiAgICAgICAgICBdKSwKICAgICAgICAgIHRoaXMucGFuZWxCdWZmZXIudW5tYXAoKSwKICAgICAgICAgICh0aGlzLmJsaXRVbmlmb3JtQnVmZmVyID0gZS5jcmVhdGVCdWZmZXIoewogICAgICAgICAgICBzaXplOiAxNiwKICAgICAgICAgICAgdXNhZ2U6IEdQVUJ1ZmZlclVzYWdlLlVOSUZPUk0gfCBHUFVCdWZmZXJVc2FnZS5DT1BZX0RTVCwKICAgICAgICAgIH0pKSwKICAgICAgICAgICh0aGlzLmJsdXJVbmlmb3JtQnVmZmVyID0gZS5jcmVhdGVCdWZmZXIoewogICAgICAgICAgICBzaXplOiAxNiwKICAgICAgICAgICAgdXNhZ2U6IEdQVUJ1ZmZlclVzYWdlLlVOSUZPUk0gfCBHUFVCdWZmZXJVc2FnZS5DT1BZX0RTVCwKICAgICAgICAgIH0pKSwKICAgICAgICAgICh0aGlzLmdsYXNzVW5pZm9ybUJ1ZmZlciA9IGUuY3JlYXRlQnVmZmVyKHsKICAgICAgICAgICAgc2l6ZTogMTEyLAogICAgICAgICAgICB1c2FnZTogR1BVQnVmZmVyVXNhZ2UuVU5JRk9STSB8IEdQVUJ1ZmZlclVzYWdlLkNPUFlfRFNULAogICAgICAgICAgfSkpKTsKICAgICAgfQogICAgICByZXNpemUoZSwgdCkgewogICAgICAgIGlmICghKHRoaXMud2lkdGggPT09IGUgJiYgdGhpcy5oZWlnaHQgPT09IHQpKSB7CiAgICAgICAgICAoKHRoaXMud2lkdGggPSBlKSwgKHRoaXMuaGVpZ2h0ID0gdCkpOwogICAgICAgICAgZm9yIChsZXQgciBvZiB0aGlzLnRhcmdldENhY2hlLnZhbHVlcygpKSB0aGlzLl9mcmVlVGFyZ2V0U2V0KHIpOwogICAgICAgICAgKHRoaXMudGFyZ2V0Q2FjaGUuY2xlYXIoKSwgKHRoaXMuYWN0aXZlVGFyZ2V0cyA9IG51bGwpKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgdXBsb2FkQW5kQmx1cihlLCB0LCByLCBuLCBpLCBzKSB7CiAgICAgICAgaWYgKCF0aGlzLl9pbml0aWFsaXplZCB8fCAhdGhpcy5kZXZpY2UgfHwgIXRoaXMuX3NldEFjdGl2ZVNpemUobiwgaSkpIHJldHVybjsKICAgICAgICBsZXQgbCA9IHRoaXMuZGV2aWNlLAogICAgICAgICAgYSA9IHRoaXMud2lkdGgsCiAgICAgICAgICB1ID0gdGhpcy5oZWlnaHQsCiAgICAgICAgICBvID0gdGhpcy5hY3RpdmVUYXJnZXRzLAogICAgICAgICAgZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImNhbnZhcyIpOwogICAgICAgICgoZC53aWR0aCA9IGEpLAogICAgICAgICAgKGQuaGVpZ2h0ID0gdSksCiAgICAgICAgICBkLmdldENvbnRleHQoIjJkIikuZHJhd0ltYWdlKGUsIC10LCAtciksCiAgICAgICAgICAoIXRoaXMuYmdUZXh0dXJlIHx8IHRoaXMuYmdUZXh0dXJlLndpZHRoICE9PSBhIHx8IHRoaXMuYmdUZXh0dXJlLmhlaWdodCAhPT0gdSkgJiYKICAgICAgICAgICAgKHRoaXMuYmdUZXh0dXJlICYmIHRoaXMuYmdUZXh0dXJlLmRlc3Ryb3koKSwKICAgICAgICAgICAgKHRoaXMuYmdUZXh0dXJlID0gbC5jcmVhdGVUZXh0dXJlKHsKICAgICAgICAgICAgICBzaXplOiBbYSwgdV0sCiAgICAgICAgICAgICAgZm9ybWF0OiAicmdiYTh1bm9ybSIsCiAgICAgICAgICAgICAgdXNhZ2U6CiAgICAgICAgICAgICAgICBHUFVUZXh0dXJlVXNhZ2UuVEVYVFVSRV9CSU5ESU5HIHwKICAgICAgICAgICAgICAgIEdQVVRleHR1cmVVc2FnZS5DT1BZX0RTVCB8CiAgICAgICAgICAgICAgICBHUFVUZXh0dXJlVXNhZ2UuUkVOREVSX0FUVEFDSE1FTlQsCiAgICAgICAgICAgIH0pKSwKICAgICAgICAgICAgKHRoaXMuYmdUZXh0dXJlVmlldyA9IHRoaXMuYmdUZXh0dXJlLmNyZWF0ZVZpZXcoKSkpLAogICAgICAgICAgbC5xdWV1ZS5jb3B5RXh0ZXJuYWxJbWFnZVRvVGV4dHVyZSgKICAgICAgICAgICAgeyBzb3VyY2U6IGQsIGZsaXBZOiAhMCB9LAogICAgICAgICAgICB7IHRleHR1cmU6IHRoaXMuYmdUZXh0dXJlIH0sCiAgICAgICAgICAgIFthLCB1XSwKICAgICAgICAgICkpOwogICAgICAgIGxldCBmID0gbC5jcmVhdGVDb21tYW5kRW5jb2RlcigpOwogICAgICAgIHRoaXMuX2JsaXRQYXNzKGYsIHRoaXMuYmdUZXh0dXJlVmlldywgby5iZy52aWV3LCBhLCB1LCAxLCAxLCAwLCAwKTsKICAgICAgICBsZXQgaCA9IG8uYmx1ckEudywKICAgICAgICAgIGIgPSBvLmJsdXJBLmg7CiAgICAgICAgaWYgKCh0aGlzLl9ibGl0UGFzcyhmLCBvLmJnLnZpZXcsIG8uYmx1ckEudmlldywgaCwgYiwgMSwgMSwgMCwgMCksIHMgPiAwKSkgewogICAgICAgICAgbGV0IGcgPSBzICogMi41OwogICAgICAgICAgZm9yIChsZXQgcCA9IDA7IHAgPCBMOyBwKyspCiAgICAgICAgICAgICh0aGlzLl9ibHVyUGFzcyhmLCBvLmJsdXJBLnZpZXcsIG8uYmx1ckIudmlldywgaCwgYiwgZyAvIGgsIDApLAogICAgICAgICAgICAgIHRoaXMuX2JsdXJQYXNzKGYsIG8uYmx1ckIudmlldywgby5ibHVyQS52aWV3LCBoLCBiLCAwLCBnIC8gYikpOwogICAgICAgIH0KICAgICAgICBsLnF1ZXVlLnN1Ym1pdChbZi5maW5pc2goKV0pOwogICAgICB9CiAgICAgIF9ibGl0UGFzcyhlLCB0LCByLCBuLCBpLCBzLCBsLCBhLCB1KSB7CiAgICAgICAgbGV0IG8gPSB0aGlzLmRldmljZTsKICAgICAgICBvLnF1ZXVlLndyaXRlQnVmZmVyKHRoaXMuYmxpdFVuaWZvcm1CdWZmZXIsIDAsIG5ldyBGbG9hdDMyQXJyYXkoW3MsIGwsIGEsIHVdKSk7CiAgICAgICAgbGV0IGQgPSBvLmNyZWF0ZUJpbmRHcm91cCh7CiAgICAgICAgICAgIGxheW91dDogdGhpcy5ibGl0UGlwZWxpbmUuZ2V0QmluZEdyb3VwTGF5b3V0KDApLAogICAgICAgICAgICBlbnRyaWVzOiBbCiAgICAgICAgICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHRoaXMuYmxpdFVuaWZvcm1CdWZmZXIgfSB9LAogICAgICAgICAgICAgIHsgYmluZGluZzogMSwgcmVzb3VyY2U6IHRoaXMuc2FtcGxlciB9LAogICAgICAgICAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQgfSwKICAgICAgICAgICAgXSwKICAgICAgICAgIH0pLAogICAgICAgICAgYyA9IGUuYmVnaW5SZW5kZXJQYXNzKHsKICAgICAgICAgICAgY29sb3JBdHRhY2htZW50czogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZpZXc6IHIsCiAgICAgICAgICAgICAgICBsb2FkT3A6ICJjbGVhciIsCiAgICAgICAgICAgICAgICBzdG9yZU9wOiAic3RvcmUiLAogICAgICAgICAgICAgICAgY2xlYXJWYWx1ZTogeyByOiAwLCBnOiAwLCBiOiAwLCBhOiAwIH0sCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgXSwKICAgICAgICAgIH0pOwogICAgICAgIChjLnNldFBpcGVsaW5lKHRoaXMuYmxpdFBpcGVsaW5lKSwKICAgICAgICAgIGMuc2V0QmluZEdyb3VwKDAsIGQpLAogICAgICAgICAgYy5zZXRWZXJ0ZXhCdWZmZXIoMCwgdGhpcy5xdWFkQnVmZmVyKSwKICAgICAgICAgIGMuc2V0Vmlld3BvcnQoMCwgMCwgbiwgaSwgMCwgMSksCiAgICAgICAgICBjLmRyYXcoNCksCiAgICAgICAgICBjLmVuZCgpKTsKICAgICAgfQogICAgICBfYmx1clBhc3MoZSwgdCwgciwgbiwgaSwgcywgbCkgewogICAgICAgIGxldCBhID0gdGhpcy5kZXZpY2U7CiAgICAgICAgYS5xdWV1ZS53cml0ZUJ1ZmZlcih0aGlzLmJsdXJVbmlmb3JtQnVmZmVyLCAwLCBuZXcgRmxvYXQzMkFycmF5KFtzLCBsLCAwLCAwXSkpOwogICAgICAgIGxldCB1ID0gYS5jcmVhdGVCaW5kR3JvdXAoewogICAgICAgICAgICBsYXlvdXQ6IHRoaXMuYmx1clBpcGVsaW5lLmdldEJpbmRHcm91cExheW91dCgwKSwKICAgICAgICAgICAgZW50cmllczogWwogICAgICAgICAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0aGlzLmJsdXJVbmlmb3JtQnVmZmVyIH0gfSwKICAgICAgICAgICAgICB7IGJpbmRpbmc6IDEsIHJlc291cmNlOiB0aGlzLnNhbXBsZXIgfSwKICAgICAgICAgICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0IH0sCiAgICAgICAgICAgIF0sCiAgICAgICAgICB9KSwKICAgICAgICAgIG8gPSBlLmJlZ2luUmVuZGVyUGFzcyh7CiAgICAgICAgICAgIGNvbG9yQXR0YWNobWVudHM6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2aWV3OiByLAogICAgICAgICAgICAgICAgbG9hZE9wOiAiY2xlYXIiLAogICAgICAgICAgICAgICAgc3RvcmVPcDogInN0b3JlIiwKICAgICAgICAgICAgICAgIGNsZWFyVmFsdWU6IHsgcjogMCwgZzogMCwgYjogMCwgYTogMCB9LAogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF0sCiAgICAgICAgICB9KTsKICAgICAgICAoby5zZXRQaXBlbGluZSh0aGlzLmJsdXJQaXBlbGluZSksCiAgICAgICAgICBvLnNldEJpbmRHcm91cCgwLCB1KSwKICAgICAgICAgIG8uc2V0VmVydGV4QnVmZmVyKDAsIHRoaXMucXVhZEJ1ZmZlciksCiAgICAgICAgICBvLnNldFZpZXdwb3J0KDAsIDAsIG4sIGksIDAsIDEpLAogICAgICAgICAgby5kcmF3KDQpLAogICAgICAgICAgby5lbmQoKSk7CiAgICAgIH0KICAgICAgcmVuZGVyR2xhc3NQYW5lbChlLCB0LCByLCBuKSB7CiAgICAgICAgaWYgKCF0aGlzLl9pbml0aWFsaXplZCB8fCAhdGhpcy5kZXZpY2UgfHwgIXRoaXMuY29udGV4dCkgcmV0dXJuOwogICAgICAgIGxldCBpID0gdGhpcy5kZXZpY2UsCiAgICAgICAgICBzID0gdGhpcy53aWR0aCwKICAgICAgICAgIGwgPSB0aGlzLmhlaWdodCwKICAgICAgICAgIGEgPSB0aGlzLmFjdGl2ZVRhcmdldHMsCiAgICAgICAgICB1ID0gbmV3IEZsb2F0MzJBcnJheShbCiAgICAgICAgICAgIHMgKiAwLjUsCiAgICAgICAgICAgIGwgKiAwLjUsCiAgICAgICAgICAgIHQgKiBuLAogICAgICAgICAgICByICogbiwKICAgICAgICAgICAgcywKICAgICAgICAgICAgbCwKICAgICAgICAgICAgZS5jb3JuZXJSYWRpdXMgKiBuLAogICAgICAgICAgICBUICogbiwKICAgICAgICAgICAgZS5yZWZyYWN0aW9uLAogICAgICAgICAgICBlLmNocm9tQWJlcnJhdGlvbiwKICAgICAgICAgICAgZS5lZGdlSGlnaGxpZ2h0LAogICAgICAgICAgICBlLnNwZWN1bGFyLAogICAgICAgICAgICBlLmZyZXNuZWwsCiAgICAgICAgICAgIGUuZGlzdG9ydGlvbiwKICAgICAgICAgICAgZS5vcGFjaXR5LAogICAgICAgICAgICBlLnNhdHVyYXRpb24sCiAgICAgICAgICAgIGUudGludFN0cmVuZ3RoLAogICAgICAgICAgICBlLnpSYWRpdXMgKiBuLAogICAgICAgICAgICBlLmJyaWdodG5lc3MsCiAgICAgICAgICAgIGUuc2hhZG93T3BhY2l0eSwKICAgICAgICAgICAgZS5zaGFkb3dTcHJlYWQgKiBuLAogICAgICAgICAgICBlLnNoYWRvd09mZnNldFkgKiBuLAogICAgICAgICAgICBlLmJldmVsTW9kZSwKICAgICAgICAgICAgMCwKICAgICAgICAgICAgMCwKICAgICAgICAgICAgMCwKICAgICAgICAgICAgMCwKICAgICAgICAgICAgMCwKICAgICAgICAgIF0pOwogICAgICAgIGkucXVldWUud3JpdGVCdWZmZXIodGhpcy5nbGFzc1VuaWZvcm1CdWZmZXIsIDAsIHUpOwogICAgICAgIGxldCBvID0gaS5jcmVhdGVCaW5kR3JvdXAoewogICAgICAgICAgICBsYXlvdXQ6IHRoaXMuZ2xhc3NQaXBlbGluZS5nZXRCaW5kR3JvdXBMYXlvdXQoMCksCiAgICAgICAgICAgIGVudHJpZXM6IFsKICAgICAgICAgICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdGhpcy5nbGFzc1VuaWZvcm1CdWZmZXIgfSB9LAogICAgICAgICAgICAgIHsgYmluZGluZzogMSwgcmVzb3VyY2U6IHRoaXMuc2FtcGxlciB9LAogICAgICAgICAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IGEuYmcudmlldyB9LAogICAgICAgICAgICAgIHsgYmluZGluZzogMywgcmVzb3VyY2U6IGEuYmx1ckEudmlldyB9LAogICAgICAgICAgICBdLAogICAgICAgICAgfSksCiAgICAgICAgICBkID0gaS5jcmVhdGVDb21tYW5kRW5jb2RlcigpLAogICAgICAgICAgYyA9IGQuYmVnaW5SZW5kZXJQYXNzKHsKICAgICAgICAgICAgY29sb3JBdHRhY2htZW50czogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZpZXc6IHRoaXMuY29udGV4dC5nZXRDdXJyZW50VGV4dHVyZSgpLmNyZWF0ZVZpZXcoKSwKICAgICAgICAgICAgICAgIGxvYWRPcDogImxvYWQiLAogICAgICAgICAgICAgICAgc3RvcmVPcDogInN0b3JlIiwKICAgICAgICAgICAgICB9LAogICAgICAgICAgICBdLAogICAgICAgICAgfSk7CiAgICAgICAgKGMuc2V0UGlwZWxpbmUodGhpcy5nbGFzc1BpcGVsaW5lKSwKICAgICAgICAgIGMuc2V0QmluZEdyb3VwKDAsIG8pLAogICAgICAgICAgYy5zZXRWZXJ0ZXhCdWZmZXIoMCwgdGhpcy5wYW5lbEJ1ZmZlciksCiAgICAgICAgICBjLnNldFZpZXdwb3J0KDAsIDAsIHMsIGwsIDAsIDEpLAogICAgICAgICAgYy5kcmF3KDQpLAogICAgICAgICAgYy5lbmQoKSwKICAgICAgICAgIGkucXVldWUuc3VibWl0KFtkLmZpbmlzaCgpXSkpOwogICAgICB9CiAgICAgIGNsZWFyKCkgewogICAgICAgIGlmICghdGhpcy5faW5pdGlhbGl6ZWQgfHwgIXRoaXMuZGV2aWNlIHx8ICF0aGlzLmNvbnRleHQpIHJldHVybjsKICAgICAgICBsZXQgZSA9IHRoaXMuZGV2aWNlLmNyZWF0ZUNvbW1hbmRFbmNvZGVyKCksCiAgICAgICAgICB0ID0gZS5iZWdpblJlbmRlclBhc3MoewogICAgICAgICAgICBjb2xvckF0dGFjaG1lbnRzOiBbCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmlldzogdGhpcy5jb250ZXh0LmdldEN1cnJlbnRUZXh0dXJlKCkuY3JlYXRlVmlldygpLAogICAgICAgICAgICAgICAgbG9hZE9wOiAiY2xlYXIiLAogICAgICAgICAgICAgICAgc3RvcmVPcDogInN0b3JlIiwKICAgICAgICAgICAgICAgIGNsZWFyVmFsdWU6IHsgcjogMCwgZzogMCwgYjogMCwgYTogMCB9LAogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF0sCiAgICAgICAgICB9KTsKICAgICAgICAodC5zZXRWaWV3cG9ydCgwLCAwLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCwgMCwgMSksCiAgICAgICAgICB0LmVuZCgpLAogICAgICAgICAgdGhpcy5kZXZpY2UucXVldWUuc3VibWl0KFtlLmZpbmlzaCgpXSkpOwogICAgICB9CiAgICAgIGRlc3Ryb3koKSB7CiAgICAgICAgZm9yIChsZXQgZSBvZiB0aGlzLnRhcmdldENhY2hlLnZhbHVlcygpKSB0aGlzLl9mcmVlVGFyZ2V0U2V0KGUpOwogICAgICAgICh0aGlzLnRhcmdldENhY2hlLmNsZWFyKCksCiAgICAgICAgICB0aGlzLmJnVGV4dHVyZSAmJiB0aGlzLmJnVGV4dHVyZS5kZXN0cm95KCksCiAgICAgICAgICB0aGlzLnF1YWRCdWZmZXIgJiYgdGhpcy5xdWFkQnVmZmVyLmRlc3Ryb3koKSwKICAgICAgICAgIHRoaXMucGFuZWxCdWZmZXIgJiYgdGhpcy5wYW5lbEJ1ZmZlci5kZXN0cm95KCksCiAgICAgICAgICB0aGlzLmJsaXRVbmlmb3JtQnVmZmVyICYmIHRoaXMuYmxpdFVuaWZvcm1CdWZmZXIuZGVzdHJveSgpLAogICAgICAgICAgdGhpcy5ibHVyVW5pZm9ybUJ1ZmZlciAmJiB0aGlzLmJsdXJVbmlmb3JtQnVmZmVyLmRlc3Ryb3koKSwKICAgICAgICAgIHRoaXMuZ2xhc3NVbmlmb3JtQnVmZmVyICYmIHRoaXMuZ2xhc3NVbmlmb3JtQnVmZmVyLmRlc3Ryb3koKSwKICAgICAgICAgIHRoaXMuZGV2aWNlPy5kZXN0cm95KCksCiAgICAgICAgICB0aGlzLmNhbnZhcy5yZW1vdmUoKSk7CiAgICAgIH0KICAgICAgX3NldEFjdGl2ZVNpemUoZSwgdCkgewogICAgICAgIGlmIChlIDw9IDAgfHwgdCA8PSAwKSByZXR1cm4gITE7CiAgICAgICAgKCh0aGlzLndpZHRoID0gZSksCiAgICAgICAgICAodGhpcy5oZWlnaHQgPSB0KSwKICAgICAgICAgICh0aGlzLmNhbnZhcy53aWR0aCA8IGUgfHwgdGhpcy5jYW52YXMuaGVpZ2h0IDwgdCkgJiYKICAgICAgICAgICAgKCh0aGlzLmNhbnZhcy53aWR0aCA9IE1hdGgubWF4KHRoaXMuY2FudmFzLndpZHRoLCBlKSksCiAgICAgICAgICAgICh0aGlzLmNhbnZhcy5oZWlnaHQgPSBNYXRoLm1heCh0aGlzLmNhbnZhcy5oZWlnaHQsIHQpKSwKICAgICAgICAgICAgdGhpcy5jb250ZXh0Py5jb25maWd1cmUoewogICAgICAgICAgICAgIGRldmljZTogdGhpcy5kZXZpY2UsCiAgICAgICAgICAgICAgZm9ybWF0OiB0aGlzLmZvcm1hdCwKICAgICAgICAgICAgICBhbHBoYU1vZGU6ICJwcmVtdWx0aXBsaWVkIiwKICAgICAgICAgICAgfSkpKTsKICAgICAgICBsZXQgciA9IGAke2V9eCR7dH1gLAogICAgICAgICAgbiA9IHRoaXMudGFyZ2V0Q2FjaGUuZ2V0KHIpOwogICAgICAgIHJldHVybiAoCiAgICAgICAgICBuIHx8CiAgICAgICAgICAgICgobiA9IHsKICAgICAgICAgICAgICBiZzogdGhpcy5fbWFrZVRhcmdldChlLCB0KSwKICAgICAgICAgICAgICBibHVyQTogdGhpcy5fbWFrZVRhcmdldChlLCB0KSwKICAgICAgICAgICAgICBibHVyQjogdGhpcy5fbWFrZVRhcmdldChlLCB0KSwKICAgICAgICAgICAgfSksCiAgICAgICAgICAgIHRoaXMudGFyZ2V0Q2FjaGUuc2V0KHIsIG4pKSwKICAgICAgICAgICh0aGlzLmFjdGl2ZVRhcmdldHMgPSBuKSwKICAgICAgICAgICEwCiAgICAgICAgKTsKICAgICAgfQogICAgICBfbWFrZVRhcmdldChlLCB0KSB7CiAgICAgICAgbGV0IHIgPSB0aGlzLmRldmljZS5jcmVhdGVUZXh0dXJlKHsKICAgICAgICAgIHNpemU6IFtlLCB0XSwKICAgICAgICAgIGZvcm1hdDogInJnYmE4dW5vcm0iLAogICAgICAgICAgdXNhZ2U6IEdQVVRleHR1cmVVc2FnZS5URVhUVVJFX0JJTkRJTkcgfCBHUFVUZXh0dXJlVXNhZ2UuUkVOREVSX0FUVEFDSE1FTlQsCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIHsgdGV4dHVyZTogciwgdmlldzogci5jcmVhdGVWaWV3KCksIHc6IGUsIGg6IHQgfTsKICAgICAgfQogICAgICBfZnJlZVRhcmdldChlKSB7CiAgICAgICAgZSAmJiBlLnRleHR1cmUuZGVzdHJveSgpOwogICAgICB9CiAgICAgIF9mcmVlVGFyZ2V0U2V0KGUpIHsKICAgICAgICAodGhpcy5fZnJlZVRhcmdldChlLmJnKSwgdGhpcy5fZnJlZVRhcmdldChlLmJsdXJBKSwgdGhpcy5fZnJlZVRhcmdldChlLmJsdXJCKSk7CiAgICAgIH0KICAgIH07CiAgdmFyIFIgPSBjbGFzcyB7CiAgICBjYW52YXM7CiAgICBjdHg7CiAgICByZW5kZXJlcjsKICAgIHNjZW5lQ2FudmFzOwogICAgc2NlbmVDdHg7CiAgICBkcmF3RWxlbWVudEltYWdlOwogICAgX2luaXRQcm9taXNlOwogICAgX2luaXRpYWxpemVkID0gITE7CiAgICBjb25zdHJ1Y3RvcihlKSB7CiAgICAgICgodGhpcy5jYW52YXMgPSBlKSwKICAgICAgICAodGhpcy5jdHggPSBlLmdldENvbnRleHQoIjJkIikpLAogICAgICAgICh0aGlzLnJlbmRlcmVyID0gbmV3IHkoKSksCiAgICAgICAgKHRoaXMuc2NlbmVDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJjYW52YXMiKSksCiAgICAgICAgKHRoaXMuc2NlbmVDdHggPSB0aGlzLnNjZW5lQ2FudmFzLmdldENvbnRleHQoIjJkIikpKTsKICAgICAgbGV0IHQgPSB0aGlzLmN0eDsKICAgICAgKCh0aGlzLmRyYXdFbGVtZW50SW1hZ2UgPSB0LmRyYXdFbGVtZW50SW1hZ2U/LmJpbmQodCkgPz8gdC5kcmF3RWxlbWVudD8uYmluZCh0KSA/PyBudWxsKSwKICAgICAgICAodGhpcy5faW5pdFByb21pc2UgPSB0aGlzLl9pbml0V2ViR1BVKCkpKTsKICAgIH0KICAgIGFzeW5jIF9pbml0V2ViR1BVKCkgewogICAgICB0cnkgewogICAgICAgIHJldHVybiAoYXdhaXQgdGhpcy5yZW5kZXJlci5pbml0KCkpCiAgICAgICAgICA/ICgodGhpcy5faW5pdGlhbGl6ZWQgPSAhMCksIGNvbnNvbGUubG9nKCJMaXF1aWRHbGFzczogV2ViR1BVIHJlbmRlcmVyIGluaXRpYWxpemVkIiksICEwKQogICAgICAgICAgOiAoY29uc29sZS5lcnJvcigiTGlxdWlkR2xhc3M6IFdlYkdQVSBub3QgYXZhaWxhYmxlIiksICExKTsKICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIHJldHVybiAoY29uc29sZS5lcnJvcigiTGlxdWlkR2xhc3M6IFdlYkdQVSBpbml0IGZhaWxlZCIsIGUpLCAhMSk7CiAgICAgIH0KICAgIH0KICAgIGdldCBpc1JlYWR5KCkgewogICAgICByZXR1cm4gdGhpcy5faW5pdGlhbGl6ZWQ7CiAgICB9CiAgICBhc3luYyB3YWl0Rm9ySW5pdCgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2luaXRQcm9taXNlOwogICAgfQogICAgcmVuZGVyKCkgewogICAgICBsZXQgZSA9IHRoaXMuY2FudmFzLndpZHRoLAogICAgICAgIHQgPSB0aGlzLmNhbnZhcy5oZWlnaHQ7CiAgICAgIGlmIChlID09PSAwIHx8IHQgPT09IDAgfHwgIXRoaXMuZHJhd0VsZW1lbnRJbWFnZSB8fCAhdGhpcy5faW5pdGlhbGl6ZWQpIHJldHVybjsKICAgICAgdGhpcy5jdHguY2xlYXJSZWN0KDAsIDAsIGUsIHQpOwogICAgICBsZXQgciA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIHx8IDEsCiAgICAgICAgbiA9IHRoaXMuY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLAogICAgICAgIGkgPSBBcnJheS5mcm9tKHRoaXMuY2FudmFzLmNoaWxkcmVuKSwKICAgICAgICBzID0gQXJyYXkuZnJvbSh0aGlzLmNhbnZhcy5xdWVyeVNlbGVjdG9yQWxsKCIubGlxdWlkLWdsYXNzIikpLAogICAgICAgIGwgPSBuZXcgU2V0KHMpOwogICAgICBpLmxlbmd0aCA9PT0gMCAmJgogICAgICAgICF0aGlzLl9fbGdfd2Fybl9lbXB0eSAmJgogICAgICAgIChjb25zb2xlLndhcm4oIkxpcXVpZEdsYXNzOiBObyBjaGlsZHJlbiBmb3VuZCBpbnNpZGUgdGhlIGNhbnZhcyB0byByZW5kZXIuIiksCiAgICAgICAgKHRoaXMuX19sZ193YXJuX2VtcHR5ID0gITApKTsKICAgICAgZm9yIChsZXQgYSBvZiBpKQogICAgICAgIGlmICghbC5oYXMoYSkpIHsKICAgICAgICAgIGxldCB1ID0gYSwKICAgICAgICAgICAgbyA9IHRoaXMuX2dldEVsZW1lbnRQb3NpdGlvbih1LCBuKTsKICAgICAgICAgIGlmIChvLncgPD0gMCB8fCBvLmggPD0gMCkgY29udGludWU7CiAgICAgICAgICBsZXQgZCA9IG8ueCAqIHIsCiAgICAgICAgICAgIGMgPSBvLnkgKiByOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgbGV0IGYgPSB0aGlzLmRyYXdFbGVtZW50SW1hZ2UoYSwgZCwgYyk7CiAgICAgICAgICAgIGYgJiYgKHUuc3R5bGUudHJhbnNmb3JtID0gZi50b1N0cmluZygpKTsKICAgICAgICAgIH0gY2F0Y2ggKGYpIHsKICAgICAgICAgICAgYS5fX2xnX2Vycm9yX2xvZ2dlZCB8fAogICAgICAgICAgICAgIChjb25zb2xlLndhcm4oCiAgICAgICAgICAgICAgICBgTGlxdWlkR2xhc3M6IEZhaWxlZCB0byBkcmF3IGJhY2tncm91bmQgZWxlbWVudCAke2EudGFnTmFtZX0uJHthLmNsYXNzTmFtZX06YCwKICAgICAgICAgICAgICAgIGYubWVzc2FnZSB8fCBmLAogICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgKGEuX19sZ19lcnJvcl9sb2dnZWQgPSAhMCkpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgZm9yIChsZXQgYSBvZiBzKQogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLl9yZW5kZXJHbGFzc0VsZW1lbnQoYSwgbiwgcik7CiAgICAgICAgfSBjYXRjaCAodSkgewogICAgICAgICAgYS5fX2xnX2Vycm9yX2xvZ2dlZF9nbGFzcyB8fAogICAgICAgICAgICAoY29uc29sZS5lcnJvcigKICAgICAgICAgICAgICBgTGlxdWlkR2xhc3M6IEZhaWxlZCB0byByZW5kZXIgZ2xhc3MgZWZmZWN0IGZvciAke2EudGFnTmFtZX0uJHthLmNsYXNzTmFtZX06YCwKICAgICAgICAgICAgICB1Lm1lc3NhZ2UgfHwgdSwKICAgICAgICAgICAgKSwKICAgICAgICAgICAgKGEuX19sZ19lcnJvcl9sb2dnZWRfZ2xhc3MgPSAhMCkpOwogICAgICAgIH0KICAgIH0KICAgIHJlbmRlckdsYXNzRWxlbWVudHMoKSB7CiAgICAgIGxldCBlID0gdGhpcy5jYW52YXMud2lkdGgsCiAgICAgICAgdCA9IHRoaXMuY2FudmFzLmhlaWdodDsKICAgICAgaWYgKGUgPT09IDAgfHwgdCA9PT0gMCB8fCAhdGhpcy5kcmF3RWxlbWVudEltYWdlIHx8ICF0aGlzLl9pbml0aWFsaXplZCkgcmV0dXJuOwogICAgICBsZXQgciA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIHx8IDEsCiAgICAgICAgbiA9IHRoaXMuY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLAogICAgICAgIGkgPSB0aGlzLmNhbnZhcy5xdWVyeVNlbGVjdG9yQWxsKCIubGlxdWlkLWdsYXNzIik7CiAgICAgIGZvciAobGV0IHMgb2YgaSkgdGhpcy5fcmVuZGVyR2xhc3NFbGVtZW50KHMsIG4sIHIpOwogICAgfQogICAgX3BhcnNlQ1NTTGVuZ3RoKGUsIHQpIHsKICAgICAgcmV0dXJuICFlIHx8IGUgPT09ICJhdXRvIgogICAgICAgID8gTmFOCiAgICAgICAgOiAoKGUgPSBlLnRyaW0oKSksCiAgICAgICAgICBlLnN0YXJ0c1dpdGgoImNhbGMoIikKICAgICAgICAgICAgPyB0aGlzLl9wYXJzZUNhbGMoZSwgdCkKICAgICAgICAgICAgOiBlLmVuZHNXaXRoKCIlIikKICAgICAgICAgICAgICA/IChwYXJzZUZsb2F0KGUpIC8gMTAwKSAqIHQKICAgICAgICAgICAgICA6IHBhcnNlRmxvYXQoZSkgfHwgMCk7CiAgICB9CiAgICBfcGFyc2VDYWxjKGUsIHQpIHsKICAgICAgbGV0IHIgPSBlLm1hdGNoKC9jYWxjXCgoLispXCkvKTsKICAgICAgaWYgKCFyKSByZXR1cm4gMDsKICAgICAgbGV0IG4gPSByWzFdLnRyaW0oKSwKICAgICAgICBpID0gbi5tYXRjaCgvKC4rKVxzKlwrXHMqKC4rKS8pLAogICAgICAgIHMgPSBuLm1hdGNoKC8oLispXHMqLVxzKiguKykvKTsKICAgICAgaWYgKHMpIHsKICAgICAgICBsZXQgbCA9IHRoaXMuX3BhcnNlQ1NTTGVuZ3RoKHNbMV0udHJpbSgpLCB0KSwKICAgICAgICAgIGEgPSB0aGlzLl9wYXJzZUNTU0xlbmd0aChzWzJdLnRyaW0oKSwgdCk7CiAgICAgICAgcmV0dXJuIGwgLSBhOwogICAgICB9CiAgICAgIGlmIChpKSB7CiAgICAgICAgbGV0IGwgPSB0aGlzLl9wYXJzZUNTU0xlbmd0aChpWzFdLnRyaW0oKSwgdCksCiAgICAgICAgICBhID0gdGhpcy5fcGFyc2VDU1NMZW5ndGgoaVsyXS50cmltKCksIHQpOwogICAgICAgIHJldHVybiBsICsgYTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5fcGFyc2VDU1NMZW5ndGgobiwgdCk7CiAgICB9CiAgICBfcGFyc2VUcmFuc2Zvcm0oZSwgdCwgcikgewogICAgICBsZXQgbiA9IDAsCiAgICAgICAgaSA9IDA7CiAgICAgIGlmICghZSB8fCBlID09PSAibm9uZSIpIHJldHVybiB7IHR4OiBuLCB0eTogaSB9OwogICAgICBsZXQgcyA9IGUubWF0Y2goL3RyYW5zbGF0ZVwoXHMqKFteLCldKykoPzpccyosXHMqKFteKV0rKSk/XHMqXCkvKTsKICAgICAgcyAmJgogICAgICAgICgobiA9IHRoaXMuX3BhcnNlVHJhbnNsYXRlVmFsdWUoc1sxXSwgdCkpLAogICAgICAgIChpID0gc1syXSA/IHRoaXMuX3BhcnNlVHJhbnNsYXRlVmFsdWUoc1syXSwgcikgOiAwKSk7CiAgICAgIGxldCBsID0gZS5tYXRjaCgvdHJhbnNsYXRlWFwoXHMqKFteKV0rKVxzKlwpLyk7CiAgICAgIGwgJiYgKG4gPSB0aGlzLl9wYXJzZVRyYW5zbGF0ZVZhbHVlKGxbMV0sIHQpKTsKICAgICAgbGV0IGEgPSBlLm1hdGNoKC90cmFuc2xhdGVZXChccyooW14pXSspXHMqXCkvKTsKICAgICAgYSAmJiAoaSA9IHRoaXMuX3BhcnNlVHJhbnNsYXRlVmFsdWUoYVsxXSwgcikpOwogICAgICBsZXQgdSA9IGUubWF0Y2goL3RyYW5zbGF0ZTNkXChccyooW14sXSspXHMqLFxzKihbXixdKylccyosXHMqW14pXStccypcKS8pOwogICAgICByZXR1cm4gKAogICAgICAgIHUgJiYgKChuID0gdGhpcy5fcGFyc2VUcmFuc2xhdGVWYWx1ZSh1WzFdLCB0KSksIChpID0gdGhpcy5fcGFyc2VUcmFuc2xhdGVWYWx1ZSh1WzJdLCByKSkpLAogICAgICAgIHsgdHg6IG4sIHR5OiBpIH0KICAgICAgKTsKICAgIH0KICAgIF9wYXJzZVRyYW5zbGF0ZVZhbHVlKGUsIHQpIHsKICAgICAgcmV0dXJuICgoZSA9IGUudHJpbSgpKSwgZS5lbmRzV2l0aCgiJSIpID8gKHBhcnNlRmxvYXQoZSkgLyAxMDApICogdCA6IHBhcnNlRmxvYXQoZSkgfHwgMCk7CiAgICB9CiAgICBfZ2V0RWxlbWVudFBvc2l0aW9uKGUsIHQpIHsKICAgICAgbGV0IHIgPSBnZXRDb21wdXRlZFN0eWxlKGUpLAogICAgICAgIG4gPSBwYXJzZUZsb2F0KGdldENvbXB1dGVkU3R5bGUodGhpcy5jYW52YXMpLndpZHRoKSB8fCB0aGlzLmNhbnZhcy53aWR0aCB8fCAxNTM2LAogICAgICAgIGkgPSBwYXJzZUZsb2F0KGdldENvbXB1dGVkU3R5bGUodGhpcy5jYW52YXMpLmhlaWdodCkgfHwgdGhpcy5jYW52YXMuaGVpZ2h0IHx8IDEwMjQsCiAgICAgICAgcyA9IGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksCiAgICAgICAgbCA9IHMud2lkdGggfHwgcGFyc2VGbG9hdChyLndpZHRoKSB8fCAwLAogICAgICAgIGEgPSBzLmhlaWdodCB8fCBwYXJzZUZsb2F0KHIuaGVpZ2h0KSB8fCAwLAogICAgICAgIHUgPSAwLAogICAgICAgIG8gPSAwLAogICAgICAgIGQgPSBlLnN0eWxlLAogICAgICAgIGMgPSBkLmxlZnQgfHwgci5sZWZ0LAogICAgICAgIGYgPSBkLnJpZ2h0IHx8IHIucmlnaHQsCiAgICAgICAgaCA9IGQudG9wIHx8IHIudG9wLAogICAgICAgIGIgPSBkLmJvdHRvbSB8fCByLmJvdHRvbSwKICAgICAgICBnID0gdGhpcy5fcGFyc2VDU1NMZW5ndGgoYywgbiksCiAgICAgICAgcCA9IHRoaXMuX3BhcnNlQ1NTTGVuZ3RoKGYsIG4pLAogICAgICAgIHYgPSB0aGlzLl9wYXJzZUNTU0xlbmd0aChoLCBpKSwKICAgICAgICBTID0gdGhpcy5fcGFyc2VDU1NMZW5ndGgoYiwgaSksCiAgICAgICAgUCA9IHBhcnNlRmxvYXQoci5tYXJnaW5MZWZ0KSB8fCAwLAogICAgICAgIHggPSBwYXJzZUZsb2F0KHIubWFyZ2luUmlnaHQpIHx8IDAsCiAgICAgICAgTSA9IHBhcnNlRmxvYXQoci5tYXJnaW5Ub3ApIHx8IDAsCiAgICAgICAgQSA9IHBhcnNlRmxvYXQoci5tYXJnaW5Cb3R0b20pIHx8IDAsCiAgICAgICAgRyA9ICFpc05hTihnKSwKICAgICAgICBVID0gIWlzTmFOKHApOwogICAgICBHICYmIFUgJiYgZyA9PT0gMCAmJiBwID09PSAwCiAgICAgICAgPyAodSA9IChuIC0gbCkgLyAyKQogICAgICAgIDogKEcgJiYgVSkgfHwgRwogICAgICAgICAgPyAodSA9IGcgKyBQKQogICAgICAgICAgOiBVICYmICh1ID0gbiAtIGwgLSBwIC0geCk7CiAgICAgIGxldCBCID0gIWlzTmFOKHYpLAogICAgICAgIEMgPSAhaXNOYU4oUyk7CiAgICAgIEIgJiYgQyAmJiB2ID09PSAwICYmIFMgPT09IDAKICAgICAgICA/IChvID0gKGkgLSBhKSAvIDIpCiAgICAgICAgOiAoQiAmJiBDKSB8fCBCCiAgICAgICAgICA/IChvID0gdiArIE0pCiAgICAgICAgICA6IEMgJiYgKG8gPSBpIC0gYSAtIFMgLSBBKTsKICAgICAgbGV0IHsgdHg6IFYsIHR5OiBGIH0gPSB0aGlzLl9wYXJzZVRyYW5zZm9ybShyLnRyYW5zZm9ybSwgbCwgYSk7CiAgICAgIHJldHVybiAoKHUgKz0gViksIChvICs9IEYpLCB7IHg6IHUsIHk6IG8sIHc6IGwsIGg6IGEgfSk7CiAgICB9CiAgICBfcmVuZGVyR2xhc3NFbGVtZW50KGUsIHQsIHIpIHsKICAgICAgaWYgKCF0aGlzLmRyYXdFbGVtZW50SW1hZ2UpIHJldHVybjsKICAgICAgbGV0IG4gPSB0aGlzLl9nZXRDb25maWdGcm9tQ1NTKGUpLAogICAgICAgIGkgPSB0aGlzLl9nZXRFbGVtZW50UG9zaXRpb24oZSwgdCksCiAgICAgICAgcyA9IGkueCwKICAgICAgICBsID0gaS55LAogICAgICAgIGEgPSBpLncsCiAgICAgICAgdSA9IGkuaCwKICAgICAgICBvID0gcyAqIHIsCiAgICAgICAgZCA9IGwgKiByLAogICAgICAgIGMgPSBhICogciwKICAgICAgICBmID0gdSAqIHIsCiAgICAgICAgaCA9IFQgKiByLAogICAgICAgIGIgPSBvIC0gaCwKICAgICAgICBnID0gZCAtIGgsCiAgICAgICAgcCA9IGMgKyBoICogMiwKICAgICAgICB2ID0gZiArIGggKiAyOwogICAgICB0aGlzLl9jYXB0dXJlUmVnaW9uKGIsIGcsIHAsIHYpOwogICAgICBsZXQgUyA9IE1hdGgucm91bmQocCksCiAgICAgICAgUCA9IE1hdGgucm91bmQodik7CiAgICAgICh0aGlzLnJlbmRlcmVyLmNsZWFyKCksCiAgICAgICAgdGhpcy5yZW5kZXJlci51cGxvYWRBbmRCbHVyKHRoaXMuc2NlbmVDYW52YXMsIDAsIDAsIFMsIFAsIG4uYmx1ckFtb3VudCksCiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXJHbGFzc1BhbmVsKG4sIGEsIHUsIHIpLAogICAgICAgIHRoaXMuY3R4LmRyYXdJbWFnZSh0aGlzLnJlbmRlcmVyLmNhbnZhcywgMCwgMCwgcCwgdiwgYiwgZywgcCwgdikpOwogICAgICB0cnkgewogICAgICAgIGxldCB4ID0gdGhpcy5fZHJhd0dsYXNzRWxlbWVudENvbnRlbnQoZSwgbywgZCk7CiAgICAgICAgeCAmJiAoZS5zdHlsZS50cmFuc2Zvcm0gPSB4LnRvU3RyaW5nKCkpOwogICAgICB9IGNhdGNoICh4KSB7CiAgICAgICAgZS5fX2xnX2Vycm9yX2xvZ2dlZCB8fAogICAgICAgICAgKGNvbnNvbGUud2FybigKICAgICAgICAgICAgYExpcXVpZEdsYXNzOiBGYWlsZWQgdG8gZHJhdyBnbGFzcyBlbGVtZW50ICR7ZS50YWdOYW1lfS4ke2UuY2xhc3NOYW1lfTpgLAogICAgICAgICAgICB4LAogICAgICAgICAgKSwKICAgICAgICAgIChlLl9fbGdfZXJyb3JfbG9nZ2VkID0gITApKTsKICAgICAgfQogICAgfQogICAgX2RyYXdHbGFzc0VsZW1lbnRDb250ZW50KGUsIHQsIHIpIHsKICAgICAgaWYgKCF0aGlzLmRyYXdFbGVtZW50SW1hZ2UpIHJldHVybjsKICAgICAgbGV0IG4gPSB0aGlzLl9zdXBwcmVzc0dsYXNzQ2hyb21lKGUpOwogICAgICB0cnkgewogICAgICAgIHJldHVybiB0aGlzLmRyYXdFbGVtZW50SW1hZ2UoZSwgdCwgcik7CiAgICAgIH0gZmluYWxseSB7CiAgICAgICAgdGhpcy5fcmVzdG9yZUlubGluZVN0eWxlcyhlLCBuKTsKICAgICAgfQogICAgfQogICAgX3N1cHByZXNzR2xhc3NDaHJvbWUoZSkgewogICAgICBsZXQgdCA9IG5ldyBNYXAoKSwKICAgICAgICByID0gWwogICAgICAgICAgImJhY2tncm91bmQiLAogICAgICAgICAgImJhY2tncm91bmRDb2xvciIsCiAgICAgICAgICAiYmFja2dyb3VuZEltYWdlIiwKICAgICAgICAgICJib3JkZXJDb2xvciIsCiAgICAgICAgICAiYm94U2hhZG93IiwKICAgICAgICAgICJmaWx0ZXIiLAogICAgICAgICAgIm91dGxpbmVDb2xvciIsCiAgICAgICAgXTsKICAgICAgZm9yIChsZXQgbiBvZiByKSB0LnNldChuLCBlLnN0eWxlW25dKTsKICAgICAgcmV0dXJuICgKICAgICAgICAoZS5zdHlsZS5iYWNrZ3JvdW5kID0gInRyYW5zcGFyZW50IiksCiAgICAgICAgKGUuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gInRyYW5zcGFyZW50IiksCiAgICAgICAgKGUuc3R5bGUuYmFja2dyb3VuZEltYWdlID0gIm5vbmUiKSwKICAgICAgICAoZS5zdHlsZS5ib3JkZXJDb2xvciA9ICJ0cmFuc3BhcmVudCIpLAogICAgICAgIChlLnN0eWxlLmJveFNoYWRvdyA9ICJub25lIiksCiAgICAgICAgKGUuc3R5bGUuZmlsdGVyID0gIm5vbmUiKSwKICAgICAgICAoZS5zdHlsZS5vdXRsaW5lQ29sb3IgPSAidHJhbnNwYXJlbnQiKSwKICAgICAgICB0CiAgICAgICk7CiAgICB9CiAgICBfcmVzdG9yZUlubGluZVN0eWxlcyhlLCB0KSB7CiAgICAgIGZvciAobGV0IFtyLCBuXSBvZiB0KSBlLnN0eWxlW3JdID0gbjsKICAgIH0KICAgIF9jYXB0dXJlUmVnaW9uKGUsIHQsIHIsIG4pIHsKICAgICAgbGV0IGkgPSBNYXRoLnJvdW5kKHIpLAogICAgICAgIHMgPSBNYXRoLnJvdW5kKG4pOwogICAgICAoKHRoaXMuc2NlbmVDYW52YXMud2lkdGggIT09IGkgfHwgdGhpcy5zY2VuZUNhbnZhcy5oZWlnaHQgIT09IHMpICYmCiAgICAgICAgKCh0aGlzLnNjZW5lQ2FudmFzLndpZHRoID0gaSksICh0aGlzLnNjZW5lQ2FudmFzLmhlaWdodCA9IHMpKSwKICAgICAgICAodGhpcy5zY2VuZUN0eC5maWxsU3R5bGUgPSAiI2ZmZmZmZiIpLAogICAgICAgIHRoaXMuc2NlbmVDdHguZmlsbFJlY3QoMCwgMCwgaSwgcyksCiAgICAgICAgdGhpcy5zY2VuZUN0eC5kcmF3SW1hZ2UodGhpcy5jYW52YXMsIGUsIHQsIHIsIG4sIDAsIDAsIGksIHMpKTsKICAgIH0KICAgIF9nZXRDb25maWdGcm9tQ1NTKGUpIHsKICAgICAgbGV0IHQgPSBnZXRDb21wdXRlZFN0eWxlKGUpLAogICAgICAgIHIgPSB7IC4uLncgfTsKICAgICAgZm9yIChsZXQgW24sIGldIG9mIE9iamVjdC5lbnRyaWVzKF8pKSB7CiAgICAgICAgbGV0IHMgPSB0LmdldFByb3BlcnR5VmFsdWUobikudHJpbSgpOwogICAgICAgIGlmIChzKSB7CiAgICAgICAgICBsZXQgbCA9IHBhcnNlRmxvYXQocyk7CiAgICAgICAgICBpc05hTihsKSB8fCAocltpXSA9IGwpOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gcjsKICAgIH0KICAgIGRlc3Ryb3koKSB7CiAgICAgIHRoaXMucmVuZGVyZXIuZGVzdHJveSgpOwogICAgfQogIH07CiAgcmV0dXJuIEkoWSk7Cn0pKCk7Cg==\"></script>\n <style>\n *,\n *::before,\n *::after {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n body {\n background: #0a0218;\n overflow: hidden;\n font-family: \"Inter\", system-ui, sans-serif;\n }\n #root {\n position: relative;\n width: 1920px;\n height: 1080px;\n overflow: hidden;\n }\n #three-canvas {\n position: absolute;\n top: 0;\n left: 0;\n width: 1920px;\n height: 1080px;\n z-index: 0;\n }\n #glass-canvas {\n position: absolute;\n top: 0;\n left: 0;\n width: 1920px;\n height: 1080px;\n z-index: 1;\n }\n\n /* ── Glass Panels ── */\n .glass-panel {\n position: absolute;\n background: rgba(255, 255, 255, 0.055);\n --lg-blur: 0.42;\n --lg-refraction: 0.92;\n --lg-corner-radius: 36;\n --lg-z-radius: 58;\n --lg-specular: 0.46;\n --lg-fresnel: 1.15;\n --lg-edge-highlight: 0.34;\n --lg-chrom-aberration: 0.08;\n --lg-shadow-opacity: 0;\n --lg-shadow-spread: 0;\n --lg-shadow-offset-y: 0;\n --lg-saturation: 1.1;\n }\n .search-panel {\n width: 640px;\n height: 72px;\n --lg-corner-radius: 24;\n }\n .toggle-panel {\n width: 640px;\n height: 64px;\n --lg-corner-radius: 44;\n }\n .media-panel {\n width: 640px;\n height: 116px;\n --lg-corner-radius: 44;\n }\n .slider-panel {\n width: 640px;\n height: 76px;\n --lg-corner-radius: 28;\n }\n\n #glass-search {\n top: 300px;\n left: 640px;\n }\n #glass-toggle {\n top: 390px;\n left: 640px;\n }\n #glass-media {\n top: 476px;\n left: 640px;\n }\n #glass-slider {\n top: 616px;\n left: 640px;\n }\n\n /* ── Text Overlays ── */\n .text-overlay {\n position: absolute;\n z-index: 2;\n pointer-events: none;\n }\n\n /* Search bar */\n .search-text {\n width: 640px;\n height: 72px;\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 0 28px;\n background: transparent;\n border-radius: 24px;\n box-shadow: none;\n }\n .search-text svg {\n width: 22px;\n height: 22px;\n stroke: rgba(255, 255, 255, 0.86);\n fill: none;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n flex-shrink: 0;\n }\n .search-label {\n font-size: 19px;\n font-weight: 650;\n color: #fff;\n text-shadow: 0 2px 12px rgba(0, 0, 0, 0.42);\n }\n .search-caret {\n width: 2px;\n height: 25px;\n border-radius: 999px;\n background: rgba(255, 255, 255, 0.82);\n opacity: 0;\n }\n #text-search {\n top: 300px;\n left: 640px;\n }\n\n /* Toggle row */\n .toggle-text {\n width: 640px;\n height: 64px;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0;\n position: relative;\n padding: 6px;\n background: transparent;\n border-radius: 44px;\n box-shadow: none;\n }\n .toggle-active-pill {\n position: absolute;\n top: 6px;\n left: 6px;\n z-index: 0;\n width: 209px;\n height: 52px;\n border-radius: 999px;\n background:\n radial-gradient(circle at 28% 18%, rgba(255, 255, 255, 0.32), transparent 42%),\n rgba(255, 255, 255, 0.14);\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, 0.32),\n inset 0 -1px 0 rgba(255, 255, 255, 0.09);\n }\n .toggle-item {\n flex: 1;\n position: relative;\n z-index: 1;\n text-align: center;\n font-size: 16px;\n font-weight: 700;\n color: rgba(255, 255, 255, 0.96);\n line-height: 52px;\n text-shadow: 0 2px 12px rgba(0, 0, 0, 0.42);\n }\n .toggle-item.active {\n color: #fff;\n }\n #text-toggle {\n top: 390px;\n left: 640px;\n }\n\n /* Media pill */\n .media-text {\n width: 640px;\n height: 116px;\n display: flex;\n align-items: center;\n gap: 22px;\n padding: 0 24px;\n background: transparent;\n border-radius: 44px;\n box-shadow: none;\n }\n .album-art {\n position: relative;\n overflow: hidden;\n width: 78px;\n height: 78px;\n border-radius: 20px;\n background:\n radial-gradient(circle at 70% 28%, rgba(255, 255, 255, 0.78), transparent 16%),\n conic-gradient(from 210deg, #06e3fa, #4fdb5e, #f59e0b, #ec4899, #06e3fa);\n flex-shrink: 0;\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, 0.28),\n 0 12px 26px rgba(0, 0, 0, 0.24);\n }\n .album-sheen {\n position: absolute;\n top: -10px;\n left: -70px;\n width: 38px;\n height: 110px;\n background: rgba(255, 255, 255, 0.34);\n filter: blur(8px);\n transform: rotate(24deg);\n }\n .media-info {\n display: flex;\n flex-direction: column;\n gap: 7px;\n flex: 1;\n min-width: 0;\n }\n .media-title {\n font-size: 22px;\n font-weight: 700;\n color: #fff;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n text-shadow: 0 2px 12px rgba(0, 0, 0, 0.42);\n }\n .media-artist {\n font-size: 16px;\n font-weight: 600;\n color: rgba(255, 255, 255, 0.84);\n text-shadow: 0 2px 12px rgba(0, 0, 0, 0.42);\n }\n .media-meta-row {\n display: flex;\n align-items: center;\n gap: 9px;\n }\n .live-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #4ade80;\n box-shadow: 0 0 14px rgba(74, 222, 128, 0.76);\n }\n .sound-wave {\n display: flex;\n align-items: end;\n gap: 3px;\n height: 16px;\n }\n .sound-wave span {\n width: 3px;\n height: 7px;\n border-radius: 999px;\n background: rgba(255, 255, 255, 0.74);\n }\n .transport {\n display: flex;\n align-items: center;\n gap: 24px;\n margin-left: auto;\n padding-right: 4px;\n }\n .transport svg {\n width: 28px;\n height: 28px;\n fill: #fff;\n stroke: none;\n }\n .transport .play-btn svg {\n width: 38px;\n height: 38px;\n }\n #text-media {\n top: 476px;\n left: 640px;\n }\n\n /* Brightness slider */\n .slider-text {\n width: 640px;\n height: 76px;\n display: flex;\n align-items: center;\n gap: 18px;\n padding: 0 28px;\n background: transparent;\n border-radius: 28px;\n box-shadow: none;\n }\n .slider-text svg {\n width: 26px;\n height: 26px;\n stroke: rgba(255, 255, 255, 0.88);\n fill: none;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n flex-shrink: 0;\n }\n .slider-track {\n flex: 1;\n height: 8px;\n background: rgba(255, 255, 255, 0.24);\n border-radius: 4px;\n position: relative;\n }\n .slider-fill {\n position: absolute;\n top: 0;\n left: 0;\n width: 34%;\n height: 100%;\n background: #fff;\n border-radius: 3px;\n box-shadow: 0 0 14px rgba(255, 255, 255, 0.5);\n }\n .slider-pct {\n font-size: 17px;\n font-weight: 600;\n color: rgba(255, 255, 255, 0.9);\n font-variant-numeric: tabular-nums;\n width: 42px;\n text-align: right;\n text-shadow: 0 2px 12px rgba(0, 0, 0, 0.42);\n }\n #text-slider {\n top: 616px;\n left: 640px;\n }\n </style>\n </head>\n <body>\n <div\n id=\"root\"\n data-composition-id=\"liquid-glass-media-controls\"\n data-width=\"1920\"\n data-height=\"1080\"\n data-start=\"0\"\n data-duration=\"8\"\n data-root=\"true\"\n >\n <canvas id=\"three-canvas\" width=\"1920\" height=\"1080\"></canvas>\n\n <canvas id=\"glass-canvas\" layoutsubtree width=\"1920\" height=\"1080\">\n <div id=\"glass-search\" class=\"glass-panel search-panel liquid-glass\"></div>\n <div id=\"glass-toggle\" class=\"glass-panel toggle-panel liquid-glass\"></div>\n <div id=\"glass-media\" class=\"glass-panel media-panel liquid-glass\"></div>\n <div id=\"glass-slider\" class=\"glass-panel slider-panel liquid-glass\"></div>\n </canvas>\n\n <!-- Search bar -->\n <div id=\"text-search\" class=\"text-overlay search-text\">\n <svg viewBox=\"0 0 24 24\">\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n </svg>\n <span id=\"search-label\" class=\"search-label\">Search</span>\n <span id=\"search-caret\" class=\"search-caret\"></span>\n </div>\n\n <!-- Toggle row -->\n <div id=\"text-toggle\" class=\"text-overlay toggle-text\">\n <div id=\"toggle-pill\" class=\"toggle-active-pill\"></div>\n <div class=\"toggle-item active\">All</div>\n <div class=\"toggle-item\">Favorites</div>\n <div class=\"toggle-item\">Recent</div>\n </div>\n\n <!-- Media pill -->\n <div id=\"text-media\" class=\"text-overlay media-text\">\n <div class=\"album-art\"><span id=\"album-sheen\" class=\"album-sheen\"></span></div>\n <div class=\"media-info\">\n <div class=\"media-title\">Midnight Drive</div>\n <div class=\"media-meta-row\">\n <span id=\"live-dot\" class=\"live-dot\"></span>\n <div class=\"media-artist\">Glass Resonance</div>\n <div id=\"sound-wave\" class=\"sound-wave\">\n <span></span><span></span><span></span><span></span>\n </div>\n </div>\n </div>\n <div class=\"transport\">\n <span>\n <svg viewBox=\"0 0 24 24\">\n <polygon points=\"19 20 9 12 19 4\" />\n <line x1=\"5\" y1=\"4\" x2=\"5\" y2=\"20\" stroke=\"#fff\" stroke-width=\"2\" />\n </svg>\n </span>\n <span class=\"play-btn\">\n <svg viewBox=\"0 0 24 24\"><polygon points=\"5 3 19 12 5 21\" /></svg>\n </span>\n <span>\n <svg viewBox=\"0 0 24 24\">\n <polygon points=\"5 4 15 12 5 20\" />\n <line x1=\"19\" y1=\"4\" x2=\"19\" y2=\"20\" stroke=\"#fff\" stroke-width=\"2\" />\n </svg>\n </span>\n </div>\n </div>\n\n <!-- Brightness slider -->\n <div id=\"text-slider\" class=\"text-overlay slider-text\">\n <svg viewBox=\"0 0 24 24\">\n <circle cx=\"12\" cy=\"12\" r=\"5\" />\n <line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\" />\n <line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\" />\n <line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\" />\n <line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\" />\n <line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\" />\n <line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\" />\n <line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\" />\n <line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\" />\n </svg>\n <div class=\"slider-track\"><div id=\"slider-fill\" class=\"slider-fill\"></div></div>\n <span id=\"slider-pct\" class=\"slider-pct\">34%</span>\n </div>\n\n <div\n id=\"driver\"\n class=\"clip\"\n data-start=\"0\"\n data-duration=\"8\"\n data-track-index=\"0\"\n style=\"position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none\"\n ></div>\n </div>\n\n <script>\n var W = 1920,\n H = 1080,\n DURATION = 8;\n\n /* ── Three.js Aurora Shader ─────────────────────────────────────── */\n var vs = \"varying vec2 vUv; void main() { vUv = uv; gl_Position = vec4(position, 1.0); }\";\n var fs = [\n \"precision highp float;\",\n \"varying vec2 vUv;\",\n \"uniform float uTime;\",\n \"vec3 mod289(vec3 x){return x-floor(x*(1.0/289.0))*289.0;}\",\n \"vec4 mod289(vec4 x){return x-floor(x*(1.0/289.0))*289.0;}\",\n \"vec4 permute(vec4 x){return mod289(((x*34.0)+1.0)*x);}\",\n \"vec4 taylorInvSqrt(vec4 r){return 1.79284291400159-0.85373472095314*r;}\",\n \"float snoise(vec3 v){\",\n \" const vec2 C=vec2(1.0/6.0,1.0/3.0);const vec4 D=vec4(0.0,0.5,1.0,2.0);\",\n \" vec3 i=floor(v+dot(v,C.yyy));vec3 x0=v-i+dot(i,C.xxx);\",\n \" vec3 g=step(x0.yzx,x0.xyz);vec3 l=1.0-g;\",\n \" vec3 i1=min(g.xyz,l.zxy);vec3 i2=max(g.xyz,l.zxy);\",\n \" vec3 x1=x0-i1+C.xxx;vec3 x2=x0-i2+C.yyy;vec3 x3=x0-D.yyy;\",\n \" i=mod289(i);\",\n \" vec4 p=permute(permute(permute(i.z+vec4(0.0,i1.z,i2.z,1.0))+i.y+vec4(0.0,i1.y,i2.y,1.0))+i.x+vec4(0.0,i1.x,i2.x,1.0));\",\n \" float n_=0.142857142857;vec3 ns=n_*D.wyz-D.xzx;\",\n \" vec4 j=p-49.0*floor(p*ns.z*ns.z);vec4 x_=floor(j*ns.z);vec4 y_=floor(j-7.0*x_);\",\n \" vec4 x=x_*ns.x+ns.yyyy;vec4 y=y_*ns.x+ns.yyyy;vec4 h=1.0-abs(x)-abs(y);\",\n \" vec4 b0=vec4(x.xy,y.xy);vec4 b1=vec4(x.zw,y.zw);\",\n \" vec4 s0=floor(b0)*2.0+1.0;vec4 s1=floor(b1)*2.0+1.0;\",\n \" vec4 sh=-step(h,vec4(0.0));\",\n \" vec4 a0=b0.xzyw+s0.xzyw*sh.xxyy;vec4 a1=b1.xzyw+s1.xzyw*sh.zzww;\",\n \" vec3 p0=vec3(a0.xy,h.x);vec3 p1=vec3(a0.zw,h.y);vec3 p2=vec3(a1.xy,h.z);vec3 p3=vec3(a1.zw,h.w);\",\n \" vec4 norm=taylorInvSqrt(vec4(dot(p0,p0),dot(p1,p1),dot(p2,p2),dot(p3,p3)));\",\n \" p0*=norm.x;p1*=norm.y;p2*=norm.z;p3*=norm.w;\",\n \" vec4 m=max(0.6-vec4(dot(x0,x0),dot(x1,x1),dot(x2,x2),dot(x3,x3)),0.0);m=m*m;\",\n \" return 42.0*dot(m*m,vec4(dot(p0,x0),dot(p1,x1),dot(p2,x2),dot(p3,x3)));\",\n \"}\",\n \"void main(){\",\n \" vec2 uv=vUv;float ar=1920.0/1080.0;vec2 p=vec2(uv.x*ar,uv.y);float t=uTime*0.06;\",\n \" float wx=snoise(vec3(p*1.4,t*0.5))*0.2;float wy=snoise(vec3(p*1.4+100.0,t*0.5))*0.2;\",\n \" vec2 wp=p+vec2(wx,wy);\",\n \" vec3 base=mix(vec3(0.10,0.02,0.22),vec3(0.04,0.10,0.25),smoothstep(0.0,1.0,uv.x*0.6+uv.y*0.4));\",\n \" float angle=0.65;float ridgeUv=dot(wp,vec2(cos(angle),sin(angle)));\",\n \" float ridge1=sin(ridgeUv*8.0+t*2.0+snoise(vec3(wp*0.8,t))*1.5);\",\n \" float ridge2=sin(ridgeUv*5.5-t*1.4+snoise(vec3(wp*1.2+50.0,t*0.7))*2.0);\",\n \" float ridge3=sin(ridgeUv*12.0+t*3.0+snoise(vec3(wp*0.6+80.0,t*0.4))*1.0);\",\n \" float crease1=pow(abs(ridge1),0.35)*sign(ridge1)*0.5+0.5;\",\n \" float crease2=pow(abs(ridge2),0.4)*sign(ridge2)*0.5+0.5;\",\n \" float crease3=pow(abs(ridge3),0.5)*sign(ridge3)*0.5+0.5;\",\n \" vec3 warm=mix(vec3(0.9,0.4,0.08),vec3(0.95,0.65,0.15),crease1);\",\n \" float warmZone=smoothstep(0.15,0.75,uv.x+uv.y*0.4+snoise(vec3(uv*2.0,t))*0.3);\",\n \" vec3 cool=mix(vec3(0.02,0.4,0.55),vec3(0.25,0.7,0.82),crease2);\",\n \" float coolZone=smoothstep(0.25,0.85,1.2-uv.x+uv.y*0.5+snoise(vec3(uv*2.0+40.0,t*0.8))*0.25);\",\n \" vec3 hot=mix(vec3(0.8,0.1,0.4),vec3(0.6,0.08,0.65),crease3);\",\n \" float hotZone=smoothstep(0.5,0.9,snoise(vec3(uv*2.5+20.0,t*0.6))*0.5+0.5);\",\n \" vec3 col=base;\",\n \" col=mix(col,warm,warmZone*0.75*smoothstep(0.3,0.7,crease1));\",\n \" col=mix(col,cool,coolZone*0.65*smoothstep(0.2,0.65,crease2));\",\n \" col=mix(col,hot,hotZone*0.5*smoothstep(0.35,0.8,crease3));\",\n \" float edgeGlow=pow(1.0-abs(ridge1),6.0)*0.4+pow(1.0-abs(ridge2),5.0)*0.25;\",\n \" col+=edgeGlow*mix(warm,cool,uv.x)*0.8;\",\n \" col*=1.0-pow(abs(ridge1),4.0)*0.15;\",\n \" float vig=1.0-smoothstep(0.5,1.5,length((uv-0.5)*vec2(1.3,1.0)));\",\n \" col*=0.65+vig*0.5;\",\n \" float luma=dot(col,vec3(0.299,0.587,0.114));col=mix(vec3(luma),col,1.5);\",\n \" col=clamp(col,0.0,1.0);col=pow(col,vec3(0.9));\",\n \" gl_FragColor=vec4(col,1.0);\",\n \"}\",\n ].join(\"\\n\");\n\n /* ── Three.js Setup ─────────────────────────────────────────────── */\n var threeCanvas = document.getElementById(\"three-canvas\");\n var renderer = new THREE.WebGLRenderer({ canvas: threeCanvas, alpha: false });\n renderer.setSize(W, H, false);\n renderer.setPixelRatio(1);\n\n var scene = new THREE.Scene();\n var camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);\n var uniforms = { uTime: { value: 0 } };\n var shaderMat = new THREE.ShaderMaterial({\n vertexShader: vs,\n fragmentShader: fs,\n uniforms: uniforms,\n });\n var quad = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), shaderMat);\n scene.add(quad);\n\n /* ── Glass Canvas ───────────────────────────────────────────────── */\n var glassCanvas = document.getElementById(\"glass-canvas\");\n var ctx = glassCanvas.getContext(\"2d\");\n var lg = new LiquidGlass.LiquidGlassCanvas(glassCanvas);\n var lgReady = false;\n\n function renderGlass(time) {\n if (!lgReady) return;\n uniforms.uTime.value = time;\n renderer.render(scene, camera);\n ctx.clearRect(0, 0, W, H);\n ctx.drawImage(threeCanvas, 0, 0, W, H);\n lg.renderGlassElements();\n }\n\n function requestGlassRender(time) {\n if (glassCanvas.requestPaint) {\n glassCanvas.onpaint = function () {\n renderGlass(time);\n };\n glassCanvas.requestPaint();\n return;\n }\n renderGlass(time);\n }\n\n lg.waitForInit().then(function (ok) {\n if (!ok) return;\n lgReady = true;\n requestGlassRender(0);\n });\n\n /* ── GSAP Timeline ──────────────────────────────────────────────── */\n window.__timelines = window.__timelines || {};\n var tl = gsap.timeline({ paused: true });\n\n var gs = document.getElementById(\"glass-search\");\n var gt = document.getElementById(\"glass-toggle\");\n var gm = document.getElementById(\"glass-media\");\n var gsl = document.getElementById(\"glass-slider\");\n var ts = document.getElementById(\"text-search\");\n var tt = document.getElementById(\"text-toggle\");\n var tm = document.getElementById(\"text-media\");\n var tsl = document.getElementById(\"text-slider\");\n var searchLabel = document.getElementById(\"search-label\");\n var sliderPct = document.getElementById(\"slider-pct\");\n var sliderValue = { value: 34 };\n\n // Glass panels live inside <canvas layoutsubtree> (html-in-canvas): the canvas lib\n // reads their sub-pixel computed top/left, so animating layout props on them does\n // NOT stutter and is exempt from gsap_non_transform_motion. They keep top/left.\n // Plain-DOM text overlays DO stutter on layout props, so they use transforms (x/y).\n // CSS resting tops — search 300, toggle 390, media 476, slider 616 — are the\n // transform base; the original set seeded top:1160, i.e. y = 1160 - restingTop.\n gsap.set([gs, gt, gm, gsl], { top: 1160, opacity: 1 });\n gsap.set(ts, { y: 860, opacity: 1 });\n gsap.set(tt, { y: 770, opacity: 1 });\n gsap.set(tm, { y: 684, opacity: 1 });\n gsap.set(tsl, { y: 544, opacity: 1 });\n gsap.set(\"#sound-wave span\", { height: 7 });\n\n tl.to(gs, { top: 300, duration: 0.48, ease: \"power3.out\" }, 0.12);\n tl.to(ts, { y: 0, duration: 0.48, ease: \"power3.out\" }, 0.12);\n tl.to(gt, { top: 390, duration: 0.44, ease: \"power3.out\" }, 0.22);\n tl.to(tt, { y: 0, duration: 0.44, ease: \"power3.out\" }, 0.22);\n tl.to(gm, { top: 476, duration: 0.44, ease: \"power3.out\" }, 0.32);\n tl.to(tm, { y: 0, duration: 0.44, ease: \"power3.out\" }, 0.32);\n tl.to(gsl, { top: 616, duration: 0.46, ease: \"power3.out\" }, 0.42);\n tl.to(tsl, { y: 0, duration: 0.46, ease: \"power3.out\" }, 0.42);\n\n tl.call(\n function () {\n searchLabel.textContent = \"Search Music\";\n },\n null,\n 0.9,\n );\n tl.to(\n \"#search-caret\",\n { opacity: 1, duration: 0.1, yoyo: true, repeat: 5, ease: \"none\" },\n 0.94,\n );\n tl.call(\n function () {\n searchLabel.textContent = \"Midnight Drive\";\n },\n null,\n 1.55,\n );\n tl.to(\"#toggle-pill\", { x: 209, duration: 0.24, ease: \"power2.out\" }, 1.82);\n tl.to(\n \".play-btn\",\n { scale: 0.86, duration: 0.12, ease: \"power2.out\", yoyo: true, repeat: 1 },\n 2.18,\n );\n tl.to(\"#album-sheen\", { x: 182, duration: 0.75, ease: \"power2.out\" }, 2.2);\n tl.to(\n \"#sound-wave span\",\n { height: 15, duration: 0.22, ease: \"power2.inOut\", stagger: 0.05, yoyo: true, repeat: 12 },\n 2.2,\n );\n tl.to(\n sliderValue,\n {\n value: 82,\n duration: 4.4,\n ease: \"none\",\n onUpdate: function () {\n sliderPct.textContent = Math.round(sliderValue.value) + \"%\";\n },\n },\n 1.2,\n );\n tl.to(\"#slider-fill\", { width: \"82%\", duration: 4.4, ease: \"none\" }, 1.2);\n tl.to(\n \"#live-dot\",\n { scale: 1.45, duration: 0.24, ease: \"power2.out\", yoyo: true, repeat: 4 },\n 2.6,\n );\n tl.to(\"#toggle-pill\", { x: 419, duration: 0.24, ease: \"power2.out\" }, 4.15);\n\n // Settle + exit. Split so glass panels keep relative top (exempt, html-in-canvas)\n // and plain-DOM text overlays use the relative transform equivalent (y). Inline\n // array literals so the linter can resolve each group's targets; a pre-declared\n // array variable resolves to __unresolved__ and would lose the canvas exemption.\n tl.to(\n [gs, gt, gm, gsl],\n { top: \"-=8\", duration: 0.22, ease: \"power2.out\", yoyo: true, repeat: 1 },\n 5.55,\n );\n tl.to(\n [ts, tt, tm, tsl],\n { y: \"-=8\", duration: 0.22, ease: \"power2.out\", yoyo: true, repeat: 1 },\n 5.55,\n );\n tl.to([gs, gt, gm, gsl], { top: \"+=760\", duration: 0.42, ease: \"power2.in\" }, 6.72);\n tl.to([ts, tt, tm, tsl], { y: \"+=760\", duration: 0.42, ease: \"power2.in\" }, 6.72);\n\n /* Duration driver */\n tl.to({ v: 0 }, { v: 1, duration: DURATION, ease: \"none\" }, 0);\n\n tl.eventCallback(\"onUpdate\", function () {\n requestGlassRender(tl.time());\n });\n\n window.__timelines[\"liquid-glass-media-controls\"] = tl;\n </script>\n </body>\n</html>\n"} |