From bda8800a89065cc37a9b8abdef6497c2158c79e3 Mon Sep 17 00:00:00 2001 From: Nino Date: Fri, 6 Nov 2026 09:28:23 -0600 Subject: [PATCH] Estante 3D: mueble, lomos, logos y vista previa de tomos --- app/public/animeface-cascade.json | 1 + app/public/animeface.js | 97 ++ app/public/app.js | 128 ++- app/public/book3d.js | 13 +- app/public/fonts/LICENSE.txt | 3 + app/public/fonts/caveat.woff2 | Bin 0 -> 51220 bytes app/public/fonts/gochihand.woff2 | Bin 0 -> 19908 bytes app/public/fonts/indieflower.woff2 | Bin 0 -> 19508 bytes app/public/fonts/kalam.woff2 | Bin 0 -> 22144 bytes app/public/fonts/patrickhand.woff2 | Bin 0 -> 23944 bytes app/public/fonts/permanentmarker.woff2 | Bin 0 -> 29564 bytes app/public/fonts/shadows.woff2 | Bin 0 -> 16296 bytes app/public/index.html | 1 + app/public/shelf3d.js | 1285 ++++++++++++++++++++++++ app/public/style.css | 21 + app/public/sw.js | 4 +- app/server.js | 9 +- app/shelf.js | 36 + app/volumes.js | 66 +- 19 files changed, 1649 insertions(+), 15 deletions(-) create mode 100644 app/public/animeface-cascade.json create mode 100644 app/public/animeface.js create mode 100644 app/public/fonts/LICENSE.txt create mode 100644 app/public/fonts/caveat.woff2 create mode 100644 app/public/fonts/gochihand.woff2 create mode 100644 app/public/fonts/indieflower.woff2 create mode 100644 app/public/fonts/kalam.woff2 create mode 100644 app/public/fonts/patrickhand.woff2 create mode 100644 app/public/fonts/permanentmarker.woff2 create mode 100644 app/public/fonts/shadows.woff2 create mode 100644 app/public/shelf3d.js create mode 100644 app/shelf.js diff --git a/app/public/animeface-cascade.json b/app/public/animeface-cascade.json new file mode 100644 index 0000000..a32167c --- /dev/null +++ b/app/public/animeface-cascade.json @@ -0,0 +1 @@ +{"license":"lbpcascade_animeface, https://github.com/nagadomi/lbpcascade_animeface\nThe MIT License (MIT)\n\nCopyright (C) 2011 by nagadomi@nurs.or.jp\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.","w":24,"h":24,"stages":[[-1.263674259185791,[[103,[-1302,-1,-2097218,-1,-1,-1,-1,-1],[-0.8628431558609009,0.8288403153419495]],[111,[-270553558,-16593,-1342197841,-24657,-1069073,-28753,-268456017,-28753],[-0.8301590085029602,0.5024479627609253]],[274,[-791883568,-570557057,-10521123,-2261129,-168835596,-14680065,-536870913,-577],[-0.6802006363868713,0.4293278455734253]]]],[-1.636199951171875,[[17,[-67110150,-1,-1,-1,-1,-1,-1,-1],[-0.7564964890480042,0.6566571593284607]],[226,[-21846,-18501,-546118,-17745,-67130689,-20481,-21589,-5185],[-0.6622880697250366,0.45048093795776367]],[167,[-17104902,269658770,-5046274,-14539742,-1,-67897614,-1,-11301],[-0.6063612699508667,0.41438210010528564]],[410,[-67109392,-5,-537133576,-1282,1154814128,-4638,-1448359800,-71304194],[-0.5924391746520996,0.35992857813835144]],[329,[-422583808,2030231298,-445326064,-35408702,1313755528,222323776,-589330296,-3146022],[-0.5127382278442383,0.39016643166542053]],[196,[-927858550,1525075679,149029012,-71367005,1365708031,-386200322,-419477761,-1110321],[-0.4261343479156494,0.3813542425632477]]]],[-1.6592464447021484,[[112,[-18,-1,-17,-1,-1,-1,-1,-1],[-0.7186874747276306,0.5039339661598206]],[76,[-98500654,-327681,-81592321,-1,-67641345,-1,-525313,-1],[-0.6528414487838745,0.40119534730911255]],[405,[-571474700,-4097,-1409548289,-1,-1939013504,-65537,-269484808,-1],[-0.5936161279678345,0.3178099989891052]],[121,[-486563073,-218104129,553639679,-88085761,1082066687,-151040033,-37889,-32769],[-0.38881537318229675,0.46969282627105713]],[91,[-28754,-4741217,-5787766,-4272213,-268464465,-71364690,-340815953,-1616049394],[-0.5380537509918213,0.3086091876029968]],[446,[419443088,285235408,254456305,-16204592,-1391444552,-1359433799,-1424163143,-1079260968],[-0.42636507749557495,0.3572568893432617]],[327,[-597814534,-555989829,-69009699,-13080945,1523056856,-23444034,-222757126,-72695094],[-0.3299240469932556,0.4131940007209778]],[564,[253993232,855774768,261231921,1605348720,1061134545,-1109396681,-8408880,-1073744225],[-0.43008872866630554,0.29400870203971863]]]],[-1.54403817653656,[[288,[-65537,-331809,-5586945,-5595969,-4524038,-5578822,-72683526,-1431651670],[-0.49188971519470215,0.4876288175582886]],[65,[-168317009,-167792753,-101341265,-677969,-201347153,-675921,-67260497,-1077966929],[-0.5765073299407959,0.3772933781147003]],[505,[-264195,-4677924,-67109379,-7370536,-16903,-16933387,-1614832472,-542162864],[-0.46903330087661743,0.4083128273487091]],[267,[-2295048,-3,-34537480,-131073,-1281,-5121,-1,-1],[-0.5294912457466125,0.295517235994339]],[359,[134218832,1346373084,485543039,-571861671,470810624,-1715453444,-671033126,-1146484562],[-0.43582525849342346,0.34078335762023926]],[531,[-205802701,855872035,-1275381997,-1751670853,-545348677,-1210587213,-71320902,-1161839685],[-0.3371037542819977,0.453489750623703]],[118,[-487093505,-218127617,-1560391937,-62721,1077346555,2063540991,-134275329,-47553],[-0.31872883439064026,0.44437479972839355]],[50,[-142610526,-253073502,-92102144,-741350074,-150497792,4218884,-785930752,-246946298],[-0.35306012630462646,0.33983978629112244]],[207,[-1024537970,-689028406,147245278,1885009118,-937884982,911296300,-280506658,-73676801],[-0.32728925347328186,0.3312322199344635]],[570,[-1086335181,-2026903933,402122549,-11553395,-2038958942,-2047885573,-747113584,-3150353],[-0.2583779990673065,0.41633638739585876]],[198,[-98401792,-257947744,744505346,-44030416,1449330176,-1224726752,-13357430,-215989504],[-0.33786505460739136,0.3310038447380066]]]],[-1.5968077182769775,[[161,[-327682,-234815982,-9217,-327702,-67108865,-19,-35169,-1025],[-0.6077409982681274,0.3348584771156311]],[42,[-234901585,-134893649,-101453937,-676433,-167792721,-840273,-67662929,-61685],[-0.5801490545272827,0.2930995523929596]],[462,[-8391180,-9439249,-262916,-265250,2137191648,-8976,-1048856,-71303446],[-0.5099717378616333,0.3178481161594391]],[295,[-607128576,-2136813818,-646465352,-33556977,-732956532,-871835636,-1461741368,-5243185],[-0.4626306891441345,0.2914928197860718]],[227,[-833836928,-547492971,-36372488,-6209,-69293062,-1788225,-67174657,-1],[-0.710062563419342,0.15655440092086792]],[120,[-1024463121,-202396945,-1428264195,-2102581,1473185007,-33559809,-83932193,-39353],[-0.2852258086204529,0.4243815243244171]],[327,[-665695145,-638053093,-634372129,2134510939,-62259176,-570765889,-66531622,-1154847045],[-0.2963193356990814,0.3593541085720062]],[548,[-1357384943,-343742928,-1612720912,-538063840,-1956010591,-2003587624,131028417,-538978871],[-0.3405310809612274,0.3084990084171295]],[535,[-138422528,588489479,1067695873,-1074794561,-27345985,-1342177351,-1360024918,-1429214225],[-0.2772350311279297,0.3785536289215088]],[32,[-69217521,318980663,-546308677,553910191,-1119418848,1023541829,-1078203530,1426587151],[-0.34162473678588867,0.2840517461299896]],[68,[-272896094,-1060178292,-563023360,-740103008,-421596795,4254308,-151788864,-804784960],[-0.3335507810115814,0.25905099511146545]],[218,[2080341787,1060846641,-1107591393,-608438981,-537157638,-1879067494,1226316347,272137786],[-0.40187957882881165,0.21486374735832214]],[171,[-1057233345,-629705185,-500534530,807650042,68650975,-92965029,2013228271,-135284769],[-0.3021503984928131,0.2727862298488617]],[221,[1509885074,2004291294,555376605,1073426430,2135919867,267332795,-620820929,1006580307],[-0.33670711517333984,0.25498929619789124]]]],[-1.5330305099487305,[[242,[-168299308,-103680513,-17039875,-16513,-104858115,-1093,-68157441,-1074807809],[-0.5250251889228821,0.3111686110496521]],[146,[-1052690,-134217745,-4114,-134744587,-67108865,-101187585,-7185,-17],[-0.5587370991706848,0.2360144555568695]],[472,[-1086455823,520682672,2147352049,-5382736,-1433403459,-21364743,-1883244099,-541076003],[-0.31670504808425903,0.4062115252017975]],[202,[1224607962,1392201471,-2097544450,-88674562,136185054,-251707461,-319042850,-67147009],[-0.435680627822876,0.2630350887775421]],[246,[-327758,-1682395368,-101499042,-4484198,-264197,-4276368,-67372516,-64294],[-0.3509634733200073,0.2855299413204193]],[568,[-1221597405,926924550,-1216481488,-7340245,-6297677,-571475207,-142608393,-81],[-0.25762778520584106,0.3931208550930023]],[145,[-550531409,-4223169,-1799410513,-40915442,-100806657,-71439443,-290865,-5271921],[-0.36129701137542725,0.25089186429977417]],[518,[973252242,1059044139,691879211,1033633599,1061157819,1052455857,1001855675,994000443],[-0.40735718607902527,0.21259017288684845]],[292,[-155561249,-121033,-227353697,822221407,-732409764,-134860169,-5579014,-81596545],[-0.2780284583568573,0.3157797157764435]],[117,[-492377361,-67966273,-487796737,-537989558,1157580795,-623117,-33726753,-571901],[-0.23659884929656982,0.3690859377384186]],[49,[-3146078,-87102466,1929375776,-110170912,-209718716,1073987584,-172501248,-263724778],[-0.3126767873764038,0.2740819752216339]],[608,[-17830961,-52594705,1894769378,-759235926,-746588864,1145539840,-476648760,-255332678],[-0.23596332967281342,0.33085909485816956]],[294,[1787490066,-264197568,2011318014,-10345952,1816350540,1309473484,-1075852357,-347121653],[-0.3239920735359192,0.23825044929981232]],[58,[538050560,10548908,633938201,761344263,1178943808,1145357893,1473577739,17132883],[-0.43849360942840576,0.17257992923259735]],[62,[-1343377669,-67129357,-1478513667,536586967,-1342462217,-1141683202,-805589267,268372159],[-0.3904886543750763,0.19998973608016968]],[469,[-1141917951,2055732023,-67115040,-5259282,891279264,-1073742033,-252723072,-70254961],[-0.32046061754226685,0.2269742637872696]],[148,[-123294037,-629126677,-129217217,-106165406,-58765569,-53989993,-92475474,-260742313],[-0.22333471477031708,0.33217769861221313]],[270,[11436672,899321384,-2035277788,-134750226,494898348,805293739,-134222129,-1330],[-0.5181822776794434,0.14062055945396423]]]],[-1.617965817451477,[[251,[-16842753,-65537,-1078263809,992149503,-21315590,-65537,-4530178,-1155334401],[-0.40925416350364685,0.37826526165008545]],[506,[-13,-37748737,-67108878,-1,-2061,-16385,-134744078,-134217729],[-0.33893144130706787,0.38312068581581116]],[123,[-33558546,-34087433,-34078866,-33554433,-68423681,-17175821,-100925441,-1025],[-0.6069239974021912,0.1872701644897461]],[495,[1061158675,993509311,-1073758401,-1077936129,2139094975,2147450879,-68175185,721352703],[-0.34320926666259766,0.2941015064716339]],[188,[-889254689,-606139649,-822276097,-536932833,-894497025,-1694560673,-302051361,1543438867],[-0.3382209241390228,0.2658557891845703]],[387,[2110840317,-170373132,-67108867,-492679,-1898390020,-458756,-5701956,-1414920152],[-0.30869945883750916,0.2828564941883087]],[40,[-390074625,-96482225,-35656193,-571112243,216501503,-1393570577,-1933586817,1087717587],[-0.3291912078857422,0.22378942370414734]],[438,[-8388612,-71569970,-12587010,-5313858,-885750552,-17113860,-303256326,-1398104918],[-0.3155522048473358,0.2283312976360321]],[300,[-44092621,1534539583,2113879867,-72385733,2147434111,-4440513,2034203967,1937456447],[-0.5197641849517822,0.14146961271762848]],[168,[-352334129,-767580353,552889982,1920724734,-713601266,1983999843,-3411973,-201588757],[-0.2473347932100296,0.2858215272426605]],[609,[-6225,-295247985,-759442752,1084948202,-68348,1141308928,-86191156,-253235222],[-0.24679842591285706,0.2772952914237976]],[419,[151016821,184578384,-550121483,524098780,139726044,-1076822018,-1879556100,-1078263671],[-0.256909042596817,0.266051709651947]],[302,[-539102470,-2497,-1107343618,-33566754,-268571713,-16450,-1093681969,-67633153],[-0.2787766456604004,0.2446342259645462]],[485,[-4743040,-1107956700,-1376293472,-812648524,-846885756,-1113473919,-2031764308,76926853],[-0.2878116965293884,0.2346356213092804]],[86,[-209870857,2010119803,83886091,1057456929,2046623741,-174587905,565776015,2012079087],[-0.21731185913085938,0.297241747379303]],[173,[2130440170,-1494225046,-1116212241,1877473231,58685261,1179325709,-612376625,-5169],[-0.24395407736301422,0.2575765550136566]],[618,[-92280577,-106446978,-151355790,1624177388,-402930100,-145101820,-1224807732,-798818356],[-0.22018355131149292,0.28403928875923157]],[199,[1711793897,430272415,788433915,1073703931,2113740797,2113925119,-33605377,553123759],[-0.30896610021591187,0.20028412342071533]],[588,[-278925405,-1884375241,-17322192,-541066313,-1755323001,126740978,-671090992,-135268353],[-0.21448580920696259,0.29228198528289795]],[15,[-134217809,-605290706,-344462688,-236258702,-12599545,1128721759,-134241472,-134220842],[-0.20150026679039001,0.3063429594039917]],[308,[-62849320,2136267568,1429265656,-39780400,2105335016,-4222980,-222437720,-131148],[-0.5517482161521912,0.11506053060293198]],[385,[269753717,520624093,-1124313601,2109618489,894436372,-1619636227,1608012104,-1414922213],[-0.2652745842933655,0.22207336127758026]]]],[-1.5240784883499146,[[209,[-16777473,-83890433,-764480770,1914896094,-8241,-4194369,-17,-8388609],[-0.37706291675567627,0.34414002299308777]],[471,[-638582861,-214171669,-503319568,-33554449,-2144,-340000769,1375195600,-671088657],[-0.401825875043869,0.28752782940864563]],[4,[-20561,-235683841,-937985,-33574963,-201774161,-67426137,-67260433,-8977137],[-0.3826923668384552,0.23733018338680267]],[538,[-142608637,858242867,-2285,-1077936385,-2121,-1073750089,-269484113,-1358958865],[-0.25483861565589905,0.3326546549797058]],[204,[1484409054,-81102033,36761342,1375797182,1248987294,-11018250,-30220550,-15466497],[-0.3411288559436798,0.24120210111141205]],[371,[-539165220,-131082,-281215236,-1130504,-54722596,-272891953,-54724376,-5138],[-0.4527590572834015,0.17377805709838867]],[25,[-1493,-202376410,-1023938528,-251920682,-140545280,1682265604,-143133120,-211288085],[-0.27601632475852966,0.2942805588245392]],[210,[2130668066,-1372889750,-1073898641,-1058833,1147095110,1192205127,-872415281,-11534385],[-0.27625253796577454,0.26642629504203796]],[99,[-4200469,-135335198,-203431774,-70261556,-67111946,-2147048126,-145230366,-203950650],[-0.19389793276786804,0.3761134743690491]],[115,[-353457425,-74805585,-353472977,-1176914,1693926379,2146838449,-134410392,2135245639],[-0.2886756360530853,0.24483714997768402]],[508,[-1148733519,780856288,-1276684815,-15737456,-1346395480,-1880315220,97883549,-570434343],[-0.24260485172271729,0.28319093585014343]],[612,[-335550942,1122675878,39428642,44487402,-202381696,147984,-530587456,-1060116485],[-0.3207935690879822,0.2175094038248062]],[487,[-2118783,-1086344025,-1094734171,-1375868937,-5919064,-1073826123,-1598643539,16056055],[-0.23602557182312012,0.2590687870979309]],[637,[-134222161,-892340722,-85984544,-521142342,-202377530,2323523,-135792960,-255066161],[-0.21411967277526855,0.2883610129356384]],[122,[-621281281,305332202,-262286,-4728238,-36700161,2138570743,-8388641,-201],[-0.21160617470741272,0.2865854501724243]],[66,[-68164637,-909443356,-415296912,-679676768,-1153701470,-2033649432,1979708660,-716703808],[-0.21729548275470734,0.2750277519226074]],[166,[-488641938,1886375671,-894547222,1886317154,1869480350,571498307,-212336949,-227541041],[-0.24970392882823944,0.22789211571216583]],[474,[-1961000015,-1450948560,-688194123,-33689132,-2113163334,-1933923148,537001,-1981819431],[-0.22741013765335083,0.2472570389509201]],[234,[16385024,813192181,1071056213,1557346127,1002160826,-1178714129,-544243969,-1420854370],[-0.5305399894714355,0.10699179023504257]],[594,[-100673809,-201327669,-117970254,-756099110,-136314996,1917240912,-77683000,-229638210],[-0.17796075344085693,0.3293799161911011]],[545,[285687569,991770411,-268453965,-586154031,248379123,-1477454505,1467478960,-556794161],[-0.22852730751037598,0.24927006661891937]],[233,[1350551227,280743415,-2000770498,855637755,1912588527,955645951,-150999109,551549951],[-0.28712141513824463,0.21096032857894897]]]],[-1.6037335395812988,[[203,[-84213766,1490747034,-136087790,-1334,-610271233,-16781314,-287582050,-9042],[-0.4084002375602722,0.24690119922161102]],[536,[-146803789,322156531,-536873673,-1111623753,-167791621,-285185,-1073742917,-1077952581],[-0.22172482311725616,0.40040645003318787]],[255,[-171060792,-620071486,-1626088625,-1078985329,-2142658748,1330043724,-78652593,1263533903],[-0.32599684596061707,0.23890890181064606]],[95,[-34493009,-235280985,-240005745,-222980691,-168720385,-240078929,-487551569,-574910835],[-0.42127540707588196,0.18673938512802124]],[325,[-539101185,2138416567,760823775,-154689,-5141009,-1229192670,771426991,15139330],[-0.3363325297832489,0.23910291492938995]],[101,[-630216070,-757354758,-1830057793,-100695298,-788821861,-1160568079,-2101537,1509884027],[-0.2783498764038086,0.23219773173332214]],[350,[-133121,-396388,-575086596,-2880236,-605245958,-2565644,-7287816,201345105],[-0.341799795627594,0.19213064014911652]],[290,[-933606177,-657453485,-298165537,302651455,-858897400,-83995559,-588587302,-13967649],[-0.2805669605731964,0.2174130082130432]],[525,[437239691,1000060863,221724059,-1073743937,2095005119,-1094770761,1043807935,1054674879],[-0.3048814535140991,0.20650653541088104]],[184,[-18895094,-131137,-176166466,-203950081,-679546994,-458838209,-68609,-83903493],[-0.47668248414993286,0.1267579048871994]],[12,[2070372663,1998954923,1360207630,1065855538,1377767440,1048259495,1532963338,1968650755],[-0.2667206823825836,0.2210763692855835]],[507,[-922484943,-2027893262,-12585487,-8266672,-1488986463,-1674711105,1393415553,-542141047],[-0.2740706503391266,0.22819964587688446]],[194,[1354368042,814917051,-1126355395,880586619,1559710910,2029785056,-89175330,553090803],[-0.3573450744152069,0.15573251247406006]],[589,[-282073181,261095098,1871689490,-541068327,55427495,8912388,612324563,-705694721],[-0.2390359789133072,0.23758962750434875]],[104,[-206573910,-422925430,-386145678,-136123704,-286278705,1141151376,-479206272,-708320058],[-0.23658229410648346,0.2405620813369751]],[206,[-654652226,-2476513,-1573208611,855821951,-660959876,-9016767,-1131742502,-14483617],[-0.26215147972106934,0.21193760633468628]],[390,[-9010944,-680453375,-1887353857,-47901136,-608526176,-574418016,-1046431574,536871426],[-0.3288300037384033,0.16450397670269012]],[448,[39859029,1953028272,222289789,-538380840,665888169,-71795760,248524477,-1950416872],[-0.2608546018600464,0.2046564668416977]],[24,[686465762,-1275658177,692424703,-1350105627,-1308678529,-1141437607,88731642,802765499],[-0.4210531413555145,0.12438227236270905]],[617,[-16784885,-92289121,-1600719916,-798303556,-159384564,805854224,-128647992,-536622122],[-0.21299290657043457,0.24448233842849731]],[163,[-521214738,-220246129,-1561452498,-219421974,1080886061,308284728,1942440958,-139730089],[-0.23567050695419312,0.20919010043144226]],[559,[-218116608,2854795,586149408,231713907,-136605256,888171669,-152650100,-1393765652],[-0.2231275737285614,0.22375470399856567]],[581,[-180380895,1437970737,1001598225,-147463246,375874851,623058979,589757370,50832259],[-0.26574811339378357,0.18162758648395538]],[176,[-349183357,-205064856,1591152880,-177359388,-1414794578,-846925632,100053228,-985415232],[-0.18771494925022125,0.2632349133491516]],[360,[1329651669,1544846740,-1624838371,-81289607,1174445848,-636449096,-811966501,-609253157],[-0.14781230688095093,0.32182273268699646]],[426,[320255795,-1122912577,1562588985,-3678414,81212071,-1345083980,1775598843,828858931],[-0.3038376569747925,0.15808410942554474]],[611,[-14681,-1041249298,551283406,1089139306,-721422588,14971399,-404950336,-1057492274],[-0.2350015789270401,0.19808870553970337]],[327,[-656473793,-1621491117,-252526727,360189542,-967046976,-54702987,2092583960,-81592757],[-0.22867658734321594,0.21082723140716553]],[195,[-213859158,-17798588,-2144935180,-674987740,-681448807,-826009773,-993984833,-74230701],[-0.17290616035461426,0.2766934335231781]]]],[-1.5635454654693604,[[29,[-218103809,276561887,-138412065,-1,822083583,1895301085,-131073,-8193],[-0.2779134511947632,0.2914063334465027]],[410,[-134217732,-2124833,-1141117716,-545051746,-327187232,-16385,-923826040,-290455878],[-0.47651201486587524,0.16560232639312744]],[291,[-488453418,-36125012,1580386906,-6863783,1078215240,1288454875,-834384306,-536917493],[-0.2843717634677887,0.23990501463413239]],[196,[-631371010,-571503013,-394375427,-53617,-699199745,-100726021,-168882689,2079264479],[-0.2852992117404938,0.22660185396671295]],[217,[-548034902,-67108929,-678035457,-33557569,-203424081,-3147385,-6913,-2097425],[-0.38240256905555725,0.16137607395648956]],[566,[-1155272272,-550848592,-304122592,-1055752,-807405859,-842933767,1224691796,-572523826],[-0.2944502532482147,0.21465636789798737]],[70,[-202375193,-152109334,-939854174,-1049502,-146817149,1111796162,-201330492,-237504574],[-0.20517322421073914,0.29565006494522095]],[362,[-562278827,-589558940,-709079073,1597507911,-242185992,-37871622,-7815682,-1423310294],[-0.2691945731639862,0.2276601344347]],[456,[938981281,1039662303,1071988533,-1077430345,2138399927,2128867248,1844920255,553084791],[-0.3116950988769531,0.1914835125207901]],[595,[-6001,-738460161,-491325280,-253577536,-101257344,-268405248,-218703928,-262931494],[-0.19845137000083923,0.28662288188934326]],[219,[-572575425,-134758593,-17432673,-33572033,-41975809,-606209,1819508539,991508795],[-0.2848263084888458,0.19544802606105804]],[309,[-923858941,16533375,687803098,16641781,1425998848,7298130,-117618036,-1459880273],[-0.3118402063846588,0.17289452254772186]],[38,[43975170,570610210,1259547439,91211681,1344147713,71570948,157771867,1194450935],[-0.40333592891693115,0.13441282510757446]],[547,[-620234959,-144179343,-146804237,-275775558,-1956118605,-1364333069,1464849904,-273678849],[-0.22020047903060913,0.2527577579021454]],[207,[-889729313,-553657669,-1560807681,1383525103,-889272690,-278931701,-3289105,-8913157],[-0.20864352583885193,0.2517823278903961]],[386,[1527208720,453049088,1849883952,-577776648,119313820,-635902472,235845803,-1081104213],[-0.2004029005765915,0.24476240575313568]],[105,[-1792337,-135877649,-877376633,-6542642,-170938369,-1158881281,-335549505,-45848810],[-0.1526852548122406,0.32784590125083923]],[45,[-207358038,-420480598,-201337216,-706480664,-2247288,38040834,-201852992,-707267118],[-0.2064659297466278,0.24018539488315582]],[489,[2125956864,876459318,801054519,-1343357377,2029731224,1039974069,517353000,549746646],[-0.34877002239227295,0.1354045271873474]],[305,[1573977072,-545230924,-503523394,-50543968,-10687586,-806753917,-132104,-131700],[-0.39878302812576294,0.11964873224496841]],[119,[-152047962,-219222301,-386358750,-134552838,1919010662,3367751,-234912529,-203950258],[-0.18678680062294006,0.2509252727031708]],[57,[-1548225838,-544303113,169017858,-1079528078,-65317898,1003848540,366421887,-8390913],[-0.3702678382396698,0.12458038330078125]],[236,[1558449156,1469328420,1056312229,972818209,2062028732,867725236,-299020370,944057152],[-0.32043197751045227,0.1403111219406128]],[372,[-935886289,247647375,584647234,1086240770,1243551262,140912131,1181705168,-433064409],[-0.25840097665786743,0.17777059972286224]],[89,[553422030,-646738485,-1378666531,-1326610755,-1193300225,-51663377,-1544714034,13992968],[-0.32469943165779114,0.13890093564987183]],[586,[-104865536,823385006,-1803553008,-137497690,73373105,557062035,-134236512,-493357073],[-0.21948955953121185,0.2058616727590561]],[575,[-621064755,-225691,-187123238,-211615832,-163588416,-834187516,-222115108,-532480182],[-0.16864611208438873,0.2542310059070587]],[359,[1080299799,403982237,-1396998339,1063594813,-1828978672,-1140929027,-64447240,-1414919521],[-0.2084922343492508,0.20172889530658722]],[429,[-278726750,1605286067,-1984582,-1183826,2008218293,-303018266,-454955821,1710712691],[-0.2077249437570572,0.20896007120609283]],[275,[1480501015,415012755,-1133019206,-1620136218,1060451253,988740863,-1174410540,-1157825603],[-0.18233922123908997,0.23548512160778046]],[5,[-14680093,-404291672,-76582128,-748686168,-138428475,-925915262,-143379488,-775432703],[-0.1731029748916626,0.2502557933330536]],[212,[-1537244639,1407124485,955327325,2007572271,1904150032,925836884,-671762604,-80740449],[-0.17120473086833954,0.24483337998390198]],[90,[242724607,-1477218697,133671801,267644576,-1896108289,-1476658180,-352868111,267886847],[-0.43268245458602905,0.09933996200561523]]]],[-1.4806630611419678,[[171,[-352321537,-16783377,-85984514,-218107170,-35652609,-5769225,-262165,-142606337],[-0.3028380870819092,0.2633202373981476]],[546,[-524299,-67633156,-537657347,-8228,-1073762819,-4219400,1300190552,-571517612],[-0.3547776937484741,0.2022661715745926]],[121,[-486544641,-136840193,-486552833,-4358,-134252545,-40001,-134258721,-41105],[-0.18016183376312256,0.3356707692146301]],[108,[-35928657,-47065673,-168170073,-172632151,-254750721,-638271497,-103690801,-610826356],[-0.34803321957588196,0.1765604317188263]],[446,[152059857,453032944,268172721,-1081999912,1058848761,-1074468867,-1155547143,-1077967479],[-0.24453158676624298,0.22779227793216705]],[512,[1060093883,-2118241,521748443,-543178753,1034941423,1054804398,1039581151,1068449727],[-0.2960316240787506,0.1986057609319687]],[74,[-1055825,-154210581,-489790880,-68688222,-143657140,1883399558,1909716800,-143132733],[-0.20965711772441864,0.2508717477321625]],[570,[2000680707,-1895041657,2143282995,-5243477,-1086853213,-1349915235,1373599043,-540016705],[-0.22155438363552094,0.22709301114082336]],[167,[-67108993,-147652614,-802882,-80484704,-8650787,-788545,-2832,-2685102],[-0.1801174432039261,0.27400344610214233]],[633,[-5393,-153096193,-85197202,-521211906,-136321466,1145489220,-67651890,-523766818],[-0.18812599778175354,0.2648163139820099]],[13,[-1105,-202377882,-537677054,-67700788,-73927229,1146024982,-147589632,-706219049],[-0.17558620870113373,0.2530442774295807]],[324,[1309147731,1342867306,1855638557,1060310665,1279543388,1581780126,2128137819,463161099],[-0.215001180768013,0.20435485243797302]],[136,[470028175,-134246505,-609905701,-40167997,-236079105,-50477073,-1544564785,-1350038900],[-0.2391396313905716,0.1823912262916565]],[627,[-335548501,49278626,-968163296,1621881580,-469768313,71821925,-135800892,-709367826],[-0.21279625594615936,0.20251362025737762]],[85,[2071061109,1597442983,2142580527,60883457,601335733,2012720631,-268461122,1151825767],[-0.24757970869541168,0.1766466647386551]],[526,[-35661939,-1077936193,-301995075,-1183745,-154163571,-122046731,-1449525588,-1933180945],[-0.12376438826322556,0.34610992670059204]],[413,[-68157449,2012427621,-135270402,-318116709,93786352,878040771,1928528416,-252444969],[-0.3528245687484741,0.1253521740436554]],[97,[-299178321,-253579410,-505086341,-106781557,-528036177,-12284558,-269619473,-918469118],[-0.18893779814243317,0.2243262231349945]],[156,[1324150526,1610280955,-1358958593,-438721,1861166843,2063056823,-33851009,1374120788],[-0.23356471955776215,0.17476162314414978]],[254,[-855766433,1584267795,1915910911,156285,-153399800,-211608747,-293675318,-553456689],[-0.2666938602924347,0.15304766595363617]],[578,[-738212306,-188874866,-1569000750,-789874034,-142702264,2031301632,-774720374,-800870518],[-0.19974224269390106,0.1993950754404068]],[549,[-466664669,648734646,1438586999,-35130723,-1414815573,717124154,94090911,-806368801],[-0.13644744455814362,0.2769096791744232]],[342,[1249838607,693062607,184519193,144110238,2055029833,204701535,2054005330,-288359529],[-0.24984607100486755,0.15084804594516754]],[72,[-9443413,-23204177,-507513166,-137462546,-159909905,-1006442233,-192945170,-235407873],[-0.11998380720615387,0.3182705342769623]],[421,[1494269173,-720349708,1063892989,-545465860,-122642948,-1074219268,-1347932744,-1417019368],[-0.24514228105545044,0.15939368307590485]],[336,[1602171163,-69345349,2092678079,-1342178561,847146299,-352846093,1809574457,2071953275],[-0.25552767515182495,0.14843150973320007]],[348,[-151650305,-572701128,-843776304,-712703488,-275972610,-611461836,-23282034,67390465],[-0.19797073304653168,0.19756489992141724]],[80,[-6353,1920937967,-1066998110,-209788174,1460628998,1095128909,1900515906,-178784682],[-0.20146924257278442,0.19506125152111053]],[535,[671069953,868219827,-1355307213,-1246761157,1008137220,1700181427,1596434984,143191592],[-0.29868990182876587,0.12109743058681488]],[102,[247622355,165839509,803910905,1273476677,134210527,-541883513,-1375763256,265808373],[-0.38485702872276306,0.0911681279540062]],[96,[-37750801,-812843030,-220433808,-144715680,-121636937,-309815552,1626855360,-716966446],[-0.16374103724956512,0.22773180902004242]],[543,[153361681,286744433,-1351190668,-1368652198,389244373,1069414655,41379716,-322010229],[-0.2370050847530365,0.15526917576789856]],[328,[-866462505,-765927816,1978289788,1058089531,1599921360,-539435782,-291741862,-1626666481],[-0.15901291370391846,0.23870913684368134]],[283,[-656868899,-1688724035,-1510113953,863235675,-1872148424,-5628044,-5072136,-1079878326],[-0.20384007692337036,0.1838795691728592]],[134,[-1367079007,-1114562671,1840407673,-80561904,-1480914455,-809727614,-374463023,67108864],[-0.23268628120422363,0.15638644993305206]],[481,[-101203328,-579340569,-676354283,-839058037,-572153460,-388903440,-859517276,214036430],[-0.19198764860630035,0.19319075345993042]],[605,[-209752881,-137424530,-487666946,1884224456,-10503608,-228324026,-84216120,-228393014],[-0.16494055092334747,0.21874834597110748]],[567,[-742399053,1128773464,2012640561,-684720133,96431507,1146418932,903034192,-2143824025],[-0.24089863896369934,0.14685575664043427]]]],[-1.531322717666626,[[118,[-755055873,-603985153,-83902465,-21765,-176712705,-21761,-173313,-45313],[-0.1970607340335846,0.3158511221408844]],[379,[-1,-5,-453312513,-67436549,-520375056,-1048577,-1409303830,-67371013],[-0.20109902322292328,0.2925731837749481]],[472,[-1157431311,721466416,-5538351,-551232336,-1442447427,-6095109,267895293,-810822183],[-0.246646910905838,0.21074186265468597]],[208,[-754987265,-635491769,-422379777,268627711,-293623114,2135249669,-12546,-11011073],[-0.22645103931427002,0.22744908928871155]],[498,[1602221841,941538719,-1107427819,-1614811905,2038431645,1073474047,-34735681,1023278847],[-0.2475070357322693,0.21533721685409546]],[596,[-4213,-655362609,-925375808,-253107478,-2099320,1145502980,-118489462,-255332370],[-0.1756095141172409,0.27202552556991577]],[246,[-262146,-575078470,-1242334370,-302312,1004126207,-16418,-449086918,-536885544],[-0.22480174899101257,0.19904428720474243]],[98,[1404276623,-239733835,2100921775,-705445473,-251883793,-84835913,-118452273,-609710193],[-0.3100532591342926,0.14657047390937805]],[21,[-1050709,-219156762,-488639934,-253308274,-9444029,1078966087,-167774398,-235408433],[-0.19676518440246582,0.224064901471138]],[210,[-17597718,390550447,1543499727,-1051889,938702543,-955581534,800062155,-4194737],[-0.2056204229593277,0.21108107268810272]],[148,[-231825238,-118708248,-126915649,-35385563,-51306769,-122622556,-64495777,1883338499],[-0.23083308339118958,0.19100864231586456]],[544,[1461976433,-687707020,-671102467,-69411352,-283119619,-34615555,-545307240,-825239080],[-0.2323579341173172,0.1847982257604599]],[214,[1076339200,27197442,-1430500781,-15102177,345466176,1407143952,1909970806,-8423553],[-0.2082488238811493,0.19525180757045746]],[562,[-1910004736,227976629,-1397791456,-1647335945,-1090738556,1023222964,-1359086680,-1431505921],[-0.2151651829481125,0.18513250350952148]],[107,[-72356977,-674304370,-88611088,-68163352,-210769969,1615099074,-186211200,-170421565],[-0.15987128019332886,0.25031208992004395]],[19,[35788594,-570473098,173184975,-63105,686291999,-5259537,205462959,-811630449],[-0.3976033329963684,0.10220080614089966]],[482,[-335567743,-134878025,-1109925897,-273158221,-68311108,-67174475,-1088045138,549775094],[-0.18809646368026733,0.20953576266765594]],[571,[-1372850253,-13974142,-1678790192,-76566280,-1973441117,247966637,1465861521,-570433813],[-0.19961197674274445,0.19941739737987518]],[635,[-687870257,-253248569,-150996374,-1058605588,-42473594,1111936836,-562907444,-730337333],[-0.17394885420799255,0.2222379446029663]],[205,[1117962991,1383945687,-500503332,809498271,243157775,2115858421,-75727153,-2363489],[-0.21008644998073578,0.18192526698112488]],[397,[1546701304,1502674361,1862028696,-68619312,1224269564,-8404279,737211100,-20651148],[-0.45097893476486206,0.08725540339946747]],[60,[-393501017,-151003489,-8925315,-1073880539,-2068927745,-1157701426,-858402901,67453124],[-0.22688327729701996,0.16925102472305298]],[232,[1510739604,863309605,-1360064513,-1713172665,1993154559,953815035,-79736866,725943043],[-0.30244749784469604,0.12280921638011932]],[293,[-431620010,1347961407,1645639766,673317522,1083067468,1591659708,-467746,-14463397],[-0.2931867241859436,0.13229398429393768]],[507,[-1912234189,788717234,2000052609,-544997440,-1960506219,-1405096517,1362056513,-913318435],[-0.2361961156129837,0.16040034592151642]],[400,[-995127773,732950504,712712466,586101759,2120161651,242180931,2013206538,-3257],[-0.21951305866241455,0.17167043685913086]],[0,[-13634581,-55838738,-1242056846,-540019520,-112200001,-1060453490,-202902559,-705171148],[-0.1406068205833435,0.2656737267971039]],[276,[1598289887,520138729,-4239399,-1224492136,796904957,-1703941,-103457531,-1141394078],[-0.13021205365657806,0.27274754643440247]],[151,[-271652182,-24632894,-899102988,-10017558,-1209538625,-201046843,-136907778,-137935742],[-0.14946521818637848,0.23473292589187622]],[116,[-756028693,-218968594,-2101451038,-7430,1120845454,2014372962,1666642894,-168057645],[-0.13821019232273102,0.2557409107685089]],[33,[1534696261,1062842133,-1342824577,16852899,2098415232,2098566439,-403313733,1346862895],[-0.22740162909030914,0.15381287038326263]],[238,[295636992,821772143,1801930031,995190037,2063248814,-1080066052,-1165455861,779029435],[-0.4081084132194519,0.087570421397686]],[299,[-10350288,1953972019,2142658045,-168792567,-849660939,-20977786,1374479412,1879061282],[-0.3079519271850586,0.1165873184800148]],[565,[674213888,234891194,1069719170,1066331550,322168757,297054135,100431778,-940649218],[-0.25961834192276,0.1387970894575119]],[461,[-857747457,-542310940,-336830604,1856806596,-35369559,-33792609,-2064905188,-858837124],[-0.14236339926719666,0.2515232264995575]],[137,[-1208749149,-808992822,1941781200,-248516152,-1493452850,-932784438,1406792916,-171445034],[-0.15282876789569855,0.22942787408828735]],[169,[-358692337,1913603755,1780904038,847543030,2130366282,1465284100,-8519941,-146296866],[-0.20485755801200867,0.16542507708072662]],[598,[-624964407,1929293739,1660384790,-235366402,-781729664,1950379016,-86250104,-251396098],[-0.14611224830150604,0.23367854952812195]],[417,[470098293,68724625,2137775989,-1892868772,2124421621,-19018243,977084317,700385347],[-0.20630234479904175,0.1670524924993515]],[326,[-366232099,-190253736,-1380867905,-69371941,540412351,2038193550,178462734,1624598175],[-0.22028318047523499,0.15421783924102783]],[615,[-341839709,-1026897234,-2084621072,-2054694368,-1493174289,191097334,-53018662,-2117081441],[-0.15134109556674957,0.2281082272529602]],[306,[-553664381,1415565023,-2072524587,1367308795,-252592630,1556899377,-22070406,-525337637],[-0.13117921352386475,0.2531299889087677]],[377,[108201239,9837407,592193301,136324358,1550649125,247541396,1311001108,1141928512],[-0.3607528507709503,0.09472320973873138]],[261,[-933699454,1776876279,-820938308,-539560229,-42108166,-554199719,-544738,-84412445],[-0.37590476870536804,0.08685655891895294]]]],[-1.496147632598877,[[327,[-620831233,-537069577,-101417505,-13168873,-556086056,-536873473,-543629570,-81080321],[-0.20265258848667145,0.2719714343547821]],[458,[2147483575,2147483647,-1073873409,-2228257,2146795519,2130572534,2130018047,2012705527],[-0.2265007197856903,0.23255248367786407]],[447,[-274730064,-1828490718,369062224,-542114548,-1364483424,-1347425350,1423397120,-978321525],[-0.36266660690307617,0.13946540653705597]],[185,[-572799778,-658813697,1438600447,-537458434,-805311745,-923335015,-800005,1610025215],[-0.20851968228816986,0.22624310851097107]],[249,[-856105761,-33882273,-1171097633,-1224545442,-861365000,-2458133,-71565606,-72679542],[-0.23597721755504608,0.18162688612937927]],[48,[-21,-3741714,-34078816,-527638,-113,13434820,-135536062,-168298546],[-0.15795913338661194,0.27534615993499756]],[410,[-202379265,-33554465,-269488146,-17891337,-1023410948,-66561,-1091883318,-1052929],[-0.15668000280857086,0.26539573073387146]],[264,[2038380347,-67289281,1824356671,-101238593,-631259777,-67492802,1886915711,528432447],[-0.35712456703186035,0.1191648617386818]],[593,[-100673841,-69224881,-118170894,-260898840,-1050808,-163419068,-195891512,-261881906],[-0.17496080696582794,0.24545976519584656]],[191,[-789133138,1357808511,344927999,276753983,-117987153,-119992597,-369100129,552039275],[-0.2423415631055832,0.15460087358951569]],[568,[993523459,1068448807,-134417102,-40896850,121108099,-1929384980,2004276738,-1207959621],[-0.23254016041755676,0.1672218292951584]],[445,[1043149619,134807472,-147062799,-1389785608,778508721,-1078985799,1052163003,-1347437061],[-0.15260687470436096,0.2397785186767578]],[224,[420417423,363269511,-1181413745,-41029713,487264223,-67125253,-1141534769,-7385137],[-0.2702747583389282,0.1346423476934433]],[510,[137232896,33988648,1929270085,1977700989,548021027,539665932,585611707,-1880109889],[-0.20664082467556,0.18262037634849548]],[83,[-537395337,1915903126,-1083662512,536906274,-1726232561,1041620991,-271596849,-780664993],[-0.3592633008956909,0.10130912810564041]],[610,[-16781429,-152051773,-469767584,1626332074,-136839290,423686,-253248888,-255332390],[-0.17431952059268951,0.2102852165699005]],[133,[-336599041,-8133922,-1141113930,-37248794,-912916546,-308113878,-1007163154,-993664890],[-0.12619158625602722,0.26890262961387634]],[157,[-491853138,1357672160,573189794,-69711698,1661179311,541861739,2002744015,-170436793],[-0.18496830761432648,0.1792939454317093]],[625,[-5457,-479461718,-343330784,-236206134,-734006329,1113998678,-486541632,-707789857],[-0.14289534091949463,0.23088638484477997]],[244,[34604197,314455839,709823416,1055849114,242550243,1006448564,777592829,-1075859328],[-0.23958338797092438,0.13976256549358368]],[331,[-1672813806,2117239444,1981954909,790760502,-1761080108,-2823052,-7282818,-352180693],[-0.204872727394104,0.1605996936559677]],[584,[-14682192,1410054962,930545776,-704669782,1462208945,485762336,2094510506,756531114],[-0.19781313836574554,0.16727229952812195]],[313,[-8917097,-1090285819,-1361920071,-1365204576,-587337803,-21561419,-1628979300,-1092178412],[-0.13299308717250824,0.24190054833889008]],[553,[-67124722,-244319281,-159678928,-235658710,-235168120,556126992,-640763208,-247201910],[-0.1459912806749344,0.21836180984973907]],[432,[-1574459869,1801694139,688355093,1137244896,1597321139,667307894,2103932223,-875206861],[-0.1999962031841278,0.1616845428943634]],[467,[1415519575,2086366073,-277518529,223099000,2085048285,-1107460609,2103254796,-2004256296],[-0.173945352435112,0.17971649765968323]],[631,[-136321265,1345830367,-352396334,1615494266,-807156,-1773853180,-156565858,-797708465],[-0.15880204737186432,0.19731280207633972]],[153,[1244179144,1261546146,-363663553,-268711247,1351877499,-280641,-84327201,184487424],[-0.294883668422699,0.10669518262147903]],[287,[139709719,43029023,716864123,145948174,72842328,-542019334,520215374,-68543909],[-0.20783309638500214,0.15214750170707703]],[388,[-12132331,-1257178152,536162265,-1073758883,1531509500,-1143015176,677185805,-1916803061],[-0.13157057762145996,0.2420303374528885]],[508,[-1297104925,908165800,-1346954911,-1658201648,-1566723143,699314924,459246985,-1918904868],[-0.18554656207561493,0.171234130859375]],[178,[-2030042720,-638576553,-856623777,-1155485679,-272560641,-73725530,-1699976999,-2013232128],[-0.19297820329666138,0.16354376077651978]],[523,[-802903936,219991281,-1380735344,-1677912129,-1196039740,-1924874396,-285426550,-1981250341],[-0.16431039571762085,0.19124364852905273]],[187,[786271998,353427327,769929200,901316269,-2013419265,1070845648,-1929524065,745335551],[-0.34417709708213806,0.09130412340164185]],[258,[678666755,1795098123,715934564,-11026437,2029921792,58675732,-672615084,-138415361],[-0.16051757335662842,0.19698475301265717]],[537,[757053313,1066712229,-1220563659,-1077439073,884821983,-1073791051,-137412097,-1343329298],[-0.1701008826494217,0.17927823960781097]],[82,[1389352639,1912983387,552783085,-1334070951,1883213615,875581417,1061134046,1628826575],[-0.2355739176273346,0.135020449757576]],[43,[-148378625,-454104340,-444894224,-3679494,-170132001,-2004452736,1979433184,-705169834],[-0.13890986144542694,0.22841182351112366]],[292,[-562163691,-612498656,-398797281,453517379,1576666200,-69248251,-836204322,-14537969],[-0.19448943436145782,0.15733850002288818]],[394,[-802954462,-214240474,-171104766,-526590,167222773,669761943,-138184978,1684498211],[-0.2066839337348938,0.15022484958171844]],[444,[-323100186,-21839924,-1663054876,-1785792953,279978382,685830218,1700463695,1075309899],[-0.23692423105239868,0.12721052765846252]],[183,[-470300502,-779440474,317666416,-237112100,-1623348022,-837984724,1892930262,-720943418],[-0.15833552181720734,0.19168458878993988]],[419,[286629325,419495792,-281560203,2100829820,-1760265995,-1107509763,-1347405073,-1416952693],[-0.14504113793373108,0.21510179340839386]],[231,[-127662976,-1087598676,773459488,-35385847,1652563440,-170590944,-386639138,675557121],[-0.2552856206893921,0.12368638068437576]],[431,[-571158532,-1123001732,-541836356,1911335552,-730029140,-520339162,-1192711304,-1090725180],[-0.416248083114624,0.07490038871765137]],[84,[-232924694,974885303,-1350574289,1336799215,291214187,-2140233508,1643271951,1607457567],[-0.20407570898532867,0.15173958241939545]],[307,[-554874737,413568674,-1442634037,281801574,2020022853,671503039,-193074614,-390597677],[-0.18695932626724243,0.1645810306072235]],[75,[-135269693,-742200265,-1410699614,-13836096,1237270351,1879118941,-203115702,-243795973],[-0.1366724967956543,0.2194761484861374]],[41,[149662391,267466357,1751289335,248190673,662646779,1052753397,-1476979457,233637266],[-0.4083424508571625,0.07441364228725433]]]],[-1.3947604894638062,[[201,[1258228431,1541393407,-362082691,-2102673,1138427903,-33607787,-36885,-8451185],[-0.22683575749397278,0.21698297560214996]],[542,[-142609485,-147341345,2147430871,-1244137569,-671091209,-536948741,-175245326,-167774241],[-0.21389076113700867,0.22244058549404144]],[311,[-67108865,-1683297558,-1522913379,-1365204446,-537268289,-340083462,-277894725,-286274934],[-0.1599258929491043,0.2807232439517975]],[385,[1493442005,487622616,796877695,-541253667,1548222680,-537371139,-4661570,-1141957985],[-0.16421283781528473,0.25366565585136414]],[453,[2012324787,-786541,2127984599,-1712157,1467463095,-21102638,635748263,552953719],[-0.23738333582878113,0.17089855670928955]],[251,[-655697441,-109412993,1067113279,251802999,-1364535078,-14766082,-1077216354,-366813250],[-0.2866738736629486,0.1445491462945938]],[44,[-67108865,-741279774,-404489384,-586351998,-68816978,-222027262,-143300086,-783949310],[-0.13955391943454742,0.2744167447090149]],[470,[335904627,688454032,-576326285,-821588848,-2057208907,-1716607047,-1955598855,-1884303895],[-0.18432578444480896,0.20841632783412933]],[577,[-603989137,-18,-1291846942,-253431302,-8388664,-1132204282,-1226317176,-800850994],[-0.15180069208145142,0.2387949675321579]],[92,[-1107974265,-1107488321,-438980181,-34271041,-705322561,-1779060809,-1852239449,1035052479],[-0.26681289076805115,0.13597114384174347]],[130,[547815938,539725376,590284047,254798327,111100181,1881297024,1050504923,1086317355],[-0.29581764340400696,0.11302649974822998]],[402,[-202970846,1997573378,-807003368,-33822848,1383556917,2146907953,-8949889,-8951981],[-0.29145026206970215,0.11627478897571564]],[548,[-1351616079,-275847760,-807451663,-7342864,-1959811935,-2102481202,91706817,-577790499],[-0.22961539030075073,0.14421683549880981]],[315,[-173279301,-570831744,-591597857,-1920606976,-875315793,-743121507,-84161761,80942663],[-0.16261959075927734,0.20734244585037231]],[154,[-295507282,-222108994,-337368354,-9054488,1695393195,1276183616,1465712383,-203995565],[-0.1629696786403656,0.20082713663578033]],[529,[743681152,1060998324,-1108396745,-1109544971,2146248364,-1131831369,-1109106804,751052416],[-0.2580071985721588,0.12539248168468475]],[624,[-134222193,-823203865,-355090400,-219170820,-9699354,1120917334,-236982078,-168297777],[-0.15296129882335663,0.21096526086330414]],[8,[-142608477,-292753778,-105415054,-168900640,924034995,1086518660,2012737924,-705178122],[-0.16148518025875092,0.19514200091362]],[164,[-635449601,1383502423,-491069862,818069179,-763408706,-132708062,-550005,-143263077],[-0.159551739692688,0.19565145671367645]],[304,[-91324273,-638948913,1459102352,-234883138,-411134456,608256066,-201791862,-213123857],[-0.124847911298275,0.24199718236923218]],[141,[1924049967,-68243729,-1443053961,-102600915,-17306377,-56061955,-17170689,-247107769],[-0.13098762929439545,0.22698824107646942]],[273,[-34538584,-36058140,-1051656288,-35789003,-268782921,-131587919,-10961985,-938149707],[-0.3826730251312256,0.08256648480892181]],[128,[-676125470,-422419785,733606671,1331165455,-1581583803,1441710245,-1152161,-1048625],[-0.20781999826431274,0.1617911159992218]],[541,[335879441,857358129,-1080172780,1036762602,812061588,-1074364481,1313293872,-1344439906],[-0.23761694133281708,0.13307097554206848]],[330,[-155579051,1977548902,-109936641,527894909,-754445200,-138473890,-72820226,-83217585],[-0.1539456993341446,0.1961182951927185]],[109,[-105978129,-89202036,1206379146,-137441666,1935124399,1946251504,-1326188912,-146279937],[-0.13842856884002686,0.21920017898082733]],[490,[1833936128,997703423,-1255263405,-1113732166,1549563407,-100835876,-1365059701,960064042],[-0.28704747557640076,0.10284743458032608]],[298,[1085179907,1558038199,-647534401,-780680693,1246731967,-495023986,-2065708378,458754],[-0.2138298749923706,0.138645738363266]],[630,[-235929793,-35017425,-974852131,-1473993990,-154806396,-39664848,-218780980,-1069420542],[-0.13126356899738312,0.2278546243906021]],[380,[1164428247,330592127,221719867,220515469,1525638961,771553661,6317897,71567872],[-0.22609888017177582,0.1348307579755783]],[450,[-168189951,-537955555,-261358634,-237300738,-220334180,-301885632,-674048822,-784091958],[-0.12464315444231033,0.23845015466213226]],[248,[202362591,529960950,687636059,715847819,49893116,-1075370050,-1090575784,-275320512],[-0.18483379483222961,0.1581660807132721]],[369,[-59776341,-546708861,-1996605390,-751324454,-5509237,1212568876,1987049206,-84414181],[-0.10926777869462967,0.2634029686450958]],[322,[-859874849,-589690915,-1078272001,-269396281,1444829252,-361363,-1088889270,-14524897],[-0.1407398134469986,0.2058841586112976]],[558,[-656422264,1404815771,215051032,1573253083,-1258510968,1056763359,-1342722118,-1431572741],[-0.1293744295835495,0.22350135445594788]],[580,[-538976242,-706933761,-1157899644,362671324,-616768120,76414080,-1145002358,-257163377],[-0.13464896380901337,0.21594136953353882]],[500,[125169463,419200829,-1376628745,952940586,936641716,-1309459009,1895069444,-389533710],[-0.19427908957004547,0.151099294424057]],[197,[-936448836,296527797,1725790972,1040187375,2094788862,989460023,-119468066,821391343],[-0.22964347898960114,0.12504659593105316]],[27,[-8452601,1934077794,1941583474,-1298074901,2048863812,2084627268,1498884488,-481959089],[-0.16685572266578674,0.1735781729221344]],[363,[-854920272,1466228596,1841174397,-1350754044,-1912043332,-544412176,-1074884950,-1351636949],[-0.1349325031042099,0.2078791856765747]],[399,[-759714941,1319853762,465518886,25093107,1311451838,262313924,1264269234,-67639305],[-0.1470017284154892,0.19267882406711578]],[285,[-62210118,-95633686,-543498916,-5647854,-582576008,-858743621,-1076589240,533272664],[-0.2338734269142151,0.122316375374794]],[63,[663490442,868591391,944180691,-1725045803,-1515212829,-35061268,-960230409,-1358689591],[-0.2431904673576355,0.11639515310525894]],[476,[-488118528,-1001853142,-1284508299,-24149798,1848082858,706898854,-822111589,-1027604833],[-0.15382418036460876,0.18594354391098022]],[68,[-344199257,-355533682,-1103629790,-672858904,1070593471,-997397002,-152595754,-246940218],[-0.1509171724319458,0.18637944757938385]],[31,[1793322823,6471586,2136661902,544275114,813647735,1076229465,388745606,1349749552],[-0.5150347352027893,0.05549565702676773]],[479,[-1051226111,-906782909,-1752851951,-573214941,-514355772,-34304515,-1917518166,-2080365046],[-0.18393677473068237,0.148982435464859]],[561,[1139012403,1401008551,133777171,366319523,381097650,1549129111,1842035418,547765943],[-0.21134988963603973,0.12946300208568573]],[53,[-525423697,-1284755713,-208931,-1357271134,1492289279,-108851201,-327389860,-694524],[-0.12473458796739578,0.2229464203119278]],[408,[-1053781711,1488768055,-1883353875,1772158314,-328087099,-1117247528,-937669396,144711680],[-0.24978365004062653,0.11137084662914276]],[158,[1652543131,308775679,-956675393,-1083456334,1883606772,377030805,980155213,1904691731],[-0.17729288339614868,0.15420784056186676]],[211,[-228447566,1986675278,-1710034373,539124387,1681978890,-2146306,2146938783,-277360677],[-0.24232980608940125,0.11379676312208176]],[344,[1316210703,384430053,-1605375990,-1886392130,1727284535,788489447,-84560439,-34605257],[-0.19972075521945953,0.137681245803833]]]],[-1.4742519855499268,[[121,[-1023416577,-4353,-218103809,-4199429,-469764097,-38913,-218146817,-33041],[-0.15614232420921326,0.2845953106880188]],[569,[-14419983,-40645392,2105497077,-17200,-1074790407,-1963226659,1509905749,-573581860],[-0.26622509956359863,0.17384453117847443]],[277,[-2228225,-537002337,-993984612,-570614067,-2360321,-539165186,-1086001221,-582353009],[-0.15457338094711304,0.2492058277130127]],[501,[1497849681,-46703179,-541254857,-152143362,1245972736,-19211521,-355578294,-930420486],[-0.22253337502479553,0.16836225986480713]],[359,[1348230493,-572761801,901578239,-575135907,-665562984,-587575815,-577217316,-1079359265],[-0.2195247858762741,0.16715624928474426]],[530,[-22751,924006327,-1242563275,-1343226995,1740615048,-286293035,-1375884146,143518351],[-0.2085951864719391,0.16993917524814606]],[18,[-4177,-252706834,-89435614,-152109174,2012210959,1212315399,-137891006,-196608261],[-0.1806883066892624,0.1935441941022873]],[619,[-16782645,-67108979,-220049174,-1292960022,-671090880,2085024332,-261162808,-261619974],[-0.1650635004043579,0.2022944837808609]],[420,[-382737744,50788352,-1994165808,-15731432,-1707289424,-1424360140,1166807040,-1995450709],[-0.2954464256763458,0.11053616553544998]],[395,[-237505662,-7875693,-44228609,-541082249,-140249609,-2689391,-168296713,1441130294],[-0.18134017288684845,0.181584432721138]],[252,[1223614047,-566850177,452714110,1377860351,1314115214,-25223481,-887124790,-14950405],[-0.1985388845205307,0.16829168796539307]],[104,[-139465237,-221860946,-386469728,-5064,-67109970,-1027308284,-252448634,-170396417],[-0.1359160840511322,0.24295561015605927]],[181,[1547110426,-594080544,1242779512,2136932364,-31486309,-633908553,-93345025,1407648427],[-0.21696040034294128,0.1479005366563797]],[370,[1499790452,2109508592,-575091844,-302188396,-591074644,-68222826,-88022980,-109264732],[-0.4229183793067932,0.07374207675457001]],[383,[-606273731,-196612,-37945347,-1078413452,-68622672,-1073833673,-886375426,-357847909],[-0.13053973019123077,0.23168803751468658]],[42,[-504256601,-103693889,-1552631861,1907462573,-248469585,-243578961,-1001289745,-181465207],[-0.2983328104019165,0.10050108283758163]],[54,[-134222325,-59852914,2059134464,-236458270,-11550966,273579030,2011488840,-179834277],[-0.16351912915706635,0.17984919250011444]],[443,[1599067921,487038815,-780142176,-36833527,-228755067,-1147797541,-67116406,-1936719953],[-0.14494937658309937,0.2044524997472763]],[423,[-1060117723,105172292,-1816406059,-25779,724509227,585891728,1289685275,-1951405137],[-0.13382528722286224,0.21853315830230713]],[478,[-86114193,-313171,1111290354,-203817238,-2438456,-162604796,-233662248,-268173862],[-0.1297757625579834,0.22842766344547272]],[34,[2046686481,456335616,2042029853,864486144,-933104412,1873167254,-196099146,1728444263],[-0.21469497680664062,0.13323721289634705]],[465,[343343103,-570466369,1857224703,672685290,1434275581,-50389665,1962159104,-1933164800],[-0.17130576074123383,0.16903875768184662]],[589,[-818941053,87013538,-111184397,-37754531,-1898061693,176551654,1383588499,-943720513],[-0.16567197442054749,0.17757371068000793]],[519,[788713130,-1156586598,521182527,-1916946,2134622139,-541888753,-1893755925,1066076831],[-0.17230549454689026,0.16435682773590088]],[143,[-922759554,318630654,616432687,-302831042,-727324161,41682483,1920329832,1348428442],[-0.2049153596162796,0.13880960643291473]],[2,[723823356,-1076777961,-548951307,84377713,737552635,-1210946315,-1625454337,51577009],[-0.3284936249256134,0.08823275566101074]],[552,[-393329,-201327633,-220237262,1908912120,-536940600,-1069443776,-222112070,-245114118],[-0.11370333284139633,0.24661171436309814]],[280,[137866647,330497943,-1369628875,-1075382238,1313256957,1000285681,770980944,-279533994],[-0.15602348744869232,0.18064066767692566]],[39,[-876627029,-341120470,1475736498,-712395712,-1079659634,-2134787454,324531680,-985140140],[-0.16076508164405823,0.16893979907035828]],[230,[-790584800,-798953804,-1461039873,-33961394,-146490212,1421872403,-21414210,-1710152177],[-0.1537749469280243,0.17769819498062134]],[170,[2122294795,1377502722,1392496187,1342876671,-21078444,1174557952,-18705082,-213683390],[-0.19270925223827362,0.13925707340240479]],[636,[-286265721,1087368110,577492704,1623915622,-135286528,1145196902,1993571328,1347679734],[-0.2657798230648041,0.09998544305562973]],[398,[1982039846,397254535,791353898,-1627349,1729455863,1974525379,1867999102,1742958439],[-0.23255635797977448,0.11416502296924591]],[155,[-930355482,1391502078,-1394668033,-36122826,385550518,889011848,1061650251,812083063],[-0.21627771854400635,0.12228459119796753]],[474,[-1575620175,1360049280,-2023751683,-2633232,-2102872143,-1474564867,724025243,-879765027],[-0.13511040806770325,0.19969221949577332]],[576,[-19674853,-209862853,-1174651909,-247081470,-947934244,-67273344,-361432166,-268305918],[-0.12421544641256332,0.21285703778266907]],[56,[1606418223,1888960082,-549204542,9024010,-1749831699,-176720023,-617002195,-117478001],[-0.2160504013299942,0.12219076603651047]],[533,[532659985,481076660,1069384497,-1109532747,897535455,-1146290249,2093248670,986457767],[-0.2275753915309906,0.11520259827375412]],[407,[4710295,70527783,636325663,772164110,73221521,255335261,1734675540,14912],[-0.2595272362232208,0.10210981220006943]],[129,[1981030261,-784558837,26018085,1070988785,1565896703,528994556,791806603,1902506983],[-0.15912999212741852,0.1656181961297989]],[260,[67381250,-1627145297,-322568424,1301083899,-547766386,-1073754371,-270867206,-1351352674],[-0.4017013907432556,0.06479436159133911]],[225,[1425967788,2082375658,-1345048904,502528730,-168390835,-32914981,-35926390,818686652],[-0.19302360713481903,0.1390720158815384]],[547,[1868527361,-1221977296,-1891735758,2074998596,-821039197,-308147286,1432343616,-812652087],[-0.22188051044940948,0.12489976733922958]],[131,[-1557400589,-1248274,-613056656,1439425388,-1213219890,-2112947072,-1027083856,-706494382],[-0.13170881569385529,0.2017805129289627]],[614,[-1006640382,1080797230,-1475932128,1123009640,865575328,113265744,-1334843708,-462948914],[-0.20952266454696655,0.12552599608898163]],[360,[-1013973025,486547392,1073128087,-1626784775,105420508,-1152767500,-874785925,-611646437],[-0.11399252712726593,0.23128414154052734]],[338,[-830633942,2127447645,-1191940048,1916927034,-251667124,1112837698,-176687438,-250616629],[-0.14943134784698486,0.17533594369888306]],[346,[1417087799,280764279,113190420,231275440,1397886477,1081212924,1978420548,-792412416],[-0.17520387470722198,0.1438317745923996]],[316,[67284919,168863207,-550613281,765994050,-1262428729,-1076672520,-649814438,-1369156349],[-0.18277360498905182,0.13956578075885773]],[320,[-1004017133,1535149056,653028909,1572339459,408031108,2023804820,147856938,1606763075],[-0.16832774877548218,0.14991748332977295]],[403,[1304393556,1433759573,77663858,-1499455289,1970754580,888309687,1747679550,1786390635],[-0.38091838359832764,0.06628952920436859]],[6,[-856294403,-2317726,-1552485576,-369560984,-469158006,-62120224,-6132168,-783949310],[-0.13586831092834473,0.18866735696792603]],[585,[-570439936,818277201,-1159260624,367517684,2128999812,1485249311,-1397821528,-1576556801],[-0.15883666276931763,0.16120925545692444]],[292,[1555765623,-1621160633,-95796705,1999587663,1161353270,-8647867,-546809186,-16056501],[-0.12610651552677155,0.20256702601909637]],[509,[-165168237,-1036863384,-962127881,2140655952,-2085503053,-1361645123,721875631,-907031362],[-0.10026291012763977,0.2529263198375702]],[138,[-1041372593,-34650142,526856810,-142651678,-134299697,-472860218,-545794344,-706219574],[-0.11102330684661865,0.2323770970106125]],[430,[-895385053,-74011487,-2139413994,-269627264,907480823,9225072,325710813,-807964109],[-0.1419346034526825,0.1777896285057068]],[532,[-33182560,431646387,-1444991724,-1883374155,873740209,-1109836522,-84107345,-1345837813],[-0.13789501786231995,0.18308758735656738]],[591,[1512284963,1141564138,1212531296,1113560758,-1557154909,177122818,100626839,-1018171923],[-0.16264808177947998,0.1549759954214096]],[621,[-465586289,-1650720961,1677193050,-1245645074,1249883404,-1321181114,-924458918,1096148570],[-0.1387788951396942,0.1835004836320877]]]],[-1.4156285524368286,[[534,[-638102187,-679525099,-1028701999,-39250355,-50358343,-16824947,-70270465,-264417],[-0.2394787222146988,0.17213819921016693]],[246,[-102,-327766,-1317552232,-2088,-5261442,-67190785,-11965510,-539143080],[-0.23085838556289673,0.16734325885772705]],[117,[-286283025,1945448179,-287698945,-1201662,1962887167,-2019343,-36869,2138326851],[-0.2055557668209076,0.16909728944301605]],[446,[202504181,487127216,2143026545,-13386576,-1088807427,-1153572867,1002289913,-1145108339],[-0.1936747282743454,0.17333285510540009]],[607,[-81,-203438129,-119610708,-788532244,-3145908,1564880128,-69535000,-247203890],[-0.14611057937145233,0.22614458203315735]],[150,[83988110,-16658643,-5992498,2139989165,-1895069745,-1184840063,-303839025,-15741813],[-0.42162150144577026,0.0763353630900383]],[290,[1281287903,-992067593,-1707189025,304231711,-1931918256,-822131563,-664085938,-553461153],[-0.24101121723651886,0.1289917677640915]],[522,[-99,-67111489,-3670529,-2097155,-16465,-4334435,-151633,-1930571891],[-0.08985897898674011,0.3546532094478607]],[67,[-138414161,-204477202,-562727296,-1706382,-7871509,-2066808860,-170413340,-706218018],[-0.12456064671278,0.23621052503585815]],[440,[-22020619,-1688271921,-1268777234,-1126483556,-731392784,-5256193,-508600094,-1343229953],[-0.21830691397190094,0.13843542337417603]],[204,[-595670817,2137779887,842165854,696450687,-898069314,-13148161,-293893442,-11035046],[-0.16304337978363037,0.1813068836927414]],[177,[654378409,-215812202,-1617431212,-104401568,214730925,-624893564,-520853376,-1001098172],[-0.1843288540840149,0.15385165810585022]],[268,[-923466703,882443319,684861821,214183562,1216310488,821823419,-385921285,552943443],[-0.26095736026763916,0.10501748323440552]],[418,[-498279535,268466432,-135469008,2098156943,-733180535,958528317,296415627,-1894785397],[-0.149624302983284,0.1872091442346573]],[587,[-80747741,-440533585,917467936,-1117913366,1400489367,108504455,-470302329,-154675522],[-0.1663636416196823,0.16690850257873535]],[55,[-18880725,-202391769,-759287262,-119277466,1457470730,1950626060,1998312834,-263979350],[-0.16729773581027985,0.1605130285024643]],[599,[-603994229,1911548847,-194527230,-236195126,-134744696,12806020,-51512662,-247205941],[-0.11797425895929337,0.22724191844463348]],[297,[-489829469,1226741,800489375,-1350581579,1377190149,1085406199,-604275713,-145],[-0.12585067749023438,0.20891451835632324]],[3,[-1971608833,-1288591395,1475176695,1563627259,-1375785217,-17649729,-537679105,1337656827],[-0.23411718010902405,0.11347461491823196]],[437,[-591344417,2063130525,-1896214768,-307205284,-571913191,-59966273,-393475068,-2001993712],[-0.20314617455005646,0.1376352310180664]],[282,[101187391,364219279,-1176650755,1000767114,912373727,-1937409,2136472389,-12101881],[-0.1254676729440689,0.21802827715873718]],[99,[-207622237,1976559278,-421595998,-36702260,-4523009,-395844156,-151653426,-168299300],[-0.106666199862957,0.24177177250385284]],[247,[-176423049,42000772,-1076962432,153287170,2069362679,-1434126487,1743140804,-1608450558],[-0.3063652515411377,0.08508893102407455]],[215,[1572799552,1555302911,502016374,-783578511,-639160325,-1910286183,-272236801,1497303731],[-0.16857950389385223,0.15063311159610748]],[618,[-536892241,-34722976,-754993444,1925642998,-440,-565086396,1902047384,-800915489],[-0.14988699555397034,0.16982515156269073]],[10,[-76547105,1459287522,-83019108,-110054718,1164994324,-91993341,-851351024,1900143122],[-0.14859989285469055,0.16797077655792236]],[493,[210804112,1014671005,-135055168,-1078395007,2113214933,-1074900241,-5022132,1021654866],[-0.2165178656578064,0.11568113416433334]],[473,[1864359859,1195796354,-1679085072,1603270029,25372035,13287051,1163609361,1166013371],[-0.2746153175830841,0.09260080009698868]],[23,[-914427905,-1288795169,-303404033,-1078546750,1419528191,-31168917,-35070209,-61577692],[-0.10754923522472382,0.24138067662715912]],[243,[-864105242,445290293,-1393758754,951036643,752302524,-1078070320,-542736642,-1126565110],[-0.1480167955160141,0.16932740807533264]],[142,[-273756954,1942415086,575448290,-237796308,-148918550,-1005259754,1940834010,-238567265],[-0.13087278604507446,0.19493532180786133]],[322,[9446003,202403103,1824152607,147849757,1288968284,1576228077,1479597122,522870367],[-0.23417076468467712,0.10817093402147293]],[139,[-487937866,-262094681,-1100039561,-6056955,-877674561,-5305710,-322568449,-1002108093],[-0.15504436194896698,0.1600046455860138]],[81,[-145030135,1397697579,-368311472,2104467426,1948713096,1040733696,1984303748,-213412093],[-0.15200254321098328,0.1641494780778885]],[582,[-553663488,457408791,1690141440,1367473802,1628234624,8189057,-168234104,-2104755233],[-0.16342587769031525,0.15110038220882416]],[559,[-536951808,429892094,-1375777504,501218759,284931200,-1195353611,-1376873302,-1410664983],[-0.15035997331142426,0.16500341892242432]],[528,[-44894976,-1624795335,-1917477097,-1074532871,-1260347476,-53365552,-94048341,-1349298635],[-0.12065671384334564,0.20961812138557434]],[393,[-391658845,-878467154,948331218,2028076114,-617926264,1225967168,810803670,-403971773],[-0.13285785913467407,0.1815747171640396]],[382,[235150099,2111413,-288488515,797719756,273701972,-3580555,235419741,775624979],[-0.22059056162834167,0.11039188504219055]],[375,[-109781508,1400132593,-553322700,-1067589039,-277020752,-893591409,-400248840,-1575945558],[-0.35007745027542114,0.07238174974918365]],[263,[1442780976,2147431737,-1666169666,-537068613,-50644545,-101694274,1208049627,1394086042],[-0.24647489190101624,0.09931936115026474]],[73,[-202903617,2062270127,905170938,-577838430,-177209377,-97988910,-7930226,-195566882],[-0.09162109345197678,0.2710406482219696]],[545,[168785687,1235052478,786401219,781123582,-1706219793,-1632109057,-1127231054,-907025697],[-0.1308988332748413,0.19008301198482513]],[406,[120052671,78952369,1815027037,40380180,1968535543,500178705,1182027596,1141154900],[-0.1992865800857544,0.12260554730892181]],[59,[-2123369037,-1007755834,-75536528,-539651674,-1347699781,-863068216,1903277778,-716704080],[-0.13662229478359222,0.18261213600635529]],[419,[18421695,-1616330919,1605960693,-1079042055,-1083695656,-583092739,-1389350577,-1414856417],[-0.10727475583553314,0.21985870599746704]],[468,[1078396753,354631550,-1967409351,428813808,2020671776,822063083,1609375984,201788848],[-0.2235974669456482,0.11054740101099014]],[425,[-136461589,-219700788,-1199836930,-205259036,-682692658,-35350016,-144121122,-246950930],[-0.09437340497970581,0.2560350298881531]],[79,[-159406545,1899276489,-465811838,1922100042,2029683712,406996630,1410543184,-800720294],[-0.16321568191051483,0.14754760265350342]],[401,[707767079,489540902,946742334,468429541,1549207925,513686359,2137543788,-839975353],[-0.20473939180374146,0.11587535589933395]],[566,[-1895302736,-1962819824,1692382641,-1351708978,1991000568,-1779630215,1152997709,-845161478],[-0.17858609557151794,0.1356053501367569]],[323,[-134476363,-2967727,-100720641,1308314038,-475336,-1368359364,-1558008326,706880550],[-0.27970603108406067,0.08576671779155731]],[110,[1109568162,965390091,-68932241,-316003794,1404437503,-152829605,-363761031,1476677383],[-0.21853850781917572,0.10969985276460648]],[555,[-134485751,-204476433,2021424858,1893059240,-59263232,-329974006,-1360480358,-1320953925],[-0.13401556015014648,0.18581999838352203]],[579,[-11036405,-777934827,2013002256,1897900916,-33842751,-1532740203,-1140932694,-1056772933],[-0.11947764456272125,0.2034149467945099]],[269,[-120159104,-590068356,1249209660,838451038,2026278092,-1460363686,-54526018,-1202980021],[-0.1263890117406845,0.1901579201221466]],[626,[-9458765,864484918,-1511008592,-1243354942,824178116,-2115851904,2108896696,-974655785],[-0.11565050482749939,0.20734450221061707]],[354,[841991296,285521189,-1619726583,-1383762267,269749288,1909506021,1324502735,136255191],[-0.18641577661037445,0.12567663192749023]],[64,[-1689540600,-171047537,367437942,-545536546,-27554929,-201455017,132968039,-56919],[-0.35486286878585815,0.06668654829263687]],[427,[-605489791,-1143709809,-33693697,-537069149,-711441259,-1200820238,-2033713755,71617805],[-0.16660074889659882,0.14271223545074463]],[477,[1308689921,584290,1663521749,-146281108,-1077992529,1108859814,-1259897617,-2080382578],[-0.13657788932323456,0.16795969009399414]],[71,[1120340511,285084254,-117988732,-1107318042,1085786093,-252053507,-1002113816,1348812912],[-0.22501066327095032,0.10219082236289978]],[352,[-1422610505,85245907,-1904285905,-1920684632,659881463,-1259208707,-11206692,-1963834010],[-0.14944109320640564,0.15598995983600616]],[52,[-10490065,1498147823,-553944480,-134217734,2145379919,1434648139,-118032742,-178274362],[-0.11018689721822739,0.20814745128154755]],[30,[-2134754710,37889724,-1915431920,794654769,608172791,1106720444,1637266185,262899994],[-0.42608824372291565,0.05488509684801102]],[557,[-601044984,2043973039,674530844,-201458955,1488507776,-1334981997,-395001942,-1827697397],[-0.13864666223526,0.167188823223114]]]],[-1.3544789552688599,[[540,[-144706765,-1289764937,-1210088649,-1073758505,-939528193,-1091062785,-1025,-1073745921],[-0.14142465591430664,0.26060691475868225]],[207,[-1025521953,-562077953,-489238786,1111423727,-896495890,-11540707,-270799138,-144703521],[-0.2282639443874359,0.16443152725696564]],[310,[-922776433,209603519,788277263,149814190,2129497804,246132079,-120197154,-1461715061],[-0.24959196150302887,0.13804991543293]],[507,[1997012981,-1089741086,2101339632,-852493088,-1154547807,-1416646978,1565513153,-1894785592],[-0.2350001186132431,0.14007705450057983]],[318,[-2621697,-572527203,-7537699,-540158759,-1285,-1084358700,-87233877,1527643417],[-0.13948769867420197,0.2373763918876648]],[516,[-12497,-67110961,1895293114,-202902104,-4473080,-582642432,-138761558,-247202870],[-0.12023023515939713,0.25221487879753113]],[489,[2138824465,1006370495,-1628438593,-1343230209,2147476917,1023206896,-323568595,619075335],[-0.22485122084617615,0.1354176253080368]],[387,[-581657131,-715649732,1609916351,-1086636163,-36644456,-201803780,-38076486,-1414920182],[-0.1813817024230957,0.16125626862049103]],[193,[1983843871,1509371575,1804010935,-76854621,1420240815,-139122955,-144183573,2068252417],[-0.19591303169727325,0.1467915028333664]],[622,[-2097425,-134218881,-20059542,-252920114,-1048690,1433398614,-134679350,-168300550],[-0.1234404668211937,0.2348768562078476]],[69,[-135790657,-101712898,1790961276,-1117268,-167790693,-1092435916,-134748966,-171444278],[-0.0936608761548996,0.2928491234779358]],[334,[1426527010,-134922701,-283812105,-2623147,-1643650329,-789597,-285199645,-2130690814],[-0.19195295870304108,0.1388207972049713]],[128,[-188748058,-604825097,228284687,-1059465,-744525073,-134502345,-74199121,-2098289],[-0.1702539324760437,0.1586102694272995]],[504,[1444369751,1571127165,1068923765,-418381862,1832345573,-1136660769,1164394880,-1928344087],[-0.17193807661533356,0.16115176677703857]],[212,[577742851,-69269885,687362130,939513855,1131934720,1456416085,930627893,-2100289],[-0.13450787961483002,0.1927766501903534]],[371,[-799212524,-209768513,-76223492,-117260294,-830701092,-357900157,-1262178576,-68422742],[-0.38245826959609985,0.06848365813493729]],[278,[207857047,271759280,-286880937,783085486,242614261,-1090523169,-287801388,-1158721947],[-0.19277557730674744,0.13489215075969696]],[220,[-509434961,-78710066,-1275726622,-753404420,-203423798,-1895375284,-673909042,-716971826],[-0.11536061018705368,0.22317345440387726]],[433,[-966602846,464451514,1072605484,-1080755764,2001878519,2011854582,-759073,2145875767],[-0.17061035335063934,0.14551682770252228]],[570,[-813715661,2085594419,2080225111,-1085276791,-2024283721,456261102,1944045462,-537989201],[-0.15524835884571075,0.16316364705562592]],[0,[-4194317,-437584658,-34446,-8391184,-1048677,-892667004,2009592769,-145255149],[-0.11445097625255585,0.21161417663097382]],[160,[-354096414,1341058784,-21551621,805293574,1727467967,2145870579,-954962,1608997489],[-0.24929216504096985,0.09536799788475037]],[175,[1133488646,19079215,1923684923,531607301,1643598741,16213639,1617959234,1911899943],[-0.2060607522726059,0.11344346404075623]],[638,[-201331985,785378799,-89140512,-506473810,-117440562,4699124,-137366572,-237519977],[-0.1317863017320633,0.17929145693778992]],[333,[1500975106,-591757505,-758294281,-159531458,1694185913,-1025496001,1422394875,2130083615],[-0.31970807909965515,0.07318614423274994]],[186,[-252197833,-222679057,-691545539,2146925322,-6971745,-20010264,-23089430,809597526],[-0.15578804910182953,0.154715895652771]],[472,[528507857,220264592,61472209,-1121194504,-1442796359,-325000515,254280095,-1913940771],[-0.16838937997817993,0.14214324951171875]],[113,[-475271441,-85279086,-969873294,-134745356,-251673889,1917934182,2004345816,-238553377],[-0.11203543841838837,0.20810666680335999]],[222,[191466152,330415091,1572941818,995482546,-438844995,1062600569,-1777930,803654826],[-0.29350510239601135,0.07969966530799866]],[149,[-357896534,-759148596,-2131974922,-70545720,-2069117009,1145131456,1431040222,-250146674],[-0.14853553473949432,0.1520741581916809]],[100,[-1045909650,-485611602,-1652363393,-544464370,-210833459,-205732025,-412155925,1161839428],[-0.18374817073345184,0.12407581508159637]],[484,[-2095020544,657773984,-1117496013,-272004556,-2094691888,-1119555728,770155170,618987575],[-0.22434021532535553,0.10049981623888016]],[551,[-604093873,-680840318,-1293353250,1356493274,-100805812,-1358042356,-255656308,-800923830],[-0.15413197875022888,0.1519971489906311]],[422,[-434654828,-1852916328,1623711061,-39002980,-1050953440,-356992779,-853603320,-909122417],[-0.15186285972595215,0.15066848695278168]],[362,[-547512961,-614724543,-5289121,1609498725,-593979176,-30505107,-4653062,-5570290],[-0.09397383779287338,0.2500700056552887]],[502,[421738261,512647543,-369466298,644660618,2014315985,-122826753,-1422579952,144522760],[-0.22758260369300842,0.1047687903046608]],[414,[-1743450761,-1667229731,-1111617731,-1918337240,-925364899,-1401618467,-396751348,149751812],[-0.20826348662376404,0.11135675758123398]],[327,[-589833067,1358228811,-1174324513,1295585037,1415054460,-677683843,-333918502,-81110961],[-0.15275685489177704,0.14786334335803986]],[513,[268447386,-768359989,971741463,-746591329,527673597,-1371129041,267492031,976958107],[-0.21398673951625824,0.1099848747253418]],[287,[458687,74623383,-2110418338,547384028,1146347479,-300476649,1564515406,-549791922],[-0.1906532496213913,0.12086330354213715]],[321,[-1292446785,-1832472107,-874707144,-1316029507,221482943,-54635093,545718286,1952442355],[-0.1822858303785324,0.12629486620426178]],[613,[-270555509,-2024964282,-340115456,-225707460,-214435894,140869335,-755499270,-514854962],[-0.12966547906398773,0.17814037203788757]],[237,[1082294452,279297776,739665110,-1112548388,1558433004,2084562652,-285242720,822082519],[-0.21644125878810883,0.10754965990781784]],[436,[-15204353,1555857143,-370262113,250109974,-813863457,-118130955,1282485260,-1069443322],[-0.11899302154779434,0.19272921979427338]],[195,[-458694430,-18865688,-1560262314,-174816220,1940735675,2090354613,1843399327,-619769841],[-0.14177682995796204,0.1578184813261032]],[396,[-281556317,1261252513,-1844107376,-1199966654,1342875535,19047986,2048844537,-968363117],[-0.12672142684459686,0.1768610030412674]],[349,[1148552471,346904839,-953859756,-2069582840,808277389,-1544759304,278153766,4483088],[-0.21089854836463928,0.10583920031785965]],[26,[-7511510,-490213457,-1597284352,-261998934,1392468480,403119942,1463169024,1346631127],[-0.28440985083580017,0.07838387042284012]],[235,[-190183264,1490329067,-1474001346,-1131666523,1952776616,-1196417886,-93570934,-1442369763],[-0.15732380747795105,0.14436712861061096]],[77,[-234098945,1368758007,-117547043,-4245393,1380304763,-1137653377,-214434069,-302694186],[-0.10450263321399689,0.21435043215751648]],[617,[-71305489,-102079985,-2135231236,-1835277350,-268448192,1963334918,-1485652036,1347612190],[-0.16540440917015076,0.1348690539598465]],[359,[-643869705,-1701290179,-88374529,-4249741,-615216080,-17244690,-248849941,-1146418449],[-0.08967950940132141,0.25216883420944214]],[259,[-2018016477,-135365668,-1220542478,-176295708,-1145529441,-809304950,-718277394,-716994988],[-0.11881193518638611,0.18229863047599792]],[521,[-659116544,-39007946,-1632034575,-1109530378,-507923208,215233620,-38434133,-1994050161],[-0.132778137922287,0.16686922311782837]],[250,[139447519,-1707244049,543030878,-1876755446,418206416,-1344311399,1070800532,-549216572],[-0.1713460087776184,0.12920229136943817]],[563,[1065351043,-1747387425,1440546065,-1130366210,1655662591,-1481415173,-1230520517,-1409895749],[-0.12196241319179535,0.18406112492084503]],[590,[-1489788317,-215482932,1167516208,-1243059476,924747395,731626188,494917253,-1008733729],[-0.14610977470874786,0.15349069237709045]],[132,[-404231235,-154083334,-386960532,-102894914,-1494941761,-523327360,-341382230,-993681342],[-0.11227646470069885,0.19230186939239502]],[189,[461571246,898745267,1045718764,1067757070,838700687,523352002,752994271,746684614],[-0.31202149391174316,0.06988177448511124]],[319,[34848759,77858295,1755294463,-1612362699,279183197,-1091412483,74513294,-583830953],[-0.11771897226572037,0.1843392699956894]],[412,[-251804257,-1722448993,2138034394,1294782986,-571552448,-178921642,-290600310,604546090],[-0.1507510393857956,0.14529505372047424]],[286,[1276237310,1447458454,-934498184,1623452708,-1280217356,1357512592,552402944,-528812416],[-0.3494941294193268,0.06317922472953796]],[449,[1663467552,416069478,-1587070595,-1216236355,394667813,694428982,203361851,-1578764654],[-0.18098776042461395,0.12132294476032257]],[554,[-54546545,-142747138,-1662192658,-117332434,-558788200,1595934520,-1372737862,-1603959254],[-0.11871227622032166,0.18538504838943481]],[580,[-136315383,1373438347,2030042960,1935331222,-1732324440,-1866576357,-104547704,-1603561958],[-0.12392864376306534,0.17591291666030884]],[37,[1179711253,932391543,-159717504,1907212206,1953330597,1588556119,1323654868,-59937033],[-0.12764546275138855,0.17045098543167114]]]],[-1.3531562089920044,[[539,[503783185,488612115,-1644183017,-6291490,1583288237,-8273,-67147553,-50467906],[-0.23604758083820343,0.14624665677547455]],[125,[-754980097,-92799137,586973151,-1206650282,-1015162113,-524401,1993957087,-172492917],[-0.20661883056163788,0.16887924075126648]],[384,[-669517935,16839696,-584633040,2098167213,17062277,404341136,716110059,789549483],[-0.19015172123908997,0.16193783283233643]],[94,[-232805713,-20973057,-34603081,-42607105,-356519937,-118109025,-387977505,-2134520828],[-0.1541261523962021,0.1933469921350479]],[466,[528479223,1904195575,-55119905,-10575890,-947918857,-288358401,1944539762,-135803137],[-0.20460499823093414,0.14255046844482422]],[47,[-201327709,-19927066,1384109026,-739317020,-12587089,1179121028,-241174704,-168296506],[-0.1505453735589981,0.185949444770813]],[339,[-581632048,-606277136,-368021128,-176383780,-956433298,-268467029,1551686188,-36312104],[-0.30771997570991516,0.09145938605070114]],[229,[1595362495,532541183,-1879371521,1474776767,2138187743,1066097155,-537382949,1073678919],[-0.21706582605838776,0.1526443213224411]],[254,[-864133153,-692189161,-1099006309,304102399,1492012696,-93634736,1580914378,1929543391],[-0.2538846433162689,0.10271452367305756]],[457,[-64904797,-305660509,1468164915,-565,1059143671,2107965041,2079816191,-18385129],[-0.1301027238368988,0.1987140029668808]],[511,[-220210673,-536887410,-757597954,-235406646,-67108980,-867369216,-31934210,-251404342],[-0.10590624809265137,0.23959128558635712]],[497,[-740299264,146795517,-50352379,-1912628641,1053777812,901722868,771235244,546303999],[-0.22008468210697174,0.11258465051651001]],[355,[343358231,213430181,-1364197793,1073696095,1515411668,-1059425,-13050290,-1078259937],[-0.11953093856573105,0.20282387733459473]],[373,[1245651467,183707959,582887578,31777007,1691296546,237724247,1348920347,-203426945],[-0.2097310721874237,0.11584123969078064]],[35,[2043933695,-144771167,19989255,1072001427,-506069031,-1929904385,592718063,-169511337],[-0.12918440997600555,0.18772880733013153]],[606,[-8388705,-6177,1207429886,-170921106,-34868280,-53228224,-120789286,-263979270],[-0.0942123755812645,0.25828978419303894]],[179,[1023876484,-256822903,-1178663971,-236886881,-236217863,-52522546,833036237,-8385148],[-0.19691897928714752,0.11818353086709976]],[124,[-85998033,1383065263,1880502784,1516235723,2004838208,1346401792,1406554770,-214434290],[-0.1725260466337204,0.1334143728017807]],[508,[-215485453,-1146159840,-1684308559,-551551504,-1448107335,-1364266068,197057439,-536879651],[-0.11676036566495895,0.1934867650270462]],[388,[1867466672,-654132904,-1678940751,-1073748483,-1814283784,982153656,163645464,-1409292229],[-0.13684672117233276,0.17416830360889435]],[241,[809177088,255278841,2052280087,2064460633,-357326549,-1147540547,1220038219,2137729130],[-0.3888067305088043,0.05829756334424019]],[463,[2113404919,2119573369,-1216467140,686062828,1599431925,-35250219,-379253932,-588874972],[-0.15329168736934662,0.15723362565040588]],[74,[-142872849,-1123585,-1226054942,-168821790,-16843777,-682478139,-148908590,-170396193],[-0.1018904522061348,0.22314058244228363]],[491,[666353457,301069589,-134324227,-1850148995,-163618376,-1430878019,-272720724,747437600],[-0.15450522303581238,0.1451505720615387]],[265,[-1520456817,-672619806,-1650134352,-739249448,-410644,1850609408,-671883070,-716704562],[-0.1173662468791008,0.1908893585205078]],[640,[-268439637,1743224491,-1062209824,2075129070,-100680209,17194724,-503319132,-705694017],[-0.1188521459698677,0.1887996941804886]],[351,[-235865865,-778321560,-773813480,-977205055,-671809621,-2037042305,-1373573570,33902919],[-0.16477152705192566,0.13532666862010956]],[281,[1288503263,496561871,-41996993,-44831381,513794520,-6296133,-11544504,-545596144],[-0.137915700674057,0.1612575650215149]],[592,[-536990993,-545437826,-526919430,1927770592,-1149453240,-12157692,-795681042,-263995441],[-0.12841881811618805,0.18196146190166473]],[200,[-998586714,1923629704,-1567936970,-106682636,1246039486,1391923172,2128445439,-1161220571],[-0.15602493286132812,0.1402648389339447]],[574,[-902847741,1122672495,1740485216,-252907012,716157611,40020694,-1354763301,-705694561],[-0.12058999389410019,0.18453432619571686]],[411,[43190589,237000119,-1479864545,218107700,1727349849,-84927193,168837124,201328132],[-0.2745037078857422,0.080660879611969]],[503,[1145396501,-596306061,-1883250830,604912112,1244529921,1003257717,2066631424,-2012515040],[-0.22889545559883118,0.0964030921459198]],[337,[-704658769,-746617960,1373614706,-235613442,-75520946,1213059150,-705694758,-783549270],[-0.10090714693069458,0.21733656525611877]],[239,[-555432832,-1192997968,-286225699,-35864850,798508188,-1108076048,-365142037,-1475542263],[-0.12968091666698456,0.16475941240787506]],[288,[-573549447,-676853411,-1052201605,118622855,2113410296,-336957660,-618632262,-1442645118],[-0.2590109705924988,0.0811891183257103]],[368,[59193218,2011775753,1576662974,-4195534,1435621351,-1702058057,-2017202266,1977972599],[-0.181268572807312,0.1182248443365097]],[499,[-988850988,1016641345,160914500,-474084890,154236052,-1078989845,1441076224,1040163634],[-0.31549975275993347,0.06667444109916687]],[364,[4349984,639681328,129645151,668510722,1148195120,2062963956,153885736,1647779843],[-0.22751913964748383,0.09298747777938843]],[602,[-276828158,1130870371,-1531186142,1894639586,1969214592,21205461,-621813270,-792462373],[-0.14819277822971344,0.1404644250869751]],[353,[118533695,270567044,1288523533,-1113072698,827708669,1605729269,-1091248161,-1141436093],[-0.11226476728916168,0.1889517605304718]],[340,[-85094773,1487850663,721041258,1374657596,1581250843,1112227395,-132434392,-362545185],[-0.11850622296333313,0.17904981970787048]],[424,[-1044577783,-3170331,-210830594,-539528456,-1410339954,-1907435776,-201789206,-213651366],[-0.10257221013307571,0.2029486894607544]],[632,[-176173273,-63971382,-92540894,549647982,-1338560,1476888389,-78600722,1081266138],[-0.18841557204723358,0.11295656859874725]],[520,[-671890176,-181237993,-1548798927,2005171473,319759748,-51300395,-1366522344,71618053],[-0.20921583473682404,0.10211694240570068]],[88,[-1602114652,-1100433156,-2115529,-1184520048,-1984574213,-297169991,366750175,88360004],[-0.1925288438796997,0.10750143229961395]],[216,[39586,2101407957,-35376942,-644184357,-1586894610,-971554785,-5808574,-784335945],[-0.38588806986808777,0.054346900433301926]],[496,[-1706958944,451947443,-277301988,-1936926482,1031093973,-1141080111,-100907,-5619417],[-0.1415555328130722,0.15182578563690186]],[385,[135519103,-1701046404,-476620169,532383797,-110098979,-17150466,789376991,-1153760421],[-0.09721077978610992,0.22095255553722382]],[119,[-68163926,-758185242,-457882974,1943200494,1903550542,1144214864,892323778,-178276493],[-0.14763863384723663,0.14450113475322723]],[163,[-894505938,1726040062,-1434959774,1382606572,877626085,912263760,854318029,-235154495],[-0.19948244094848633,0.11108753830194473]],[114,[-391748914,-87495070,1790763645,-34746582,-1894316363,-151775424,1299316735,-380410251],[-0.13808603584766388,0.15448948740959167]],[514,[-222361681,-142684161,-1011944610,-254805175,-178667764,-968192512,-267197752,-251479346],[-0.12034154683351517,0.17198434472084045]],[377,[202861343,507076415,721758013,687907104,1979993013,-907174864,1142178076,1145104400],[-0.21315360069274902,0.09752862900495529]],[510,[-928024797,453054,-218994892,-185220464,-2126798169,577432266,713554911,-1090527317],[-0.11146946996450424,0.18797753751277924]],[611,[-4213,-1009925217,-1562674624,-1151402642,-234885490,-590488821,-269837110,-774636550],[-0.10050378739833832,0.2044314742088318]],[442,[-797631013,362314737,-1347420291,-1079419975,1280903925,-1262749233,-1377484823,-2001796897],[-0.10836073011159897,0.19475993514060974]],[432,[-316169693,-1344106541,942691362,-202380558,930163489,240608166,1442141879,-470334095],[-0.17380046844482422,0.11888035386800766]],[252,[148589439,-598544709,1720098523,302055418,1690358359,-537721785,1465335308,-581808818],[-0.1894366443157196,0.10867591947317123]],[272,[-227276285,417733055,141878230,-1930563657,443500552,-1197990268,-1091601874,-1428702701],[-0.15042302012443542,0.13850454986095428]],[365,[-295443825,1881192242,602866173,-1583502408,217335229,1880585519,771686574,74185330],[-0.15697461366653442,0.13160589337348938]],[240,[-266098716,966942003,-1407291626,-1109396138,1947725557,517720022,-2137792561,822083471],[-0.1492486596107483,0.14093182981014252]],[467,[1147473171,1279326997,-821293199,17582980,1561349141,1035756917,1693723716,134813760],[-0.26860836148262024,0.0791471004486084]],[480,[-745413331,-1188194,1267976940,-244057892,-117834344,-1182421888,-1244286022,-675048758],[-0.09677238017320633,0.22355352342128754]],[378,[-602815049,2117625195,-1582168171,-443273818,-810235495,-1412593179,-906457953,-301186044],[-0.12496618181467056,0.16549517214298248]],[223,[784214531,-1481197765,-1175381145,-142769749,-1364414680,-1560957006,1999583123,705541055],[-0.21282529830932617,0.10288743674755096]],[528,[-182344572,446549361,-1443603113,-1212176388,-554397288,-1963900929,-84743208,-1364216305],[-0.1101992055773735,0.18950794637203217]],[616,[-1303385209,-896561650,-523800238,-151652106,-548431989,1168430244,-503320351,-2064649010],[-0.1337122768163681,0.15766866505146027]],[22,[-218105953,-679114691,-1267388358,-73099594,1743867279,2020921186,-6432370,-179836046],[-0.09166912734508514,0.2281249612569809]],[332,[1790410753,1194205785,712913755,1475242910,1659961600,360013679,1966797212,-10529238],[-0.139383465051651,0.14807218313217163]],[488,[-56065920,-160826232,1866034740,-2282635,-1612249423,-2037227788,-1350786837,-1091042443],[-0.12180531024932861,0.16849491000175476]]]],[-1.3695704936981201,[[120,[-893410561,-536892673,-353374337,-2103706,-203480129,-21509,-167809029,-1881225],[-0.16063986718654633,0.20273709297180176]],[505,[-33816579,2073344700,-1558201345,-4208492,-1141113363,-1076259588,1055902713,-575711916],[-0.26204735040664673,0.12330465018749237]],[335,[-293634177,1400863359,-389223329,-201985,-834109825,-285447041,1851805055,1870364287],[-0.2892760634422302,0.11206240952014923]],[357,[1515124725,369927936,-1610666831,925855537,272631836,1531994580,528108223,455021023],[-0.1916453242301941,0.1483595371246338]],[560,[1060087328,398437823,79655216,-1914176017,1558052245,520000392,-1268336765,212632751],[-0.26242268085479736,0.10239273309707642]],[623,[-2629905,-78655505,-891554078,-1058015250,-264250,13096772,-168561212,-235405345],[-0.13851559162139893,0.19113600254058838]],[162,[-202375721,-2111636702,-721301001,-1574913280,56560078,-18677777,1087758426,-353913415],[-0.24820300936698914,0.10685873031616211]],[50,[-8917009,-103854097,-225450462,-1575174,-8377,608239190,-209718336,-171445561],[-0.13929376006126404,0.17934627830982208]],[588,[-543165517,533196199,-1426074862,-544347146,1130218371,8697232,2010559954,-741343554],[-0.15528613328933716,0.153925821185112]],[527,[-411054193,-1281884233,-1115833348,-1079673394,-1581284984,-1148589108,-289498744,-2000102976],[-0.10468549281358719,0.2299884855747223]],[172,[-25174417,2117286413,-804523330,539753215,-1568838361,2136045431,-87049377,2002249599],[-0.24891264736652374,0.09397143125534058]],[366,[1210754048,537666304,161348605,627257024,1158955796,1668769269,2008953695,1744796787],[-0.22588098049163818,0.10365047305822372]],[180,[-281288273,-70327314,-796921740,-738730264,-76562513,-808792948,-1745881398,-136841842],[-0.09550877660512924,0.24650630354881287]],[341,[-886059513,168764323,-267976118,-973090298,2097352643,176495367,1802990159,-385882317],[-0.1835000216960907,0.1264064460992813]],[595,[-1,-134221825,-218431816,-235405578,-573046902,-35956864,-177472566,-170394389],[-0.08009938150644302,0.28082871437072754]],[314,[-14155881,-1111314545,-1353609437,-1358649856,-20250627,-75628649,2146789220,-69994733],[-0.10310708731412888,0.214595764875412]],[404,[85077823,206351119,984419861,20769365,1278506495,509705715,1276407516,-599458444],[-0.18984027206897736,0.11972358822822571]],[206,[-665271074,1464887091,-2145223045,83944575,-664089410,1012828430,-1092945194,-12125474],[-0.20856955647468567,0.10800682753324509]],[49,[-138414161,-152571922,-234883034,-218173190,-69748337,-796834004,-51382306,-235410218],[-0.1027757078409195,0.20767506957054138]],[420,[-75500559,-1089602040,-645940751,-3162657,-1738551119,-1692862817,1308311003,-1993363541],[-0.09340593218803406,0.2308514267206192]],[455,[-853368159,-1054814,389048702,-1710123,-1154186313,249649875,-10095637,-606120681],[-0.1059320941567421,0.20079787075519562]],[11,[-2094007297,-442069004,-605586698,-34146080,-538208337,-1964457677,1912461024,-168302604],[-0.1310754418373108,0.16108058393001556]],[198,[-158677344,-181113360,-1528008969,-571176396,1048269475,1988456372,-27492353,-11978479],[-0.128440260887146,0.16143999993801117]],[544,[1596188085,-987304491,452284863,-5645158,-497029639,-48137,1575704025,-806361704],[-0.15479210019111633,0.13679373264312744]],[416,[-803355391,269612059,-103964896,-584190505,-1253042176,-1287846874,-1364704630,70252047],[-0.1722220629453659,0.1234646886587143]],[486,[-474377216,339541264,1577057677,-1916842185,-281745276,-1666877764,1774055176,135393823],[-0.17964713275432587,0.11774364113807678]],[381,[-169103377,-138944407,-4966664,-1117990427,-67251458,-75752779,-34803588,-1920930339],[-0.1593102514743805,0.13285309076309204]],[1,[575365347,953914139,-1078241825,530438005,8352735,-1140861665,-2360355,100616191],[-0.20287837088108063,0.1128615140914917]],[301,[-2087738451,-236978972,1945051832,-204474216,-4213090,1812100654,-163122454,-721178166],[-0.10795794427394867,0.1885324865579605]],[406,[-763363841,1161592123,1218843669,589341989,1147453433,878107283,1673862468,71320641],[-0.1465872824192047,0.14068178832530975]],[448,[338702321,-955723536,223548671,-1618687592,640728233,-1892106840,253306637,160038936],[-0.2504936456680298,0.0826164186000824]],[309,[-1069741553,285037405,549372488,157368060,1549206792,476787267,-223284936,-1460015186],[-0.17551939189434052,0.11551206558942795]],[16,[-559645958,-82033479,-315888674,990559098,-363475207,-1143281825,-279609123,2137035924],[-0.11419827491044998,0.18112944066524506]],[641,[-1880100957,172207746,-2042666496,-1609982232,-877665398,84329482,1961357506,1153890247],[-0.2089102417230606,0.09833736717700958]],[19,[139296,2079280460,-1035450949,-69253746,155985087,2113766731,135764411,1608486923],[-0.4137556254863739,0.04951225593686104]],[312,[-732977643,277903282,-1368217772,-459228376,813142006,837885431,267818252,-1528500380],[-0.15581859648227692,0.13339102268218994]],[517,[-83917399,-173673311,1626321594,-237716638,-42225124,1728340229,-1232225590,-217329398],[-0.11577171832323074,0.1834014356136322]],[316,[771960639,134409859,258363165,-1394364928,1598414807,2012884973,1584664128,708838210],[-0.216262087225914,0.0954771488904953]],[572,[666873121,-1893565126,-805613104,2079585760,774873761,571125668,387929937,-1046488867],[-0.19903813302516937,0.10453511774539948]],[28,[1635451153,957686021,-451272973,1032273426,1958556740,1036989745,177547808,720439818],[-0.23054862022399902,0.08963410556316376]],[70,[-12625,-404502550,-612371614,-540029722,-8650866,-1469579796,-67108900,-171445794],[-0.09864431619644165,0.21435028314590454]],[451,[1576224017,1500983061,-1166946313,1564704015,-289709104,-1073863490,-828084534,469780763],[-0.16094450652599335,0.12683431804180145]],[245,[1216020163,491947673,-499451301,-71647474,170564572,-37852258,-346584676,-75029248],[-0.15302763879299164,0.13355283439159393]],[524,[77630976,505053924,-1913377232,-1381980602,569648564,1022552432,-1514830304,12870692],[-0.2971450686454773,0.06969578564167023]],[550,[-496000253,-894677310,586380658,-1071684144,-1104764373,640414632,1062711983,-537927685],[-0.11207269877195358,0.1844300478696823]],[317,[-805261899,832624929,-898801809,-1107465875,-413863428,-1242559753,-17457656,783226135],[-0.11341021209955215,0.1786959171295166]],[578,[-672676857,-671259169,-1426431184,-255886694,2067195272,1640486343,-139008630,-247225717],[-0.11504149436950684,0.17776061594486237]],[144,[-257186129,-55922845,-1077084195,-144891130,-20726341,-119362033,-410783813,-850035177],[-0.10251285135746002,0.19268713891506195]],[600,[-143655125,1979709255,1894602946,-754483258,-161491838,1154539319,-192615542,-237504533],[-0.10122653841972351,0.19483508169651031]],[356,[2135702864,-1079215788,-36702019,800889112,-1154973384,-1120359512,-340087880,-1574789070],[-0.2610571086406708,0.07492011785507202]],[367,[-1064320849,-888408663,-1962966286,1885579722,-23076338,773293122,-85339410,-481827590],[-0.11406119912862778,0.1742027997970581]],[374,[-213751904,1605143820,-154679544,-16761,1735620549,1320605166,-504922689,2011657827],[-0.1686951071023941,0.11749855428934097]],[503,[341128023,1349080691,-1529909789,1250525156,1550284273,-72450689,1588033856,-2012225976],[-0.1634955108165741,0.11994868516921997]],[256,[-32515877,-176855289,-261031297,1057333783,-1032058104,-9935818,-5099570,-13137826],[-0.07970619946718216,0.24850650131702423]],[61,[-2068804128,-614601995,1600116177,-71247792,2029357231,-1082179864,-2010903395,205586689],[-0.1640268862247467,0.11898551881313324]],[213,[-1435261405,1677689511,645850208,-236093449,657455952,121542592,2002383380,-210522417],[-0.12863418459892273,0.15204958617687225]],[439,[157636991,-102735875,1049370419,1031056562,208487861,712996735,-44814592,-1994037727],[-0.15739968419075012,0.1273098737001419]],[435,[-1060257076,2111306357,-1702557168,-590175618,2013791500,2051870375,-52680182,-1454021666],[-0.19914233684539795,0.10423366725444794]],[358,[-625293571,-19622942,-8397475,-314591297,27992299,2121821739,136847918,1146475566],[-0.19054318964481354,0.10671291500329971]],[492,[1789983778,1018022897,1861236018,-1611852202,876642213,975183222,1055947774,-1343409645],[-0.15487708151340485,0.12867331504821777]],[279,[327569,218144993,-1778603565,-1353503484,1175427833,-1882729345,-1546330360,-1154386112],[-0.17322303354740143,0.11569347232580185]],[601,[-349703245,1433019314,-818911184,-1010310506,1433778070,920808880,1642167992,-1328024681],[-0.12355220317840576,0.1641998440027237]],[93,[-14441821,-609294870,-757607712,2138420300,60657067,-893238130,-182328108,-706218300],[-0.12934589385986328,0.15674130618572235]],[474,[-1928604261,-1929346844,-581011079,-541065844,-1962793025,-1959006544,563584939,-1880104977],[-0.08118641376495361,0.24935099482536316]],[597,[-420879597,-589318153,-893880704,-1313297248,2046665348,-1124139690,-1345913272,-264117294],[-0.11719886213541031,0.16577914357185364]],[382,[405429943,35157617,-142668179,-1390625436,1507609804,-621125793,-1973510450,-1165812617],[-0.1302436739206314,0.1481214165687561]],[147,[-3217685,-30740518,1938426620,-538214752,-18219057,-1255846052,-201922374,-237023073],[-0.08887697756290436,0.21971827745437622]],[639,[-738726997,187692013,2011134000,-1955661828,-210119423,38790407,-755108400,-987308314],[-0.144447460770607,0.13702638447284698]],[452,[-206995293,-545767542,1907093886,1935741694,-335563268,-280903864,-675039554,-211558710],[-0.09513164311647415,0.210707426071167]],[271,[-1002116576,1325996544,-665522936,-597824890,1711699965,-73301301,-20448286,-110104046],[-0.41298919916152954,0.04899816960096359]],[407,[207949127,547888959,694611503,671116356,81544535,-709767,4261201,4220420],[-0.286625474691391,0.0699523314833641]],[127,[-1060119505,1644687048,-1964847366,582987502,-784636060,827683077,1339008607,1415048063],[-0.34356600046157837,0.056598760187625885]],[266,[-803222897,-61161545,1635244831,-1845510438,2098171271,-116434698,-21512229,-513563541],[-0.09976167976856232,0.2059866040945053]],[51,[-347603025,-1870744068,679009562,-113708376,1464161920,-312465308,-41992630,-246943142],[-0.11211391538381577,0.17646948993206024]],[190,[-2013321968,-742767341,1337165114,-72328646,-1787329601,-841026207,512443531,314072475],[-0.18131621181964874,0.1113327294588089]],[319,[236183479,76657666,176155709,908181400,409361495,-1141645905,-36647350,-1153869993],[-0.1289842575788498,0.15491998195648193]],[586,[1266667810,1511123775,2094253840,-44707245,333808663,628498310,-402685040,-962095185],[-0.17281804978847504,0.11423593014478683]],[192,[-236396348,-727146278,1815085813,-38007520,-171378486,-37738304,-206180609,-107261665],[-0.10720640420913696,0.18341147899627686]]]],[-1.3276469707489014,[[434,[1206384503,2004349367,-587202625,-570458153,1962898935,-135266313,-1091309570,-20973573],[-0.17421774566173553,0.17884284257888794]],[165,[-134742022,-627902534,1968427302,-560480,806424439,-67650565,51447330,-2133022],[-0.2147657871246338,0.133590966463089]],[515,[1057161146,-6307941,496502567,-1617216785,391903915,959252225,772505566,974076347],[-0.2319275587797165,0.12110722810029984]],[257,[-1700555934,-500504126,370126658,-1079154897,-284626360,-1924137013,387672847,-3156277],[-0.252623975276947,0.10572800785303116]],[159,[-1000152458,1895493330,-281178273,2146355560,2093311095,855405813,-543404209,821946229],[-0.206059068441391,0.12582625448703766]],[87,[-34608193,-201856262,-352407873,-1461520,-1057490945,-307438354,-52433718,-1060773758],[-0.11796126514673233,0.224318727850914]],[106,[1362202543,-776621899,-193898077,-652093965,-805254933,-1070494539,-755921969,-553071219],[-0.2505123019218445,0.1018962562084198]],[168,[-897588481,1378039343,586731134,849323774,-615806066,1984956738,-10032198,-212598805],[-0.1737886518239975,0.13972662389278412]],[620,[-1329,-67371793,-1023412510,-219219134,-146872510,-950677692,-170852800,-263718034],[-0.14755988121032715,0.1593601256608963]],[409,[-807993858,-444659489,-222269284,-806825748,-620958468,-268492551,-286463746,203485430],[-0.2265692502260208,0.10586404800415039]],[14,[-33558609,-65083682,-811175422,-123558262,2138007431,436495750,2139054674,-263724334],[-0.13516700267791748,0.16823019087314606]],[327,[-749235619,-740780991,1904177247,1594623829,1529354448,-172286859,-15541176,-1358771366],[-0.18130488693714142,0.12141185253858566]],[182,[1584990352,-473857834,1605700853,-100717318,-212604370,2125138082,-883446021,1534527706],[-0.15860173106193542,0.14470864832401276]],[573,[-1507874397,113426414,310100625,-621282947,573547171,583934606,1300686811,-908069413],[-0.11836400628089905,0.18674106895923615]],[429,[1929570099,1923122619,-1622715780,-1577842,-213749257,-303632667,-168461162,1626695507],[-0.17876005172729492,0.12363989651203156]],[391,[-73430485,-9438562,2060940976,-201347366,-1144276274,-2029070526,-134228252,-146546470],[-0.1017240658402443,0.21338729560375214]],[376,[240453683,156000191,695730801,151579604,1499214964,243072615,1282672708,1080359008],[-0.28052809834480286,0.0774340033531189]],[470,[962023287,34183056,-852552331,-1347425040,1042303461,-1413613637,-2073063769,-1884301079],[-0.13582970201969147,0.15512573719024658]],[140,[-816847897,-235995450,1886384818,-707134232,-335615089,1147431968,-136072004,-171444858],[-0.11215072125196457,0.1839037537574768]],[564,[1059584305,-1155622093,766342448,-1098140737,337323539,-289461769,222106113,-1917846854],[-0.20957885682582855,0.09911903738975525]],[78,[-2102645,-249598262,318267466,-345408,-622854336,1577202951,-246163506,-247012394],[-0.1202320083975792,0.16939368844032288]],[343,[1291652149,416690045,162229011,199289850,16481324,2128737110,2062154440,-287838248],[-0.16363579034805298,0.12322180718183517]],[135,[167774464,-153547823,2081759095,-34798827,1856352957,-1309945394,-343857497,-1476130752],[-0.1910814493894577,0.10656961053609848]],[5,[-207883269,-337118226,-220200976,-672139828,-205541893,1284500906,1402970448,-984099979],[-0.12751424312591553,0.159833624958992]],[361,[-46205443,-77802884,1811618781,-675364873,-61313858,-1149589828,-824262757,-487644637],[-0.10761560499668121,0.1867380440235138]],[289,[-1308578941,545317504,-1228750258,-546977248,1313629625,1084548279,-448115765,1312899649],[-0.1779690682888031,0.11297041922807693]],[236,[2124418214,497585588,-273412583,-36860403,410545912,-21749827,-57253938,977282818],[-0.20535370707511902,0.0986572876572609]],[634,[-2628625,1397615486,-222948678,1760951400,-707857434,-108282272,-255668840,-246153218],[-0.09891577810049057,0.20372001826763153]],[441,[1349520221,349187989,1306762509,220739316,1551189437,-1786970795,-860861440,137176337],[-0.21401090919971466,0.09538363665342331]],[483,[-127866240,-1243498252,2075148792,-656172,-1077434979,1089506804,-1075988545,-1614085205],[-0.1046956405043602,0.19067412614822388]],[253,[-573002017,446301319,-1152229985,51053115,-585457444,-897361,-2109064294,-1442650241],[-0.18012882769107819,0.11004448682069778]],[494,[-252189692,66845267,-974148203,-1923221545,1325215904,951641541,2060832424,677760795],[-0.18193097412586212,0.1096099242568016]],[583,[-738863711,1434287531,1197897784,1438902146,1641133962,-66261760,-37880920,-2004551028],[-0.10881505161523819,0.18144680559635162]],[174,[573541027,1676608015,2242082,-206569477,997981440,1449923588,911537988,-212864065],[-0.1332176774740219,0.14928372204303741]],[421,[1746154929,-570884612,1069104059,1601896941,-1187998728,-1080239892,196885913,-1414887399],[-0.15190990269184113,0.13106991350650787]],[428,[-821319005,-814945359,1779284706,-1712448,-210261089,1179740053,-1214778225,-136349857],[-0.09939505159854889,0.20520499348640442]],[380,[-145235969,-541098113,-1368522945,-1478098961,-177733697,-13142085,-1287296305,-1073370811],[-0.08019614964723587,0.24394263327121735]],[7,[-1846704337,-178936003,-1015991060,-772726649,-1444167761,-1145590493,-772690101,1503989547],[-0.20097000896930695,0.10192957520484924]],[202,[1316145887,271851495,572705407,273870363,2131758335,-246658261,-14692406,-143193986],[-0.1798076182603836,0.10900650173425674]],[347,[-103681070,2069215860,1035229628,-688071392,596173394,-72609495,-80709704,-669718415],[-0.21817618608474731,0.09075445681810379]],[417,[495269373,487127029,1072919743,2108013936,2055212316,-1615987457,175799945,-1359017709],[-0.12845875322818756,0.1588725596666336]],[296,[585867779,-2097176059,-2098537921,-539000365,1583727364,1442265348,-1814891014,-204483334],[-0.10467831045389175,0.18451270461082458]],[303,[-607653333,-9692435,-247750602,-747325454,-13637809,38165774,-204802086,-775686706],[-0.10023513436317444,0.19359007477760315]],[629,[-545306625,2064440055,-352337922,318168918,-74269108,-143238655,-828194850,-1069094165],[-0.1195247545838356,0.16566169261932373]],[97,[-1610421825,2086727596,2091054521,-43774102,1956117671,-1079985741,529529502,-855371243],[-0.1406981199979782,0.1364859640598297]],[604,[581936675,583427210,717332896,1614603900,1779402659,71308546,930838418,1172302558],[-0.2065264880657196,0.09351257979869843]],[541,[404419349,932903717,1877421366,755818324,743838869,-1145519202,2007639040,-1363402412],[-0.17568394541740417,0.10853296518325806]],[603,[-67115261,1783467842,62649872,-177358022,1674508167,1627845012,2071982800,-1061706326],[-0.14163950085639954,0.1350509077310562]],[464,[-725234227,-65396777,-1603801204,-2002121734,-574092835,-559480843,-664465910,-928072645],[-0.11832091212272644,0.16329441964626312]],[9,[1740090031,-119056410,-48862274,-36986092,1905130415,-458821676,-1686142136,-789056533],[-0.09134785085916519,0.20984113216400146]],[389,[1163198464,-642500693,2032893884,-68817014,486915972,-364436958,2111264989,1551847259],[-0.32341209053993225,0.05920873209834099]],[454,[-89996128,2143001535,-319868938,-303249964,-941319771,-17356811,-1376506227,12609509],[-0.16184104979038239,0.12333205342292786]],[407,[224468919,20399931,275107615,218193753,359924797,357845277,1715740495,67410948],[-0.20427259802818298,0.09396296739578247]],[116,[2093999747,2076877547,-1536818480,-68260112,342087583,977675846,-2054892578,-143178538],[-0.11508999764919281,0.16942168772220612]],[262,[61902593,-1083933765,-53051661,-19728780,-758080769,-274773161,-2065401704,-2140078764],[-0.13256002962589264,0.14487990736961365]],[532,[-357248640,-1176763950,-1380155585,-537027259,844380056,805091765,787808170,-287169169],[-0.1147993728518486,0.1661256104707718]],[34,[1897919481,934478619,1607954095,1062273795,-568662347,2092388823,-471626574,1140325367],[-0.13866116106510162,0.13873730599880219]],[372,[-1037057913,-1657025808,46547560,273413291,1868532619,1378320161,-743476278,-347081181],[-0.11563215404748917,0.16552960872650146]],[546,[-1199314443,-408265787,-913588740,-1655009092,-1372935763,1873526476,-914524407,-979905444],[-0.1930251270532608,0.10073655843734741]],[392,[1034106418,-711186286,-1664267794,-171720173,606214007,-1128035247,564213287,1934636578],[-0.329284131526947,0.05941547453403473]],[126,[-687891445,-614004341,-433115782,2129635058,385995416,1494300484,1184757738,-237518882],[-0.11321404576301575,0.17364130914211273]],[558,[-50542464,-203846926,-1517043500,2113515223,-1091188084,-1864583803,-387006582,-880564821],[-0.10755964368581772,0.17839278280735016]],[475,[-357780685,-2045314380,429770709,-139071500,-1492218965,61726170,728218027,-339771255],[-0.10421722382307053,0.18218158185482025]],[556,[-302139391,1593041108,735992730,1353726386,-1293624936,-1196135168,-340731990,-1591537478],[-0.12337599694728851,0.15013375878334045]],[275,[1547535029,278984577,-1224785328,-1934989504,788137925,955118580,-1444508712,-1463819671],[-0.1586635708808899,0.11958929151296616]],[176,[-1439519837,-336661820,-1812236650,-712007984,-1960207458,-868173878,857715686,-973873982],[-0.12497423589229584,0.15143482387065887]],[359,[-761946313,1449128951,2079574803,1577003953,1515347100,-537167905,-67450178,-4500465],[-0.0817737728357315,0.2283615618944168]],[152,[-496441618,-750877463,-389118725,-37689332,1436594609,-578584890,-706221607,1893151375],[-0.13894660770893097,0.13676303625106812]],[504,[68506993,604858146,237580290,-2121958112,1638929,-1097225097,340092224,34511200],[-0.27272871136665344,0.0688985139131546]],[415,[-2147155497,1560733239,-303387241,-42356291,-598665995,-1162842499,-295060500,-1410399929],[-0.09935402125120163,0.19108591973781586]],[228,[-202202453,-590590115,1756643743,2109944543,871348042,-786157488,1542764527,-1693726949],[-0.09322153031826019,0.2062782347202301]],[460,[-1500254282,1435658607,582487508,484240674,2099271125,-46970395,1709452864,-467317454],[-0.15570642054080963,0.11965727806091309]],[46,[-919902696,-123093042,398152976,-135141176,1743172232,-1396378320,2083515430,1413872256],[-0.18301638960838318,0.10124789923429489]],[36,[-751855101,-145897929,2019538276,817985198,803892992,71726960,2134193492,1932970373],[-0.18066957592964172,0.099701888859272]],[20,[268485266,-899463709,586345979,2106381807,541077489,-84983361,1246258371,-1474337],[-0.30872756242752075,0.05945972725749016]],[322,[1213715019,-2076172757,615109711,232265406,1473517724,-1362446289,-1316954598,-1153808357],[-0.15449893474578857,0.12041906267404556]],[628,[-357568517,323871454,788404112,300650740,1538176507,-1983070516,-707831379,-1002326334],[-0.10190636664628983,0.18244536221027374]],[459,[1757579808,985458211,-1912341890,329521286,922752757,2094473459,132997598,-336317625],[-0.16428998112678528,0.1118251159787178]],[345,[-771571504,-9274104,969443530,77684746,-1178752308,1794067453,-1562083078,-604642545],[-0.1964097023010254,0.09406990557909012]],[284,[583589,-1811895121,-1462990311,-1594353,1953890287,-420466765,-104632354,-1678170365],[-0.10462117195129395,0.18044032156467438]]]]],"features":[[0,0,1,1],[0,0,5,7],[0,0,6,5],[0,0,6,6],[0,0,7,6],[0,1,1,1],[0,1,1,3],[0,1,8,6],[0,2,1,1],[0,2,1,2],[0,2,1,4],[0,2,2,1],[0,3,2,7],[0,4,1,1],[0,4,1,2],[0,5,1,1],[0,5,6,2],[0,5,8,6],[0,6,1,1],[0,6,6,5],[0,6,6,6],[0,7,1,1],[0,7,1,2],[0,7,3,2],[0,7,6,3],[0,8,1,1],[0,9,1,1],[0,9,1,2],[0,9,2,5],[0,9,4,3],[0,9,5,2],[0,11,4,2],[0,13,4,3],[0,14,5,3],[0,15,5,3],[0,15,8,3],[0,16,1,1],[0,16,3,2],[0,19,8,1],[1,0,1,1],[1,0,4,4],[1,0,5,6],[1,0,7,6],[1,1,1,1],[1,1,1,4],[1,2,1,1],[1,2,1,2],[1,3,1,1],[1,4,1,1],[1,5,1,1],[1,6,1,1],[1,6,1,2],[1,7,1,1],[1,7,3,2],[1,8,1,1],[1,9,1,1],[1,12,4,2],[1,14,7,2],[1,18,7,2],[2,0,1,1],[2,0,4,3],[2,0,5,2],[2,0,5,6],[2,0,6,4],[2,0,6,7],[2,0,7,6],[2,1,1,1],[2,2,1,1],[2,3,1,1],[2,3,1,2],[2,4,1,1],[2,4,2,4],[2,5,1,1],[2,5,1,2],[2,6,1,1],[2,7,1,1],[2,7,5,5],[2,8,2,3],[2,9,1,1],[2,9,1,2],[2,10,1,1],[2,11,1,2],[2,11,2,2],[2,12,4,3],[2,14,7,1],[2,15,5,3],[2,15,7,3],[3,0,1,4],[3,0,3,2],[3,0,4,4],[3,0,4,6],[3,0,6,5],[3,0,7,6],[3,1,1,1],[3,1,3,3],[3,1,6,5],[3,2,1,1],[3,2,2,3],[3,2,6,4],[3,3,1,1],[3,3,2,4],[3,3,2,5],[3,3,4,5],[3,3,6,7],[3,4,1,1],[3,4,2,3],[3,4,6,3],[3,5,1,1],[3,5,6,3],[3,6,1,1],[3,6,2,2],[3,6,6,3],[3,6,6,4],[3,7,1,1],[3,7,2,1],[3,7,2,2],[3,8,1,1],[3,8,2,2],[3,8,2,3],[3,9,1,1],[3,9,2,2],[3,10,2,2],[3,10,3,3],[3,10,6,1],[3,11,1,1],[3,11,2,2],[3,14,1,1],[3,14,2,1],[3,15,6,1],[3,15,7,3],[3,19,7,1],[4,0,1,1],[4,0,1,2],[4,0,1,3],[4,0,5,2],[4,0,5,3],[4,0,5,4],[4,1,1,1],[4,2,1,1],[4,2,2,3],[4,3,1,1],[4,3,2,3],[4,4,1,1],[4,4,1,4],[4,4,2,2],[4,4,5,3],[4,4,5,5],[4,5,1,1],[4,5,2,2],[4,6,1,1],[4,6,5,2],[4,7,1,1],[4,7,1,2],[4,7,2,3],[4,8,1,1],[4,8,2,1],[4,8,2,2],[4,9,1,1],[4,9,1,2],[4,9,2,1],[4,9,2,2],[4,9,3,4],[4,9,3,5],[4,10,1,1],[4,10,1,2],[4,10,3,3],[4,11,1,1],[4,11,3,3],[4,12,1,1],[4,13,1,1],[4,14,1,1],[4,14,2,1],[4,15,2,1],[4,15,5,1],[4,16,1,1],[4,18,3,2],[5,0,1,1],[5,0,3,1],[5,0,5,2],[5,0,5,4],[5,1,1,1],[5,1,1,6],[5,1,1,7],[5,2,1,1],[5,2,5,6],[5,3,1,5],[5,3,2,3],[5,3,3,4],[5,4,1,4],[5,4,4,3],[5,4,6,3],[5,5,2,2],[5,6,1,1],[5,6,1,3],[5,6,2,2],[5,7,1,1],[5,7,1,3],[5,7,2,2],[5,8,1,1],[5,8,2,2],[5,9,1,1],[5,9,1,2],[5,10,1,2],[5,10,2,3],[5,11,1,2],[5,12,1,1],[5,12,1,2],[5,13,1,1],[5,14,1,1],[5,15,2,1],[5,15,5,1],[5,16,3,1],[5,17,1,1],[5,18,1,1],[5,18,2,1],[6,0,1,7],[6,0,3,8],[6,0,4,7],[6,0,6,5],[6,0,6,6],[6,1,1,1],[6,1,1,6],[6,1,3,5],[6,1,6,6],[6,3,4,3],[6,4,2,3],[6,4,4,4],[6,4,4,5],[6,5,1,1],[6,5,1,4],[6,6,1,1],[6,6,1,2],[6,6,1,3],[6,6,2,2],[6,6,6,5],[6,7,1,1],[6,7,1,2],[6,7,2,2],[6,7,6,4],[6,8,1,1],[6,8,2,2],[6,8,6,3],[6,8,6,4],[6,10,1,1],[6,11,1,1],[6,11,1,2],[6,11,2,3],[6,11,2,4],[6,12,1,1],[6,12,1,2],[6,13,1,1],[6,13,1,2],[6,14,1,1],[6,14,1,2],[6,15,1,1],[6,15,4,1],[6,16,2,1],[6,16,4,1],[6,18,1,1],[7,0,1,1],[7,0,3,7],[7,0,3,8],[7,0,4,1],[7,0,5,5],[7,0,5,6],[7,1,1,1],[7,3,2,2],[7,5,3,5],[7,6,1,2],[7,7,1,1],[7,7,3,2],[7,7,3,4],[7,8,1,1],[7,8,3,4],[7,8,5,4],[7,10,1,1],[7,10,1,2],[7,10,3,3],[7,11,1,1],[7,11,1,2],[7,12,1,1],[7,12,1,2],[7,13,1,1],[7,13,1,2],[7,13,2,1],[7,13,2,2],[7,13,4,3],[7,14,1,1],[7,14,1,2],[7,14,2,1],[7,15,1,1],[7,15,2,1],[7,16,1,1],[7,16,2,1],[7,16,3,1],[7,16,4,1],[7,18,1,1],[7,19,3,1],[8,0,2,3],[8,0,5,4],[8,0,5,6],[8,1,1,1],[8,1,3,7],[8,2,1,1],[8,4,1,1],[8,5,2,5],[8,6,1,1],[8,6,2,1],[8,6,2,5],[8,7,1,1],[8,8,1,1],[8,9,1,5],[8,10,1,1],[8,10,1,2],[8,11,1,2],[8,12,2,2],[8,13,1,1],[8,13,2,1],[8,13,3,2],[8,14,1,1],[8,14,2,1],[8,14,5,3],[8,15,1,1],[8,15,1,2],[8,15,2,1],[8,15,3,3],[8,15,5,3],[8,16,1,1],[8,16,2,1],[8,16,3,1],[8,17,1,1],[8,17,2,1],[8,19,1,1],[9,0,3,6],[9,0,4,3],[9,0,5,6],[9,1,4,6],[9,2,1,1],[9,3,1,1],[9,5,1,5],[9,6,1,1],[9,6,2,1],[9,7,1,1],[9,8,1,1],[9,8,2,1],[9,8,2,3],[9,9,1,1],[9,9,2,4],[9,10,2,3],[9,11,1,1],[9,11,2,3],[9,12,2,2],[9,13,1,1],[9,14,1,1],[9,14,2,1],[9,15,1,1],[9,15,1,2],[9,15,2,1],[9,15,5,3],[9,16,1,1],[9,16,2,1],[9,16,2,2],[9,17,1,1],[9,17,2,1],[9,18,2,1],[9,18,5,2],[9,19,2,1],[10,4,1,1],[10,4,3,2],[10,5,1,1],[10,5,1,5],[10,5,2,5],[10,6,1,1],[10,7,1,1],[10,7,3,1],[10,8,2,4],[10,9,1,1],[10,10,1,1],[10,10,1,2],[10,10,4,3],[10,11,1,1],[10,11,2,3],[10,15,1,1],[10,15,1,2],[10,15,2,1],[10,16,1,1],[10,16,2,1],[10,17,1,1],[10,17,2,1],[11,0,2,7],[11,0,3,3],[11,1,1,1],[11,1,3,4],[11,4,1,1],[11,4,2,2],[11,4,3,2],[11,5,1,1],[11,5,1,5],[11,5,2,2],[11,6,1,1],[11,7,1,1],[11,8,1,1],[11,8,2,1],[11,8,4,3],[11,9,1,1],[11,9,3,4],[11,10,1,1],[11,11,1,1],[11,11,1,2],[11,11,2,3],[11,11,3,3],[11,12,1,1],[11,12,2,2],[11,12,4,2],[11,13,1,1],[11,14,1,1],[11,14,2,1],[11,15,1,1],[11,15,2,1],[11,16,1,1],[11,16,2,1],[11,17,1,1],[11,17,2,1],[11,18,2,1],[12,0,1,1],[12,1,1,1],[12,3,2,3],[12,4,3,2],[12,5,1,1],[12,5,2,2],[12,6,1,1],[12,6,1,5],[12,7,1,1],[12,8,2,1],[12,9,4,3],[12,10,2,2],[12,11,1,1],[12,11,1,2],[12,11,2,3],[12,12,1,1],[12,12,3,2],[12,13,1,1],[12,14,1,1],[12,14,2,1],[12,14,4,3],[12,15,1,1],[12,16,1,1],[12,16,2,1],[12,17,1,1],[12,18,2,2],[13,0,1,1],[13,0,3,3],[13,2,1,1],[13,4,2,3],[13,5,2,2],[13,6,1,1],[13,6,2,2],[13,7,1,1],[13,7,2,2],[13,8,1,1],[13,10,1,1],[13,10,1,2],[13,10,2,3],[13,11,1,1],[13,11,1,2],[13,12,1,1],[13,12,3,2],[13,13,1,1],[13,14,1,1],[13,14,2,1],[13,15,1,1],[13,15,2,1],[13,16,1,1],[13,16,2,1],[13,17,1,1],[13,18,1,1],[13,18,2,1],[13,19,1,1],[14,0,1,1],[14,1,2,3],[14,2,1,1],[14,4,2,2],[14,4,2,3],[14,5,1,1],[14,5,1,2],[14,5,2,2],[14,6,2,1],[14,6,2,2],[14,7,1,1],[14,7,2,2],[14,7,2,3],[14,7,3,2],[14,8,1,1],[14,8,1,2],[14,8,2,1],[14,8,2,2],[14,9,1,1],[14,9,2,1],[14,9,2,2],[14,9,2,4],[14,11,1,1],[14,11,1,2],[14,12,1,1],[14,13,1,1],[14,14,1,1],[14,14,1,2],[14,14,2,1],[14,15,1,1],[14,16,1,1],[14,17,1,1],[14,18,1,1],[15,0,1,1],[15,0,1,6],[15,0,1,7],[15,1,1,1],[15,1,1,6],[15,2,1,1],[15,3,1,1],[15,3,1,5],[15,4,1,5],[15,4,2,3],[15,5,1,1],[15,5,2,3],[15,6,1,1],[15,6,1,2],[15,6,1,3],[15,6,2,2],[15,6,3,2],[15,7,1,1],[15,7,1,2],[15,7,2,2],[15,7,2,3],[15,8,1,1],[15,8,1,2],[15,8,1,5],[15,8,2,2],[15,8,2,3],[15,9,1,2],[15,9,2,2],[15,10,1,2],[15,10,2,2],[15,11,1,1],[15,11,2,2],[15,12,1,1],[15,12,1,2],[15,13,1,1],[15,13,1,2],[15,14,1,1],[15,15,1,1],[15,17,1,1],[15,18,1,1],[16,0,1,1],[16,2,1,1],[16,3,1,1],[16,3,1,2],[16,4,1,1],[16,5,1,1],[16,6,1,1],[16,7,1,1],[16,8,1,1],[16,8,1,2],[16,8,2,3],[16,9,1,1],[16,9,1,2],[16,10,1,2],[16,11,1,1],[16,11,1,2],[16,11,2,2],[16,12,1,1],[16,12,1,2],[16,13,1,1],[16,14,1,1],[16,15,1,1],[16,16,1,1],[16,17,1,1],[17,0,1,1],[17,0,1,3],[17,2,1,1],[17,3,1,1],[17,5,1,1],[17,6,1,1],[17,6,1,3],[17,7,1,1],[17,7,1,2],[17,7,1,3],[17,8,1,1],[17,10,1,1],[17,11,1,1],[17,12,1,1],[17,13,1,1],[17,14,1,1],[17,16,1,1],[18,0,1,1],[18,1,1,1],[18,2,1,1],[18,3,1,1],[18,4,1,1],[18,4,1,2],[18,5,1,1],[18,6,1,1],[18,7,1,1],[18,8,1,2],[18,9,1,1],[18,10,1,1],[18,16,1,1],[19,0,1,1],[19,1,1,2],[19,2,1,1],[19,3,1,1],[19,4,1,1],[19,5,1,1],[19,6,1,1],[19,8,1,1],[19,9,1,1],[19,10,1,1],[19,11,1,1],[19,12,1,1],[20,0,1,1],[20,1,1,1],[20,2,1,1],[20,3,1,1],[20,3,1,3],[20,4,1,1],[20,5,1,1],[20,7,1,1],[20,8,1,1],[20,8,1,2],[20,9,1,1],[20,11,1,2],[21,0,1,1],[21,0,1,4],[21,1,1,1],[21,2,1,1],[21,3,1,1],[21,3,1,2],[21,4,1,1],[21,5,1,1],[21,6,1,1],[21,7,1,1],[21,8,1,1],[21,9,1,1],[21,10,1,1]]} \ No newline at end of file diff --git a/app/public/animeface.js b/app/public/animeface.js new file mode 100644 index 0000000..d2fff29 --- /dev/null +++ b/app/public/animeface.js @@ -0,0 +1,97 @@ +// Detector de rostros de anime, en un Worker para no trabar el estante. +// Evalúa en JavaScript la cascada LBP «lbpcascade_animeface» de nagadomi: https://github.com/nagadomi/lbpcascade_animeface +// La cascada (animeface-cascade.json) es MIT, (C) 2011 nagadomi@nurs.or.jp; el aviso completo va en el propio archivo. +const integral = (gray, w, h) => { + const I = new Int32Array((w + 1) * (h + 1)) + for (let y = 0; y < h; y++) { + let row = 0 + for (let x = 0; x < w; x++) { + row += gray[y * w + x] + I[(y + 1) * (w + 1) + x + 1] = I[y * (w + 1) + x + 1] + row + } + } + return I +} +function equalize(gray) { + const hist = new Int32Array(256), n = gray.length + for (let i = 0; i < n; i++) hist[gray[i]]++ + let i = 0 + while (i < 255 && !hist[i]) i++ + const out = new Uint8Array(n), first = hist[i] + if (first === n) return out.fill(i) + const scale = 255 / (n - first), lut = new Uint8Array(256) + let sum = 0 + for (i++; i < 256; i++) { sum += hist[i]; lut[i] = Math.max(0, Math.min(255, Math.round(sum * scale))) } + for (let k = 0; k < n; k++) out[k] = lut[gray[k]] + return out +} +function shrink(gray, w, h, W, H) { // promedio por área, como INTER_LINEAR al reducir poco + const out = new Uint8Array(W * H), fx = w / W, fy = h / H + for (let y = 0; y < H; y++) { + const sy = (y + 0.5) * fy - 0.5, y0 = Math.max(0, Math.floor(sy)), y1 = Math.min(h - 1, y0 + 1), ty = sy - Math.floor(sy) + for (let x = 0; x < W; x++) { + const sx = (x + 0.5) * fx - 0.5, x0 = Math.max(0, Math.floor(sx)), x1 = Math.min(w - 1, x0 + 1), tx = sx - Math.floor(sx) + const a = gray[y0 * w + x0] * (1 - tx) + gray[y0 * w + x1] * tx, b = gray[y1 * w + x0] * (1 - tx) + gray[y1 * w + x1] * tx + out[y * W + x] = a * (1 - ty) + b * ty + 0.5 + } + } + return out +} +function scan(cascade, gray, W, H, step, emit) { + const I = integral(gray, W, H), S = W + 1, { stages, features, w: cw, h: ch } = cascade + for (let wy = 0; wy + ch <= H; wy += step) { + for (let wx = 0; wx + cw <= W; wx += step) { + let pass = true + for (let s = 0; s < stages.length && pass; s++) { + const [limit, weak] = stages[s] + let sum = 0 + for (let q = 0; q < weak.length; q++) { + const [f, subset, leaf] = weak[q], r = features[f], fx = wx + r[0], fy = wy + r[1], bw = r[2], bh = r[3] + const a = fy * S + fx, y1 = a + bh * S, y2 = a + 2 * bh * S, y3 = a + 3 * bh * S + const p0 = I[a], p1 = I[a + bw], p2 = I[a + 2 * bw], p3 = I[a + 3 * bw] + const p4 = I[y1], p5 = I[y1 + bw], p6 = I[y1 + 2 * bw], p7 = I[y1 + 3 * bw] + const p8 = I[y2], p9 = I[y2 + bw], p10 = I[y2 + 2 * bw], p11 = I[y2 + 3 * bw] + const p12 = I[y3], p13 = I[y3 + bw], p14 = I[y3 + 2 * bw], p15 = I[y3 + 3 * bw] + const c = p10 - p9 - p6 + p5 + const code = ((p5 - p4 - p1 + p0 >= c) << 7) | ((p6 - p5 - p2 + p1 >= c) << 6) | ((p7 - p6 - p3 + p2 >= c) << 5) | ((p11 - p10 - p7 + p6 >= c) << 4) | ((p15 - p14 - p11 + p10 >= c) << 3) | ((p14 - p13 - p10 + p9 >= c) << 2) | ((p13 - p12 - p9 + p8 >= c) << 1) | (p9 - p8 - p5 + p4 >= c) + sum += leaf[subset[code >> 5] & (1 << (code & 31)) ? 0 : 1] + } + if (sum < limit) pass = false + } + if (pass) emit(wx, wy) + } + } +} +// Agrupa ventanas parecidas, como groupRectangles de OpenCV. +function group(rects, minNeighbors, eps = 0.2) { + const parent = rects.map((_, i) => i), find = i => (parent[i] === i ? i : (parent[i] = find(parent[i]))) + const close = (a, b) => { const d = eps * 0.5 * (Math.min(a.w, b.w) + Math.min(a.h, b.h)); return Math.abs(a.x - b.x) <= d && Math.abs(a.y - b.y) <= d && Math.abs(a.x + a.w - b.x - b.w) <= d && Math.abs(a.y + a.h - b.y - b.h) <= d } + for (let i = 0; i < rects.length; i++) for (let j = 0; j < i; j++) if (close(rects[i], rects[j])) parent[find(i)] = find(j) + const by = new Map() + rects.forEach((r, i) => { const k = find(i); const g = by.get(k) || { x: 0, y: 0, w: 0, h: 0, n: 0 }; g.x += r.x; g.y += r.y; g.w += r.w; g.h += r.h; g.n++; by.set(k, g) }) + const out = [...by.values()].filter(g => g.n > minNeighbors).map(g => ({ x: Math.round(g.x / g.n), y: Math.round(g.y / g.n), w: Math.round(g.w / g.n), h: Math.round(g.h / g.n), n: g.n })) + // Quita los que quedan dentro de otro mayor con más apoyos. + return out.filter(a => !out.some(b => b !== a && b.n >= a.n && a.x >= b.x - b.w * 0.2 && a.y >= b.y - b.h * 0.2 && a.x + a.w <= b.x + b.w * 1.2 && a.y + a.h <= b.y + b.h * 1.2 && b.w > a.w)) +} +/** data: RGBA. Devuelve los rostros en píxeles de la imagen, con `n` = ventanas que los apoyan (más es más fiable). */ +function detectFaces(cascade, data, w, h, { scale = 1.1, minNeighbors = 5, minSize = 24 } = {}) { + const raw = new Uint8Array(w * h) + for (let i = 0; i < raw.length; i++) raw[i] = data[i * 4] * 0.299 + data[i * 4 + 1] * 0.587 + data[i * 4 + 2] * 0.114 + 0.5 + const gray = equalize(raw), rects = [] + for (let f = 1; ; f *= scale) { + const size = Math.round(cascade.w * f) + const W = Math.round(w / f), H = Math.round(h / f) + if (W < cascade.w || H < cascade.h) break + if (size < minSize) continue + scan(cascade, f === 1 ? gray : shrink(gray, w, h, W, H), W, H, f > 2 ? 1 : 2, (x, y) => rects.push({ x: Math.round(x * f), y: Math.round(y * f), w: size, h: size })) + } + return group(rects, minNeighbors) +} + +let cascade = null +self.onmessage = async ({ data: { id, pixels, w, h } }) => { + try { + cascade ||= await fetch(`/animeface-cascade.json${self.location.search}`).then(r => { if (!r.ok) throw new Error(r.status); return r.json() }) + self.postMessage({ id, faces: detectFaces(cascade, new Uint8ClampedArray(pixels), w, h, { minNeighbors: 3 }) }) + } catch (e) { self.postMessage({ id, faces: null }) } +} diff --git a/app/public/app.js b/app/public/app.js index 44e5cad..93cf720 100644 --- a/app/public/app.js +++ b/app/public/app.js @@ -364,6 +364,7 @@ window.addEventListener('beforeinstallprompt', e => { e.preventDefault(); instal // ---------- Router ---------- let prevHash = '', curHash = '' // para volver atrás sin pasar por el lector +let shelfTrip = null // { mangaId } mientras se lee algo abierto desde el estante: libro 3D y vuelta al estante async function router() { if (location.hash !== curHash) { prevHash = curHash; curHash = location.hash } if (cleanup) { cleanup(); cleanup = null } @@ -371,6 +372,7 @@ async function router() { const [pathPart, query] = location.hash.slice(1).split('?') const parts = (pathPart || '/').split('/').filter(Boolean) const params = new URLSearchParams(query || '') + if (parts[0] !== 'read' && parts[0] !== 'shelf') shelfTrip = null document.querySelectorAll('#topbar nav a').forEach(a => a.classList.toggle('active', a.getAttribute('href') === `#/${parts[0] ?? ''}`)) if (!me) { @@ -386,6 +388,7 @@ async function router() { if (parts[0] === 'read') return await viewReader(parts[1], parts[2], Number(params.get('page') || 0) - 1) if (parts[0] === 'history') return (location.hash = '#/library') // antiguo nombre if (parts[0] === 'library') return await viewLibrary(params) + if (parts[0] === 'shelf') return await viewShelf() if (parts[0] === 'downloads') return (location.hash = '#/queues') // antiguo nombre if (parts[0] === 'queues') return await viewQueues() if (parts[0] === 'stats') return await viewStats() @@ -2102,7 +2105,7 @@ async function viewReader(mangaId, chapterId, startPage) { app.innerHTML = `
- ${icon('back')} + ${icon('back')}
${esc(manga.title)}
@@ -3067,7 +3070,8 @@ async function viewReader(mangaId, chapterId, startPage) { } // --- Libro 3D: otro módulo dibuja el libro; el lector sigue llevando la página, el progreso y los gestos. - const b3dWanted = () => B3D_OK && !!settings.book3d && isPaged() && settings.fit !== 'width' + const fromShelf = shelfTrip?.mangaId === mangaId // desde el estante se lee en 3D aunque el ajuste diga otra cosa (sin guardarlo) + const b3dWanted = () => B3D_OK && (!!settings.book3d || fromShelf) && isPaged() && settings.fit !== 'width' const b3dOn = () => b3dWanted() && !atEnd const b3dPaper = () => { const hex = book ? (BOOK_PAPERS[bookSettings().paper] || BOOK_PAPERS.light).bg : '#efeadf' @@ -3817,6 +3821,120 @@ const libCard = ({ href, cover, title, sub, pct, badge, del }) => `${esc(title)}
${sub ? `
${sub}
` : ''}
` +// ---------- Estante 3D ---------- +const SHELF_OK = 'WebGL2RenderingContext' in window // también con ratón o teclado: a diferencia del lector, no depende de los gestos táctiles +// Foto del último fotograma del estante, encima de todo mientras el lector se monta; se desvanece cuando el libro 3D ya está dibujado. +function handoffCover(src) { + document.querySelector('.handoff')?.remove() + const img = Object.assign(document.createElement('img'), { className: 'handoff', src, alt: '' }) + document.body.append(img) + const t0 = performance.now() + const fade = () => { img.classList.add('out'); setTimeout(() => img.remove(), 450) } + const wait = () => { + if (!img.isConnected) return + const ready = document.querySelector('#b3d:not([hidden]) canvas') + if (ready) return setTimeout(fade, 350) // las texturas de la tapa tardan un instante + if (performance.now() - t0 > 2500 || !location.hash.startsWith('#/read/')) return fade() + setTimeout(wait, 60) + } + wait() +} +async function viewShelf() { + if (!SHELF_OK) { + app.innerHTML = `

Estante 3D

Este navegador no tiene WebGL2.

${icon('library')} Volver a la librería

` + return + } + document.body.classList.add('reading') // sin la barra de arriba + app.innerHTML = `
${icon('back')} Librería

Colocando los tomos…

+ ` + const note = $('#shelfnote'), card = $('#shelfpeek') + const focusOn = shelfTrip?.mangaId || null // al volver del lector, con ese tomo a la vista + shelfTrip = null + let shelf = null, gone = false + const onKey = e => { if (e.key === 'Escape') shelf?.unpeek() } + document.addEventListener('keydown', onKey) + cleanup = () => { gone = true; document.removeEventListener('keydown', onKey); shelf?.destroy(); shelf = null } + // Vistazo: lo que se sabe del tomo sacado, junto a él. + const readOf = info => { + const { work, vol, state } = info + if (state === 'reading' && work.chapterId) return readUrl(work.id, work.chapterId, work.page || 0) + if (vol.chapters?.length) return readUrl(work.id, vol.chapters[0]) + return work.chapterId ? readUrl(work.id, work.chapterId, work.page || 0) : `#/manga/${work.id}` + } + // A la mesa: el estante posa el tomo como el lector lo mostrará y una foto del último fotograma tapa el cambio. + let leaving = false + const toTable = info => { + if (leaving) return + const href = readOf(info) + const go = snap => { + if (gone) return + if (href.startsWith('#/read/')) shelfTrip = { mangaId: info.work.id } + if (snap) handoffCover(snap) + location.hash = href + } + leaving = true + if (!href.startsWith('#/read/') || !shelf?.fly(go)) go(null) + } + const showPeek = info => { + if (!info) { card.classList.remove('on'); clearTimeout(card.hideTimer); card.hideTimer = setTimeout(() => { if (!card.classList.contains('on')) card.hidden = true }, 250); return } + const { work, vol, state } = info, n = vol.chapters?.length || 0, at = n && work.chapterId ? vol.chapters.indexOf(work.chapterId) : -1 + const facts = [vol.vol ? `Tomo ${esc(vol.vol)}` : '', n ? `${n} ${n === 1 ? 'capítulo' : 'capítulos'}` : '', vol.pages ? `${vol.pages} páginas` : ''].filter(Boolean).join(' · ') + const pct = state === 'read' ? 100 : at >= 0 ? Math.round((at / n) * 100) : 0 + const where = state === 'read' ? 'Leído' : state === 'reading' ? (at >= 0 ? `Vas por el capítulo ${at + 1} de ${n} de este tomo` : 'Lo estás leyendo') : 'Sin empezar' + card.innerHTML = ` +

${esc(work.title)}

${facts ? `

${facts}

` : ''} +

${where}

+ ` + card.querySelector('.peekx').addEventListener('click', () => shelf?.unpeek()) + card.querySelector('#peekread').addEventListener('click', e => { e.preventDefault(); toTable(info) }) + clearTimeout(card.hideTimer) + card.hidden = false + requestAnimationFrame(() => card.classList.add('on')) + } + const ver = name => document.querySelector(`meta[name=${name}-version]`)?.content || '' + try { + const [{ works }, lib, mod] = await Promise.all([api('/api/shelf'), import(`/book3d.js?v=${ver('b3d')}`), import(`/shelf3d.js?v=${ver('shelf')}`)]) + if (gone) return + if (!works.length) { note.textContent = 'Aún no hay nada en tu biblioteca: los tomos de lo que leas, sigas o descargues aparecerán aquí.'; return } + shelf = mod.createShelf3D($('#shelf3d'), lib, { + works, + still: matchMedia('(prefers-reduced-motion: reduce)').matches, + onPeek: showPeek, + onOpen: info => toTable(info), // tocar el tomo sacado lo lleva a la mesa + table: me?.tableV ? `/api/table?v=${me.tableV}` : null, + // Un tomo sin portada saca el arte del lomo de sus primeras páginas: la 0 suele ser de créditos. + pagesOf: chapterId => api(`/api/chapter/${chapterId}?saver=0&hd=0`).then(d => (d?.pages || []).slice(1, 6), () => []), + }) + if (!shelf) throw new Error('sin WebGL2') + if (focusOn) shelf.focus(focusOn) + // Los tomos llegan aparte, de pocos en pocos: la primera vez pueden tardar por las fuentes externas. + let next = 0, pending = works.length + const worker = async () => { + while (next < works.length && !gone) { + const w = works[next++] + const r = await api(`/api/volumes/${w.id}?lang=${encodeURIComponent(w.lang || 'es')}`).catch(() => null) + if (gone) return + if (r?.volumes?.length) shelf.setVolumes(w.id, r.volumes) + if (--pending === 0) note.hidden = true + } + } + for (let k = 0; k < 3; k++) worker() + // Logos para el título de los lomos: la primera vez el servidor los busca en Wikimedia Commons, sin prisa. + let nextLogo = 0 + const logoWorker = async () => { + while (nextLogo < works.length && !gone) { + const w = works[nextLogo++] + const r = await api(`/api/logo/${w.id}?lang=${encodeURIComponent(w.lang || 'es')}`).catch(() => null) + if (gone) return + if (r?.logo) shelf.setLogo(w.id, r.logo) + } + } + for (let k = 0; k < 2; k++) logoWorker() + } catch (e) { + if (!gone) note.textContent = `No se pudo abrir el estante: ${e.message}` + } +} + async function viewLibrary(params) { const tab = params.get('tab') || 'reading' app.innerHTML = '
Cargando…
' @@ -3837,7 +3955,7 @@ async function viewLibrary(params) { ...lists.map(l => [`list-${l.id}`, l.name, 'bookmark', contentMode() === 'both' ? l.count : 0]), // el total de la lista incluye lo filtrado ] const curList = tab.startsWith('list-') ? lists.find(l => `list-${l.id}` === tab) : null - app.innerHTML = `

Librería

+ app.innerHTML = `

Librería

${SHELF_OK ? `${icon('library')} Estante 3D` : ''}
${tabs.map(([k, label, ic, n]) => ``).join('')} ${online ? `` : ''}
${curList ? `
Lista propia · añade mangas desde su ficha con ${icon('bookmark')} Listas @@ -4046,7 +4164,7 @@ async function viewQueues() {

${icon('book')} Biblioteca descargada

-

CBZ en /zdata/media/mangas (compatibles con Kavita, Komga, Mihon…); se leen desde el disco.${list.length ? ` Total: ${fmtSize(total)}.` : ''}

+

CBZ en ./mangas (compatibles con Kavita, Komga, Mihon…); se leen desde el disco.${list.length ? ` Total: ${fmtSize(total)}.` : ''}

${library.length ? `
${library.map(d => qcard({ key: `lib:${d.manga_id}`, id: d.manga_id, cover: d.cover, title: d.title, pct: d.total ? Math.min(100, (d.done / d.total) * 100) : null, @@ -4269,7 +4387,7 @@ function viewSettings() { Si un manga tiene copia local, los capítulos nuevos se descargan automáticamente. Además puedes recibir una notificación:

ntfy - + Telegram (opcional) diff --git a/app/public/book3d.js b/app/public/book3d.js index f7cc9d4..3c314bb 100644 --- a/app/public/book3d.js +++ b/app/public/book3d.js @@ -115,9 +115,9 @@ export function fitCamera(points, aspect, marginX, marginY) { // Colores de la portada para la contraportada y sus botones. const luma = c => { const f = v => (v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4); return 0.2126 * f(c[0]) + 0.7152 * f(c[1]) + 0.0722 * f(c[2]) } const contrast = (a, b) => { const x = luma(a), y = luma(b); return (Math.max(x, y) + 0.05) / (Math.min(x, y) + 0.05) } -const inkOn = c => (contrast(c, [1, 1, 1]) >= contrast(c, [0.07, 0.06, 0.05]) ? [1, 1, 1] : [0.07, 0.06, 0.05]) +export const inkOn = c => (contrast(c, [1, 1, 1]) >= contrast(c, [0.07, 0.06, 0.05]) ? [1, 1, 1] : [0.07, 0.06, 0.05]) const mixColor = (a, b, t) => a.map((n, k) => n + (b[k] - n) * t) -const css = c => `rgb(${c.map(n => Math.round(n * 255)).join(' ')})` +export const css = c => `rgb(${c.map(n => Math.round(n * 255)).join(' ')})` // Color dominante y color de acento: el acento es el que más destaca sobre el dominante, sin ser una mota de la imagen. export function coverPalette(data) { const boxes = new Map() @@ -143,7 +143,7 @@ export function coverPalette(data) { } // Madera generada: se repite sin que se note el corte. -function woodCanvas() { +export function woodCanvas() { const S = 1024, PLANKS = 5, canvas = Object.assign(document.createElement('canvas'), { width: S, height: S }), g = canvas.getContext('2d') let seed = 7 const rnd = () => (seed = (seed * 16807) % 2147483647) / 2147483647 @@ -243,7 +243,7 @@ void main() { }` // Junta rejillas en una malla: pos(3) normal(3) uv(2). -class Shape { +export class Shape { constructor() { this.v = []; this.i = [] } grid(cols, rows, at) { const base = this.v.length / 8 @@ -305,8 +305,9 @@ function rimShape(pts, y0, y1, thick) { // El sensor: los ejes de la pantalla a partir de la orientación del dispositivo. La inclinación se desvanece con el tiempo. // MAX_DEG: lo que hay que girar el dispositivo para llegar al tope. ORBIT_*: cuánto rodea entonces la cámara al libro, en grados. -const MAX_DEG = 15, FADE_S = 2.5, QUIET = 0.6, ORBIT_TILT = 7, ORBIT_YAW = 10, ORBIT_BACK = 0.06 -function createTilt(onChange) { +export const MAX_DEG = 15 +const FADE_S = 2.5, QUIET = 0.6, ORBIT_TILT = 7, ORBIT_YAW = 10, ORBIT_BACK = 0.06 +export function createTilt(onChange) { const target = { x: 0, y: 0 } let listening = false, gotOrientation = false, lastT = 0, lastOri = null, lastFade = 0, askOnTouch = null const clamp = v => Math.max(-MAX_DEG, Math.min(MAX_DEG, v)) diff --git a/app/public/fonts/LICENSE.txt b/app/public/fonts/LICENSE.txt new file mode 100644 index 0000000..ced165d --- /dev/null +++ b/app/public/fonts/LICENSE.txt @@ -0,0 +1,3 @@ +Fuentes manuscritas de las notas del estante, de Google Fonts (solo el subconjunto latino): +Caveat, Patrick Hand, Kalam, Gochi Hand, Indie Flower y Shadows Into Light: SIL Open Font License 1.1 (https://openfontlicense.org). +Permanent Marker: Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0). diff --git a/app/public/fonts/caveat.woff2 b/app/public/fonts/caveat.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..36e42dcc27ef3652aa8f210827f57154511766a9 GIT binary patch literal 51220 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 Z|BDc|l&n&Dt6G!e_j~`Z9WMX?004Ad42A#z literal 0 HcmV?d00001 diff --git a/app/public/fonts/gochihand.woff2 b/app/public/fonts/gochihand.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..b929dadca9009b8d0607563e386de19687a59301 GIT binary patch literal 19908 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 Hx&{CMPCS)9 literal 0 HcmV?d00001 diff --git a/app/public/fonts/indieflower.woff2 b/app/public/fonts/indieflower.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..f28fef8a35ebac78ca6f0c0b1514d1f7fbf7a003 GIT binary patch literal 19508 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 XB8~@}r;Gr+90Een5BetHiQxbMRXqy9 literal 0 HcmV?d00001 diff --git a/app/public/fonts/kalam.woff2 b/app/public/fonts/kalam.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..0a6bd556a497783e70b3a0dc941bc81133c63842 GIT binary patch literal 22144 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 HNd*7^%DAr& literal 0 HcmV?d00001 diff --git a/app/public/fonts/patrickhand.woff2 b/app/public/fonts/patrickhand.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..e80b54b43638b7eca06658defe672ac887030713 GIT binary patch literal 23944 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 literal 0 HcmV?d00001 diff --git a/app/public/fonts/permanentmarker.woff2 b/app/public/fonts/permanentmarker.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..203ccaeb9c2bab914dbb05e4501915a16315200b GIT binary patch literal 29564 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
    S}D~Xz1ggD{L7{ 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 Jo`3ha{{z9RE`|UA literal 0 HcmV?d00001 diff --git a/app/public/fonts/shadows.woff2 b/app/public/fonts/shadows.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..f15b2036a950b82c2235c151eb558ff40e7d49ad GIT binary patch literal 16296 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
  1. -(=ACq(s(flW!S+D zNBLO;>El_as?I$>)FSiir)HvZ$ms)6AJo*^$Sp_unkA1p;l)T>7MrS?6YrL)Vs^T? z-2~J#idSx@AW8OpkeFxF-HQn%LTe zH_9iqX{DPFbG;3*VHjn$oX)rm=?`;`j7~S+a)ESiani+c`l{4*k9Chtgsv{jZpUC@ z;iN>fjD4iZWB}a83__F~r&2=^ja+8n63x5;w+S67{DRNS`W309q6MioGKBF6aV)bh#B>Ao%&t*=dJNa!ATo# z6lGgP>sfbsrIT*@>@o;~wf87yjF*oB1gM)Ydb|0%+uVVGErf5TfQ}?w$Pt}Z z*m~IVl#)0$8#xgrO<3NUCaNlo)MZ9;ve)Kt5-X(0c3bf$s$gy(O%qjDZHUCVL9%v! z1fQP*rL7`f=@~}mrOd?Iy{0r=IVWMG5>-Lqjq|1XrmSBYU!*9(O3N_WM&*!_Z5nhF zbDb8Qr`LJV&Fz5>yx{nFWnuz~BptkEQc6~Pk6t5rYglEg-R^WZ6Gao%M%%X9)<_fV zjLq)VE+wIv{(Lj3kcE(zaP6u9Wln0(Nh~E%YozH9qa647{5LC(Pd7Se1;?_40ED2u zweVDBhXiZMe}@ZvS?=AA{4V-Xj(a`aqd~M=xf*@#M8*lHy+5fOlU^Z9#-+UCgCr`)eoj$47COe6REK zoc^QG&{0$yRbx+ig~L!G&r02`u$P8hqYT zO|FMQUP@~uFC;PW4b^pTcbxQteG}1~v9va2hfQ|W%$<0|Xwo616#2&xxH6yY3R%T( zX!|sX@w-HGlQ>*)fG+y7o~c_^K3*c!1D(iSZmt{c4!iZqZN)=!iG~Vv)=#@(Ve3W7 zP{ztY`Q>YRg^q)dDy79M%l03wl7Q~1HL|L=zoV735k#!>cwg&`J|c(Gk3mF*Ez2bH zPdbmyR};tWWGE%9gTJ19Suxn!_-cs>z_@I+r2YBpP6YvXxZ2+&lSw>silo$=Ah@p@ ztM^?xhr10~RQ1BATXz>E@e-Q5UnVI{65rw# zMefdSHaG5#d8-~@Eh+Z89Sw4$L+I)3$d>>!JVL5ye+3e4Ux=J~N~_2`dm>*WPzf{~ zQ_cK?*`mTl(#476y^w0rmd*=m>CU+ouK6BV^+473z*;N+BYchy={E8TT~cry(_`C6>79(^U2pubP#a{t7(PpY9-S|sfF}G z!g>rl8Tm%%9mi*l><-1zIyMB|_4nIrign>p$}|Z>)l|qTkJw(uLN5 zRdt#*y|B2|E;tTrXRpeseELGHFg2i@nRB<`<9g&J z4ebK$EtN1w5jv~a zxdP*s!xXPx8tI0P6z_)fYeZO3!D(LScTK90{jRLq+0M>0aVrgB&6k=F^Zd)!0)N}` zSN)g9TJn5YtA**5f1+Z5OIN( zk5^rE80MqaGz7nzxvI|EC84qd|HElxQHZ{*OaGQS~(M*eC9wNae8=Q=?-EppM?tx8a`oEC(y)*FU7A~Vos^wwJ-*Bl<-U;6hkp4rX=LK~7wEm4292^<589g&@ zd%1VV^v53C;C2l=`*H+^uWWm-czf*1N=>92NKT@Zxgti+Es;&TV+C>EwBGg|@CC6w zM5w*o5ke5GAvRYwS49S5Vh+s0A6Nh~@=%5+E)O z%(BIKzqN2Q8LKn~k!d$LSQ*2v(-p_&UV~7aYNHVt$P9U&<(y_iAXTrb3N379>68v_ zp0WgNWNdwMp*omi%U>c-r#M#kSR>Z7_Xh8L_$TAOBjMy6S#amNg~@Yf*Z+4hiu{az z=jlck4Xyae`R^>GB4m{-nN?m4wv>vG(8nGfVu<%U|4Iq^xq9w`&=((nv;HC2z*g;> zQXNb&r-iQ!pUS*-{u%dX_G%L^^}lm(I=zz1TL%x&OG)CeSlWkZ5ChOnpd=JQL9tF5 zqB^5kvMY#f`w!5U&{f*~E_H!NuA4Vj=#LYq9MZeE2E2{nT?1==jO8lic1c}iJVHaqHr^2mJfe4mj1T%Uw6Bz)l z`jN<5-+Eayxx9KfHNjw*%cdX{^1wd*-6Ke41tp?-k2?QS12YrqMX+y&=HroNs%m+; zEQ=)u+tpmH{;r3=yUg&{JYiNvtt}AYAPBVY(m5u3;9}Pq$N$r6V?Pi&1CakOGm9b(I{&oFHBP&Szt~}8uAAN0F0jH zm@$iyaJ>}OGMGISL_(r*ZYu<}RI*Ei$5xylDBDea6szSK*M;)L9FsE5E90uSPj*e` z>1X%%tgKB5sJ?Xh!#z;*xtEhlrJbY~O>F975ZVlW8LyCKX0YUP9E0WsOmd$l>W+7F zOW(9i)<*T#M^R~vMVhPHl_1BVdc4iBz484Q-9w7$Tw_9bd*kRa)Sd58+SQihl1uE9 zO1CLf{1p0H`j}!{W?MyMiyALyz&Xe`yalU4 z3&OhF&d7w-WycPvBeOgWhR{6Vxr(!#Cs(j!9FB#>WK{}9nJlK2qXQ}y%bi69%VhTc z5tPnD9pnFH+0YgU3jEL9Tt77H2Yoz%A;2=kSVEj(UyO&=w~xw08n#b1_^P7gCLH)} z$n2fsH|1F-5VfPTweFS53U!qtSXIF0%AB9!$ifgCNA@iRO!d&j3 zFl+u}2iHPPqIDo}mAly%of-EG+9z3~TZy9fX$wL__V(oa8Z9Ylrqr0)T}PPi;DDZY zfytZ9Wjk2-XML&R>%8^GsivrD`eYx;#OURG&44pnL5qd7#A*=UW3a^5O{bJ$VdHGB zbmxgf^;2zh|5AO%RJkDTni|MFjeg707dLiymoJF6##KdH3%r^mL%0=w>5icIkm`+f zH77)Ls3YEF4fK)}OO;A{PxtjeG#kOoGIPvQfp-E z(?iPLt3s0XW>K=7Zw~l+af3GIZ$}{KH5dqp!&4XyoVCKs-1#IzFz*ko&R>%%F-go4 zgLUTMjC)^PUwnc%c^PPSdF|$|GVu!#XG`zNdoLiNk@Zx!jlbl=-pUz34nqvgp z+ZfB*`3{j&W`6_@1AXm`JPt;t49&_qIyhcfnS1%6iaM|mu)M&P)Rc$Q7nMnaIl4O$ zLZOE>HrJYOv^tp^k~`{to3iHej1;dtd0I%k`L=Ry|6GNzPz?7%Qn@FY{pi<=(DQN4 z9QrvWbqLJvd?4MgpOx+qzZ4&lc&pni9WKZM(Rc=@P5*03=npjff+6x4NReeh8;}9!dS(Wk8Xp5=ExT@1?0-Jp55Mp5NOwyYx|1#a(mpTBGhR<# zX}4JZ0aN)QS$~u!uuh(SwBqizAeeef)7L$U5=#?{LJ8JOpjt%@3xpNrMt+Xos4>WI z5v4futYLtb*}ZFGjGm_1o4F7y#%N4n;h4Og{zk7|*Z^w@#e}GAq6zDOJ3y5OIJf`& z&(@GsjjuTN0!~FpTSKOrCuda^#RU=Y(~p?g*DG@uCK$>?YjjO6Wm({Nl8%f(t0l&j z@DV*a(p~sHi%A@CIG}Ck4s-3i3D6XB^7w{hzvRVxYk{S3TkH32+cN(PTcco0*!Xoq z+>6iFAR7;E=0!nua06a7b7QJ{%Kt2xD0jy+-aky%o!MeiU5;lm3W{piaDW%nEjRRpnGqyf}@KoH2SHn}_>7WZ#xd$N6wrOIZGH5C^6P}4Q;!Z&KAp^+e zu`TT$n!kFnEY?QRplA?eVeEt{6ti2p!YiQPn=<`5-Cu9kIo#|(woV?z#6O!}g6Um( zdP8`Ad})mN?x=r?sVdZ}`-I<)nrmO?AU#ki=T~9vv|0s!L<|g&xTC9@ATcA6M^qB| zL9vL&h8aj^i0W}pX=X{b%XCwb8vp1*=Gg9KgcIu5=*mh5)%*+ClL*F{h*t{rVL ztqE;GaWbG<7xF;jlvk+B)!AbQcXwa*O!dj}aQxD8$X96PY~%0bY)y&&x^8P9!v%(+ zBdnvs66hvVTKo6H<1sG;gPmwkBkQ`*>jiNj9k%xzsT4xcrDD$1DeK zwZZiLLsRSZeHyeFbfP_sR?0b_vz^Ng`^Z5+kPRw<>)>MGfLL?qPNapW_|%g=Bx%>} zXj@W7jICMDH+Pw}F=QvVgWDdccBu9Fx zRLQh0S!Pi>)$X7A)JUhHleptnn#sRzD)L1xP64Q;g&&id=tpyIP{c73fuPAv>)S|j zL2>K2Z&PG8(u_}?kOw03Gp(hO>0VyEI>t4e={DleFe5h9vU5{uU|yWrMoYCK8;`mO zwgF{27jv>JWwpAzr)u=UVS6-VL4GC2-B)K36cg2O4YOF_*n&bJu^nPSN(GK`-LDfr zgh2~=-@a@alKTDegUZZv;C6|~wk!3+Z(1=_wqDA>AlHc0FaU)>)a7ZqKrUYt+kEkp zKGnly#W(l)7M7(I#VH!Vv;Coc-<*W7P|AfIKVcWVva^le!RPF;MKSr2DM9=p=Y-4CZQadlnYjRKbvjnC+`-8F3 zOqwP8!Q?>MwkG6K?NIx_gt23qA(G)Wp3 z6)avXb#F9CbC`KV4sPJJ$oIT3c)PqyH3i~FKkox-+W4WTZ*ftQnq7{#+VkhcE!b$$7`p0zYjHq z*nRBddT78zc^mm~FVw?K*%j|)@iabPN>y`F7&>0IMg!3(#wy&h(ijH5l6r{DG7I1A z`L)Gi%8bcZ0vM$w)F-j&328~zXROFbWvaSZ=@O>dAdKUyl9%bGh@BruzAD#mj;0ps zh2$?}18B1siZM`v044D2!ILZgUir-+@+Ya_%>FMGHABH|cOi(t zh$8j@{sG=WxDb^EC^a1R5n#aFQdu_czE>B=@@3A7bGuqm0KoUpVr-GqF?^qwYUnbA z;k7m z2ZGHfrEK!$05ye}yA40e_>%g9`7t#`OLF}0boCR=<@G>u2u7h9zanu=C>RWV8P-Ih z{!`CUC@MkN9_D0L+jEeZJMxRvsf(1(3S;OMr5o~ZJl)~nJT68 zsM2KGAVwBOoZM5m!7s-%PvNwAxW*RiO+l;Xtg3*(8Z;f=hh0JcgqAYfwHH{PXa&)Z z&b9{}$&Q|>%1D~36govVV^Xy##eLE#P`NAl;66*x9-oXPb`NtU-_zh#>|?$RWKZ3( zTslXX>Kkg1ZQscj3Rm9q^oI-(@5~~ejcIA*$`T?XuX}!f@}FP-d$fOR9E0hrNGox8 z1bZhdQ<&-Cm1E5>bMv$u{L0WY4QOMwDaVCdGE{wjNGVZARIo`#h*k?tg?@#9MxJ*v zy}9^dae(HbS)U`RMoYLUCF1PYl4RB_7Nv+g2_kP8!m>!3$g9bEAu}iqIX%6+Ph%%a zQm*iyeELO=y-*Khf`Iz9R0lZAMfyb5jrnD!d0Rv3^^@HP}E^GE&n635M5R7JZb9W#Vm!QyhqbvUvq)bymnsax1Zqy&pJzyHnR2 z(hZYlIaHd~@J35XT6hjz36k+_MlDf~mFuFpJ?@hu8?2^$J_FfX6T=Ps1QhwF`4#(C z_%K%@hwPU! zqJbBy#9);XU52iNmUMF;AZ!LF4lDvo`=sD!CjGDAF8!7g4)BVk9;0B-HNm3^@5jyz z3bsaEZPv4(RC+bJ3R{CZW40slzl zD5w`8a?CXU1Z0Oxh+3=)Dhx(o5SGq<=FW!1D+LEYbnpndjz2nMR-2_+Rj0- zsFh3<2C8<7Wz!jFfJZIpLa+hbLiW=WE9agiiGDA^D0>NVnpA`9nevZ;5%xpMkv4P+ z*1{-s2*qretyzMW!QQrhM7APx)a`{grwElawxV}6)2hdBYAM_H+VB=$m3&xW?|_^w-XI-J=P zVD!g>f_!p~33(m?{MADCWDe9mu^oDM;8%rJ$?SWop@fUaFBVf%!*6p+19EbUV!6UP z5Wb_IdiQcBJ|mfrmPcY^%7c&LSzLK~BGYTNPq5R-1KU$b*o2fIjYu(MCRJ)TAnAyE zvF<8QvshG0v_maL`j}CYF=}Tbhyk$%>6my>)y`hdPd7ew4iVf$D22nT0-4AxsGZYf z*U3>CaQXv!9fU%hPKtTZ-y=nDp6`zpVLfm`7?T0>&oNnFaA5;Fhn$6V`|^Hx`4CyL zGAu2sJhaf$4n}3^J*o_Cp(>-N+%-?KVu;C(Y1gv|8Z|L%Y%{SHP)npxM>GXOa#) z7s*k$dt{2m4mz8k&B=<{w;v=RxT0}O@0I$y{}f{Yn|exI3*-p&5m2J6Spqa#kR6y8 znirM+i)2333zNcF1T?_o;aWC=X5iI~@x(YRlNSy)l2)!wo#$KZovk+IKrjp=(9vYM zNoo*o360@at<@IFOWa*Lu~zFLHG3HMco=0S54y!cuq!sN4o7F6o?OjauLOeNFrP)k zx>+{L<`-8=JosN{??}Z%WJT^u$t)C&)jT`Eu(DJ1>Vno~>s=8fg7r#rh+d z?WSS&z?lP=P9O3un`RYk+3~W2&FS(wx-RZUgT>;f@7C2tUOg0FLv8r|6(Yq z``+$VGYnF2C|2dBt|Zt^qO&rLoUCXL&p6*YZ|?Q`z811OKq=VGx}O1;fmwTS%1D;oObZ(bKMQXvMt*i1%G%F~?=j)^knahl+N;Q>7ZW$}OfW4{vEm%Qi7TOBBjc{WLq!Ig<1ITL^IfglSA`;Jg;h*5WCW9(>iII>BiN z=Zgu@mh5jTybVy5!lIua?frl-!u3QNrPEmgPamLkAjc&soK$kGXzmYaanhJVvTn+p z12IQ0uATU>uQOQ}^$WhGufOCT&-dvapQn>81I5v|ZVo-Z?TfQg;f zcIxbEQE`Y0T3c4gM|;2LAuzxmvmq4nn#0^5^6K+1HI{f?j(=tEc99aU_#u=OHIYKYNJT(Um$l zjS>;?NTp5#tKhaD<~(hOGM8;t8kFW{HV796;FW}nkrHM*H%5nN;rVE`05QM@qzuXj zC2T`_8So;!03HW-!qzx;V|-L8ADOrK2YKftC+4{a@cTuqa26zneo;2j8=eW?lGZ*E zb6VJKP~xBMvE{XtAKPw(QXt`z%b)CPv&?kHe)13`Ji_kHyKZEUdz_d{{=Shoeur~j z9?JymYeYx*Zu=xxf(y?K{+7j=FPoJxsi3GSa!}R&lz!^$Acj+Jhzk%Eu0ZIpmG9(o zU>N=3c|M1YET7lm$fy`!v~M0tR0@0jQ~ow9O_qo{?feXxMUke?G)kx6gV&$;=o9N! zRdn*ut`YW$-qVp;2mq>ot--0I2^Y;e;2YZTSqrylN9E{mt1J(iZ{xFaV5mhm@%K03 zt#}>gjWsB7B7)Osz_y&k33MZb+=$2FszfQR7VwE~c*rj6gxuIXI4$H`y-~i9+Z)wU zkkb*I3{4-zIjPB6-){!+3dE(#Hu;Vn}U<>S8@UmMR-$}ra;=m%UUI$X@@~@9=b|v zG>}gvi>fx;3DtUx;aKrFwRXERJSNjW!jl=EpCcy+YbFhh&B**A2zG5rTXVOXw~rP9Y7ITSiVm8(t!a%bwv8nNL4C`QYlU?!M|t6g5`T`jR=W~I9D$IKJ+9<0yUC8&i68Hv z!T{)SZ$IFlrIlPO`n`S+{Kz}2(nC}Pn>Pp}*6$#ymQl=_O!P{=7Q5yiAkZIg*&$}y zkq3jB7#c!Pn7wZgS906^wl|1t-7a#7FI@r$HxbCmT!(GPi;IQP)}0gWdoj(A_-2AM zp$FNz%8^t>cyKE5*-rgm`RKNS*gyGoYZLysE?PaW9f3 ze}(|TIjm)F`AQsxJ>S1644plCnF|4!3u~s>;z7627IF6>ZBxOo_H)H)q&OunX=qx&gAfND=Ip;pb27zEEBN>_qeS#lke2Er++i#q` z7|vaM<8beRr%$po@(9+RC|hS?a|FylWvCQF9+=8f4n=y{HS+!UQQY_9cpJw@qBx^{ zC?HEGer6x5-wpp|?Fb9AV~XvCFpXEjwyODPruaTlFw_b%uC{G4)46@qi0I@X5MOe? z6U9efzDyLuf(K`FA@2-OL`m*jA6|6q$k){~+IYL;CW@m@=zjQgxHHz}1>u5(uJvxZ zPr38QmXlN$%|G?#FdsPV)jB>GsoW30CGsjhlykY0dgpP;%U;Q#g^kX4@ZOH)2fPUi zH=kL!J;&QBc*&-N7!;ay->iAy4u=_)h+NwJovhiqe#4SLnxKc+mbQlABc}4MZcbm_ z47lV)_vO|5v6f#DM-h(zR}iDNp4|-;w{zEPK}QAO`~b(G6|byp8{RS{fidjF;^V zW)04SGPZ({zfOgIKWhn?>T$Yr($!}D_S-+aDv4S5myYu%7ie`=0I{+-n)?N+SdSEG z!GW{dik0^zux6`WtYGG0$z-j4Qh^*zQ*hZjA%58ahC59Nh{i40_$sUjtGNC6wknsI zO`Yl8Y0q}tGc(uy?67;A;;nX5O6*-9o+w7H1e@4{8l))f^FXhXB6dlBcv^g1+9At( zK}s&)?iXozgIffd%&av2DfQR2iD*R8YJ&-3h+o0EwvF$mDToKn?qu02*+o#1ev#DW z_I%4vHMuHf@$8Xnk7nK-c8l)fId?fP%MuI2Bs40zRqGfORNSV}BJo3|ZQAC&yielh zileUZf7mlz?QrP@xF8;}joJg&jxGNH_q{#*^HH(?%|zIyaY-DD)|$!2ODK=rNm~N} z;YrWU+9+Nni^hRp9UyllCakK7oHGwZoiArk9UtoVgneh`?HAw23w)@w?JM0xCqLy% zE_z&ymT4uGmGoXUzjda7Z|h@-QB481H#O5BBUtY5lU=olFp-j zo4F8+cv$Mc&q_Z~Qwn_^kHS)k`WT!OwD8-o8aE{7jc2!C`>YUs#2wEAUI}|V{46a0 zC~A*i>y~wEqlP;Ftgl6yPh8K=eHC?ZrgYo$FJ;Pwp~&a*Iv!nT^%PhIKeUkjcf2P> zlqJXbNVPN8NchQWcP`<2IW<)$bDy7t|KtOR`C4aSV<(DNOwc7N?_3!gt^CK6Qd#2~ zb>11gWS#C)?gNO<<&Hmm)aqvDESGAYT)QF{Zok@X<0gNBqN}v~rfroh$T&Dkx&s?L z5b{9mRJ4D3TkfufcaCSkcE8{qn+}Gct;7~O`=<;t9W$VHsqM#a->S0jkONO;Y?Ntb zt*AbD3ZWU{Ie(01ZR!|Q@x^*eks;mwWa9i&FWjwj=swNO#4hI<;HCf+&@hNPb@gQ@ z+zbHd)BCv%hKm3OR(LM)V1$bS3U+(edQ^l90RldW{>0s0EgL{!Nf<+8-TGtP}& zh5QILj=cfPJlc%CJXV= zz$Ng=V@{f?0N^h%6M&ta`I9Biz48q-N`PQHg}e%^5rlovxYZ3dx2-j6pieiwHGAm_ z0-e=ON?YBT6HA;s5gKfK2DtO8+VG7(f*zM_Y9VqK&*BD`@E?F%=PB9Qq#o|=MloQR zv-TBx@BcUH->ymbr|%vc>lqvSa;*IRV;#cZKqavH>Tv6jU6ctVxqfTp_rAJ}xd+sm zHzIxT#}ovCP^FXTH0EHh5OZG!cV0-dtZ$K^CRx#D@<2RpJ^B6Rr$M0kKDgb_slI7@ z$7L;9Y8!+{u(SVg)A9E4*r2kXDeWfXw!exnG<9RcFQ{*^BTYkt@ekg;d}YJZ0($Q1 zsbaULO!psf=5=C){gV#<)3j34_ZoA2j2bg_K=0BPYA-_PzPA`ek_7-+s18bZhJ-B0AB zK^bT?FUlah#Rk=P$cdUL?#-44gVMA^)hh3wTP9&?^o#nobcgJ!n>0Yn9o5ohtn_j$ zcssB1?Qc*>v<@y7@6g_NB#t<@_qXZvp#1=+eXIT{>2tNlotqxEmBM1f^TTV6;O`!q zTP)Z>utH1rj3lN$Z3$rysN^B(yTVscZhcb50F@keMLVW`E$3`6xBGYt`%={H*!V8d z8`rt3%DZdh&7aTR@Gh2=LLI(GEcK-KO2FNCAB-sr$-bkdnN=IDYa67YyW@qax&p66 zeeWweX})~N@4$GHJlXv{3oo${zjQOJ1J03=l67pZG}d~KCHHPoH#~}^`D(w1#E$kZ zm9Tw5LcwU`G2uPzd1gsy_F_vHEg%0(7HQkDK5w8)!D}DI7Oe!sAmFFc+P(XkZ6>}VK5YeG2PZmx_!&dk zK(KQ>`?u*;PW&H3{lK>IYX$#juJkg$^lS`008oS>M|Lg$Q-HiZ;=Nh0=5L8FT>%W; zneZ?U-^h&!=OI+$YQgQ(wERr-TQa|4KfZ)d>r@7?I7luQu6XWsq#g^@yM;Rx6zXRJ zy=1PTl}GG37VAlyp30CA$BA7LKm8L#m)asntAy1lfk(7HlB89L_Rxkc;`wD%BubO^^vRYE6}>%ihBXzv2) z4E<^5dS(pWy0@x`jNs@;x)vm?<1&3g-jc-2;^q%-c=&#&u!+bTa$RHuch3@9O=z1b zeT%1)cvC3UU=AV8EccJ=^b_#Q^jDoXmH~r)782yT(w7%2(O+=*2k@m3kWu0CU^G5a zOh#f&uxh>S+$6As!bOtiB;=4(M{eDQeyhu zPCgNsMxIh|JP4id4ov@h(fAZb{g%bRMDhd>wNB}&?`s!Gz5WgqrjaMX7Th~;O5d%V z@uT0Eq4C`<{&6QzMasXQ2qQ=$AevLu#<2xy_dAZ~;Fp3*Bf)gwhGmBpM9}V#-y?~T zt?CrsmXH@3$_$U8hD(sS3a#;cf}YxD=ndm2^bryzZu8MqiC`}=4zAg7<2|k}R5^o{ zQ;vF-s^PlUkX@@z&Y9rrhMM_mv=5-vXr&SS9Tg%_Fqi7aTT}&&W>chCqeGV(Av43p z(j3yJX=Rl~bB@88T(b zmLpf5d<9$z6)9GtRGD%WD(y04j=4@)daNQ5CsrQTDEYzq$lNQZd z4H|EPHtjl0)M=6~Kbvf-DW>T*-LQ>%%+PD5U;XZ=8}{1grh9JL?|{R;aN0qKoH5@{ eU;4`NLZ3gL*xC>rY&4^miS6Tm)2 + Manga Reader diff --git a/app/public/shelf3d.js b/app/public/shelf3d.js new file mode 100644 index 0000000..9fb55db --- /dev/null +++ b/app/public/shelf3d.js @@ -0,0 +1,1285 @@ +// Estante 3D: un mueble de madera con los tomos de la biblioteca. Mira hacia +z, con y hacia arriba; se reciben las piezas comunes de book3d.js. +export const SHELF = { PITCH: 1.2, BOOK_H: 1, DEPTH: 0.82, FRONT: 0.74, FACE_W: 0.7, FACE_Z: 0.58, FACE_T: 0.09, GAP: 0.07, BOARD: 0.055, SIDE: 0.075 } + +// ----- Arte del lomo ----- +const hslOf = (r, g, b) => { + const max = Math.max(r, g, b), min = Math.min(r, g, b) + return { sat: max ? (max - min) / max : 0, val: max / 255, chroma: (max - min) / 255 } +} +/** Lo a color que es una imagen: la parte de sus píxeles con color de verdad. El blanco, el negro y los grises no cuentan. */ +export function colorfulness(data) { + let colored = 0, n = 0 + for (let p = 0; p < data.length; p += 4) { + n++ + if (hslOf(data[p], data[p + 1], data[p + 2]).chroma > 0.16) colored++ + } + return n ? colored / n : 0 +} +export const COLOR_PAGE = 0.25 +/** La columna más vistosa de una imagen, para el lomo: mucho color y detalle, sin los bordes, donde suele haber marcos. Devuelve su x izquierda. */ +export function bestColumn(data, w, h, colW, from = 0) { + const cols = new Float64Array(w), detail = new Float64Array(w) + for (let x = 0; x < w; x++) { + let last = 0 + for (let y = from; y < h; y++) { + const p = (y * w + x) * 4, { chroma } = hslOf(data[p], data[p + 1], data[p + 2]), lum = (data[p] * 0.3 + data[p + 1] * 0.59 + data[p + 2] * 0.11) / 255 + cols[x] += chroma + if (y > from) detail[x] += Math.min(0.25, Math.abs(lum - last)) + last = lum + } + } + const lo = Math.round(w * 0.06), hi = Math.max(lo, Math.round(w * 0.94) - colW) + let best = lo, bestScore = -1 + for (let x = lo; x <= hi; x++) { + let score = 0 + for (let k = x; k < x + colW && k < w; k++) score += cols[k] + detail[k] * 0.8 + if (score > bestScore) { bestScore = score; best = x } + } + return best +} + +const FACE_LOGO_Y = 0.24, FACE_LOGO_W = 0.26 +const FACE_MIN = 0.14 // Los rostros más pequeños, respecto al ancho de la portada, casi siempre son errores o figuras lejanas. + +/** El rostro para el lomo: el mayor entre los de tamaño suficiente. Devuelve [x, y, ancho, alto] en fracciones de la imagen, o 0. */ +export function chooseFace(faces, w, h) { + // Pequeño y en lo alto de la portada suele ser el logo: la calavera de One Piece tiene cara de rostro. + const big = (faces || []).filter(f => f.w >= w * FACE_MIN && !(f.y + f.h / 2 < h * FACE_LOGO_Y && f.w < w * FACE_LOGO_W)) + if (!big.length) return 0 + const f = big.reduce((a, b) => (b.w > a.w ? b : a)) + return [f.x / w, f.y / h, f.w / w, f.h / h].map(v => Math.round(v * 1000) / 1000) +} +/** La franja alrededor de un rostro, como en los lomos de verdad: algo de pelo arriba y la cara debajo. Todo en píxeles de la imagen. */ +export function faceStrip(face, w, h) { + const fx = face[0] * w, fy = face[1] * h, fw = face[2] * w, fh = face[3] * h + const visible = 1 / ART_RATIO, sw = Math.min(fw * 1.3, h / visible, w) // visible: alto que se ve, en anchos de franja + return { + sx: Math.max(0, Math.min(w - sw, fx + fw / 2 - sw / 2)), + sy: Math.max(0, Math.min(h - sw * visible, fy - fh * 0.4)), + sw, + } +} + +// Medidas de un tomo, en altos de un B6 (18,2 cm). El grosor sale de las páginas, como en papel: unos 0,07 mm por página más las tapas. +// Sin páginas contadas se estiman por capítulos. Con tope, para que un tomo enorme no parezca un ladrillo. +export const SPINE_MIN = 0.06, SPINE_MAX = 0.1 +export const spineWidth = (pages, chapters) => { + const p = pages > 0 ? pages : chapters ? chapters * 19 : 180 + return Math.max(SPINE_MIN, Math.min(SPINE_MAX, (2 + p * 0.07) / 182)) +} +// Alto y fondo de una colección, según la proporción de sus portadas: la de bolsillo de las revistas shōnen (11,2 × 17,6 cm) +// es más estrecha que la B6 de las seinen (12,8 × 18,2 cm). Todos los tomos de una obra miden lo mismo; solo cambia el grosor. +export function bookSize(aspect) { + const a = Math.max(0.6, Math.min(0.76, aspect || 0.703)), mm = a < 0.655 ? 176 : 182 + return { h: mm / 182, d: (SHELF.FACE_W * mm * a) / 128 } +} + +/** El tomo que se muestra de frente: por el que se va o, si no se ha empezado, el primero. */ +export function faceIndex(vols, chapterId) { + const i = vols.findIndex(v => (v.chapters || []).includes(chapterId)) + return i < 0 ? 0 : i +} + +/** Reparte las obras en filas de un ancho dado. Una obra sin tomos conocidos es un solo libro, de frente. */ +export function layoutShelf(works, rowWidth, sizeOf = () => bookSize()) { + const rows = [[]] + let x = 0 + const place = (item, w) => { + if (x + w > rowWidth && rows.at(-1).length) { rows.push([]); x = 0 } + rows.at(-1).push({ ...item, x, w }) + x += w + } + for (const work of works) { + if (rows.at(-1).length) x += SHELF.GAP + const vols = work.vols?.length ? work.vols : [{ vol: null, chapters: [], thumb: work.cover }] + const face = faceIndex(vols, work.chapterId), { h, d } = sizeOf(work) + vols.forEach((vol, i) => { + const isFace = i === face, t = spineWidth(vol.pages, vol.chapters?.length) + place({ work, vol, face: isFace, h, d, t }, isFace ? d : t) + }) + } + return rows.filter(r => r.length) +} + +const VS = `#version 300 es +uniform mat4 uM, uModel; // uModel: solo el tomo que se saca; lo demás ya está en el mueble +layout(location = 0) in vec3 aPos; +layout(location = 1) in vec3 aNor; +layout(location = 2) in vec2 aUV; +out vec3 vPos; out vec3 vNor; out vec2 vUV; +void main() { vec4 p = uModel * vec4(aPos, 1.0); vPos = p.xyz; vNor = mat3(uModel) * aNor; vUV = aUV; gl_Position = uM * p; }` +const FS = `#version 300 es +precision highp float; +uniform int uKind; +uniform sampler2D uTex; +uniform vec3 uColor; +uniform float uHas, uPitch, uDepth, uDim, uAlpha; +uniform vec4 uSpot; // mesa: centro del tomo y radio de la luz +uniform vec2 uTab; // mesa propia: escala de la foto; sin ella, madera repetida +uniform vec2 uSize; +uniform vec4 uHide; // x0, x1, y0, y1 del hueco del tomo sacado: ni él ni sus costados se pintan en la fila +in vec3 vPos; in vec3 vNor; in vec2 vUV; +out vec4 color; +const vec3 L = normalize(vec3(-0.22, 0.42, 0.88)); +void main() { + if (uKind != 0 && uHide.y > uHide.x && vPos.y > uHide.z && vPos.y < uHide.w) { + const float e = 0.0002; + bool inside = vPos.x > uHide.x + e && vPos.x < uHide.y - e; + bool own = (abs(vPos.x - uHide.x) <= e && vNor.x < -0.5) || (abs(vPos.x - uHide.y) <= e && vNor.x > 0.5); + if (inside || own) discard; // los costados de los vecinos sí quedan a la vista + } + vec3 c; + if (uKind == 0) c = texture(uTex, vUV, -0.4).rgb * vec3(0.92, 0.84, 0.76); // madera del mueble, algo más oscura que la mesa + else if (uKind == 1) c = texture(uTex, vUV).rgb; // lomos + else if (uKind == 2) c = uHas > 0.5 ? texture(uTex, vUV, -0.5).rgb : uColor; // portada + else if (uKind == 3 || uKind == 5) { // las hojas, vistas por arriba: rayas irregulares a lo ancho del tomo, medidas en el mueble + float a = uKind == 3 ? vUV.x : vUV.y, v = a / 0.0042, w = fwidth(v), k = floor(v); + float n = fract(sin(k * 12.9898) * 43758.5453); + float line = 1.0 - smoothstep(0.08, 0.08 + max(w, 0.25), abs(fract(v) - 0.5)); + float dense = 1.0 - smoothstep(0.45, 0.9, w); // muy lejos, las rayas se funden en un tono + c = vec3(0.91, 0.88, 0.81) * (1.0 - (0.1 + 0.05 * n) * dense) * (1.0 - line * (0.16 + 0.22 * n) * dense); + // Entre un tomo y otro queda una rendija oscura. + if (uKind == 3) c *= mix(0.45, 1.0, smoothstep(0.0, 0.0035, min(vUV.x, vUV.y - vUV.x))); + } else if (uKind == 6) { // la mesa del lector, que aparece detrás del tomo + vec3 t = uHas > 0.5 ? texture(uTex, clamp(vUV * uTab + 0.5, 0.0, 1.0)).rgb : texture(uTex, vUV / 1.7).rgb; + float d = length(vPos - uSpot.xyz) / uSpot.w; + color = vec4(t * mix(1.04, 0.42, smoothstep(0.35, 1.6, d)), uAlpha); + return; + } else c = uColor; // tapas, de canto + float lit = mix(0.62, 1.05, clamp(dot(normalize(vNor), L), 0.0, 1.0)); + // Lo del fondo y lo que queda bajo la balda de arriba recibe menos luz. + float z = clamp(vPos.z / uDepth, 0.0, 1.0); + float under = fract(vPos.y / uPitch); + float shade = mix(0.5, 1.0, smoothstep(0.0, 0.95, z)) * mix(mix(0.5, 1.0, z), 1.0, smoothstep(0.62, 0.98, 1.0 - under)); + vec2 q = gl_FragCoord.xy / uSize - 0.5; + float room = 1.0 - 0.34 * smoothstep(0.25, 0.8, length(q * vec2(1.0, 0.8))); + color = vec4(c * lit * shade * room * uDim * vec3(1.03, 1.0, 0.95), uAlpha); +}` + +// Un cuadrilátero: origen, dos lados, normal y coordenadas de textura en sus esquinas. +function quad(sh, o, a, b, n, uv = [0, 0, 1, 1]) { + sh.grid(1, 1, (c, r) => [o[0] + a[0] * c + b[0] * r, o[1] + a[1] * c + b[1] * r, o[2] + a[2] * c + b[2] * r, ...n, uv[0] + (uv[2] - uv[0]) * c, uv[1] + (uv[3] - uv[1]) * r]) +} +const hash = s => { let h = 7; for (const ch of String(s)) h = (h * 31 + ch.charCodeAt(0)) | 0; return Math.abs(h) } +const hsl = (h, s, l) => { const a = s * Math.min(l, 1 - l), f = n => { const k = (n + h / 30) % 12; return l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1)) }; return [f(0), f(8), f(4)] } + +const STORE = 'shelfPalette' +const STRIP_PER_UNIT = 440, STRIP_MAX = 2048, STRIP_H = 512, IMG_AT_ONCE = 4 // ancho de la tira según el de la fila; más de 2048 no se nota y gasta memoria +const blurBox = typeof document === 'undefined' ? null : document.createElement('canvas') // de paso, para desenfocar bajo las letras +const ART_SKIP = 0.26, FACE_INPUT = 360 // sin rostro se salta lo alto de la portada; ancho con que se buscan los rostros +const ART_RATIO = 0.14, ART_H = 512, ART_KEEP = 240 // franja guardada: algo más ancha que el lomo más grueso +// Notas adhesivas con el nombre de cada colección: fuentes manuscritas propias (fonts/LICENSE.txt) y colores de pósit. +const NOTE_FONTS = [['Caveat', 'caveat', 600, 1.15], ['Patrick Hand', 'patrickhand', 400, 1], ['Kalam', 'kalam', 700, 0.95], ['Gochi Hand', 'gochihand', 400, 1], ['Indie Flower', 'indieflower', 400, 0.95], ['Permanent Marker', 'permanentmarker', 400, 0.85], ['Shadows Into Light', 'shadows', 400, 1.05]] +const NOTE_COLORS = ['#fff27a', '#ffb8cf', '#a9dcff', '#c4f2a8', '#ffd38f', '#e3c8ff'] +const NOTE_INKS = ['#24242e', '#1b2b6e', '#3a1f5c', '#123c2c'] +const NOTE_H = 0.13, NOTE_PX = 128 +// El nombre de la nota: como mucho 40 letras, cortando entre palabras. +export function shortTitle(title, max = 40) { + const t = String(title || '').replace(/\s+/g, ' ').trim() + if (t.length <= max) return t + const cut = t.slice(0, max), sp = cut.lastIndexOf(' ') + return `${(sp > 0 ? cut.slice(0, sp) : cut).replace(/[\s,.;:·–—-]+$/, '')}…` +} +// Aspecto de la nota de una obra: el mismo en el mueble y en la ficha del tomo sacado. +export function noteStyle(id) { + const seed = hash(id), [family, , weight, scale] = NOTE_FONTS[seed % NOTE_FONTS.length] + return { seed, family: `shelf ${family}`, weight, scale, paper: NOTE_COLORS[(seed >> 3) % NOTE_COLORS.length], ink: NOTE_INKS[(seed >> 6) % NOTE_INKS.length], tilt: ((seed % 97) / 96 - 0.5) * 0.1 } +} +let notesFonts = null +export function loadNoteFonts() { + if (notesFonts || typeof FontFace === 'undefined') return notesFonts || Promise.resolve() + notesFonts = Promise.all(NOTE_FONTS.map(([name, file, weight]) => new FontFace(`shelf ${name}`, `url(/fonts/${file}.woff2)`, { weight: String(weight) }).load().then(f => { document.fonts.add(f) }, () => {}))) + return notesFonts +} +const IDENTITY = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) +const FLY_MS = 900 +const PEEK_OPEN_MS = 720, PEEK_CLOSE_MS = 520, PEEK_SLIDE = 0.34 // el tomo sale recto de la fila y luego gira hacia la cámara +const ZOOM_MAX = 3, ORBIT_TILT = 10, ORBIT_YAW = 18, ORBIT_BACK = 0.08, REST_TILT = -3, FRICTION_MS = 320 + +export function createShelf3D(container, lib, { works: firstWorks = [], rowsLandscape = 2.3, rowsPortrait = 3, still = false, pagesOf = null, onPeek = null, onOpen = null, table = null } = {}) { + const { Shape, woodCanvas, cameraMatrix, project, FOV, coverPalette, inkOn, css, createTilt, MAX_DEG } = lib + const canvas = document.createElement('canvas') + canvas.className = 'shelfcanvas' + const gl = canvas.getContext('webgl2', { alpha: false, antialias: true, depth: true, powerPreference: 'high-performance' }) + if (!gl) return null + container.replaceChildren(canvas) + const maxTex = gl.getParameter(gl.MAX_TEXTURE_SIZE) || 2048 + + let dead = false, raf = 0, u = {}, prog = null, wood = null, furniture = null, works = firstWorks, aniso = null + let rows = [], rowWidth = 3, size = { w: 1, h: 1 }, visibleH = 2.8, top = 0, bottom = 0, y = 0, layoutTimer = 0, rowsKey = '' + const built = new Map(), covers = new Map(), loadingImg = new Map(), waiting = [] + const arts = new Map(), panels = new Map(), askedPanel = new Set() // arte de los lomos, y página a color de los tomos sin portada + let x = 0, zoom = 1, velocity = 0, lastMove = 0, focusId = null // focusId: obra que se mantiene a la vista hasta que se toque el mueble + const tiltNow = { x: 0, y: 0 } + const tilt = createTilt(() => draw()) + let imgBusy = 0 + let palettes = {} + try { palettes = JSON.parse(localStorage.getItem(STORE) || '{}') } catch {} + let saveTimer = 0 + const savePalettes = () => { + clearTimeout(saveTimer) + saveTimer = setTimeout(() => { try { localStorage.setItem(STORE, JSON.stringify(palettes)) } catch {} }, 800) + } + + function makeMesh(sh) { + const vao = gl.createVertexArray(), vb = gl.createBuffer(), ib = gl.createBuffer() + gl.bindVertexArray(vao) + gl.bindBuffer(gl.ARRAY_BUFFER, vb) + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(sh.v), gl.STATIC_DRAW) + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ib) + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(sh.i), gl.STATIC_DRAW) + gl.enableVertexAttribArray(0); gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 32, 0) + gl.enableVertexAttribArray(1); gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 32, 12) + gl.enableVertexAttribArray(2); gl.vertexAttribPointer(2, 2, gl.FLOAT, false, 32, 24) + gl.bindVertexArray(null) + return { vao, vb, ib, n: sh.i.length } + } + const freeMesh = m => { if (m) { gl.deleteVertexArray(m.vao); gl.deleteBuffer(m.vb); gl.deleteBuffer(m.ib) } } + const drawMesh = m => { gl.bindVertexArray(m.vao); gl.drawElements(gl.TRIANGLES, m.n, gl.UNSIGNED_SHORT, 0) } + function texFrom(source, tex = gl.createTexture()) { + gl.bindTexture(gl.TEXTURE_2D, tex) + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source) + gl.generateMipmap(gl.TEXTURE_2D) + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) + if (aniso) gl.texParameterf(gl.TEXTURE_2D, aniso.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(8, gl.getParameter(aniso.MAX_TEXTURE_MAX_ANISOTROPY_EXT))) + return tex + } + + function initGL() { + const shader = (type, text) => { const s = gl.createShader(type); gl.shaderSource(s, text); gl.compileShader(s); return s } + prog = gl.createProgram() + gl.attachShader(prog, shader(gl.VERTEX_SHADER, VS)) + gl.attachShader(prog, shader(gl.FRAGMENT_SHADER, FS)) + gl.linkProgram(prog) + if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) throw new Error(gl.getProgramInfoLog(prog) || 'shader') + gl.useProgram(prog) + u = {} + for (const n of ['uM', 'uModel', 'uKind', 'uTex', 'uColor', 'uHas', 'uPitch', 'uDepth', 'uSize', 'uDim', 'uHide', 'uAlpha', 'uSpot', 'uTab']) u[n] = gl.getUniformLocation(prog, n) + gl.uniform1i(u.uTex, 0) + gl.uniformMatrix4fv(u.uModel, false, IDENTITY) + gl.uniform1f(u.uDim, 1) + gl.uniform1f(u.uAlpha, 1) + gl.uniform4f(u.uHide, 0, 0, 0, 0) + gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) + gl.uniform1f(u.uPitch, SHELF.PITCH) + gl.uniform1f(u.uDepth, SHELF.DEPTH) + gl.enable(gl.DEPTH_TEST) + gl.depthFunc(gl.LEQUAL) + gl.enable(gl.CULL_FACE) + gl.disable(gl.CULL_FACE) // las mallas no siguen un solo sentido de giro + gl.clearColor(0.09, 0.055, 0.035, 1) + aniso = gl.getExtension('EXT_texture_filter_anisotropic') + wood = texFrom(woodCanvas()) + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT) + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT) + } + + // ----- Colocación ----- + const rowBase = k => -(k + 1) * SHELF.PITCH // la cara de arriba de la balda de esa fila + function buildFurniture() { + freeMesh(furniture) + const sh = new Shape(), { BOARD, SIDE, DEPTH } = SHELF, W = rowWidth, low = rowBase(Math.max(rows.length, 1) - 1) - BOARD, TILE = 1.7 + // Fondo. + quad(sh, [-SIDE, low, 0], [W + 2 * SIDE, 0, 0], [0, -low + BOARD, 0], [0, 0, 1], [0, low / TILE, (W + 2 * SIDE) / TILE, BOARD / TILE]) + // Laterales, por dentro y de canto. + for (const [x, n] of [[0, 1], [W, -1]]) quad(sh, [x, low, 0], [0, 0, DEPTH], [0, -low + BOARD, 0], [n, 0, 0], [0.2, low / TILE, 0.2 + DEPTH / TILE, BOARD / TILE]) + for (const x of [-SIDE, W]) quad(sh, [x, low, DEPTH], [SIDE, 0, 0], [0, -low + BOARD, 0], [0, 0, 1], [x, low / TILE, x + SIDE / TILE, BOARD / TILE]) + // Baldas, con la veta a lo largo. + const board = yTop => { + const uv = (a, b) => [yTop * 0.37, a / TILE, yTop * 0.37 + b / TILE, 0] + quad(sh, [W, yTop, 0], [-W, 0, 0], [0, 0, DEPTH], [0, 1, 0], [yTop * 0.37, 0, yTop * 0.37 + DEPTH / TILE, W / TILE]) + quad(sh, [0, yTop - BOARD, DEPTH], [W, 0, 0], [0, BOARD, 0], [0, 0, 1], uv(W, 0)) + quad(sh, [0, yTop - BOARD, 0], [W, 0, 0], [0, 0, DEPTH], [0, -1, 0], [yTop * 0.37, 0, yTop * 0.37 + DEPTH / TILE, W / TILE]) + } + for (let k = 0; k < Math.max(rows.length, 1); k++) board(rowBase(k)) + // Tapa de arriba. + quad(sh, [-SIDE, 0, DEPTH], [W + 2 * SIDE, 0, 0], [0, BOARD, 0], [0, 0, 1], [0, 0, W / TILE, 0.04]) + quad(sh, [-SIDE, BOARD, 0], [W + 2 * SIDE, 0, 0], [0, 0, DEPTH], [0, 1, 0], [0, 0, W / TILE, DEPTH / TILE]) + quad(sh, [0, 0, 0], [W, 0, 0], [0, 0, DEPTH], [0, -1, 0], [0, 0, W / TILE, DEPTH / TILE]) + furniture = makeMesh(sh) + } + const urlOf = item => item.vol.art || item.vol.thumb || item.work.cover || null + const panelKey = item => item.vol.chapters?.[0] || null + // De dónde sale el arte de este lomo: su portada, una página a color o, en último caso, la portada de la obra. + const artOf = item => item.vol.art || item.vol.thumb || panels.get(panelKey(item)) || item.work.cover || null + const fallbackPalette = item => { + const h = hash(item.work.id) % 360, base = hsl(h, 0.42, 0.34) + return { base, accent: hsl((h + 40) % 360, 0.55, 0.72) } + } + const paletteOf = item => palettes[artOf(item)] || fallbackPalette(item) + // Una obra sin portada: su color y su título. + function plainCover(item) { + const c = Object.assign(document.createElement('canvas'), { width: 358, height: 512 }), g = c.getContext('2d'), { base, accent } = paletteOf(item) + g.fillStyle = css(base) + g.fillRect(0, 0, c.width, c.height) + g.strokeStyle = css(accent) + g.lineWidth = 5 + g.strokeRect(22, 22, c.width - 44, c.height - 44) + g.fillStyle = css(inkOn(base)) + g.textAlign = 'center' + g.font = '700 34px system-ui, sans-serif' + const lines = [] + for (const word of String(item.work.title).split(/\s+/)) { + const last = lines.at(-1) + if (last != null && g.measureText(`${last} ${word}`).width <= c.width - 80) lines[lines.length - 1] = `${last} ${word}` + else lines.push(word) + } + const shown = lines.slice(0, 8) + shown.forEach((line, i) => g.fillText(line, c.width / 2, c.height / 2 + (i - (shown.length - 1) / 2) * 42 + 12, c.width - 70)) + return c + } + const coverKey = item => urlOf(item) || `plain:${item.work.id}` + const plainFor = key => item => { if (!covers.has(key)) { covers.set(key, texFrom(plainCover(item))); draw() } } + function loadImage(url, done) { + if (loadingImg.has(url)) { loadingImg.get(url).push(done); return } + loadingImg.set(url, [done]) + waiting.push(url) + pumpImages() + } + function pumpImages() { + while (!dead && imgBusy < IMG_AT_ONCE && waiting.length) { + const url = waiting.pop() // lo último pedido es lo que está a la vista + imgBusy++ + const im = new Image() + im.decoding = 'async' + // Una imagen que no acaba (una fuente colgada) no puede tapar la cola: a los 15 s deja su hueco, y si llega luego se usa igual. + let freed = false + const free = () => { if (!freed) { freed = true; imgBusy--; clearTimeout(slow); pumpImages() } } + const slow = setTimeout(free, 15000) + const finish = ok => { + const list = loadingImg.get(url) || [] + loadingImg.delete(url) + if (!dead) for (const f of list) f(ok ? im : null) + free() + } + im.onload = () => finish(true) + im.onerror = () => finish(false) + im.src = url + } + } + // Alto y fondo de cada obra, por la proporción de su portada. Lo aprendido rehace el mueble una vez; luego se recuerda. + const sizeOf = work => bookSize(palettes[`size:${work.id}`]) + function learnSize(item, url, im) { + const work = item.work + const key = `size:${work.id}` + if (palettes[key] || !im?.naturalHeight || !url || url !== (item.vol.art || item.vol.thumb || work.cover)) return // solo portadas, no páginas + const before = sizeOf(work) + palettes[key] = Math.round((im.naturalWidth / im.naturalHeight) * 1000) / 1000 + savePalettes() + const now = sizeOf(work) + if (now.h !== before.h || Math.abs(now.d - before.d) > 0.004) api.relayout() + } + function learnPalette(url, im) { + if (palettes[url]) return + try { + const small = Object.assign(document.createElement('canvas'), { width: 48, height: 72 }), g = small.getContext('2d', { willReadFrequently: true }) + g.drawImage(im, 0, 0, 48, 72) + const { base, accent } = coverPalette(g.getImageData(0, 0, 48, 72).data) + palettes[url] = { base, accent } + savePalettes() + } catch {} + } + + // Rostros: de uno en uno y lo último pedido primero. Lo encontrado se recuerda, y también lo no encontrado. + const faceWaiting = [] + let faceWorker = null, faceBusy = false, faceSeq = 0 + function askFace(url) { + if (faceWaiting.some(q => q === url)) return + faceWaiting.push(url) + pumpFaces() + } + function startFaceWorker() { + try { + faceWorker = new Worker(`/animeface.js${new URL(import.meta.url).search}`) + faceWorker.onerror = () => { faceWorker?.terminate(); faceWorker = false; faceBusy = false; faceWaiting.length = 0 } + } catch { faceWorker = false } + return faceWorker + } + function pumpFaces() { + if (dead || faceBusy || !faceWaiting.length || faceWorker === false || (!faceWorker && !startFaceWorker())) return + const url = faceWaiting.pop() + if (palettes[`face:${url}`] !== undefined) return pumpFaces() + faceBusy = true + let given = false + const giveUp = setTimeout(() => { given = true; faceBusy = false; pumpFaces() }, 30000) // la imagen no llega: se sigue con las demás + loadImage(url, im => { + clearTimeout(giveUp) + if (given) return + let pixels = null, w = FACE_INPUT, h = 0 + if (im) try { + h = Math.max(1, Math.round((w * im.naturalHeight) / im.naturalWidth)) + const c = Object.assign(document.createElement('canvas'), { width: w, height: h }), g = c.getContext('2d', { willReadFrequently: true }) + g.drawImage(im, 0, 0, w, h) + pixels = g.getImageData(0, 0, w, h).data.buffer + } catch { pixels = null } + if (!pixels || !faceWorker) { faceBusy = false; return pumpFaces() } + const id = ++faceSeq + faceWorker.onmessage = ({ data }) => { + if (data.id !== id) return + faceBusy = false + if (dead) return + if (data.faces) { + const face = chooseFace(data.faces, w, h) + palettes[`face:${url}`] = face + savePalettes() + if (face) { + cropArt(url, im, face) + // La fila pudo rehacerse mientras tanto: se avisa a las que hay ahora. + for (const b of built.values()) if (rows[b.k]?.some(it => !it.face && artOf(it) === url)) b.repaint?.() + } + } + pumpFaces() + } + faceWorker.postMessage({ id, pixels, w, h }, [pixels]) + }) + } + function learnArt(url, im, wantFace) { + if (!arts.has(url)) cropArt(url, im, palettes[`face:${url}`] || null) + if (wantFace && palettes[`face:${url}`] === undefined) askFace(url) + } + function cropArt(url, im, face) { + try { + const w = im.naturalWidth, h = im.naturalHeight + const small = Object.assign(document.createElement('canvas'), { width: 64, height: Math.max(1, Math.round((64 * h) / w)) }), g = small.getContext('2d', { willReadFrequently: true }) + g.drawImage(im, 0, 0, small.width, small.height) + const colW = Math.max(2, Math.round(small.height * ART_RATIO)) + const out = Object.assign(document.createElement('canvas'), { width: Math.round(ART_H * ART_RATIO), height: ART_H }) + if (face) { + const { sx, sy, sw } = faceStrip(face, w, h) + out.getContext('2d').drawImage(im, sx, sy, sw, sw / ART_RATIO, 0, 0, out.width, out.height) + } else { + // Sin rostro: de la banda de en medio hacia abajo, porque arriba suelen ir el logo y la editorial. + const keep = 1 - ART_SKIP, from = Math.round(small.height * ART_SKIP), cw = Math.max(2, Math.round(colW * keep)) + const at = bestColumn(g.getImageData(0, 0, small.width, small.height).data, small.width, small.height, Math.min(cw, small.width), from) + out.getContext('2d').drawImage(im, (at / small.width) * w, h * ART_SKIP, h * ART_RATIO * keep, h * keep, 0, 0, out.width, out.height) + } + arts.set(url, out) + if (arts.size > ART_KEEP) arts.delete(arts.keys().next().value) // se vuelve a sacar de la caché del navegador si hace falta + } catch {} + } + // Tomo sin portada: la primera de sus páginas que sea a color. Lo encontrado se recuerda; lo no encontrado, también, para no volver a descargar páginas. + function findPanel(item, done) { + const key = panelKey(item) + if (!key || !pagesOf || askedPanel.has(key)) return + askedPanel.add(key) + const saved = palettes[`panel:${key}`] + if (saved !== undefined) { if (saved) { panels.set(key, saved); done() } return } + pagesOf(key).then(async urls => { + let found = null + for (const url of urls) { + const im = await new Promise(res => loadImage(url, res)) + if (dead) return + if (!im) continue + try { + const c = Object.assign(document.createElement('canvas'), { width: 40, height: 60 }), g = c.getContext('2d', { willReadFrequently: true }) + g.drawImage(im, 0, 0, 40, 60) + if (colorfulness(g.getImageData(0, 0, 40, 60).data) >= COLOR_PAGE) { found = url; break } + } catch {} + } + palettes[`panel:${key}`] = found || false + savePalettes() + if (found) { panels.set(key, found); done() } + }, () => {}) + } + // Los lomos de una fila se dibujan juntos en una tira: una textura por fila, por muchos tomos que tenga. + const stripWidth = () => Math.max(512, Math.min(STRIP_MAX, maxTex, Math.round(rowWidth * STRIP_PER_UNIT))) + // ----- Logos de las obras (Wikimedia Commons, por el proxy propio para poder pintarlos en la tira) ----- + const logos = new Map() + function logoLight(im) { + try { + const c = Object.assign(document.createElement('canvas'), { width: 96, height: Math.max(1, Math.round((96 * im.naturalHeight) / im.naturalWidth)) }), g = c.getContext('2d', { willReadFrequently: true }) + g.drawImage(im, 0, 0, c.width, c.height) + const px = g.getImageData(0, 0, c.width, c.height).data + let lum = 0, a = 0 + for (let p = 0; p < px.length; p += 4) { const al = px[p + 3] / 255; lum += al * (px[p] * 0.299 + px[p + 1] * 0.587 + px[p + 2] * 0.114); a += al } + return a ? lum / a / 255 : 0.5 + } catch { return 0.5 } + } + function setLogo(id, url) { + if (!url || logos.has(id)) return + loadImage(url, im => { + if (!im || dead || im.naturalWidth < im.naturalHeight * 1.2) return + logos.set(id, { im, light: logoLight(im) }) + for (const b of built.values()) if ((rows[b.k] || []).some(i => i.work.id === id)) b.repaint?.() + }) + } + + // ----- Notas: un pósit por colección, pegado al canto de la balda de arriba ----- + function rowNotes(row) { + const groups = [] + for (let i = 0; i < row.length;) { + let j = i + while (j + 1 < row.length && row[j + 1].work === row[i].work) j++ + groups.push({ work: row[i].work, x0: row[i].x, x1: row[j].x + row[j].w }) + i = j + 1 + } + const out = [] + let free = 0.02 + for (const n of groups) { + const span = n.x1 - n.x0, w = Math.max(0.26, Math.min(0.42, span * 0.85)) + let x = Math.max(free, n.x0 + Math.min(0.03, span * 0.1)) + if (x + w > rowWidth - 0.02) x = rowWidth - 0.02 - w + if (x < free - 1e-6 || x > n.x1 + 0.12) continue // no cabe junto a los suyos + out.push({ ...n, x, w, seed: hash(n.work.id) }) + free = x + w + 0.03 + } + return out + } + function paintNotes(notes, canvas) { + const g = canvas.getContext('2d') + g.setTransform(1, 0, 0, 1, 0, 0) + g.clearRect(0, 0, canvas.width, canvas.height) + let x = 0 + for (const n of notes) { + const W = n.px, H = NOTE_PX, { family, weight, scale, paper, ink } = noteStyle(n.work.id) + g.save() + g.translate(x, 0) + g.fillStyle = paper + g.fillRect(0, 0, W, H) + g.fillStyle = 'rgba(0,0,0,.07)' // la franja con pegamento + g.fillRect(0, 0, W, H * 0.16) + const curl = g.createLinearGradient(0, H * 0.7, 0, H) + curl.addColorStop(0, 'rgba(0,0,0,0)') + curl.addColorStop(1, 'rgba(0,0,0,.14)') + g.fillStyle = curl + g.fillRect(0, 0, W, H) + g.fillStyle = ink + g.textAlign = 'center' + g.textBaseline = 'middle' + const title = shortTitle(n.work.title), font = px => `${weight} ${Math.round(px)}px "${family}", cursive` + let size = H * 0.5 * scale + g.font = font(size) + const room = W * 0.9 + if (g.measureText(title).width > room) size = Math.max(H * 0.3 * scale, (size * room) / g.measureText(title).width) + g.font = font(size) + if (g.measureText(title).width > room) { + // Dos renglones, partiendo por el espacio más cercano al centro. + const words = title.split(/\s+/) + let best = 1, bestD = Infinity + for (let i = 1; i < words.length; i++) { const d = Math.abs(words.slice(0, i).join(' ').length - title.length / 2); if (d < bestD) { bestD = d; best = i } } + const a = words.slice(0, best).join(' '), b = words.slice(best).join(' ') + size = Math.min(H * 0.36 * scale, (size * room) / Math.max(g.measureText(a).width, g.measureText(b).width, 1) * 1) + g.font = font(size) + g.fillText(a, W / 2, H * 0.4, room) + g.fillText(b, W / 2, H * 0.4 + size * 0.95, room) + } else g.fillText(title, W / 2, H * 0.56, room) + g.restore() + x += W + } + } + function buildNotes(b, k) { + const notes = rowNotes(rows[k]) + if (!notes.length) return + const base = rowBase(k), edge = k === 0 ? base + SHELF.PITCH : base + SHELF.PITCH - SHELF.BOARD, top = edge + SHELF.BOARD * 0.75, z = SHELF.DEPTH + 0.004 + for (const n of notes) n.px = Math.round((NOTE_PX * n.w) / NOTE_H) + const canvas = Object.assign(document.createElement('canvas'), { width: Math.min(maxTex, notes.reduce((a, n) => a + n.px, 0)), height: NOTE_PX }) + const sh = new Shape() + let u = 0 + for (const n of notes) { + const a = noteStyle(n.work.id).tilt, c = Math.cos(a), sn = Math.sin(a), U0 = u / canvas.width, U1 = (u + n.px) / canvas.width + quad(sh, [n.x, top, z], [n.w * c, n.w * sn, 0], [NOTE_H * sn, -NOTE_H * c, 0], [0, 0, 1], [U0, 0, U1, 1]) + u += n.px + } + paintNotes(notes, canvas) + b.notes = { mesh: makeMesh(sh), canvas, tex: texFrom(canvas), list: notes } + loadNoteFonts().then(() => { if (!dead && built.get(k) === b && b.notes) { paintNotes(notes, canvas); texFrom(canvas, b.notes.tex); draw() } }) + } + + function paintStrip(row, strip) { + const g = strip.getContext('2d'), toPx = strip.width / rowWidth + g.setTransform(1, 0, 0, 1, 0, 0) + g.fillStyle = '#222' + g.fillRect(0, 0, strip.width, STRIP_H) + for (const it of row) { + if (it.face) continue + const { base, accent } = paletteOf(it) + const x = it.x * toPx, w = it.w * toPx, PX = STRIP_H / it.h + // Se escribe en unidades de la pantalla: en una fila estrecha la tira se estira a lo ancho y el texto se deformaría. + const sx = toPx / PX, wText = it.w * PX + g.setTransform(1, 0, 0, 1, x, 0) + const art = arts.get(artOf(it)) + let ink = inkOn(base), backing = null + if (art) { + // El arte ocupa todo el lomo; de la franja guardada se usa el centro, lo que corresponde a su grosor. + const part = Math.min(art.width, (art.height * it.w) / it.h) + g.imageSmoothingEnabled = true + g.imageSmoothingQuality = 'high' + g.drawImage(art, (art.width - part) / 2, 0, part, art.height, 0, 0, w, STRIP_H) + backing = (x0, y0, bw, bh, force) => { + // Desenfoque suave bajo las letras: se reduce lo pintado y se vuelve a estirar. + const X = x + x0, sw = Math.max(2, Math.round(bw / 4)), sh = Math.max(2, Math.round(bh / 4)) + blurBox.width = sw; blurBox.height = sh + const bg = blurBox.getContext('2d', { willReadFrequently: true }) + bg.imageSmoothingEnabled = true + bg.drawImage(strip, X, y0, bw, bh, 0, 0, sw, sh) + const px = bg.getImageData(0, 0, sw, sh).data + let lum = 0 + for (let p = 0; p < px.length; p += 4) lum += px[p] * 0.299 + px[p + 1] * 0.587 + px[p + 2] * 0.114 + const light = force ? force === 'light' : lum / (px.length / 4) / 255 > 0.6 + g.save() + g.beginPath() + if (g.roundRect) g.roundRect(x0, y0, bw, bh, Math.min(bw, bh) * 0.45) + else g.rect(x0, y0, bw, bh) + g.clip() + g.drawImage(blurBox, 0, 0, sw, sh, x0 - bw * 0.04, y0 - bh * 0.04, bw * 1.08, bh * 1.08) + g.fillStyle = light ? 'rgba(255,255,255,.34)' : 'rgba(0,0,0,.32)' + g.fillRect(x0, y0, bw, bh) + g.restore() + return light ? [0.08, 0.08, 0.09] : [0.98, 0.97, 0.95] + } + } else { + g.fillStyle = css(base) + g.fillRect(0, 0, w, STRIP_H) + g.fillStyle = css(accent) + g.fillRect(0, STRIP_H * 0.045, w, STRIP_H * 0.012) + g.fillRect(0, STRIP_H * 0.86, w, STRIP_H * 0.012) + } + g.textAlign = 'center' + g.textBaseline = 'middle' + // El título, en la mitad de abajo para no tapar la cara: primero se reduce la letra; si aun así no cabe, se estrecha. + const from = art ? 0.4 : 0.07, to = art ? 0.865 : 0.85, room = STRIP_H * (to - from) + const logo = logos.get(it.work.id) + if (logo) { + // El logo de la obra en lugar del texto, girado como el título; la pastilla contrasta con el propio logo. + const lw = logo.im.naturalWidth, lh = logo.im.naturalHeight, sc = Math.min(room / lw, (wText * 0.74) / lh), len = lw * sc, thick = lh * sc + const mid = art ? to - len / STRIP_H / 2 - 0.012 : (from + to) / 2 + if (backing) { const bw = Math.min(w * 0.96, (thick + wText * 0.2) * sx), pad = wText * 0.16; ink = backing((w - bw) / 2, STRIP_H * mid - len / 2 - pad, bw, len + pad * 2, logo.light > 0.55 ? 'dark' : 'light') } + g.save() + g.scale(sx, 1) + g.translate(wText / 2, STRIP_H * mid) + g.rotate(Math.PI / 2) + if (!backing) { g.shadowColor = logo.light > 0.55 ? 'rgba(0,0,0,.6)' : 'rgba(255,255,255,.6)'; g.shadowBlur = 4 } + g.imageSmoothingEnabled = true + g.imageSmoothingQuality = 'high' + g.drawImage(logo.im, -len / 2, -thick / 2, len, thick) + g.restore() + } + let size = wText * (art ? 0.44 : 0.5) + g.font = `700 ${Math.round(size)}px system-ui, sans-serif` + let long = g.measureText(it.work.title).width + if (long > room) { size = Math.max(wText * 0.32, (size * room) / long); g.font = `700 ${Math.round(size)}px system-ui, sans-serif`; long = g.measureText(it.work.title).width } + const len = Math.min(long, room), mid = art ? to - len / STRIP_H / 2 - 0.012 : (from + to) / 2 + if (backing && !logo) { + const bw = size * 1.45 * sx, pad = size * 0.55 + ink = backing((w - bw) / 2, STRIP_H * mid - len / 2 - pad, bw, len + pad * 2) + } + g.save() + g.scale(sx, 1) + if (logo) g.globalAlpha = 0 // ya está el logo + g.fillStyle = css(ink) + if (backing) { g.shadowColor = ink[0] > 0.5 ? 'rgba(0,0,0,.55)' : 'rgba(255,255,255,.5)'; g.shadowBlur = 3 } + g.translate(wText / 2, STRIP_H * mid) + g.rotate(Math.PI / 2) + g.fillText(it.work.title, 0, 0, room) + g.restore() + if (it.vol.vol != null) { + const nSize = wText * 0.5, label = String(it.vol.vol), cy = STRIP_H * 0.935 + g.font = `800 ${Math.round(nSize)}px system-ui, sans-serif` + let numInk = ink + if (backing) { + const tw = Math.min(g.measureText(label).width, wText * 0.86) * sx, bw = Math.min(w * 0.94, tw + nSize * 0.6 * sx), bh = nSize * 1.35 + numInk = backing((w - bw) / 2, cy - bh / 2, bw, bh) + } + g.save() + g.scale(sx, 1) + g.fillStyle = css(numInk) + if (backing) { g.shadowColor = numInk[0] > 0.5 ? 'rgba(0,0,0,.55)' : 'rgba(255,255,255,.5)'; g.shadowBlur = 3 } + g.fillText(label, wText / 2, cy, wText * 0.86) + g.restore() + } + // Redondez del lomo: se oscurece hacia los bordes. + const round = g.createLinearGradient(0, 0, w, 0) + round.addColorStop(0, 'rgba(0,0,0,.38)'); round.addColorStop(0.16, 'rgba(0,0,0,.05)'); round.addColorStop(0.42, 'rgba(255,255,255,.12)'); round.addColorStop(0.8, 'rgba(0,0,0,.05)'); round.addColorStop(1, 'rgba(0,0,0,.42)') + g.fillStyle = round + g.fillRect(0, 0, w, STRIP_H) + } + g.setTransform(1, 0, 0, 1, 0, 0) + } + function buildRow(k) { + const row = rows[k], base = rowBase(k), F = SHELF.FRONT, strip = Object.assign(document.createElement('canvas'), { width: stripWidth(), height: STRIP_H }) + const spines = new Shape(), paper = new Shape(), faces = [] + for (const it of row) { + const x0 = it.x, x1 = it.x + it.w, U0 = x0 / rowWidth, U1 = x1 / rowWidth, H = it.h, D = it.d + if (it.face) { + const z = SHELF.FACE_Z, t = it.t, sh = new Shape(), edge = new Shape(), pages = new Shape() + quad(sh, [x0, base + H, z], [it.w, 0, 0], [0, -H, 0], [0, 0, 1]) + quad(edge, [x0, base, z - t], [0, 0, t], [0, H, 0], [-1, 0, 0]) + quad(edge, [x1, base, z], [0, 0, -t], [0, H, 0], [1, 0, 0]) + quad(pages, [x0, base + H, z - t], [it.w, 0, 0], [0, 0, t], [0, 1, 0], [0, 0, it.w, t]) + faces.push({ it, mesh: makeMesh(sh), edge: makeMesh(edge), pages: makeMesh(pages) }) + continue + } + quad(spines, [x0, base + H, F], [it.w, 0, 0], [0, -H, 0], [0, 0, 1], [U0, 0, U1, 1]) + // Los costados son las tapas: un solo color del lomo, no una columna de la tira estirada a lo largo del fondo. + const Um = (U0 + U1) / 2, side = [Um, 0.02, Um, 0.02] + quad(spines, [x0, base, F - D], [0, 0, D], [0, H, 0], [-1, 0, 0], side) + quad(spines, [x1, base, F], [0, 0, -D], [0, H, 0], [1, 0, 0], side) + quad(paper, [x0, base + H, F - D], [it.w, 0, 0], [0, 0, D], [0, 1, 0], [0, it.w, it.w, it.w]) // u: a lo ancho, en el mueble; v: el grosor + } + paintStrip(row, strip) + const b = { k, key: rowKey(row), strip, tex: texFrom(strip), spines: spines.i.length ? makeMesh(spines) : null, paper: paper.i.length ? makeMesh(paper) : null, faces, stale: 0 } + built.set(k, b) + buildNotes(b, k) + // Colores y portadas, de poco en poco: lo de fuera de la vista espera. + for (const it of row) { + const url = it.face ? urlOf(it) : artOf(it) + if (!url) { + if (it.face) plainFor(coverKey(it))(it) + } + // A intervalos, y no durante un gesto: repintar y subir la tira en pleno arrastre daría tirones. + const repaint = () => { + if (built.get(k) !== b || b.stale) return + b.stale = setTimeout(() => { + b.stale = 0 + if (built.get(k) !== b || dead) return + if (pointers.size || velocity) return repaint() + paintStrip(row, strip) + texFrom(strip, b.tex) + draw() + }, 400) + } + b.repaint = repaint + if (!it.face && !it.vol.art && !it.vol.thumb) findPanel(it, () => { + const panel = artOf(it) + if (panel && !arts.has(panel)) loadImage(panel, im => { if (im) { learnPalette(panel, im); learnArt(panel, im, true); repaint() } }) + else repaint() + }) + if (!url) continue + if (it.face) { + if (!covers.has(url)) loadImage(url, im => { + if (!im) return plainFor(url)(it) + learnSize(it, url, im) + learnPalette(url, im) + learnArt(url, im) + covers.set(url, texFrom(im)) + draw() + }) + } else if (arts.has(url)) { + if (palettes[`face:${url}`] === undefined) askFace(url) // su arte salió de la portada de frente, donde no se buscan rostros + } else loadImage(url, im => { + if (!im) return + learnSize(it, url, im) + learnPalette(url, im) + learnArt(url, im, true) + repaint() + }) + } + return b + } + function freeRow(b) { + clearTimeout(b.stale) + gl.deleteTexture(b.tex) + freeMesh(b.spines); freeMesh(b.paper) + for (const f of b.faces) { freeMesh(f.mesh); freeMesh(f.edge); freeMesh(f.pages) } + if (b.notes) { freeMesh(b.notes.mesh); gl.deleteTexture(b.notes.tex) } + built.delete(b.k) + } + const rowKey = row => row ? row.map(i => `${i.work.id}/${i.vol.vol}/${i.x.toFixed(4)}/${i.w.toFixed(4)}/${i.h.toFixed(3)}/${i.d.toFixed(3)}/${i.face ? 1 : 0}/${urlOf(i)}`).join() : '' + function dropAllRows() { for (const b of [...built.values()]) freeRow(b) } + + // Lo que se puede recorrer depende del zoom: de cerca hay más mueble fuera de la pantalla. + function limits() { + const half = visibleH / 2 / zoom + top = SHELF.BOARD + 0.045 - half + bottom = Math.min(top, rowBase(Math.max(rows.length, 1) - 1) - SHELF.BOARD - 0.045 + half) + } + function clampView() { + const hit = y > top || y < bottom + y = Math.max(bottom, Math.min(top, y)) + if (hit) velocity = 0 + const room = (visibleH * (size.w / size.h) / 2) * (1 - 1 / zoom) + x = Math.max(-room, Math.min(room, x)) + } + function setZoom(next, cx = size.w / 2, cy = size.h / 2) { + const z = Math.max(1, Math.min(ZOOM_MAX, next)) + if (z === zoom) return + // El punto bajo los dedos no se mueve. + const per = visibleH / size.h, dx = cx - size.w / 2, dy = cy - size.h / 2 + x += dx * per * (1 / zoom - 1 / z) + y -= dy * per * (1 / zoom - 1 / z) + zoom = z + limits() + clampView() + draw() + } + function layout() { + const rect = container.getBoundingClientRect() + size = { w: Math.max(1, rect.width), h: Math.max(1, rect.height) } + const aspect = size.w / size.h + visibleH = (size.w >= size.h ? rowsLandscape : rowsPortrait) * SHELF.PITCH + rowWidth = visibleH * aspect - 2 * SHELF.SIDE - 0.05 + rows = layoutShelf(works, rowWidth, sizeOf) + // Solo se rehace lo que cambia: al aprender tamaños, casi todas las filas siguen igual. + const key = `${rowWidth.toFixed(3)}:${rows.length}` + if (key !== rowsKey) { + rowsKey = key + dropAllRows() + buildFurniture() + } else for (const b of [...built.values()]) if (b.key !== rowKey(rows[b.k])) freeRow(b) + const was = top + limits() + y = y === was || !y ? top : y + if (focusId) { const k = rows.findIndex(r => r.some(i => i.work.id === focusId)); if (k >= 0) y = rowBase(k) + SHELF.PITCH * 0.42 } + clampView() + } + + // ----- Dibujo ----- + function draw() { + if (dead || raf) return + raf = requestAnimationFrame(paint) + } + function stepInertia(now) { + if (!velocity || pointers.size) return false + const dt = Math.min(120, now - lastMove) + lastMove = now + y += velocity * dt + velocity *= Math.exp(-dt / FRICTION_MS) + clampView() + if (Math.abs(velocity) < 0.00004) velocity = 0 + return !!velocity + } + function stepTilt(now) { + tilt.fade(now) + const on = !still && zoom === 1 + const want = on ? { x: tilt.target.x / MAX_DEG, y: tilt.target.y / MAX_DEG } : { x: 0, y: 0 } + let moving = !!(tilt.target.x || tilt.target.y) && on + for (const k of ['x', 'y']) { + const d = want[k] - tiltNow[k] + if (Math.abs(d) < 0.002) tiltNow[k] = want[k] + else { tiltNow[k] += d * 0.25; moving = true } + } + return moving + } + function paint() { + raf = 0 + if (dead) return + const rect = container.getBoundingClientRect(), dpr = Math.min(devicePixelRatio || 1, 2.5) + const w = Math.max(1, Math.round(rect.width * dpr)), h = Math.max(1, Math.round(rect.height * dpr)) + if (canvas.width !== w || canvas.height !== h) { canvas.width = w; canvas.height = h } + if (rect.width !== size.w || rect.height !== size.h) layout() + const now = performance.now() + let again = stepInertia(now) + if (stepTilt(now)) again = true + if (stepPeek(now)) again = true + gl.viewport(0, 0, w, h) + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) + if (again) draw() + if (!furniture) return + const aspect = rect.width / rect.height + const round = Math.max(Math.abs(tiltNow.x), Math.abs(tiltNow.y)) + const dist = (visibleH / 2 / Math.tan(FOV / 2) / zoom) * (1 + ORBIT_BACK * round) + const M = cameraMatrix([rowWidth / 2 + x, y, SHELF.DEPTH], dist, aspect, ((REST_TILT - tiltNow.x * ORBIT_TILT) * Math.PI) / 180, (-tiltNow.y * ORBIT_YAW * Math.PI) / 180) + gl.uniformMatrix4fv(u.uM, false, M) + lastM = M + gl.uniform2f(u.uSize, w, h) + gl.uniform1f(u.uDim, peek ? (1 - 0.42 * ease(peek.t)) * (1 - 0.6 * ease(peek.fly?.t || 0)) : 1) + if (peek) gl.uniform4f(u.uHide, peek.it.x, peek.it.x + peek.it.w, peek.base - 0.002, peek.base + peek.it.h + 0.002) + gl.activeTexture(gl.TEXTURE0) + gl.uniform1i(u.uKind, 0) + gl.bindTexture(gl.TEXTURE_2D, wood) + drawMesh(furniture) + const nearest = Math.round((-y - SHELF.PITCH / 2) / SHELF.PITCH) + const reach = Math.ceil(visibleH / zoom / SHELF.PITCH / 2) + 1 + for (const b of [...built.values()]) if (Math.abs(b.k - nearest) > reach + 2) freeRow(b) + for (let k = Math.max(0, nearest - reach); k <= Math.min(rows.length - 1, nearest + reach); k++) { + const b = built.get(k) || buildRow(k) + if (b.spines) { + gl.uniform1i(u.uKind, 1) + gl.bindTexture(gl.TEXTURE_2D, b.tex) + drawMesh(b.spines) + } + if (b.notes) { + gl.uniform1i(u.uKind, 1) + gl.bindTexture(gl.TEXTURE_2D, b.notes.tex) + drawMesh(b.notes.mesh) + } + gl.uniform1i(u.uKind, 3) + if (b.paper) drawMesh(b.paper) + for (const f of b.faces) { + const tex = covers.get(coverKey(f.it)), { base } = paletteOf(f.it) + gl.uniform1i(u.uKind, 2) + gl.uniform1f(u.uHas, tex ? 1 : 0) + gl.uniform3fv(u.uColor, base) + if (tex) gl.bindTexture(gl.TEXTURE_2D, tex) + drawMesh(f.mesh) + gl.uniform1i(u.uKind, 4) + drawMesh(f.edge) + gl.uniform1i(u.uKind, 5) + drawMesh(f.pages) + } + } + if (peek) { + // Ya delante, el tomo no sigue al giroscopio: su cámara pierde la inclinación a medida que se acerca. + const k = 1 - ease(peek.t), dk = (visibleH / 2 / Math.tan(FOV / 2) / zoom) * (1 + ORBIT_BACK * round * k) + peekM = cameraMatrix([rowWidth / 2 + x, y, SHELF.DEPTH], dk, aspect, ((REST_TILT - tiltNow.x * ORBIT_TILT * k) * Math.PI) / 180, (-tiltNow.y * ORBIT_YAW * k * Math.PI) / 180) + gl.uniformMatrix4fv(u.uM, false, peekM) + if (peek.fly) drawTable() + drawPeek() + if (peek.fly && peek.fly.t >= 1 && !peek.fly.shot) { + // Último fotograma, tomado ahora que el lienzo aún lo tiene: tapa el cambio al lector. + peek.fly.shot = true + let snap = null + try { snap = canvas.toDataURL('image/jpeg', 0.9) } catch {} + const done = peek.fly.done + setTimeout(() => done?.(snap), 0) + } + } + } + + // ----- Vistazo: el tomo sale recto de la fila, gira y se acerca enseñando la portada ----- + let peek = null, lastM = null, peekM = null, deferLayout = false + const ease = t => (t < 0.5 ? 4 * t * t * t : 1 - (-2 * t + 2) ** 3 / 2) + const lerp3 = (a, b, t) => a.map((v, i) => v + (b[i] - v) * t) + // Caja centrada en el origen con la portada hacia +z y el lomo a la derecha (+x), como un manga: en la fila, la portada mira a la izquierda. + function peekBox(W, H, T, U0, U1) { + const cover = new Shape(), spine = new Shape(), back = new Shape(), paper = new Shape(), X = W / 2, Y = H / 2, Z = T / 2 + quad(cover, [-X, Y, Z], [W, 0, 0], [0, -H, 0], [0, 0, 1]) + quad(spine, [X, Y, Z], [0, 0, -T], [0, -H, 0], [1, 0, 0], [U0, 0, U1, 1]) // en la fila, con el giro, coincide con su trozo de la tira + quad(back, [X, Y, -Z], [-W, 0, 0], [0, -H, 0], [0, 0, -1]) + quad(paper, [-X, Y, -Z], [W, 0, 0], [0, 0, T], [0, 1, 0], [0, 0, W, T]) + quad(paper, [-X, -Y, -Z], [W, 0, 0], [0, 0, T], [0, -1, 0], [0, 0, W, T]) + quad(paper, [-X, -Y, -Z], [0, H, 0], [0, 0, T], [-1, 0, 0], [0, 0, H, T]) + return [cover, spine, back, paper].map(makeMesh) + } + // Dónde queda delante de la cámara: a un lado de la ficha en apaisado, encima en vertical. + function peekTarget(W, H) { + const aspect = size.w / size.h, tan = Math.tan(FOV / 2), dist = visibleH / 2 / tan / zoom, wide = aspect >= 1 + let dd = H / ((wide ? 0.62 : 0.42) * 2 * tan) + if (!wide) dd = Math.max(dd, W / (0.6 * 2 * tan * aspect)) + dd = Math.min(dd, dist * 0.92) + const vh = 2 * tan * dd, vw = vh * aspect + // Sobre el eje de la cámara en reposo (mira algo hacia abajo), y desplazado en su plano. + const tl = (REST_TILT * Math.PI) / 180, T = [rowWidth / 2 + x, y, SHELF.DEPTH], eye = [T[0], T[1] - dist * Math.sin(tl), T[2] + dist * Math.cos(tl)] + const f = [0, T[1] - eye[1], T[2] - eye[2]], n = Math.hypot(f[1], f[2]), F = [0, f[1] / n, f[2] / n], U = [0, -F[2], F[1]] // derecha: +x + const dx = wide ? -vw * 0.2 : 0, dy = wide ? 0 : vh * 0.16 + return [eye[0] + dx, eye[1] + F[1] * dd + U[1] * dy, eye[2] + F[2] * dd + U[2] * dy] + } + function peekInfo(it) { + const vols = it.work.vols || [], i = vols.indexOf(it.vol), ch = it.work.chapterId + const cur = ch ? vols.findIndex(v => (v.chapters || []).includes(ch)) : -1 + const state = !ch ? 'new' : !vols.length ? 'reading' : cur < 0 ? 'unknown' : i < cur ? 'read' : i === cur ? 'reading' : 'new' + return { work: it.work, vol: it.vol, index: i, count: vols.length, state } + } + function startPeek(it, k) { + const b = built.get(k) + if (!b) return + if (peek) freePeek() + const base = rowBase(k), out = !it.face, W = out ? it.d : it.w, H = it.h, T = out ? it.w : it.t + const from = out ? { pos: [it.x + it.w / 2, base + H / 2, SHELF.FRONT - it.d / 2], rot: -Math.PI / 2 } : { pos: [it.x + it.w / 2, base + H / 2, SHELF.FACE_Z - it.t / 2], rot: 0 } + const mid = { pos: [from.pos[0], from.pos[1] + 0.006, from.pos[2] + (out ? it.d + 0.03 : 0.14)], rot: from.rot } + peek = { it, k, b, base, out, W, H, T, from, mid, to: { pos: peekTarget(W, H), rot: 0 }, box: peekBox(W, H, T, it.x / rowWidth, (it.x + it.w) / rowWidth), t: 0, dir: 1, at: performance.now(), tex: null, rank: -1 } + velocity = 0 + // Portada: primero la que ya hay, luego la grande. + const p = peek, shared = covers.get(coverKey(it)) + if (shared) p.shared = shared + else { p.tex = texFrom(plainCover(it)); p.rank = 0 } + ;[it.vol.thumb || it.work.cover, it.vol.art, it.vol.front].forEach((url, rank) => { + if (url) loadImage(url, im => { + if (peek !== p || !im || rank + 1 <= p.rank) return + if (p.tex) gl.deleteTexture(p.tex) + p.tex = texFrom(im); p.rank = rank + 1; p.shared = null + draw() + }) + }) + onPeek?.(peekInfo(it)) + draw() + } + function freePeek() { + if (!peek) return + for (const m of peek.box) freeMesh(m) + if (peek.tex && !gl.isContextLost()) gl.deleteTexture(peek.tex) + peek = null + if (deferLayout) { deferLayout = false; api.relayout() } + } + function unpeek() { + if (!peek || peek.dir < 0 || peek.fly) return + peek.dir = -1 + peek.at = performance.now() + onPeek?.(null) + draw() + } + function peekPose(p) { + if (p.fly) { + const a = p.fly.from, e = ease(p.fly.t) + return { pos: lerp3(a.pos, p.fly.to.pos, e), rot: a.rot + (p.fly.to.rot - a.rot) * e, lean: (a.lean || 0) + (p.fly.to.lean - (a.lean || 0)) * e } + } + const t = p.t + if (t <= PEEK_SLIDE) return { pos: lerp3(p.from.pos, p.mid.pos, ease(t / PEEK_SLIDE)), rot: p.from.rot } + const e = ease((t - PEEK_SLIDE) / (1 - PEEK_SLIDE)) + return { pos: lerp3(p.mid.pos, p.to.pos, e), rot: p.from.rot + (p.to.rot - p.from.rot) * e } + } + function stepPeek(now) { + if (!peek) return false + if (peek.fly) { + const f = peek.fly + f.t = still ? 1 : Math.min(1, f.t + (now - f.at) / FLY_MS) + f.at = now + return f.t < 1 || !f.shot + } + const dt = still ? 1 : (now - peek.at) / (peek.dir > 0 ? PEEK_OPEN_MS : PEEK_CLOSE_MS) + peek.at = now + peek.t = Math.max(0, Math.min(1, peek.t + peek.dir * dt)) + if (peek.dir < 0 && peek.t === 0) { freePeek(); return true } + return peek.t < 1 || peek.dir < 0 + } + function drawPeek() { + const p = peek, pose = peekPose(p), [cover, spine, back, paper] = p.box + gl.uniform4f(u.uHide, 0, 0, 0, 0) + gl.uniform1f(u.uDim, 1) + gl.uniformMatrix4fv(u.uModel, false, modelOf(pose)) + const tex = p.tex || p.shared + gl.uniform3fv(u.uColor, paletteOf(p.it).base) + gl.uniform1i(u.uKind, 2) + gl.uniform1f(u.uHas, tex ? 1 : 0) + if (tex) gl.bindTexture(gl.TEXTURE_2D, tex) + drawMesh(cover) + if (p.out && built.get(p.k) === p.b) { gl.uniform1i(u.uKind, 1); gl.bindTexture(gl.TEXTURE_2D, p.b.tex) } else gl.uniform1i(u.uKind, 4) + drawMesh(spine) + gl.uniform1i(u.uKind, 4) + drawMesh(back) + gl.uniform1i(u.uKind, 5) + drawMesh(paper) + gl.uniformMatrix4fv(u.uModel, false, IDENTITY) + } + // Giro del tomo: primero sobre su eje vertical (sacarlo y enseñar la portada), luego hacia atrás (posarlo en la mesa). + function modelOf({ pos, rot, lean = 0 }) { + const cy = Math.cos(rot), sy = Math.sin(rot), cx = Math.cos(lean), sx = Math.sin(lean) + return new Float32Array([cy, sx * sy, -cx * sy, 0, 0, cx, sx, 0, sy, -sx * cy, cx * cy, 0, pos[0], pos[1], pos[2], 1]) + } + // ----- A la mesa: el tomo se centra y se recuesta como en el lector, y la mesa aparece detrás ----- + let tableTex = null, tableAspect = 1, tableMesh = null + if (table) loadImage(table, im => { if (im && !dead) { tableTex = texFrom(im); tableAspect = im.naturalWidth / im.naturalHeight; draw() } }) + function flyTarget(W, H) { + // Como el encuadre del tomo cerrado en el lector: centrado, con un margen de 14 a 40 px. + const aspect = size.w / size.h, tan = Math.tan(FOV / 2), dist = visibleH / 2 / tan / zoom + const m = Math.max(14, Math.min(40, Math.min(size.w, size.h) * 0.04)) + let dd = (H * 1.04) / (2 * tan * (1 - (2 * m) / size.h)) + dd = Math.max(dd, (W * 1.06) / (2 * tan * aspect * (1 - (2 * m) / size.w))) + dd = Math.min(dd, dist * 0.95) + const tl = (REST_TILT * Math.PI) / 180, T = [rowWidth / 2 + x, y, SHELF.DEPTH], eye = [T[0], T[1] - dist * Math.sin(tl), T[2] + dist * Math.cos(tl)] + const f = [T[1] - eye[1], T[2] - eye[2]], n = Math.hypot(f[0], f[1]) + return { pos: [eye[0], eye[1] + (f[0] / n) * dd, eye[2] + (f[1] / n) * dd], rot: 0, lean: (-(14 - REST_TILT) * Math.PI) / 180 } // en el lector la mesa se ve a 14° + } + function drawTable() { + const f = peek.fly, a = Math.min(1, Math.max(0, (f.t - 0.1) / 0.75)) + if (a <= 0) return + const pose = peekPose(peek), Tz = peek.T / 2 + 0.003 + if (!tableMesh) { + const sh = new Shape(), S = 14 + quad(sh, [-S, S, 0], [2 * S, 0, 0], [0, -2 * S, 0], [0, 0, 1], [-S, S, S, -S]) + tableMesh = makeMesh(sh) + } + gl.uniform4f(u.uHide, 0, 0, 0, 0) // el hueco del tomo en la fila no recorta la mesa + const M = modelOf(pose) + // La mesa queda bajo el tomo: se baja a lo largo de su normal. + M[12] -= M[8] * Tz; M[13] -= M[9] * Tz; M[14] -= M[10] * Tz + gl.uniformMatrix4fv(u.uModel, false, M) + gl.uniform4f(u.uSpot, pose.pos[0], pose.pos[1], pose.pos[2], Math.max(peek.W, peek.H) * 0.9) + const tex = tableTex || wood, k = Math.max(peek.H * 1.6, (peek.W * 2.2) / tableAspect) + gl.uniform1f(u.uHas, tableTex ? 1 : 0) + gl.uniform2f(u.uTab, 1 / (k * tableAspect), -1 / k) + gl.bindTexture(gl.TEXTURE_2D, tex) + gl.uniform1i(u.uKind, 6) + gl.uniform1f(u.uAlpha, ease(a)) + // De fondo, aunque al recostarse se meta tras el mueble; luego el tomo se dibuja encima sin que el mueble lo tape. + gl.enable(gl.BLEND) + gl.disable(gl.DEPTH_TEST) + drawMesh(tableMesh) + gl.enable(gl.DEPTH_TEST) + gl.disable(gl.BLEND) + gl.clear(gl.DEPTH_BUFFER_BIT) + gl.uniform1f(u.uAlpha, 1) + } + function fly(done) { + if (!peek || peek.dir < 0 || peek.fly) return false + const from = peekPose(peek) + peek.fly = { t: 0, at: performance.now(), from, to: flyTarget(peek.W, peek.H), done, shot: false } + onPeek?.(null) + draw() + return true + } + + // Pantalla: píxeles CSS dentro del lienzo. + const toScreen = (q, m = lastM) => { const [nx, ny] = project(m, q); return [((nx + 1) / 2) * size.w, ((1 - ny) / 2) * size.h] } + function itemRect(it, k) { + const base = rowBase(k), z = it.face ? SHELF.FACE_Z : SHELF.FRONT, [ax, ay] = toScreen([it.x, base + it.h, z]), [bx, by] = toScreen([it.x + it.w, base, z]) + return { l: Math.min(ax, bx), r: Math.max(ax, bx), t: Math.min(ay, by), b: Math.max(ay, by) } + } + // El lomo bajo el dedo; con lomos estrechos, el de centro más cercano. + function pickAt(px, py) { + if (!lastM) return null + let best = null + for (const b of built.values()) for (const it of rows[b.k] || []) { + const r = itemRect(it, b.k), slack = 4 + if (px < r.l - slack || px > r.r + slack || py < r.t || py > r.b) continue + const d = Math.abs(px - (r.l + r.r) / 2) / Math.max(1, r.r - r.l) + if (!best || d < best.d) best = { it, k: b.k, d } + } + return best + } + function peekRect() { + if (!peekM || !peek) return null + const { pos } = peekPose(peek), [ax, ay] = toScreen([pos[0] - peek.W / 2, pos[1] + peek.H / 2, pos[2]], peekM), [bx, by] = toScreen([pos[0] + peek.W / 2, pos[1] - peek.H / 2, pos[2]], peekM) + return { l: Math.min(ax, bx), r: Math.max(ax, bx), t: Math.min(ay, by), b: Math.max(ay, by) } + } + function onPeekBook(px, py) { + const r = peekRect() + return !!r && px >= r.l && px <= r.r && py >= r.t && py <= r.b + } + function onTap(cx, cy, wasMoving) { + const r = canvas.getBoundingClientRect(), px = cx - r.left, py = cy - r.top + if (peek?.fly) return + if (peek) { + if (peek.dir > 0 && peek.t >= 1 && onPeekBook(px, py) && onOpen) return onOpen(peekInfo(peek.it)) + return unpeek() + } + if (wasMoving) return // ese toque solo frenó la inercia + const hit = pickAt(px, py) + if (hit) startPeek(hit.it, hit.k) + } + + // ----- Gestos: un dedo recorre, dos acercan ----- + const pointers = new Map() + let pinch = null, track = null, tap = null + const unitsPerPx = () => visibleH / Math.max(1, size.h) / zoom + const spread = () => { const [a, b] = [...pointers.values()]; return { d: Math.hypot(a.x - b.x, a.y - b.y), cx: (a.x + b.x) / 2, cy: (a.y + b.y) / 2 } } + function onDown(e) { + pointers.set(e.pointerId, { x: e.clientX, y: e.clientY }) + try { canvas.setPointerCapture(e.pointerId) } catch {} + tap = pointers.size === 1 ? { x: e.clientX, y: e.clientY, t: e.timeStamp, moving: !!velocity } : null + focusId = null + velocity = 0 + track = null + if (pointers.size === 2) { const s = spread(); pinch = { ...s, zoom } } + else if (pointers.size === 1) track = { x: e.clientX, y: e.clientY, t: e.timeStamp, v: 0 } + draw() + } + function onMove(e) { + const p = pointers.get(e.pointerId) + if (!p) return + const dx = e.clientX - p.x, dy = e.clientY - p.y + p.x = e.clientX + p.y = e.clientY + if (tap && Math.hypot(e.clientX - tap.x, e.clientY - tap.y) > 8) tap = null + if (peek) return // con un tomo fuera, el mueble se queda quieto + if (pinch && pointers.size >= 2) { + const s = spread() + setZoom(pinch.zoom * (s.d / Math.max(1, pinch.d)), s.cx, s.cy) + return + } + if (pointers.size !== 1) return + y += dy * unitsPerPx() + x -= dx * unitsPerPx() + clampView() + if (track) { + const dt = Math.max(1, e.timeStamp - track.t) + track.v = track.v * 0.6 + ((dy * unitsPerPx()) / dt) * 0.4 + track.t = e.timeStamp + } + draw() + } + function onUp(e) { + if (!pointers.delete(e.pointerId)) return + if (pointers.size < 2) pinch = null + if (tap && !pointers.size && e.type === 'pointerup' && e.timeStamp - tap.t < 450) { const { moving } = tap; tap = null; track = null; return onTap(e.clientX, e.clientY, moving) } + tap = null + if (!pointers.size && track && e.timeStamp - track.t < 80 && Math.abs(track.v) > 0.0002) { + velocity = track.v + lastMove = performance.now() + draw() + } + if (pointers.size) track = null + } + canvas.addEventListener('pointerdown', onDown) + canvas.addEventListener('pointermove', onMove) + canvas.addEventListener('pointerup', onUp) + canvas.addEventListener('pointercancel', onUp) + canvas.addEventListener('wheel', e => { + e.preventDefault() + if (peek) return + focusId = null + velocity = 0 + if (e.ctrlKey) return setZoom(zoom * Math.exp(-e.deltaY * 0.01), e.clientX, e.clientY) // pellizco en el panel táctil + y -= e.deltaY * unitsPerPx() + x += e.deltaX * unitsPerPx() + clampView() + draw() + }, { passive: false }) + const onVis = () => { if (document.visibilityState === 'visible') { if (!still) tilt.permit() } else tilt.listen(false) } + document.addEventListener('visibilitychange', onVis) + + const ro = new ResizeObserver(() => { layout(); draw() }) + ro.observe(container) + canvas.addEventListener('webglcontextlost', e => { + e.preventDefault() + built.clear(); covers.clear(); furniture = null; rowsKey = '' + if (peek) { const f = peek.fly; peek = null; onPeek?.(null); f?.done?.(null) } // sus mallas y texturas se perdieron con el contexto + tableMesh = null; tableTex = null + }) + canvas.addEventListener('webglcontextrestored', () => { initGL(); layout(); draw() }) + initGL() + layout() + if (!still) tilt.permit() + draw() + + const api = { + setWorks(next) { works = next; api.relayout() }, + relayout() { + clearTimeout(layoutTimer) + layoutTimer = setTimeout(() => { + if (dead) return + if (peek) { deferLayout = true; return } // con un tomo fuera, el mueble no se reordena hasta que vuelva + layout(); draw() + }, 350) + }, + setVolumes(id, vols) { + const w = works.find(x => x.id === id) + if (!w) return + w.vols = vols + api.relayout() + }, + unpeek, + setLogo, + fly, + focus(id) { focusId = id; layout(); draw() }, + peeked: () => (peek && peek.dir > 0 ? peekInfo(peek.it) : null), + // Centro en pantalla de un tomo (para las pruebas y para enfocar). + screenOf(id, vol) { + if (!lastM) return null + for (const b of built.values()) for (const it of rows[b.k] || []) if (it.work.id === id && (vol === undefined || it.vol.vol === vol)) { const r = itemRect(it, b.k); return { x: (r.l + r.r) / 2, y: (r.t + r.b) / 2, w: r.r - r.l, h: r.b - r.t } } + return null + }, + scrollTo(next) { velocity = 0; y = next; clampView(); draw() }, + setZoom, + draw, + // Para las pruebas. + debug: () => ({ faces: Object.entries(palettes).filter(([k, v]) => k.startsWith('face:') && v).length, facesAsked: Object.keys(palettes).filter(k => k.startsWith('face:')).length, faceWaiting: faceWaiting.length, faceBusy, faceWorker: faceWorker === false ? 'off' : !!faceWorker, rows: rows.map(r => r.map(i => ({ id: i.work.id, vol: i.vol.vol, x: i.x, w: i.w, h: i.h, d: i.d, face: i.face }))), rowWidth, y, x, zoom, velocity, top, bottom, peek: peek && { id: peek.it.work.id, vol: peek.it.vol.vol, t: peek.t, dir: peek.dir, rank: peek.rank, rect: peekRect(), fly: peek.fly ? peek.fly.t : null }, focusId, notes: [...built.values()].map(b => ({ k: b.k, notes: (b.notes?.list || []).map(n => ({ id: n.work.id, x: n.x, w: n.w })) })), logos: logos.size, tilt: { ...tiltNow }, listening: tilt.listening, arts: arts.size, panels: panels.size, built: [...built.keys()], covers: covers.size, palettes: Object.keys(palettes).length, waiting: waiting.length, busy: imgBusy, ctx: !gl.isContextLost() }), + destroy() { + if (faceWorker) faceWorker.terminate() + dead = true + cancelAnimationFrame(raf) + clearTimeout(layoutTimer) + clearTimeout(saveTimer) + ro.disconnect() + tilt.stop() + document.removeEventListener('visibilitychange', onVis) + try { localStorage.setItem(STORE, JSON.stringify(palettes)) } catch {} + freePeek() + freeMesh(tableMesh) + if (tableTex) gl.deleteTexture(tableTex) + dropAllRows() + for (const t of covers.values()) gl.deleteTexture(t) + covers.clear() + freeMesh(furniture) + gl.deleteTexture(wood) + gl.deleteProgram(prog) + gl.getExtension('WEBGL_lose_context')?.loseContext() + canvas.remove() + }, + } + canvas.shelf = api + return api +} diff --git a/app/public/style.css b/app/public/style.css index e4d5e54..8bc42d4 100644 --- a/app/public/style.css +++ b/app/public/style.css @@ -460,6 +460,11 @@ body.reading #netbanner { display: none; } @media (max-width: 640px) { .kv { grid-template-columns: 1fr; gap: 0; } .kv dd { margin-bottom: 8px; } .banner { height: 120px; } } .chapters .meta .cdate.approx { opacity: .7; } /* Libro 3D: el canvas dibuja el libro y #pages sigue debajo de los dedos, invisible, para los gestos. */ +#shelf3d { position: fixed; inset: 0; z-index: 0; touch-action: none; background: #17100b; } +#shelf3d canvas { display: block; width: 100%; height: 100%; } +.shelfback { position: fixed; z-index: 2; top: calc(10px + env(safe-area-inset-top)); left: calc(10px + env(safe-area-inset-left)); } +.shelfnote { position: fixed; z-index: 2; left: 50%; bottom: calc(14px + env(safe-area-inset-bottom)); transform: translateX(-50%); margin: 0; padding: 6px 12px; max-width: calc(100vw - 32px); border-radius: 8px; background: rgb(0 0 0 / .62); color: #fff; font-size: .85rem; text-align: center; } +.libhead { justify-content: space-between; align-items: center; } #b3d { position: fixed; inset: 0; z-index: 0; } #b3d[hidden] { display: none; } #b3d canvas { display: block; width: 100%; height: 100%; } @@ -481,3 +486,19 @@ body.reading #netbanner { display: none; } .reader.b3d.b3dcrop { background: #000; } .reader.b3d.b3dcrop > #b3d { display: none; } .reader.b3d.b3dcrop > #pages img { visibility: visible; } +/* Vistazo del estante: junto al tomo sacado, a la derecha en apaisado y abajo en vertical */ +.shelfpeek { position: fixed; z-index: 3; right: calc(4vw + env(safe-area-inset-right)); top: 50%; width: min(38vw, 380px); transform: translate(12px, -50%); opacity: 0; transition: opacity .22s, transform .22s; padding: 18px 18px 16px; border-radius: 14px; background: rgb(20 14 10 / .78); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); color: #f4ede4; box-shadow: 0 10px 30px rgb(0 0 0 / .4); } +.shelfpeek.on { opacity: 1; transform: translate(0, -50%); } +.shelfpeek .ptitle { margin: 0 34px 4px 0; font-size: 1.2rem; line-height: 1.25; } +.shelfpeek .psub, .shelfpeek .pwhere { margin: 4px 0; color: #cdbfae; font-size: .9rem; } +.shelfpeek .pbar { height: 4px; margin: 12px 0 6px; border-radius: 2px; background: rgb(255 255 255 / .16); overflow: hidden; } +.shelfpeek .pbar i { display: block; height: 100%; background: var(--accent); } +.shelfpeek .pacts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; } +.shelfpeek .pacts .btn { flex: 1 1 auto; justify-content: center; } +.shelfpeek .peekx { position: absolute; top: 10px; right: 10px; width: 32px; height: 32px; display: grid; place-items: center; border: 0; border-radius: 50%; background: rgb(255 255 255 / .1); color: inherit; cursor: pointer; } +@media (orientation: portrait) { + .shelfpeek { left: calc(12px + env(safe-area-inset-left)); right: calc(12px + env(safe-area-inset-right)); top: auto; bottom: calc(12px + env(safe-area-inset-bottom)); width: auto; transform: translateY(12px); } + .shelfpeek.on { transform: none; } +} +.handoff { position: fixed; inset: 0; z-index: 60; width: 100vw; height: 100vh; object-fit: cover; pointer-events: none; transition: opacity .35s ease; } +.handoff.out { opacity: 0; } diff --git a/app/public/sw.js b/app/public/sw.js index bc4a48a..b0783e6 100644 --- a/app/public/sw.js +++ b/app/public/sw.js @@ -2,7 +2,7 @@ // dispositivo" (caché OFFLINE, la llena app.js) se leen sin red. const SHELL = 'shell-v1' const OFFLINE = 'offline-v1' -const SHELL_FILES = ['/', '/app.js', '/style.css', '/book3d.js', '/icon.svg', '/manifest.webmanifest', '/icon-192.png', '/icon-512.png'] +const SHELL_FILES = ['/', '/app.js', '/style.css', '/book3d.js', '/shelf3d.js', '/animeface.js', '/animeface-cascade.json', '/fonts/caveat.woff2', '/fonts/patrickhand.woff2', '/fonts/kalam.woff2', '/fonts/gochihand.woff2', '/fonts/indieflower.woff2', '/fonts/permanentmarker.woff2', '/fonts/shadows.woff2', '/icon.svg', '/manifest.webmanifest', '/icon-192.png', '/icon-512.png'] // Se guarda la portada tal como la sirve el servidor y justo las versiones de app.js y style.css que // enlaza (?v=…); cache: 'reload' para no copiar lo que tenga la caché HTTP (un proxy puede alargarla horas). @@ -21,7 +21,7 @@ self.addEventListener('install', e => { }) self.addEventListener('activate', e => { e.waitUntil(caches.keys() - .then(keys => Promise.all(keys.filter(k => k !== SHELL && k !== OFFLINE).map(k => caches.delete(k)))) + .then(keys => Promise.all(keys.filter(k => k !== SHELL && k !== OFFLINE && !k.startsWith('shelf-')) // shelf-*: lo que guarda el estante (shelf3d.js).map(k => caches.delete(k)))) .then(() => self.clients.claim())) }) diff --git a/app/server.js b/app/server.js index 6d05d65..218ded3 100644 --- a/app/server.js +++ b/app/server.js @@ -17,6 +17,7 @@ import { setupConnectivity } from './connectivity.js' import { setupMeta } from './meta.js' import { setupVolumes } from './volumes.js' import { setupCredits } from './credits.js' +import { setupShelf } from './shelf.js' import { setupBooks, isBookId } from './books.js' const PORT = Number(process.env.PORT || 3352) @@ -834,7 +835,7 @@ const requireUser = req => { return u } -const MIME = { '.html': 'text/html; charset=utf-8', '.js': 'text/javascript; charset=utf-8', '.css': 'text/css; charset=utf-8', '.svg': 'image/svg+xml', '.webmanifest': 'application/manifest+json', '.png': 'image/png' } +const MIME = { '.html': 'text/html; charset=utf-8', '.js': 'text/javascript; charset=utf-8', '.css': 'text/css; charset=utf-8', '.svg': 'image/svg+xml', '.webmanifest': 'application/manifest+json', '.png': 'image/png', '.json': 'application/json', '.woff2': 'font/woff2', '.txt': 'text/plain; charset=utf-8' } // index.html enlaza app.js y style.css con ?v=: si un proxy delante cambia el // no-cache por una caché larga (Nginx Proxy Manager con «Cache Assets»), cada versión nueva tiene otra // URL y el navegador no se queda con la vieja. Los archivos no cambian mientras el contenedor vive. @@ -843,6 +844,7 @@ const INDEX_HTML = fs.readFileSync(path.join(PUBLIC_DIR, 'index.html'), 'utf8') .replace('src="/app.js"', `src="/app.js?v=${assetVersion('app.js')}"`) .replace('href="/style.css"', `href="/style.css?v=${assetVersion('style.css')}"`) .replace('', ``) + .replace('', ``) .replace('', ``) function serveStatic(res, pathname) { let file = path.join(PUBLIC_DIR, path.normalize(pathname).replace(/^(\.\.[/\\])+/, '')) @@ -924,6 +926,7 @@ async function route(req, res) { if (p.startsWith('/api/bans') && security.route(p, method, req, res, json) !== false) return if ((await features.route(p, method, q, req, res, user)) !== false) return if ((await credits.route(p, method, req, res, user)) !== false) return + if (shelf.route(p, method, res, user) !== false) return if ((await upscale.route(p, method, req, res)) !== false) { // Pedir el reescalado (o el automático) lo pone en la biblioteca de quien lo pide. if (method === 'POST' && (m = /^\/api\/upscale\/([^/]+)(\/auto)?$/.exec(p)) && db.prepare('SELECT 1 FROM downloads WHERE manga_id = ?').get(m[1])) linkDownload(user.id, m[1]) @@ -996,6 +999,9 @@ async function route(req, res) { if ((m = /^\/api\/volumes\/([^/]+)$/.exec(p)) && MANGA_ID.test(m[1]) && method === 'GET') { return json(res, 200, { volumes: isBookId(m[1]) ? [] : await volumes.list(m[1], lang) }) } + if ((m = /^\/api\/logo\/([^/]+)$/.exec(p)) && MANGA_ID.test(m[1]) && method === 'GET') { + return json(res, 200, { logo: isBookId(m[1]) ? null : await volumes.logo(m[1], lang).catch(() => null) }) + } if ((m = /^\/api\/tome\/([^/]+)\/([^/]+)\/(front|back)$/.exec(p)) && method === 'GET') { let vol try { vol = decodeURIComponent(m[2]) } catch { throw new HttpError(404, 'Cubierta no encontrada') } @@ -1170,6 +1176,7 @@ const library = setupLibrary({ db, HttpError, json, readBody, MANGA_ID, CHAPTER_ net.whenOnline(() => pumpDownloads()) const meta = setupMeta({ db, md, sourceOf, fetchMangaFull, HttpError, json, net, decode, imgUrl, UA, prepareBanner }) const credits = setupCredits({ db, HttpError, json, readBody, MANGA_ID, CHAPTER_ID }) +const shelf = setupShelf({ db, json, isBookId, downloadCover, MY_DOWNLOADS }) const volumes = setupVolumes({ md, sourceOf, fetchMangaFull, stored: meta.stored, mdMatches: meta.mdMatches, muVolumes: meta.muVolumes, similar: meta.similar, miSearch: q => mi.search(q), imgUrl, DATA_DIR, UA, HttpError, net }) const clips = setupClips({ db, DATA_DIR, HttpError, json, readBody, MANGA_ID, CHAPTER_ID, upscale }) diff --git a/app/shelf.js b/app/shelf.js new file mode 100644 index 0000000..f764faf --- /dev/null +++ b/app/shelf.js @@ -0,0 +1,36 @@ +// Estante 3D: las obras de un usuario que pueden ir en el mueble. Los tomos de cada una se piden aparte (/api/volumes), porque pueden tardar. +import { hasNoVolumes } from './volumes.js' + +export function setupShelf({ db, json, isBookId, downloadCover, MY_DOWNLOADS }) { + function works(userId) { + const out = new Map() + const add = (id, fields) => { + const w = out.get(id) || { id, title: '', cover: null, last: 0, chapterId: null, page: 0, lang: null } + w.title ||= fields.title || '' + w.cover ||= fields.cover || null + w.last = Math.max(w.last, fields.at || 0) + if (fields.chapterId) Object.assign(w, { chapterId: fields.chapterId, page: fields.page || 0, lang: fields.lang || null }) + out.set(id, w) + } + for (const r of db.prepare('SELECT manga_id, manga_title, cover, chapter_id, page, lang, updated_at FROM progress WHERE user_id = ?').all(userId)) { + add(r.manga_id, { title: r.manga_title, cover: r.cover, chapterId: r.chapter_id, page: r.page, lang: r.lang, at: r.updated_at }) + } + for (const r of db.prepare('SELECT manga_id, title, cover, last_new_at, created_at FROM follows WHERE user_id = ? AND active = 1').all(userId)) { + add(r.manga_id, { title: r.title, cover: r.cover, at: r.last_new_at || r.created_at }) + } + for (const r of db.prepare(`SELECT manga_id, title, folder, updated_at, json_extract(meta, '$.manga.cover') meta_cover FROM downloads WHERE ${MY_DOWNLOADS}`).all(userId)) { + add(r.manga_id, { title: r.title, cover: downloadCover(r.manga_id, r.folder, r.meta_cover), at: r.updated_at }) + } + for (const r of db.prepare('SELECT i.manga_id, i.title, i.cover, i.added_at FROM list_items i JOIN lists l ON l.id = i.list_id WHERE l.user_id = ?').all(userId)) { + add(r.manga_id, { title: r.title, cover: r.cover, at: r.added_at }) + } + const typeOf = db.prepare('SELECT type FROM manga_meta WHERE manga_id = ?') + return [...out.values()].filter(w => !isBookId(w.id) && !hasNoVolumes(typeOf.get(w.id)?.type)).sort((a, b) => b.last - a.last) + } + function route(p, method, res, user) { + if (p !== '/api/shelf' || method !== 'GET') return false + json(res, 200, { works: works(user.id) }) + return true + } + return { route, works } +} diff --git a/app/volumes.js b/app/volumes.js index cef66dd..a8f05be 100644 --- a/app/volumes.js +++ b/app/volumes.js @@ -454,6 +454,28 @@ export function workTitle(title) { /** Manhwa y manhua no se publican por tomos: se leen por capítulos. */ export const hasNoVolumes = (type, original) => ['manhwa', 'manhua', 'webtoon'].includes(String(type || '').toLowerCase()) || ['ko', 'zh', 'zh-hk'].includes(original) +// Palabras de un título para comparar con nombres de archivo: sin tildes ni vocales largas («Sōsō» y «Sousou» son «soso»). +const LOGO_STOP = new Set(['the', 'and', 'wa', 'no', 'ga', 'wo', 'ni', 'de', 'to']) +const LOGO_EXTRA = new Set(['logo', 'logotype', 'wordmark', 'manga', 'anime', 'series', 'title', 'english', 'japanese', 'png', 'svg', 'webp', 'file', 'the', 'and', 'tv', 'version', 'new', 'old', 'int', 'international', 'with', 'colour', 'color', 'gradient', 'variant', 'alt', 'alternative', 'text', 'black', 'white', 'transparent', 'vector', 'official']) +export const logoWords = s => String(s).normalize('NFD').replace(/\p{M}/gu, '').toLowerCase().replace(/ou/g, 'o').replace(/uu/g, 'u').replace(/oo/g, 'o').split(/[^\p{L}\p{N}]+/u).filter(w => w.length >= 2 && !LOGO_STOP.has(w) && !/^\d+$/.test(w)) +/** El archivo que mejor encaja con algún nombre de la obra: tiene «logo», casi todas las palabras del nombre y nada más que relleno. */ +export function pickLogo(files, names) { + let best = null, bestScore = 0 + files.forEach((file, i) => { + if (!/\.(png|svg|webp)$/i.test(file)) return + const fw = logoWords(file.replace(/^File:/, '')) + if (!fw.includes('logo')) return + names.forEach((name, k) => { + const nw = logoWords(name) + if (!nw.length || nw.join('').length < 4) return + const hit = nw.filter(w => fw.includes(w)).length / nw.length + const stray = fw.filter(w => !nw.includes(w) && !LOGO_EXTRA.has(w)) + const score = hit + (k ? 0 : 0.05) - i * 0.001 // el nombre principal manda + if (hit >= 0.66 && !stray.length && score > bestScore) { best = file; bestScore = score } + }) + }) + return best +} export const wikiKey = t => String(t).toLowerCase().replace(/×/g, 'x').replace(/[^\p{L}\p{N}]/gu, '') export function setupVolumes({ md, sourceOf, fetchMangaFull, stored, mdMatches, muVolumes, similar, miSearch, imgUrl, DATA_DIR, UA, HttpError, net }) { @@ -642,6 +664,44 @@ export function setupVolumes({ md, sourceOf, fetchMangaFull, stored, mdMatches, return inflight.get(key) } + // ---------- Logo de la obra (Wikimedia Commons), para el título del lomo ---------- + const COMMONS = 'https://commons.wikimedia.org/w/api.php' + let commonsRest = 0 // si Commons pide calma, no se le pregunta nada en un rato (y no se guarda el fallo) + async function commonsGet(params) { + if (Date.now() < commonsRest) throw new HttpError(503, 'Wikimedia Commons pidió esperar') + await turn() + net.guard() + const r = await fetch(`${COMMONS}?${new URLSearchParams({ ...params, format: 'json', formatversion: '2', maxlag: '5' })}`, { headers: { 'User-Agent': UA }, signal: AbortSignal.timeout(30000) }).catch(() => { net.failed(); return null }) + const text = r?.ok ? await r.text() : '' + if (r?.status === 429 || (r?.ok && !text.startsWith('{')) || /"code":\s*"maxlag"/.test(text)) commonsRest = Date.now() + 10 * 60e3 + const data = text.startsWith('{') ? JSON.parse(text) : null + if (!data || data.error) throw new HttpError(502, 'No se pudo consultar Wikimedia Commons') + return data + } + async function commonsLogo(names) { + const queries = [...new Set([...names.slice(0, 3), ...names.slice(0, 1).flatMap(n => logoWords(n).sort((a, b) => b.length - a.length).slice(0, 1))])] + for (const q of queries) { + const res = await commonsGet({ action: 'query', list: 'search', srnamespace: '6', srsearch: `${q} logo`, srlimit: '15' }) + const best = pickLogo((res.query?.search || []).map(h => h.title), names) + if (!best) continue + const info = await commonsGet({ action: 'query', titles: best, prop: 'imageinfo', iiprop: 'url|size|mime', iiurlwidth: '960' }) // Wikimedia solo sirve miniaturas de ciertos anchos (960 sí, 800 no) + const ii = info.query?.pages?.[0]?.imageinfo?.[0] + if (ii && ii.width >= ii.height * 1.2) return ii.thumburl || ii.url || null // un logotipo es apaisado + } + return null + } + // Una vez por obra; lo no encontrado se vuelve a buscar a la semana. + function logo(mangaId, lang) { + return stored(`logo:${mangaId}`, v => (v ? 60 : 7) * DAY, async () => { + const { manga } = await fetchMangaFull(mangaId, lang) + if (hasNoVolumes(manga.type)) return null + const ids = sourceOf(mangaId) === 'md' ? [mangaId] : (await mdMatches(mangaId).catch(() => [])).slice(0, 1) + const data = ids.length ? await mdVolumes(ids[0], lang).catch(() => null) : null + const names = [...new Set([workTitle(manga.title), manga.title, ...(data?.enTitles || []), ...(data?.roTitles || [])])].filter(Boolean) + return commonsLogo(names) + }, true) + } + // ---------- API ---------- async function list(mangaId, lang) { const { manga, chapters } = await fetchMangaFull(mangaId, lang) @@ -680,12 +740,16 @@ export function setupVolumes({ md, sourceOf, fetchMangaFull, stored, mdMatches, if (!groups.has(vol)) groups.set(vol, []) groups.get(vol).push(chapters[i].id) }) + // Páginas del tomo, para el grosor del lomo en el estante. Si falta algún capítulo por contar, no se da. + const pagesOf = ids => { let n = 0; for (const id of ids) { const p = chapters.find(c => c.id === id)?.pages; if (!(p > 0)) return null; n += p } return n } return [...groups.keys()].sort(volOrder).map(vol => { const cover = data?.covers[vol] return { vol, chapters: groups.get(vol), + pages: pagesOf(groups.get(vol)), thumb: cover ? imgUrl(`https://uploads.mangadex.org/covers/${mdId}/${cover.file}.256.jpg`) : null, + art: cover ? imgUrl(`https://uploads.mangadex.org/covers/${mdId}/${cover.file}.512.jpg`) : null, // para sacar el arte del lomo front: mdId && VOL.test(vol) ? `/api/tome/${mdId}/${encodeURIComponent(vol)}/front` : null, back: mdId && VOL.test(vol) ? `/api/tome/${mdId}/${encodeURIComponent(vol)}/back` : null, } @@ -702,5 +766,5 @@ export function setupVolumes({ md, sourceOf, fetchMangaFull, stored, mdMatches, res.writeHead(200, { 'Content-Type': imageKind(head) || 'application/octet-stream', 'Cache-Control': 'private, max-age=2592000', 'X-Content-Type-Options': 'nosniff' }) fs.createReadStream(file).pipe(res) } - return { list, sendFace } + return { list, sendFace, logo: async (mangaId, lang) => { const u = await logo(mangaId, lang); return u ? imgUrl(u) : null } } }